chiark / gitweb /
JPEG support and other fixes from Nick Clark
[ssr] / StraySrc / Libraries / Sapphire / s / transWin
1 ;
2 ; transWin.s
3 ;
4 ; Transient window handling (MDW)
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sapphire library.
12 ;
13 ; Sapphire is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Sapphire is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sapphire.  If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29                 GET     libs:header
30                 GET     libs:swis
31
32                 GET     libs:stream
33
34 ;----- External dependencies ------------------------------------------------
35
36                 GET     sapphire:event
37                 GET     sapphire:sapphire
38
39 ;----- Main code ------------------------------------------------------------
40
41                 AREA    |Sapphire$$Code|,CODE,READONLY
42
43 ; --- transWin_subWaiting ---
44 ;
45 ; On entry:     --
46 ;
47 ; On exit:      CS if a submenu is waiting to be opened, CC otherwise
48 ;
49 ; Use:          Informs the caller whether the menu system is waiting for
50 ;               a submenu to be attached.
51
52                 EXPORT  transWin_subWaiting
53 transWin_subWaiting ROUT
54
55                 ORR     R14,R14,#C_flag         ;Assume there is one waiting
56                 STMFD   R13!,{R0,R1,R12,R14}    ;Save some registers
57                 WSPACE  tw__wSpace              ;Find my workspace
58
59                 ; --- First, try asking TMS ---
60
61                 LDR     R1,tw__twin             ;Load the global area address
62                 LDR     R1,[R1,#twin_tmsHook]   ;Load the hook address
63                 CMP     R1,#1                   ;Has the hook been set up?
64                 MOVCS   R14,PC                  ;Yes -- set up return address
65                 ADDCS   PC,R1,#tmsh__subWaiting ;And call the routine
66                 LDMCSFD R13!,{R0,R1,R12,PC}^    ;Return true
67
68                 ; --- Now find out about the normal WIMP ---
69
70                 BL      event_last              ;Find the last event
71                 CMP     R0,#17                  ;Is it some kind of message?
72                 CMPNE   R0,#18                  ;Either type of message?
73                 LDREQ   R0,[R1,#16]             ;Get the message code
74                 MOVEQ   R14,#&40000             ;The message base number
75                 ORREQ   R14,R14,#&000C0         ;We're looking for submenus
76                 CMPEQ   R0,R14                  ;Do they match?
77                 LDMEQFD R13!,{R0,R1,R12,PC}^    ;Return true
78                 LDMFD   R13!,{R0,R1,R12,R14}    ;Unstack some registers
79                 BICS    PC,R14,#C_flag          ;Return false
80
81                 LTORG
82
83 ; --- transWin_openSub ---
84 ;
85 ; On entry:     R0 == window handle to open
86 ;
87 ; On exit:      --
88 ;
89 ; Use:          Opens the given window as a submenu.
90
91                 EXPORT  transWin_openSub
92 transWin_openSub ROUT
93
94                 STMFD   R13!,{R0-R3,R12,R14}    ;Save some registers
95                 WSPACE  tw__wSpace              ;Find my workspace
96
97                 ; --- First of all, try TMS ---
98
99                 LDR     R1,tw__twin             ;Load the global area address
100                 LDR     R1,[R1,#twin_tmsHook]   ;Load the hook address
101                 CMP     R1,#1                   ;Has the hook been set up?
102                 MOVCS   R14,PC                  ;Yes -- set up return address
103                 ADDCS   PC,R1,#tmsh__subWaiting ;And call the routine
104                 MOVCS   R14,PC                  ;If it is waiting...
105                 ADDCS   PC,R1,#tmsh__openSub    ;...get it to open the menu
106                 BCS     %90transWin_openSub     ;And then return to caller
107
108                 ; --- Now try the normal system ---
109
110                 MOV     R2,R0                   ;Look after the window handle
111                 BL      event_last              ;Find the last event
112                 CMP     R0,#17                  ;Is it some kind of message?
113                 CMPNE   R0,#18                  ;Either type of message?
114                 LDREQ   R0,[R1,#16]             ;Get the message code
115                 MOVEQ   R14,#&40000             ;The message base number
116                 ORREQ   R14,R14,#&000C0         ;We're looking for submenus
117                 CMPEQ   R0,R14                  ;Do they match?
118                 BNE     %99transWin_openSub     ;No -- return then
119
120                 ; --- Open as a normal submenu ---
121
122                 ADD     R14,R1,#24              ;Point to the coordinates
123                 MOV     R1,R2                   ;Get the window handle back
124                 LDMIA   R14,{R2,R3}             ;Read the coordinates
125                 SWI     Wimp_CreateSubMenu      ;Display the menu nicely
126                 MOV     R0,R1                   ;Get window handle in R0
127
128                 ; --- Register the transient menu
129
130 90              BL      transWin_register       ;Register the window
131 99              LDMFD   R13!,{R0-R3,R12,PC}^    ;And return to caller
132
133                 LTORG
134
135 ; --- transWin_register ---
136 ;
137 ; On entry:     R0 == window handle to register
138 ;
139 ; On exit:      --
140 ;
141 ; Use:          Registers a window as being the current transient window.
142
143                 EXPORT  transWin_register
144 transWin_register ROUT
145
146                 STMFD   R13!,{R12,R14}          ;Save some registers
147                 WSPACE  tw__wSpace              ;Find my workspace
148                 LDR     R12,tw__twin            ;Find the global area
149                 STR     R0,[R12,#twin_trans]    ;Save the transient window
150                 LDR     R14,[R12,#twin_flags]   ;Load the TWIN flags word
151                 BIC     R14,R14,#twinFlag_recrt ;Don't recreate the menu
152                 STR     R14,[R12,#twin_flags]   ;Save the flags back again
153                 LDMFD   R13!,{R12,PC}^          ;And return to caller
154
155                 LTORG
156
157 ; --- transWin_close ---
158 ;
159 ; On entry:     R0 == window handle to close
160 ;
161 ; On exit:      --
162 ;
163 ; Use:          Closes the current transient window.
164
165                 EXPORT  transWin_close
166 transWin_close  ROUT
167
168                 STMFD   R13!,{R0,R1,R10,R12,R14} ;Save some registers
169                 WSPACE  tw__wSpace              ;Find my workspace
170                 LDR     R14,tw__flags           ;Load my flags word
171                 TST     R14,#twFlag__wimpCls    ;Did the WIMP close it?
172                 MOVEQ   R1,#-1                  ;No -- kill the whole menu
173                 SWIEQ   Wimp_CreateMenu         ;Using this neat trick
174                 MOV     R1,R13                  ;Point at caller's handle
175                 SWI     Wimp_CloseWindow        ;Close the window
176                 LDR     R0,[R13,#0]             ;Load his window again
177                 LDR     R12,tw__twin            ;Find the global area
178                 LDR     R14,[R12,#twin_trans]   ;Load the current transient
179                 SUBS    R14,R0,R14              ;Do they match nicely?
180                 STREQ   R14,[R12,#twin_trans]   ;Yes -- zero the current one
181                 LDMFD   R13!,{R0,R1,R10,R12,PC}^ ;And return to caller
182
183                 LTORG
184
185 ; --- tw__faker ---
186 ;
187 ; On entry:     R0 == event code
188 ;               R1 == pointer to event data
189 ;
190 ; On exit:      CS and new event set up, or CC and registers preserved
191 ;
192 ; Use:          Generates dummy close events for transient windows.
193
194 tw__faker       ROUT
195
196                 ; --- Ignore redraw events ---
197
198                 CMP     R0,#1                   ;Is it a redraw event?
199                 MOVEQS  PC,R14                  ;Yes -- return right now
200
201                 ; --- Start up the faking business ---
202
203                 STMFD   R13!,{R9,R10,R14}       ;Save some registers
204                 LDR     R14,tw__flags           ;Load my flags word
205                 BIC     R14,R14,#twFlag__wimpCls ;Wimp hasn't closed it
206                 STR     R14,tw__flags           ;Save the flags back again
207
208                 LDR     R10,tw__twin            ;Find the global area
209                 LDR     R9,[R10,#twin_trans]    ;Load the transient window
210                 CMP     R9,#0                   ;Is there one defined?
211                 LDMEQFD R13!,{R9,R10,PC}^       ;No -- return right now
212
213                 ; --- See if the window's still open ---
214
215                 CMP     R0,#9                   ;Is this a menu hit event?
216                 BEQ     %10tw__faker            ;Yes -- window will close
217
218                 STMFD   R13!,{R0,R1}            ;Save some more registers
219                 SUB     R13,R13,#36             ;Make some stack space
220                 STR     R9,[R13,#0]             ;Save window handle in there
221                 MOV     R1,R13                  ;Point at the block
222                 SWI     Wimp_GetWindowState     ;Read the window information
223                 LDR     R14,[R13,#32]           ;Load the window flags
224                 TST     R14,#&00010000          ;Is the window open still?
225                 ADD     R13,R13,#36             ;Reclaim the stack space?
226                 LDMNEFD R13!,{R0,R1,R9,R10,PC}^ ;Yes -- return to caller
227                 LDMFD   R13!,{R0,R1}            ;Restore those registers
228
229                 ; --- Fake the event ---
230
231                 LDR     R14,tw__flags           ;Load my flags word
232                 ORR     R14,R14,#twFlag__wimpCls ;Wimp has closed the window
233                 STR     R14,tw__flags           ;Save the flags back again
234 10tw__faker     STR     R9,[R1,#0]              ;Save window handle in block
235                 MOV     R0,#3                   ;It's a close event
236                 LDMFD   R13!,{R9,R10,R14}       ;Unstack the registers
237                 ORRS    PC,R14,#C_flag          ;And return with C set
238
239                 LTORG
240
241 ; --- transWin_init ---
242 ;
243 ; On entry:     --
244 ;
245 ; On exit:      --
246 ;
247 ; Use:          Initialises the transWin system.
248
249                 EXPORT  transWin_init
250 transWin_init   ROUT
251
252                 STMFD   R13!,{R12,R14}          ;Save some registers
253                 WSPACE  tw__wSpace              ;Find my workspace
254
255                 ; --- Make sure I'm not already running ---
256
257                 LDR     R14,tw__flags           ;Load my flags word
258                 TST     R14,#twFlag__inited     ;Is my initialised flag set?
259                 LDMNEFD R13!,{R12,PC}^          ;Yes -- return to caller
260                 MOV     R14,#twFlag__inited     ;Set the intialised flag
261                 STR     R14,tw__flags           ;And save the flags back
262
263                 ; --- Set up the TWIN global area ---
264
265                 STMFD   R13!,{R0-R2}            ;Save some more registers
266                 LDR     R0,tw__TWIN             ;Load the global name word
267                 MOV     R1,#twin_size           ;And the size value
268                 BL      sapphire_global         ;Find the global area
269                 STR     R0,tw__twin             ;Save the address of this
270                 BCS     %10transWin_init        ;If already created, skip on
271
272                 MOV     R1,#0                   ;No flags set currently
273                 MOV     R2,#0                   ;No transient window set up
274                 MOV     R14,#0                  ;TMS hasn't registered itself
275                 STMIA   R0,{R1,R2,R14}          ;Save them in the area
276
277                 ; --- Now set up my fake event handler ---
278
279 10transWin_init BL      event_init              ;Make sure event is awake
280                 ADR     R0,tw__faker            ;Point to the fake handler
281                 MOV     R1,R12                  ;Pass it my workspace address
282                 BL      event_fakeHandler       ;Register the handler
283                 LDMFD   R13!,{R0-R2,R12,PC}^    ;And return to caller
284
285 tw__TWIN        DCB     "TWIN"
286
287                 LTORG
288
289 tw__wSpace      DCD     0
290
291 ;----- Workspace ------------------------------------------------------------
292
293                 ; --- TWIN global area layout ---
294                 ;
295                 ; This global area is intended to allow communication
296                 ; between transWin and menu system providers.
297                 ;
298                 ; The TMS hook is set by TMS to point to a pair of branch
299                 ; instructions to routines tmsh_subWaiting and tmsh_openSub
300                 ; respectively.
301                 ;
302                 ; tmsh_subWaiting should return CS if TMS is waiting to open
303                 ; a submenu, and CC otherwise.  tmsh_openSub is passed a
304                 ; window handle in R0, which it should open as a submenu in
305                 ; whatever way it sees fit.
306                 ;
307                 ; If the tmsHook pointer is zero, transWin will assume that
308                 ; TMS is not available.
309
310                 ^       0
311 twin_flags      #       4                       ;Various useful flags
312 twin_trans      #       4                       ;The current transient window
313 twin_tmsHook    #       4                       ;A hook to the TMS system
314 twin_size       #       0                       ;The size of the global area
315
316 twinFlag_recrt  EQU     (1<<0)                  ;Menu will be recreated
317
318 tmsh__subWaiting EQU    0
319 tmsh__openSub   EQU     4
320
321                 ; --- Workspace ---
322
323                 ^       0,R12
324 tw__wStart      #       0
325
326 tw__flags       #       4                       ;Various useful flags
327 tw__twin        #       4                       ;Pointer to the TWIN global
328
329 tw__wSize       EQU     {VAR}-tw__wStart
330
331 twFlag__inited  EQU     (1<<0)                  ;We have been initialised
332 twFlag__wimpCls EQU     (1<<1)                  ;Wimp closed last dbox
333
334                 AREA    |Sapphire$$LibData|,CODE,READONLY
335
336                 DCD     tw__wSize
337                 DCD     tw__wSpace
338                 DCD     0
339                 DCD     transWin_init
340
341 ;----- That's all, folks ----------------------------------------------------
342
343                 END