Suivez-nous sur X
|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Assembleur - les écrans publics
(Article écrit par Frédéric Delacroix et extrait d'Amiga News - novembre 1994)
|
|
Avec les écrans publics, les ingénieurs de Commodore ont introduit lors du Kickstart 2.0 une des notions
qui faisaient cruellement défaut au système 1.3 : la possibilité pour tout programme d'ouvrir une fenêtre
sur un écran autre que celui du Workbench. Nous allons voir cette notion du point de vue du programmeur.
Généralités
Tout d'abord, précisons qu'une tâche ne peut pas simplement ouvrir une fenêtre sur un écran appartenant
à une autre tâche pour la simple raison que celle-ci peut décider à tout moment de le fermer.
Certains programmes se le permettaient au temps du 1.3 et posaient souvent des problèmes.
Le Kickstart 2.0 propose ainsi la notion d'écran public ("public screen" en anglais)
qui permet, sous certaines conditions, d'ouvrir des fenêtres "visiteuses" sur de tels écrans.
Nous allons d'abord aborder ce vaste sujet sous l'angle du "screen manager" (gestionnaire d'écrans),
c'est-à-dire le programme chargé d'ouvrir et de fermer l'écran. Son rôle n'est bien évidemment pas
limité à cela, rien ne l'empêche d'utiliser cet écran à ses propres fins.
En mémoire, un écran public est constitué non seulement de toutes les données d'un écran normal,
matérialisées au sein de la fameuse structure "Screen", mais aussi de certaines données
supplémentaires : un nom (limité à 140 caractères), grâce auquel les autres tâches peuvent
trouver l'écran, certains drapeaux, le nombre de fenêtres de visiteurs, éventuellement l'adresse
d'une tâche à signaler lorsque la fenêtre du dernier visiteur se ferme.
Ouverture et fermeture
L'ouverture d'un écran public se fait donc par la fonction "OpenScreenTagList()"
de l'intuition.library. On lui passe en paramètres la structure "NewScreen" éventuelle
et une liste de tags. Outre le champ "ns_Type" de la structure "NewScreen" (qui doit avoir
le drapeau "PUBLICSCREEN"), les nouveaux attributs sont passées par l'intermédiaire de ces
tags spécifiques aux écrans publics :
- SA_PubName : ce tag indique que l'écran est un écran public dont le nom est pointé par
le champ "ti_Data" de ce tag. Ce tag doit se trouver avant les deux suivants.
- SA_PubTask : grâce à ce tag, on indique à Intuition quelle tâche ("ti_Data" est l'adresse
de la structure "Task") doit être prévenue que la dernière fenêtre a été fermée sur cet
écran. Si ce tag est omis, aucune tâche ne sera signalée.
- SA_PubSig : le champ "ti_Data" est le numéro du signal à utiliser pour prévenir la tâche.
Grâce à "SA_PubTask" et "SA_PubSig", on peut faire en sorte que l'écran se ferme dès
que la dernière fenêtre a disparu.
Lorsqu'un nouvel écran public est ouvert, il se trouve en mode "privé", c'est-à-dire introuvable
pour les autres tâches (bien qu'on puisse encore le trouver en scrutant la liste des écrans publics).
Pour cela, il faut utiliser la fonction "PubScreenStatus()" qui prend en paramètre la structure
"Screen" en A0 et un masque de drapeaux en D0. Le seul drapeau défini pour l'instant est "PSNF_PRINATE",
qu'il faut donc mettre à 0.
La fermeture d'un écran public se fait comme celle d'un écran privé par la fonction "CloseScreen()",
à l'exception du fait que celle-ci peut échouer dans le cas où des fenêtres de visiteurs sont encore
ouvertes. Dans ce cas, "CloseScreen()" retourne 0 en D0 (CloseSreen() ne retournait pas de résultat
avant le Kickstart 2.0). La meilleure chose à faire dans ce cas est d'attendre le signal précisé au
moment de l'ouverture par le tag "SA_PubSig" et de réessayer.
Dernière chose : dans un écran public, Intuition (ainsi que d'autres tâches) peut faire des
opérations graphiques à tout moment (ouverture de fenêtres, rafraîchissement...).
C'est pourquoi il ne faut pas faire d'opérations de bitmap sans ouvrir de fenêtre comme on peut
le faire facilement sur un "Custom Screen", sous peine d'interférer avec ces opérations.
Si c'est réellement indispensable, on peut toujours repasser en mode privé (mais il ne faut plus
qu'il y ait de visiteur !).
Autres possibilités
Dans le système, il y a un écran public qui a un statut spécial : le "default public screen"
(écran public par défaut). C'est l'écran sur lequel les fenêtres qui fournissent un nom d'écran
nul s'ouvrent. La plupart du temps, c'est l'écran du Workbench (nommé "Workbench"), mais on
peut l'ajuster comme on le désire. C'est la fonction "SetDefaultPubScreen()" de l'intuition.library
qui s'en charge, en prenant en A0 un pointeur sur le nom du nouvel écran public par défaut
(si ce paramètre est nul, l'écran du Workbench est utilisé).
Intuition permet aussi d'ajuster le comportement des écrans publics grâce à la fonction
"SetPubScreenModes()" (à ne pas confondre avec "PubScreenStatus()"),
qui modifie certains drapeaux. Ces drapeaux sont globaux, c'est-à-dire qu'ils affectent tous les
écrans publics. Ils ne sont donc à manipuler qu'à la demande de l'utilisateur.
La fonction "SetPubScreenModes()" prend en paramètres un masque constitué des nouveaux drapeaux
en D0. Les valeurs actuellement définies sont les suivantes :
- Shanghai : les fenêtres s'ouvrant normalement sur l'écran du Workbench s'ouvrent sur
l'écran public par défaut. Ce drapeau est utile quand on veut faire fonctionner des vieux
programmes (conçus pour le Kickstart 1.3, donc incapables de changer d'écran public)
sans encombrer l'écran du Workbench.
- PopPubScreen : avec ce mode, chaque fois qu'une fenêtre de visiteur s'ouvre sur un
écran public, celui-ci est amené en avant.
Comme je l'ai précisé plus haut, Intuition possède évidemment une liste de tous les écrans publics.
Cette liste étant globale, Intuition propose un système d'arbitrage (à base de sémaphore, voir
cet article) au sein des fonctions "LockPubScreenList()"
et "UnlockPubScreenList()". La première ne prend pas de paramètres, elle assure la non-modification
de la liste, et retourne en D0 un pointeur sur une structure "ListHeader". Cette structure sert
à relier d'autres structures, nommées "PubScreenNode". décrivant les écrans publics existants.
La seule chose à faire est de copier rapidement cette liste et la libérer grâce à
"UnlockPubScreenList()" (sans paramètres). On peut alors présenter la copie à
l'utilisateur dans une fenêtre de requête pour qu'il choisisse un nom.
Il ne faut surtout pas utiliser le champ "psn_Screen" car il n'y a aucune garantie
que l'écran reste ouvert. Le seul drapeau défini actuellement est "PSNF_PRIVATE",
qui indique si l'écran est en mode privé.
Le champ "psn_Size" indique la celle de la structure "PubScreenNode" plus celle du
tampon mémoire du nom de l'écran ; il suffit donc, pour copier la structure,
d'utiliser la valeur de ce champ pour l'allocation de mémoire. Étant donné que le champ
"In_Name" de la structure "Node" pointe sur le nom de l'écran, il faut le modifier
pour que le champ "In_Name" de la copie pointe bien sur la copie du nom et non sur le
nom original, auquel cas on ferait référence à une zone de mémoire qui pourrait être
libérée à tout moment. Pour cela, on peut remplacer le champ "In_Name" copié par le
résultat de la formule suivante :
Exemple
L'exemple que je vous propose est un gestionnaire d'écran public minimal :
il ouvre un nouvel écran public haute résolution 4 couleurs ayant pour nom
"AmigaNews", puis ouvre un Shell dessus grâce à la commande "NewShell", et
attend un signal "Ctrl-C" déclenché soit depuis la fenêtre CLI où le programme a
été lancé (et non pas celui qui vient d'être créé) soit par Intuition, signifiant
que la dernière fenêtre vient d'être fermée. Le programme referme alors l'écran et
quitte.
La prochaine fois, nous verrons l'utilisation des écrans publics vue du côté
des applications qui ouvrent leurs fenêtres dessus, avec notamment une routine
bien pratique qui ouvre une fenêtre sur l'écran public le plus en avant.
|