Obligement - L'Amiga au maximum

Vendredi 23 janvier 2026 - 13:00  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in English


Réseaux sociaux

Suivez-nous sur Mastodon




Liste des jeux Amiga

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


Trucs et astuces

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


Glossaire

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


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : Assembleur - exploitation des types d'outils
(Article écrit par Frédéric Delacroix et extrait d'Amiga News - juin 1994)


Je vous propose ce mois-ci une méthode, assez optimisée, pour exploiter les arguments passés à une commande. Nous ne nous attarderons pas cette fois-ci sur l'utilisation du CLI et de la puissante fonction ReadArgs(), mais plutôt à l'utilisation - plus rare sans doute - des types d'outils (tooltypes), aussi bien à partir du Worbench que du CLI (ou Shell, c'est pareil).

Les fichiers icônes

C'est bien connu maintenant, pour afficher une icône associée à un fichier, le Workbench a besoin d'un fichier ".info" correspondant, contenant des informations sur l'objet à afficher. Ce n'est plus vrai à partir du Kickstart 2.0 grâce à l'option "Show all files", mais c'est un cas particulier que nous laissons de côté. Nous laissons également de côté les fichiers nommés ".info" tout court que l'on pouvait rencontrer jadis, au temps du Kickstart 1.3, qui semblaient contenir le listing du répertoire concerné, et qui ont depuis disparu de nos contrées.

Voyons donc le contenu d'un fichier icône. Il s'agit en réalité principalement d'une structure DiskObject, définie dans le fichier d'inclusion "workbench/workbench.[hi]" :

struct DiskObject {
	UWORD			do_Magic;	/* indication d'une icône */
	UWORD			do_Version;
	struct Gadget		do_Gadget;	/* définit l'icône même */
	UBYTE			do_Type;	/* projet, outil, etc */
	char	*		do_DefaultTool;	/* outil des projets */
	char	**		do_ToolTypes;
	LONG			do_CurrentX;	/* position de l'icône */
	LONG			do_CurrentY;
	struct	DrawerData *	do_DrawerData;	/* la fenêtre des tiroirs */
	char	*		do_ToolWindow;	/* pas réellement utilisé */
	LONG			do_StackSize;	/* taille de la pile */
};
La manière dont ces informations sont réellement stockées dans le fichier n'est pas documentée et risque de changer dans des versions ultérieures du système. En conséquence, l'accès aux fichiers icônes doit toujours se faire par l'intermédiaire de l'icon.library. Cette bibliothèque possède par ailleurs quelques fonctions comme FindToolType() ou FreeFreeList() qui sont très utiles dans certains cas.

Le cas qui nous intéresse

Nous voulons savoir si tel ou tel type d'outils a été spécifié par l'utilisateur. Pour cela, il faut évidemment d'abord obtenir la structure DiskObject. Pour ce faire, l'icon.library (sur disque jusqu'au Kickstart 1.3, en ROM depuis), propose la fonction GetDiskObject(), à laquelle on fournit en A0 le nom de l'icône à charger (sans le suffixe ".info"). On obtient en retour la structure DiskObject correspondante. ou "0" s'il n'en existe pas, ou si une erreur est survenue pendant le chargement (dans ce cas IoErr() en donne la cause).

Le premier problème se pose : comment savoir quelle icône charger ? Cela dépend surtout de ce que l'on veut faire. En général, il suffit de charger l'icône du programme lui-même, mais il peut s'avérer nécessaire par exemple pour un programme lancé à partir du Workbench par une sélection multiple, d'examiner toutes les icônes sélectionnées. Là, c'est le programmeur qui décide.

En général, un programme lancé à partir du Workbench examine le premier ou le deuxième argument donné par la structure WBStartup reçue en début d'exécution à son port de message. En général, il vaut mieux s'intéresser au second, étant donné que cela signifie que l'utilisateur a soit fait une sélection multiple (grâce à la touche "Shift") ou cliqué sur une icône projet dont l'outil par défaut était le programme en cours d'exécution. Dans le premier cas, les arguments sont envoyés au programme dans l'ordre de la sélection : dans le second, c'est l'icône de l'outil par défaut en premier, puis l'icône projet qui a été cliquée.

Un programme lancé à partir du CLI a la tâche plus difficile, surtout si on n'utilise pas le Kickstart 2.0. Il s'agit pour lui de trouver d'où il vient, c'est-à-dire son répertoire (à priori, ce n'est pas le même que le répertoire courant) et l'exécutable. Le Kickstart 2.0 rend les choses assez simples grâce aux fonctions GetProgramDir() et GetProgramName() de la dos.library, évitant ainsi quelques migraines à se plonger dans les pointeurs BCPL. Il suffit alors d'aller chercher l'icône grâce à l'icon.library. A noter qu'il peut être judicieux de prévoir également le passage d'arguments par le CLI, ces arguments surpassant alors ceux donnés en type d'outils. Il suffit alors d'examiner l'icône de la façon la plus classique, à grand renfort de FindToolType() et MatchToolValue().

Un exemple !

Le programme que je vous propose ce mois-ci affiche tous les types d'outils d'une icône dans la fenêtre du CLI, ou dans une fenêtre CON: si invoqué à partir du Workbench. A partir du CLI, il se contente d'afficher les types d'outils de son icône à lui, et à partir du Workbench affiche ses types d'outils, ou ceux du second argument s'il y en a un. Il y a deux façons de donner un deuxième argument : soit cliquer sur l'icône du programme puis "Shift-double-cliquer" sur l'icône à examiner, soit utiliser une icône de type projet dont l'outil par défaut est le programme dont le listing suit. J'oubliais : ce programme ne marche que sur Kickstart 2.04 et supérieur.

En guise de conclusion

Une dernière chose : lorsqu'un de vos programmes crée une icône projet, il est de bon aloi de régler le bon outil par défaut. Ceci se fait, si on vient du CLI, en réservant deux espaces contigus sur la pile (ou ailleurs, mais la pile c'est bien pratique). Dans l'un on met le chemin du programme grâce à GetProgramDir() et NameFromLock(), dans l'autre on y met le nom du programme obtenu par GetProgramName(), et on réunit le tout dans le premier tampon mémoire grâce à AddPart(). Il reste alors à mettre dans le champ do_DefaultTool de la structure DiskObject le pointeur sur le tampon mémoire et à sauvegarder l'icône.

	include	exec/execbase.i
	include	exec/exec.i
	include	exec/exec_lib.i
	include	dos/dos.i
	include	dos/dos_lib.i
	include	dos/dosextens.i
	include	workbench/workbench.i
	include	workbench/startup.i
	include	workbench/icon_lib.i

	move.l	4.w,a6	; ExecBase
	move.l	ThisTask(a6),a4	; notre tâche
	tst.l	pr_CLI(a4)	; vient-elle du CLI?
	bne.s	FromCLI
	lea	pr_MsgPort(a4),a0	; non: va checher
	jsr	_LVOWaitPort(a6)	; le message du
	lea	pr_MsgPort(a4),a0	; workbench
	jsr	_LVOGetMsg(a6)
	move.l	d0,WB.Startup

; On ouvre d'abord la bibliothèque dos.library
FromCLI	lea	DOSName(pc),a1
	moveq	#37,d0	; Kickstart 2.04+
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,DOSBase
	beq	exit

; puis la bibliothèque icon.library
	lea	IconName(pc),a1
	moveq	#37,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,IconBase
	beq	FermeDOS

	tst.l	WB.Startup
	beq.s	FenCLI

; pour le workbench, on ouvre une fenêtre
	move.l	#WBFenetre,d1
	move.l	#MODE_OLDFILE,d2
	move.l	DOSBase(pc),a6
	jsr	_LVOOpen(a6)
	move.l	d0,Fenetre
	beq.s	FermeIcon

; s'il y a au moins 2 arguments, on prend le deuxième,
; sinon on se contente du premier
	move.l	WB.Startup(pc),a2
	tst.l	sm_NumArgs(a2)
	beq.s	FermeFenetre
	move.l	sm_ArgList(a2),a3	; liste de structures
	cmp.l	#2,sm_NumArgs(a2)	; WBArg (lock+nom)
	blt.s	UnArg
	addq.l	#wa_SIZEOF,a3
UnArg	move.l	wa_Lock(a3),d3
	move.l	wa_Name(a3),d4
	bsr.s	GetIcon			; charge l'icône en mémoire
	bsr	Affiche			; affiche les tooltypes
	bsr	FreeIcon		; libère l'icône
	bra.s	FermeFenetre

FenCLI	move.l	DOSBase(pc),a6		; le CLI a déjà une fenêtre
	jsr	_LVOOutput(a6)
	move.l	d0,Fenetre

	jsr	_LVOGetProgramDir(a6)	; verrou sur le répertoire
	move.l	d0,d3			; du programme (accessible aussi par
	beq.s	FermeIcon		; le pseudo-assign PROGDIR:
	lea	-108(sp),sp		; on se réserve un tampon sur la pile
	move.l	sp,d1			; (108 octets sont suffisants pour un nom de
	moveq	#108,d2			; fichier)
	jsr	_LVOGetProgramName(a6)	; on y copie le nom du programme
	move.l	sp,d4
	bsr.s	GetIcon			; on charge l'icône
	lea	108(sp),sp		; plus besoin du nom, on libère l'espace
	bsr.s	Affiche			; affichage des types d'outils
	bsr	FreeIcon		; libération de l'icône
	bra.s	FermeIcon

FermeFenetre
	move.l	Fenetre(pc),d1
	move.l	DOSBase(pc),a6
	jsr	_LVOClose(a6)
FermeIcon
	move.l	IconBase(pc),a1
	move.l	4.w,a6
	jsr	_LVOCloseLibrary(a6)
FermeDOS
	move.l	DOSBase(pc),a1
	jsr	_LVOCloseLibrary(a6)
exit	move.l	WB.Startup(pc),d0
	beq.s	CLIExit
	move.l	d0,a1			; il faut toujours faire un Forbid() avant
	jsr	_LVOForbid(a6)		; de répondre au Workbench !
	jsr	_LVOReplyMsg(a6)
CLIExit	moveq	#0,d0
	rts

; la routine suivante charge l'icône en mémoire
GetIcon	; (D6)DiskObject=GetIcon(directory,Nom)(D3,D4)
	move.l	d3,d1			; on se place dans le bon directory
	move.l	DOSBase(pc),a6	(D3 est un Lock)
	jsr	_LVOCurrentDir(a6)
	move.l	d0,d5			; on sauve l'ancien
	move.l	d4,a0			; on charge l'icône (D4
	move.l	IconBase(pc),a6		; pointe sur son nom)
	jsr	_LVOGetDiskObjectNew(a6)
	move.l	d0,d6
	move.l	d5,d1			; on remet l'ancien dir
	move.l	DOSBase(pc),a6
	jsr	_LVOCurrentDir(a6)
	rts

; la routine suivante affiche les types d'outils
; (do_ToolTypes pointe sur un tableau de pointeurs sur des
; chaînes de caractères, terminée par un pointeur nul).
Affiche	; Affiche(DiskObject)(D6)
	move.l	d6,a4
	move.l	a4,d6
	beq.s	.Fin
	cmp.b	#WBPROJECT,do_Type(a4)	; bonus: si l'icône
	bne.s	.PasProjet		; est un projet, on affiche
	lea	do_DefaultTool(a4),a1	; l'icône par défaut
	lea	DefTool.MSG(pc),a0
	bsr.s	PrintF
.PasProjet
	move.l	#ToolTypes.MSG,d0
	bsr.s	Print
	move.l	do_ToolTypes(a4),a2
.Loop	move.l	(a2)+,d0
	beq.s	.Fin
	bsr.s	Print
	bra.s	.Loop
.Fin	rts

; cette routine libère la mémoire associée à la structure
; DiskObject.
FreeIcon				; FreeIcon(DiskObject)(D6)
	move.l	d6,a0
	move.l	a0,d6
	beq.s	.Rien
	move.l	IconBase(pc),a6
	jsr	_LVOFreeDiskObject(a6)
.Rien	rts

Print					; Print(Message)(d0)
	move.l	d0,d2
	move.l	Fenetre(pc),d1
	move.l	DOSBase(pc),a6
	jsr	_LVOFPuts(a6)
	move.l	Fenetre(pc),d1
	moveq	#10,d2
	jsr	_LVOFPutC(a6)
	rts

PrintF	; PrintF(Format,Args)(A0,A1)
	move.l	a0,d2
	move.l	a1,d3
	move.l	Fenetre(pc),d1
	move.l	DOSBase(pc),a6
	jsr	_LVOVFPrintf(a6)
	move.l	Fenetre(pc),d1
	moveq	#10,d2
	jsr	_LVOFPutC(a6)
	rts

WB.Startup	dc.l	0
DOSBase	dc.l	0
IconBase	dc.l	0
Fenetre	dc.l	0

DOSName		dc.b	"dos.library",0
IconName	dc.b	"icon.library",0
WBFenetre	dc.b	"CON:////ToolTypes/AUTO/CLOSE/WAIT/SCREEN*",0
DefTool.MSG	dc.b	"Outil par défaut de ce projet: %s",10,0
ToolTypes.MSG	dc.b	"Types d'outils de l''icône:",0


[Retour en haut] / [Retour aux articles]