Initial commit
[amiga/OpenBoopsi.git] / docs / NoteBOOPSI
1
2 Alcune note sulla struttura GadgetInfo
3 --------------------------------------
4
5 Apparentemente l'input handler di Intuition riutilizza sempre, quando ciò è
6 possibile, la stessa struttura GadgetInfo quando invoca un metodo di un
7 gadget custom. Del resto il singolo task dell'input.device può solo invocare
8 un metodo dopo l'altro in sequenza e nella maggioranza dei casi non necessita
9 di avere contemporaneamente più di una struttura GadgetInfo.
10
11 Nella struttura GadgetInfo un gadget custom riceve nel campo gi_Layer il
12 puntatore al layer associato al "contenitore logico" in cui si trova il
13 gadget stesso.
14
15 · Un gadget custom situato in una finestra normale, oppure nella zona interna
16   di una finestra GIMMEZEROZERO riceve in gi_Layer il puntatore al layer di
17   Window.RPort. Il "contenitore logico" è l'area dell'intera finestra, oppure
18   l'area della sua zona interna.
19
20 · Un gadget custom situato nella zona esterna di una finestra GIMMEZEROZERO
21   (GZZGADGET) riceve in gi_Layer il puntatore al layer di Window.BorderRPort.
22   Il "contenitore logico" è l'area dell'intera finestra.
23
24 · Un gadget custom situato in un requester (REQGADGET) riceve in gi_Layer il
25   puntatore al layer del requester (Requester.ReqLayer).
26   Il "contenitore logico" è l'area del requester.
27
28 · Un gadget custom situato nella titlebar di uno schermo (SCRGADGET) riceve
29   in gi_Layer il puntatore al layer della titlebar (Screen.BarLayer).
30   Il "contenitore logico" è l'area della titlebar.
31
32 · Un gadget custom situato in un gruppo (cioè appartenente alla lista interna
33   di un gadget "groupgclass") riceve in gi_Layer un valore che dipende dal
34   "contenitore logico" del gruppo stesso, ricadendo così in uno dei quattro
35   casi precedenti.
36
37 Il campo gi_RastPort è uguale a gi_Screen->BarLayer->rp quando il gadget
38 appartiene ad una finestra o ad un requester, e punta a gi_Screen.RastPort
39 quando invece il gadget appartiene alla titlebar dello schermo.
40 Ignoro le ragioni di questo fatto; in ogni caso questa RastPort per
41 qualche motivo non deve venire utilizzata per il rendering (nel caso di
42 un gadget SCRGADGET essa non ha nemmeno un layer).
43
44 Chiamando ObtainGIRPort() si ottiene un clone della RastPort di gi_Layer, che
45 punta allo stesso layer, il quale punta alla RastPort originale (quella della
46 finestra interna, o quella del bordo per le finestre GIMMEZEROZERO, ecc.).
47
48 Inoltre ObtainGIRPort() esegue un LockLayer() su gi_Layer. Apparentemente
49 gi_Layer ha già tre lock quando Intuition invoca il metodo GM_RENDER (solo due
50 nel caso di un gadget SCRGADGET) mentre non è bloccato nel caso di tutti gli
51 altri metodi.
52
53 Per il metodo GM_RENDER il valore di gpr_RPort è esattamente lo stesso che
54 si otterrebbe chiamando ObtainGIRPort(), il che suggerisce che tale RastPort
55 clonata sia unica e conservata da qualche parte. In effetti a quanto ho visto
56 finora ObtainGIRPort() restituisce sempre lo stesso indirizzo, qualunque sia
57 il contesto.
58
59 I valori di gi_Screen, gi_Window e gi_Requester sono inizializzati in modo
60 opportuno (oppure nulli se non applicabili, a parte gi_Screen).
61
62 Tabella di esempio per un gadget in una finestra non GZZ:
63
64  +-------------------------------------------------------------------------+
65  |                                              gi_Window: W               |
66  |                                  gi_Layer: RL, LWindow: W, LRastPort: R |
67  | gi_RastPort:         S, BitMap: bm, Layer: SL, LWindow: 0, LRastPort: S |
68  | gi_Window->RPort:    R, BitMap: bm, Layer: RL, LWindow: W, LRastPort: R |
69  | gi_Window->BorderRP: 0, BitMap: --, Layer: --, LWindow: -, LRastPort: - |
70  | gpr_RPort:           C, BitMap: bm, Layer: RL, LWindow: W, LRastPort: R |
71  | ObtainGIRPort():     C, BitMap: bm, Layer: RL, LWindow: W, LRastPort: R |
72  +-------------------------------------------------------------------------+
73
74 Tabella di esempio per un gadget non GZZ in una finestra GZZ:
75
76  +-------------------------------------------------------------------------+
77  |                                              gi_Window: W               |
78  |                                  gi_Layer: RL, LWindow: W, LRastPort: R |
79  | gi_RastPort:         S, BitMap: bm, Layer: SL, LWindow: 0, LRastPort: S |
80  | gi_Window->RPort:    R, BitMap: bm, Layer: RL, LWindow: W, LRastPort: R |
81  | gi_Window->BorderRP: B, BitMap: bm, Layer: BL, LWindow: W, LRastPort: B |
82  | gpr_RPort:           C, BitMap: bm, Layer: RL, LWindow: W, LRastPort: R |
83  | ObtainGIRPort():     C, BitMap: bm, Layer: RL, LWindow: W, LRastPort: R |
84  +-------------------------------------------------------------------------+
85
86 Tabella di esempio per un gadget GZZ in una finestra GZZ:
87
88  +-------------------------------------------------------------------------+
89  |                                              gi_Window: W               |
90  |                                  gi_Layer: BL, LWindow: W, LRastPort: B |
91  | gi_RastPort:         S, BitMap: bm, Layer: SL, LWindow: 0, LRastPort: S |
92  | gi_Window->RPort:    R, BitMap: bm, Layer: RL, LWindow: W, LRastPort: R |
93  | gi_Window->BorderRP: B, BitMap: bm, Layer: BL, LWindow: W, LRastPort: B |
94  | gpr_RPort:           C, BitMap: bm, Layer: BL, LWindow: W, LRastPort: B |
95  | ObtainGIRPort():     C, BitMap: bm, Layer: BL, LWindow: W, LRastPort: B |
96  +-------------------------------------------------------------------------+
97
98 Il campo gi_Domain contiene larghezza e altezza del "contenitore logico" del
99 gadget. Nel caso di un gadget SCRGADGET, l'altezza è stranamente quella dello
100 schermo, mentre sarebbe più corretto se fosse quella della titlebar. Inoltre
101 un gadget che appartenga ad un gruppo ha come "contenitore logico" quello che
102 contiene il gruppo, e non il gruppo stesso (probabilmente in quanto il gruppo
103 non ha un layer proprio).
104 Gli offset contenuti in gi_Domain sono la distanza della posizione (espressa
105 in coordinate di schermo) del layer associato al "contenitore logico" del
106 gadget dalla posizione (sempre in coordinate di schermo) del suo "contenitore
107 fisico primario" (cioè lo schermo per i gadget SCRGADGET e la finestra per
108 tutti gli altri, anche se REQGADGET oppure appartenenti ad un gruppo).
109
110 La funzione DoGadgetMethodA() crea una struttura GadgetInfo appropriata
111 in base al tipo di gadget di cui viene invocato il metodo. Se è di tipo
112 GZZGADGET, REQGADGET o SCRGADGET viene scelto il layer corretto, e anche
113 gi_Domain viene inizializzato adeguatamente.
114
115 Un problema è che "gadgetclass" e "icclass" nell'implementare il metodo
116 OM_NOTIFY non chiamano DoGadgetMethodA() per invocare il metodo OM_UPDATE
117 dell'oggetto ICA_TARGET, bensì gli passano direttamente il puntatore a
118 GadgetInfo ricevuto, che fa riferimento al contesto dell'oggetto notificante
119 e non, come sarebbe corretto, a quello dell'oggetto notificato!
120
121 Non si devono annidare chiamate a ObtainGIRPort(), altrimenti la RastPort
122 clonata (sempre la stessa) può venire modificata ad ogni chiamata. In
123 realtà probabilmente se si rimane nello stesso contesto la RastPort clonata
124 viene reinizializzata ogni volta con gli stessi valori, per cui non cambia
125 niente. Il vero pericolo sta nell'invocare un metodo di un altro gadget che
126 chiami ObtainGIRPort() mentre si è ancora all'interno del proprio blocco
127 ObtainGIRPort().
128 In entrambi i casi comunque può verificarsi un errore 01000008 (Semaphore
129 in illegal state).
130 Del resto chiamare tanto ObtainGIRPort() quanto DoGadgetMethodA() all'interno
131 di un blocco ObtainGIRPort() dovrebbe essere scorretto comunque (sono due
132 funzioni di Intuition).
133
134
135 Note varie
136 ----------
137
138 GACT_IMMEDIATE viene sempre rispettato anche per i gadget custom o BOOPSI.
139 Il valore di Code del messaggio IDCMP_GADGETDOWN è sempre zero e non può
140 essere impostato dal dispatcher in alcun metodo (GM_HITTEST/GM_GOACTIVE).
141
142 GACT_RELVERIFY è necessario affinché l'uso di GMR_VERIFY + gpi_Termination
143 generi effettivamente un messaggio IDCMP_GADGETUP; in sua assenza esso non
144 viene generato. Viceversa la sua presenza non garantisce l'invio di tali
145 messaggi; ciò è deciso dal dispatcher nei metodi GM_GOACTIVE e GM_HANDLEINPUT.
146
147 La documentazione del metodo IM_FRAMEBOX sul RKM è sbagliata! Viene invertito
148 il ruolo di imp_ContentsBox e imp_FrameBox.
149