Cochon qui s'en dédie
Ainsi, au lieu d'appeler le sélecteur de fichier de MagiC à la main, Il suffit de faire :
Pdomain(n) ou ~GEMDOS(281,W:n)
Deuxième remise en cause : la variable d'environnement. Je vous avais
expliqué qu'elle était totalement absconse pour OLGA & cie. Et bien
ce n'est pas totalement vrai. Faut toujours l'écrire à la main, mais si
vous voulez économiser de la mémoire, je vous
conseille d'utiliser celle d'OLGA. Cette application a la
faculté de quitter elle-même la mémoire quand aucune application la
gérant est en mémoire. Par contre, préférez le lancement en AUTO,
ACC ou dossier START de MagiC car BubbleGEM n'utilise pas le Daemon avec la variable
d'environnement. Donc dans MAGX.INF, écrivez :
#_ENV OLGAMANAGER=chemin+nom de OLGADans MINT.CNF, remplacez #_ENV par setenv.
Pour récupérer le chemin et nom complet d'OLGA à partir de la variable d'environnement, on utilise la fonction SHEL_ENVRN(adresse%,chaine$). Pour OLGA, ça donnera :
~SHEL_ENVRN(adresse%,"OLGAMANAGER=") ! n'oubliez pas le "=" IF adresse%>0 nom_olga$=CHAR{adresse%} ENDIFEn C, adresse% est un pointeur sur un pointeur. Vu que j'ai pas trop confiance dans cette fonction GFA, la voici réécrite par votre serviteur :
get_env("OLGAMANGER="+CHR$(0),nom_olga$) ' PROCEDURE get_env(get_env$,VAR ret_env$) ' ret_env$=CHR$(0) ' IF aa_start%>0 ! aa_start% est l'adresse ' d'un buffer mémoire de 256 octets INT{ADD(GCONTRL,2)}=0 INT{ADD(GCONTRL,4)}=1 INT{ADD(GCONTRL,6)}=2 INT{ADD(GCONTRL,8)}=0 ' LONG{ADDRIN}=aa_start% LONG{ADD(ADDRIN,4)}=V:get_env$ ' GEMSYS 125 ' IF LONG{aa_start%}>0 ret_env$=CHAR{{aa_start%}}+CHR$(0) ! pointeur sur pointeur ! ENDIF ENDIF ' RETURNAyant récupéré le nom de fichier complet d'OLGA, vous pouvez maintenant faire un SHEL_WRITE. Puis soit attendre que APPL_FIND() trouve OLGA pour se déclarer à OLGA, soit le faire plus loin, avec EVNT_MULTI et MU_TIMER avec un flag.
La question bête...
~GEMDOS(14,W:SUB(ASC(nom_prg$),65)) CHDIR LEFT$(nom_prg$,RINSTR(nom_prg$,"\"))+CHR$(0) ' lancement petit délai si SHEL_WRITE ' ~GEMDOS(14,W:SUB(ASC(votre_chemin$),65)) CHDIR votre_chemin$+CHR$(0)nom_prg est le nom complet (avec chemin) du programme à lancer, terminé comme d'hab par CHR$(0).
votre_chemin$=CHR$(ADD(GEMDOS(25),65)+":"+DIR$(SUCC(GEMDOS(25))+"\"Faites attention, cette chaine ne se termine pas par un null-byte. A vous de le mettre en cas de besoin.
Secondement, il va de soi que vous ne monopolisez pas toute la mémoire avec votre application. Je vous conseille de lire un article d'un certain Féroce Lapin (ST Magazine numéro 63 page 60, Cubase en couverture). Tous mes programmes s'en inspirent. Vous pouvez donc regarder mes sources pour voir ça en réel (par exemple dans le dossier BONUX du numéro 4 de STimulus).
Qu'il est paresseux, l'animal !
Après la demande à MagxDesk, et celui-ci va lancer le programme selon les
préférences que vous avez définies dans le bureau (Déclarer une
application).
Petit délice : si vous avez indiqué le mode Single pour ce programme,
MagixDesk va le lancer en mode Single. C'est la seule manière de lancer les programmes
en vrai monotache. Il existe un code spécial pour SHEL_WRITE (101) pour le mode Single,
mais je n'ai jamais réussi à le faire marcher. Ceci est probablement
réservé à l'application dont l'ap_id&=0 et impose quelques manips de plus
(justement au niveau de l'ap_id&).
Ça donne :
CHAR{nom_prg%}=nom_prg$ CHAR{commande%}=commande$ ! au format Pascal ' INT{buf_adr%}=&H4722 ! AV_STARTPROG INT{buf_adr%+2}=ap_id& ! l'identificateur de votre application INT{buf_adr%+4}=0 LONG{buf_adr%+6}=nom_prg% ! pointeur vers le chemin+nom LONG{buf_adr%+10}=commande% ! pointeur vers la commande INT{buf_adr%+14}=0 ! ? la doc-dev de MagiC indique 0 ' ! mais d'autres valeurs sont possibles ~APPL_WRITE(0,16,buf_adr%)buf_adr% est un buffer de 16 octets situé en mémoire globale GEMDOS(68,L:taille%,W:32) si possible. nom_prg% un buffer de 256 octets contenant le nom complet de l'application. A noter que ça peut être n'importe quoi : c'est MagxDesk qui se débrouille après (ACC, TTP, PRG, etc). commande% est un buffer de 128 octets qui contiendra une chaîne au format Pascal (CHR$(SUCC(LEN(commande$)))+commande$+CHR$(0)) qui ne doit pas dépasser 128 octets (sinon ça va foirer).
On vérifie l'aileron arrière et on se lance !
ret&=EXEC(0,nom_prg$,commande_formate$,env$)Quoiqu'il arrive, c'est un lancement en monotâche : si vous faites cela en mutlitâche, votre application sera "endormie" jusqu'à ce que vous quittiez le programme que vous avez lancé. Il y a plusieurs modalités à cette fonction (c'est en réalité un GEMDOS(75,W:0,...) ). A vous de voir les doc-dev.
ret& est la variable de retour de l'appel au programme. Si par exemple dans le programme lancé vous quittez avec QUIT 3, alors vous obtiendrez ret&=3 dans votre application. Cool non ? Je m'en sert pour interfacer Joe avec ses modules en monotâche : selon la variable de retour du module, Joe va charger ce qu'il y a dans le clipboard sur disque. Et qu'est-ce qu'il y a dans le clipboard sur disque ? Hein ? Les tags que le module a produits !
Il est préférable de terminer vos chaînes par un nullbyte. C'est surtout important pour commande_formate$ (toujours au format Pascal, cf ci-dessus), et pour env$.
env$ va inscrire des variables d'environnement dans le tampon AES, du style GFALIB=chemin+nom... env$ n'et pas limitée à 128 caractères, ce qui permet d'en mettre pas mal. Chaque expression est terminée par un nullbyte, la fin de env$ est terminée par 2 nullbytes. C'est en général pas très utilisé sauf si...
Petit problème : votre commande mise au format Pascal dépasse les 128
caractères. Ça ne marche plus et il faut ruser. Ou va-t-on fourrer les
paramètres à donner au programme à lancer ? Bravo ! dans
env$. Cela donne pour préparer cette chaîne d'environnement
(tiré des docs d'ERGO-PRO donc à vérifier) :
commande$=commande$+" " a&=INSTR(commande$," ") ! séparation des arguments par des nullbytes WHILE a& MID$(commande$,a&,1)=CHR$(0) a&=INSTR(commande$," ") WEND ' env$="ARGV=0"+CHR$(0) env$=env$+nom_prg$+CHR$(0) env$=env$+cmd$+CHR$(0)+CHR$(0) ' commande$=CHR$(127)+CHR$(0) ! pour indiquer qu'on doit aller dans env$On lance avec ces paramètres, et dans le programme "fils", on va récupérer la commande avec les argv bien connus du C. En GFA, je n'ai jamais fait, mais on pourrait regarder le tampon AES et récupérer avec la fonction get_env$ citée plus haut la commande.
Pour récupérer la commande classiquement, on effectue :
a&=BYTE{BASEPAGE+128} IF a&<127 commande$=CHAR{BASEPAGE+129} ENDIFAttention, il faut récupéer cette chaîne avant tout appel au niveau des fichiers genre OPEN, FILESELECT et surtout EXIST (cette fonction est à proscrire, utilisez celle que je vous ai donnée dans le numéro 2 de notre si merveilleux Fanzine :) ).
Accélération, le vent fouette le visage
(sans parler des mouches qui s'y écrasent).
~SHEL_WRITE(mode&,wisgr&,wiscr&,nom_prg$,commande_formate$)La voici écrite plus décemment :
PROCEDURE shl_write(mode&,wisgr&,wiscr&,nom_prg$,commande_formate$) ' GCONTRL(0)=121 GCONTRL(1)=3 GCONTRL(2)=1 GCONTRL(3)=2 GCONTRL(4)=0 ' GINTIN(0)=mode& GINTIN(1)=wisgr& GINTIN(2)=wiscr& ' ~FRE(0) ! petite sécurité, on provoque un garbage collection avant ' ! que le GFA ne le fasse pour nous (important quand on fait des V:chaine$) ' IF mode&>256 ! je vais vous expliquer ADDRIN(0)=shel_write_buffer% ADDRIN(1)=V:commande$ ELSE ADDRIN(0)=V:nom_prg$ ADDRIN(1)=V:commande$ ENDIF ' GEMSYS ' IF GINTOUT(0)=0 ' alerte = problème au lancement ENDIF ' RETURNComme d'hab les chaine$ sont au format C, voire Pascal. Les mode& qui nous intéressent sont :
Ici, plus besoin de s'occuper de la taille de la commande$, elle a été étendue à 256 caractères voire gérée si trop grande par SHEL_WRITE lui-même.
Comportement de cette fonction ? A vous d'expérimenter... Ça donne des
choses magnifiques comme par exemple en mode Single, vous lancez une application fille en
multitâche.
A noter que SHEL_WRITE pour le monoTOS marche sans problèmes (sauf les lancements
d'accessoires). Seulement il faut quitter de vous-même votre application, et au lieu de
retourner sur le bureau, l'application fille sera automatiquement lancée.
Tel un Faucon, je survole et matrîse le sujet.
Si les bits 8,9,10 et 11 de mode& sont allumés (c'est à dire mode& supérieur à 256), SHEL_WRITE considérera en C qu'il tombe sur un pointeur d'une structure plutôt d'un pointeur d'une chaîne de texte (nom_prg$). Cela donne ce petit artifice en GFA.
Elément | Nature | Contenu |
0 | LONG{} (32 bits) | Adresse de la chaîne de texte correspondant à nom_prg$ |
1 | WORD{} (16 bits) | Valeur de Psetlimit (en Ko ?) |
2 | WORD{} (16 bits) | Valeur de Prenice (-20 à +20) |
3 | LONG{} (32 bits) | Adresse de la chaîne contenant le chemin par défaut |
4 | LONG{} (32 bits) | Adresse de la chaîne correspondant à env$ |
PS : j'ai un doute mais il semblerait que la variable de retour de shel_write indique l'ap_id& de l'application lancée. A vérifier.
On se retourve dans 3 mois !
Rajah Lone
écrit le 8 Septembre 1998