GFA
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
Le Deal du moment :
Display Star Wars Unlimited Ombres de la Galaxie : ...
Voir le deal

Stimulus 09 C'est la rentrée !!!

Aller en bas

Stimulus 09  C'est la rentrée !!! Empty Stimulus 09 C'est la rentrée !!!

Message par Shadow272 Lun 16 Nov - 15:28

C'est la rentrée !!!
Programmation GFA (Cool



Après les vacances, c'est encore les vacances : il suffit pour cela d'allumer votre bon vieil Atari. Un petit jeu sympa comme on n'en fait plus depuis longtemps ? on Calamuse un chouillat ? on s'adonne à la programmation GEM ? Oui ? Alors aujourd'hui, ça va être façon dolce vita...
Le confort avant tout...
Vous connaissez le protocle DHST ? Moi non plus, jusqu'à ce que mon correspondant allemand me demande de l'implémenter dans mon bébé de Joe version 1.46 . Il s'agit en fait de la même chose que les raccourcis pour lancer les documents dans le menu "démarrer" de zin00. Assez pratique, n'est-ce pas ? Mais savez-vous qu'on peux le faire nous aussi, pauvres peguenots d'Ataristes, grâce à Monsieur Thomas MUCH.
Vous aurez conclu que ce protocole Document HiSTory est géré par le petit Start (à partir de la version 8.0). MultiStrip le gère aussi, pour ne pas faire de jaloux Smile

Aussi, au lieu de regarder l'ap_id& de START ou de MultiStrip (lequel est le serveur DHST ?), il faut aller regarder dans la Cookie-Jar et chercher la chaine "DHST". La valeur du cookie contient (dans le mot de poids faible) l'ap_id& du serveur DHST. C'est aussi simple. Je vous donne ma fonction pour regarder les cookies :

FUNCTION test_cookie(cookie_name$,VAR cookie_valeur%)
LOCAL read_cook%,nom_cook%,cookie%
'
nom_cook%=CVL(cookie_name$)
cookie%=LPEEK(&H5A0)
cookie_valeur%=0
'
IF cookie%<>0
REPEAT
read_cook%=LPEEK(cookie%)
cookie_valeur%=LPEEK(ADD(cookie%,4))
ADD cookie%,8
UNTIL read_cook%=0 OR read_cook%=nom_cook%
IF read_cook%=nom_cook%
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ELSE
RETURN FALSE
ENDIF
ENDFUNC
Comme cela, on sait qui appeler avec notre sempiternel APPL_WRITE. Il faudra donc utiliser le tube GEM, et donner au serveur DHST une adresse vers une structure. En C, cela donne la structure (qui doit être en mémoire partagée) :
typedef struct
{
char *appname, // adresse vers le nom de l'application gérant le document
*apppath, // adresse vers le nom complet (chemin+nom) de l'appliction
*docname, // adresse vers le nom du document
*docpath; // adresse vers le nom complet (chemin+nom) du document
} DHSTINFO

En GFA, ça donne lors de l'initialisation générale :
IF magic! OR mint!
dhst_mem%=GEMDOS(68,L:1056,W:3) ! allocation en mémoire partagée
dhst_appname%=ADD(dhst_mem%,16) ! on réserve 256 octets pour chaque
dhst_apppath%=ADD(dhst_mem%,272) ! item
dhst_docname%=ADD(dhst_mem%,528)
dhst_docpath%=ADD(dhst_mem%,784)
'
LONG{dhst_mem%}=dhst_appname% ! on remplie la "structure"
LONG{ADD(dhst_mem%,4)}=dhst_apppath% ! par les adresses
LONG{ADD(dhst_mem%,Cool}=dhst_docname% !
LONG{ADD(dhst_mem%,12)}=dhst_docpath% !
'
CHAR{dhst_appname%}="Joe" ! par exemple
CHAR{dhst_apppath%}=chemin$+"JOE.PRG" ! nom complet
CHAR{dhst_docname%}="" ! rempli avant appel
CHAR{dhst_docpath%}="" ! rempli avant appel
ENDIF

En même temps, on a créé les buffers pour le contenu. Pour les puristes, vous pouvez effacer et reconstruire les buffers et la structure DHSTINFO. En ce qui me concerne, elle est permanente dans Joe.
Reste plus qu'à prévenir le serveur DHST qu'on a utilisé tel document. La doku, écrite par Thomas MUCH lui-même, indique qu'il faut faire l'appel à chaque chargement d'un nouveau fichier. Okay, mais si l'on sauvegarde le fichier sous un nouveau nom ? Là je ne sais pas trop.
L'appel est de la forme (tiré du source de Joe ;-) :

IF @test_cookie("DHST",dhst_id%)=TRUE ! toujours tester avant l'appel
dhst_id&=WORD(dhst_id%) ! on récupère l'ap_id& dans le mot de poids faible
' remplisage des buffers de DHSTINFO avec le nom du document
CHAR{dhst_docname%}=LEFT$(MID$(nom_htm$,SUCC(RINSTR(nom_htm$,"\"))),254)
CHAR{dhst_docpath%}=LEFT$(nom_htm$,254)
IF dhst_id&>0
INT{m_adr%}=56029 ! DHST_ADD ou 0xDADD
INT{ADD(m_adr%,2)}=ap_id& ! ap_id& de votre programme
INT{ADD(m_adr%,4)}=0
LONG{ADD(m_adr%,6)}=dhst_mem% ! adresse de la struture
INT{ADD(m_adr%,10)}=0
INT{ADD(m_adr%,12)}=0
INT{ADD(m_adr%,14)}=0
~APPL_WRITE(dhst_id&,16,m_adr%)
ENDIF
ENDIF
Voilà ! Au cas où vous voulez effacer la struture et les buffers après cet appel, le serveur DHST vous renvoie un DHST_ACK (56030 ou 0xDADE) par l'EVNT_MULTI principal de votre programme. Le message correspond presque exactement aux 16 octet que vous avez envoyé avec APPL_WRITE, c'est à dire l'adresse de DHSTINFO dans LONG{msg_adr%+3}. Il y a en plus dans INT{msg_adr%+14} une réponse : si c'est nul alors il y a un blème, sinon les informations ont été indexées dans une petite base attenante à Start ou MultiStrip.
Oh ! j'oubliais qu'il faut la version 8.0 de Start et que vous devez rajouter les lignes dans le start.set (SMUSetup ne gérant pas encore cela) :
/documents
/documents_max 20
/documents_maxperapp 5

Atariste Phone Home

Modernes ces allemands ! Toutes les nouveautés viennent de chez eux. Une petit ajout par-ci, un autre par-là... pas forcément par les mêmes logiciels. Tout cela donne donc un OS très modulaire, on a ce qu'on veux mais le petit revers de la médaille est qu'il faut connaître les petits programmes (ou gros) qui rendent nos Atari plus confortable qu'un PC sous zin00, voire plus convivial qu'un MacG3.
Ainsi parmi les variables d'environnement, ajoutez $HOME sous la forme : #_ENV HOME=C:\GEMSYS\HOME\ dans MAGX.INF par exemple. Les programmes modernes prennent en compte ce répertoire et sauvent leurs fichiers de configuration dans celui-ci. (On a vu comment récupérer une variable d'environnement dans les chapitres précédents de ce fanzine merveilleux qu'est le STimulus)

Avantages ?

vous pouvez essayer la dernière version de votre application préférée à partir d'un cédérom (ou d'un répertoire temporaire) et vous avez votre configuration habituelle.
mieux, et je me demande pourquoi cela n'a pas été fait avant : faites plusieurs dossiers de type HOME, que vous renommez USER1, USER2, USERn... avec plusieurs MAGX.INF, un pour chaque type de HOME et vous bricolez un petit sélecteur au démarrage, genre XBOOT pour MagiC, qui va copier le bon MAGX.INF dans C:\ selon l'utilisateur ou la configuration choisie. Comme dans un certain zin00 avec ses "profils utilisateurs".
Bref, on a le beurre (sans l'avoir rance Smile et l'argent du beurre. Mais que reste-t-il donc à zin00 ? Les ActiveX ? Ben non : on les a aussi ! Toujours grâce à Monsieur MUCH (too much, ce gars ;-).


Comment je contrôle une application : GEMScript

Le principe d'ActiveX, en gros, est de pouvoir contrôler une application zin au travers d'une langage dérivé de Visual Basic et d'une interface regroupant des "composants", qui ne sont autres que des équivalent des objects GEM comme les boutons de dialogue. On peut ainsi refaire l'interface de IE4 (vu de mes yeux vus), faire un applicatif avec base de données sous Excel5 (mon boulot à l'armée), ou quelques gentils macro-virus qui vous salopent le disque dur.
Vous comprendrez donc que cette fonctionnalité est puissante mais également dangeureuse.
GEMScript est une application indépendante qui peut interpréter des scripts (fichiers *.SIC) et les éxécuter. Le langage ressemble au C, mais est très accessible. On peut ainsi lancer avec une instruction une application comme Texel et lui faire faire plein de choses par l'intermédiaire du script, comme des copier/coller, chargement de fichiers, etc.

GEMScript s'occupe de traduire votre code et de l'envoyer, via un protocole spécial, à l'application voulue. Il est nécessaire que l'application supporte ce protocole, ainsi que les commandes usuelles qui lui seront fournies par GEMScript.

Je ne fais ici que déchiffrer la documentation, n'ayant pas encore intégré ce protocole dans Joe. msg% est un buffer de réception de l'EVNT_MULTI ou d'envoi de APPL_WRITE :

GS_REQUEST : GEMScript vers votre application (reçu par EVNT_MULTI)

INT{msg%}-> 4944
INT{ADD(msg%,2)}-> ap_id& ! de GEMScript
INT{ADD(msg%,4)}-> 0
LONG{ADD(msg%,6)}-> gs_info% ! adresse de la structure GS_INFO
INT{ADD(msg%,10)}-> 0
INT{ADD(msg%,12)}-> 0
INT{ADD(msg%,14)}-> gems_id& ! votre identité sous GEMScript
GS_REPLY : vous supportez GEMScript et vous écrivez avec APPL_WRITE

INT{msg%}=4945
INT{ADD(msg%,2)}=ap_id& ! de votre application
INT{ADD(msg%,4)}=0
LONG{ADD(msg%,6)}=gs_info% ! même adresse de la struture GS_INFO reçue
INT{ADD(msg%,10)}=0
INT{ADD(msg%,12)}=0 ! OK, vous supportez le protocole de communication
>1 ! une autre valeur sinon.
INT{ADD(msg%,14)}=gems_id& ! votre id& sous GEMScript
Pour information, la struture GS_INFO est de la forme :

typedef struct {
long len; /* longueur de la struture en octets */
int version; /* numéro de version (si MKI$ donne 0110 alors c'est la 1.1) */
int msgs; /* Bitmap des fonctionnalités GSM_xxx */
long ext; /* extension du fichier script : MKL$ donne ".SIC" */
} GS_INFO;
Pour les fonctionnalités, veuillez vous taper la doc en allemand, merci. Il existe plusieurs protocoles, dont l'écriture de macros entières !!! En ce qui nous concerne ici, on ne s'occupe que des commandes vers une application, qui est supporté si le bit 0 est à 1, c-a-d les valeur de msgs impaires.

Passé l'étape de reconnaissance, notre application peut recevoir des ordres via des commandes, toujours données par GEMScript, via le tube GEM. Ces commandes sont de la forme :

GS_COMMAND : GEMScript vers notre application

INT{msg%}->4946
INT{ADD(msg%,2)}-> ap_id& ! de GEMScript
INT{ADD(msg%,4)}-> 0
LONG{ADD(msg%,6)}-> adresse vers une chaine de commande en mémoire non protégée
INT{ADD(msg%,10)}-> 0
INT{ADD(msg%,12)}-> 0
INT{ADD(msg%,14)}-> votre identifiant donné par GS_REQUEST
Attention, car la chaine de commande est formatée d'une façon particulière : tous les paramètres sont séparés par un null-byte, la fin de chaîne étant terminée elle-même par 2 null-bytes, comme dans la chaîne d'environement d'un SHEL_WRITE (voir épisodes précédents du Stimulus)

"Commande"+CHR$(0)+"Paramètre 1"+CHR$(0)+"Paramètre n"+CHR$(0)+CHR$(0)

Faites donc attention, il n'y a pas forcément 1 paramètre, et il faut manipuler CHAR{} avec précaution. Ci-dessous les commandes standard que toute application digne de ce nom se doit de supporter. Vous pouvez, si votre programme gère d'autres fonctions, les faire commander par un script. Il faut alors déclarer les paramètres de commande dans votre documentation pour que l'utilisateur les emploie dans ses scripts.

Commande Paramètre 1 Retour 1 Commentaire
Close nom du fichier (optionnel) -
Copy nom du fichier (optionnel) - fonction du clipboard
Cut nom du fichier (optionnel) - fonction du clipboard
Delete nom du fichier (optionnel) - fonction du clipboard
GetFront - nom du fichier on demande le fichier géré en avant plan
New - - ouverture d'un fichier vierge
Open nom du fichier -
Paste nom du fichier (optionnel) - fonction du clipboard
Print nom du fichier (optionnel) -
Quit - -
Save nom du fichier (optionnel) -
SaveAs nom du fichier (obligatoire) -
SelectAll nom du fichier (optionnel) - fonction du clipboard
ToFront nom du fichier - mettre en avant plan le fichier
Undo nom du fichier (optionnel) -
AppGetLongName - nom de l'application pour le mettre dans MultiStrip ou autre
Vous aurez compris que, si vous devez supporter GEMScript, votre application doit au moins obéir à ces commandes et agir, c'est-à-dire sauver le fichier EN VRAI si la commande est "Save".

D'autres commandes sont décrites dans la doc de GEMScript : il s'agit des commandes pour faire charger et écécuter un script par GEMScript ! C'est le serpent qui se mort la queue Smile

Mais on a pas fini. Car il faut renvoyer un ACK, c'est-à-dire le message de retour disant j'ai bien compris et éxécuté la chose (ou non), avec renvoi de certaines informations (d'où la colonne Retour 1 dans notre tableau).

GS_ACK : de l'application vers GEMScript

INT{msg%}=4947
INT{ADD(msg%,2)}=ap_id& ! de votre application
INT{ADD(msg%,4)}=0
LONG{ADD(msg%,6)}=commande_adr% ! adresse de la chaine de commande qui vous a été envoyée
LONG{ADD(msg%,10)}=retour_adr% ! chaine de retour, en mémoire non protégée
INT{ADD(msg%,14)}=0 ! GSACK_OK-> c'est tout bon
1 ! GSACK_UNKNOWN-> commande inconnue
2 ! GSACK_ERROR-> erreur
On donne donc l'adresse d'une chaine de retour. Celle-ci est formatée comme la chaine de commande, c'est-à-dire avec 1 null-byte entre les propositions et 2 null-bytes finaux. La chaine de retour peut contenir un message d'erreur si l'opération ne s'est pas bien passée.
Et on est propre sur soi. Quand on quitte, on oublie pas de prévenir GEMScript par :

GS_QUIT : application vers GEMSscript

INT{msg%}=4948
INT{ADD(msg%,2)}=ap_id& ! de votre application
INT{ADD(msg%,4)}=0
INT{ADD(msg%,6)}=0
INT{ADD(msg%,Cool}=0
INT{ADD(msg%,10)}=0
INT{ADD(msg%,12)}=0
INT{ADD(msg%,14)}=gems_id& ! votre identifiant sous GEMScript
Il y a donc un début et une fin : une intialisation et terminaison pour le protocole GEMScript. Les plus malins verront qu'on peut très bien s'en passer ;-) . En effet, GEMScript ne sert qu'à analyser vos scripts et envoyer des commandes à l'application voulue.
Mais on peut très bien envisager une autre application qui se servirait de la vôtre par l'intermédiaire des commandes, sans passer par l'initialisation et terminaison GEMScript.

Par exemple, un module de Joe pourrait dire à celui-ci : cherche la balise <BODY...>, met-la dans un buffer mémoire et donne moi l'adresse. J'analyse ça et affiche les paramètres dans ma boîte de dialogue en fenêtre. Quand l'utilisateur ferme et veut intégrer ça dans le texte édité sous Joe, alors je lui demande d'effacer son <BODY..> et de lire le tag que je lui donnerai.
Lumineux, non ?

Il y a donc plein d'applications possibles du concept de commandes introduit par GEMScript et son protocole. Le tout est de bien l'utiliser, car une application ou des gens mal intentionnés pourraient en faire mauvais usage. Des macro-virus sur Atari ? Zut ! notre système commence à devenir un peu trop moderne ! Il faut songer, si l'on passe des commandes sans passer par GEMScript de protéger les actions d'une manière quelconque.

Je vous conseille de lire la doc de GEMScript. Après ces quelques lignes, l'allemand vous sera plus facile à déchiffrer Smile Et n'oubliez pas d'ajouter dans les variables d'environnement :

#_ENV GEMSCRIPT=chemin+nom de GEMScript

A la prochaine !


Rajah Lone
écrit le 19 Août 1999
Shadow272
Shadow272
Admin

Messages : 329
Date d'inscription : 28/12/2017
Age : 65
Localisation : Hainaut Belgique

http://toutatari.blog4ever.xyz/

Revenir en haut Aller en bas

Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum