Initial revision
[ssr] / StraySrc / Libraries / Sapphire / tms / s / tmsGlue
1 ;
2 ; tmsGlue.s
3 ;
4 ; Supplies underlying tms workings -- filters, window creation etc. (TMA)
5 ;
6 ; © 1994 Straylight
7 ;
8
9 ;----- Standard Header ------------------------------------------------------
10
11 GET libs:header
12 GET libs:swis
13
14 GET libs:stream
15
16 ;----- External dependencies ------------------------------------------------
17
18 GET libs:tearSupt.sh.tearSupt
19
20 GET sapphire:event
21 GET sapphire:errorBox
22 GET sapphire:heap
23 GET sapphire:mem
24 GET sapphire:sapphire
25 GET sapphire:screen
26 GET sapphire:wimp
27 GET sapphire:win
28
29 ; --- Internal header files ----
30
31 GET sapphire:_tms.tmsGlobal
32 GET sapphire:_tms.tmsMain
33
34 ;----- Main code ------------------------------------------------------------
35
36 AREA |Sapphire$$Code|,CODE,READONLY
37
38 ;----- Window creation ------------------------------------------------------
39
40 ; --- tms__calcHeight ---
41 ;
42 ; On entry: R10 == pointer to menu
43 ;
44 ; On exit: R0 == The height of the menu, including tearoff bar (-ve)
45 ;
46 ; Use: Calculates the height of the window, and also sets up
47 ; the yCoord fields in the items
48
49 tms__calcHeight ROUT
50
51 STMFD R13!,{R1-R3,R14} ;Stack registers
52 MOV R14,R10 ;Keep this pointer
53 MOV R0,#0 ;The height so far
54 LDR R3,[R14,#hFlags] ;Get the flags word
55 TST R3,#hFlag__tearable ;Is there a tearoff bar?
56 SUBNE R0,R0,#tms__barHeight ;Yes -- allow for it
57 LDR R14,[R14,#hItems] ;Point to the items
58
59 00 CMP R14,#0 ;Are we at the end
60 RSBEQ R1,R0,#0 ;Get +ve height
61 STREQ R1,[R10,#hHeight] ;And store in height field
62 LDMEQFD R13!,{R1-R3,PC}^ ;Yes -- return
63 LDR R1,[R14,#iNumber] ;Get number of items in block
64 ADD R2,R14,#iHdrSize ;Point to the first item
65 01 LDR R3,[R2,#iFlags] ;Get the item flags
66 STR R0,[R2,#iyCoord] ;Store this coordinate
67 SUB R0,R0,#44 ;The size of one item
68 TST R3,#iFlag__dotted ;Is there a dotted line?
69 SUBNE R0,R0,#24 ;Yes -- allow for it
70 SUBS R1,R1,#1 ;Decrement item count
71 ADDNE R2,R2,#iItemSize ;Point to the next item
72 BNE %01tms__calcHeight ;...and count it
73 LDR R14,[R14,#iItems] ;If at end -- point to next
74 B %00tms__calcHeight ;...and count the next block
75
76 LTORG
77
78 ; --- tms__createWindow ---
79 ;
80 ; On entry: R0 == the menu height (-ve)
81 ; R10 == pointer to the menu
82 ;
83 ; On exit: V and R0 == The standard error block, if an error occured
84 ; R0 == the window handle
85 ;
86 ; Use: This call will create a window for the given menu. The
87 ; block pointed to by R10 will be filled in appropriately
88 ; with the handle.
89
90 EXPORT tms__createWindow
91 tms__createWindow ROUT
92
93 BIC R14,R14,#V_flag ;Assume no error yet
94 STMFD R13!,{R1-R9,R14} ;Stack some registers
95
96 SUB R13,R13,#88 ;Create a block
97 MOV R9,R13 ;Point to the block
98 MOV R5,R0 ;The menu height
99 LDR R6,[R10,#hMaxHeight] ;Get the maximum height
100 CMP R6,#0 ;Is there one?
101 BEQ %05tms__createWindow ;No -- jump this bit
102 CMN R6,R5 ;Is actual height greater?
103 MVNLE R5,R6 ;Yes -- make it maxHeight
104 05 ADR R0,tms__coords ;Point to the coords
105 LDMIA R0,{R0,R3} ;And get them
106 LDR R6,tms__flags ;Get the flags
107 TST R6,#tFlag__iBar ;Is menu from icon bar
108 ADDEQ R1,R3,R5 ;No -- miny = maxy-height
109 MOVNE R1,#96 ;Yes -- miny = 96
110 SUBNE R3,R1,R5 ;...maxy = miny+height
111 BNE %10tms__createWindow ;Jump the next text
112 LDR R6,[R10,#hFlags] ;Get the header flags
113 TST R6,#hFlag__tearable ;Is there a tearoff bar?
114 ADDNE R1,R1,#tms__barHeight ;Yes -- shift up menu
115 ADDNE R3,R3,#tms__barHeight ;Up, up, up we go
116 10 LDR R2,[R10,#hSprWidth] ;The sprite width
117 LDR R4,[R10,#hTextWidth] ;The text width
118 LDR R5,[R10,#hKeyWidth] ;The shortcut width
119 ADD R2,R2,R4 ;Calculate the width
120 ADD R2,R2,R5 ;Oh yes... Pleeeease!
121 ADD R2,R2,#64 ;Left/Right edges+16 for luck
122 LDR R14,[R10,#hTitleWidth] ;Get the title width
123 CMP R14,R2 ;Is this greater?
124 MOVGT R2,R14 ;Yes -- use this later
125 STR R2,[R10,#hTotWidth] ;Remember this value
126 ADD R2,R2,R0 ;And offset from x0
127 MOV R4,#0 ;Scroll x offset
128 MOV R5,#0 ;Scroll y offset
129 MOV R6,#-1 ;The behind value
130 LDR R7,=&84000002 ;The wimp flags
131
132 ; --- Add a scroll bar if we need to ---
133
134 LDR R14,[R10,#hFlags] ;Get the flags word
135 TST R14,#hFlag__folded ;Is the menu folded?
136 BNE %17tms__createWindow ;Yes -- no bar needed
137 LDR R8,[R10,#hHeight] ;Get the actual height
138 LDR R14,[R10,#hMaxHeight] ;Get the maximum height
139 CMP R14,#0 ;Is there one?
140 BEQ %12tms__createWindow ;No -- compare to screen hght
141 CMP R8,R14 ;Is it greater than max?
142 BGT %15tms__createWindow ;Yes -- add scroll bar
143 12 ADD R8,R8,#50 ;Add 50 to actual
144 STMFD R13!,{R0} ;preserve R0
145 BL screen_getInfo ;Get screen information
146 LDR R0,[R0,#screen_height] ;Get the screen height
147 CMP R8,R0 ;Is menu taller than screen?
148 LDMFD R13!,{R0} ;Get R0 back
149 BLE %17tms__createWindow ;No -- don't add bar
150
151 15 ORR R7,R7,#(1<<28) ;Give window a scroll bar
152 LDR R14,[R10,#hFlags] ;Get the menu flags
153 ORR R14,R14,#hFlag__scrBar ;There is a scroll bar
154 STR R14,[R10,#hFlags] ;Store the flags back
155 B %20tms__createWindow ;Jump ahead a bit
156
157 17 LDR R14,[R10,#hFlags] ;Get the menu flags
158 BIC R14,R14,#hFlag__scrBar ;There is a scroll bar
159 STR R14,[R10,#hFlags] ;Store the flags back
160
161 20 LDR R8,=&00070207 ;Colours
162 LDR R14,=&000c0103 ;More colours
163 STMIA R9!,{R0-R8,R14} ;Store in the block
164 SUB R2,R2,R0 ;Get the real width back
165 MOV R0,#0 ;Workarea x0
166 LDR R1,[R10,#hHeight] ;Get the actual height
167 RSB R1,R1,#0 ;Make it -ve
168 MOV R3,#0 ;y1 as for above
169 LDR R4,=&00000139 ;The title bar flags
170 LDR R5,=&00003000 ;The workarea button type
171 MOV R6,#1 ;The sprite area to use
172 MOV R7,#0 ;Minimum width/height
173 STMIA R9!,{R0-R7} ;Store in the block
174 LDR R0,[R10,#hText] ;Point to the text
175 MOV R1,#-1 ;no validation string
176 MOV R2,#&ff ;The buffer length
177 MOV R3,#0 ;No items yet
178 STMIA R9!,{R0-R3} ;Store this data
179 MOV R1,R13 ;Point to the block
180 SWI XWimp_CreateWindow ;Try to create the window
181 ADD R13,R13,#88 ;Get my block back
182 LDMVSFD R13!,{R1-R9,R14} ;On error, get the registers
183 ORRVSS PC,R14,#V_flag ;...and return with error
184 STR R0,[R10,#hHandle] ;Store the handle in menu
185 LDMFD R13!,{R1-R9,PC}^ ;And return to caller
186
187 LTORG
188
189 ;----- Pre and Post fileters ------------------------------------------------
190
191 ; --- tms__open ---
192 ;
193 ; On entry: R0 == pointer to menu to open
194 ;
195 ; On exit: ---
196 ;
197 ; Use: Opens the given tearoff menu in the right place
198
199 tms__open ROUT
200
201 STMFD R13!,{R0-R3,R10,R14} ;Stack some registers
202
203 ; --- Create the window ---
204
205 MOV R10,R0 ;Keep pointer to the menu
206 BL tms__calcHeight ;Work out the height of menu
207 BL tms__createWindow ;Create the window
208 MOVVS R1,#1 ;On error -- show 1 icon
209 BLVS errorBox ;...display the error
210 BVS %99tms__open ;...and return to caller
211
212 ; --- Set up an event handler for the menu ---
213
214 LDR R1,=tms__eventHandler ;Point to the event handler
215 MOV R2,R10 ;The handle of the menu
216 MOV R3,R12 ;R12 value to call with
217 BL win_eventHandler ;Add the handler
218
219 ; --- Now, open the window ---
220
221 SUB R13,R13,#36 ;Get a block
222 STR R0,[R13,#0] ;Store the handle in block
223 MOV R1,R13 ;Point to the block
224 SWI Wimp_GetWindowState ;Get the window state
225 SWI Wimp_OpenWindow ;Open the window
226 ADD R13,R13,#36 ;Get my block back
227
228 ; --- Fill in any extra information ---
229
230 LDR R0,tms__current ;Get the current transient
231 CMP R0,#0 ;Is there one
232 STREQ R10,tms__current ;No -- store this one then
233 BLEQ wimp_taskHandle ;...get the task handle
234 BLEQ tearSupport_opened ;...start tearoffsupt sending
235 LDR R0,tms__prevLevel ;Point to the previous menu
236 CMP R0,#0 ;Is there one?
237 STRNE R10,[R0,#hSubMenu] ;Yes -- store in sub menu ptr
238 STR R0,[R10,#hPrevMenu] ;Yes -- Point back to it
239 MOV R0,#0 ;Time to set some values
240 STR R0,[R10,#hSelected] ;No item selected yet
241 STR R0,[R10,#hSubMenu] ;No current submenu either
242
243 ; --- And return to the caller ---
244
245 99tms__open MOV R0,#0 ;We are no longer creating
246 STR R0,tms__creating ;So say that!
247 LDMFD R13!,{R0-R3,R10,PC}^ ;Return
248
249 LTORG
250
251 ; --- tms__preFilter ---
252 ;
253 ; On entry: R0 == event mask and flags
254 ; R1 == pointer to block to use
255 ; R2 == earliest time to return with NULL event
256 ; R3 == pointer to fxp_poll word
257 ;
258 ; On exit: --
259 ;
260 ; Use: Called as an event pre-filter. Its purpose is to open
261 ; a previously created menu in the right place.
262
263 tms__preFilter ROUT
264
265 STMFD R13!,{R0,R14} ;Stack some registers
266 LDR R0,tms__flags ;Get the main flags word
267 TST R0,#tFlag__doFake ;Should we fake a NULL?
268 BNE %10tms__preFilter ;Yes -- jump ahead then
269
270 ; --- Open a menu if we need to ---
271
272 LDR R0,tms__creating ;Point to menu being created
273 CMP R0,#0 ;Is there one?
274 LDMEQFD R13!,{R0,PC}^ ;No -- return
275 BL tms__open ;Open the menu
276 LDMFD R13!,{R0,PC}^ ;And return to the caller
277
278 ; --- Fake a NULL event ---
279
280 10 BIC R0,R0,#tFlag__doFake ;Don't fake again
281 ORR R0,R0,#tFlag__faking ;Remember that we're faking
282 STR R0,tms__flags ;Store back the flags
283 MOV R0,#0 ;Return event 0 (NULL)
284 ADD R13,R13,#4 ;Skip over old event code
285 LDMFD R13!,{R14} ;Load the link back
286 ORRS PC,R14,#C_flag ;And return with carry set
287
288 LTORG
289
290 ; --- tms__postFilter ---
291 ;
292 ; On entry: R0 == wimp event
293 ; R1 == the Wimp_Poll block
294 ;
295 ; On exit: --
296 ;
297 ; Use: Called as a post handle by event to look out for clever
298 ; things such as button clicks
299
300 tms__postFilter ROUT
301
302 STMFD R13!,{R0-R3,R14} ;Stack some regisr
303 CMP R0,#6 ;Was it a button click?
304 BEQ %10tms__postFilter ;Yes -- deal with it
305 LDR R2,tms__flags ;Get the flags
306 BIC R2,R2,#tFlag__iBar ;It wasn't a click on ibar
307 STR R2,tms__flags ;Store the flags back
308 CMP R0,#17 ;User_Message?
309 CMPNE R0,#18 ;User_Message_Recorded?
310 BEQ %20tms__postFilter ;Yes -- check it out
311 LDMFD R13!,{R0-R3,PC}^ ;Return
312
313 ; --- Deal with button click ---
314
315 10 LDR R0,[R1,#12] ;Get the window handle
316 CMP R0,#-2 ;Is it the icon bar
317 LDR R0,tms__flags ;Get the flags
318 ORREQ R0,R0,#tFlag__iBar ;Yes -- set relevent bit
319 BICNE R0,R0,#tFlag__iBar ;No -- clear it then
320 STR R0,tms__flags ;Store the flags back
321 ADR R2,tms__coords ;Point to coords block
322 LDMIA R1,{R0,R1} ;Get x and y coords
323 SUB R0,R0,#64 ;Correct the x coord
324 STMIA R2,{R0,R1} ;Store them in the block
325 LDMFD R13!,{R0-R3,PC}^ ;Return
326
327 ; --- It was a message ---
328
329 20 LDR R2,[R1,#16] ;Get the message type
330 LDR R0,=&400C1 ;Mode change
331 CMP R2,R0 ;Is that the message?
332 LDRNE R0,=&400CF ;Fonts changed
333 CMPNE R2,R0 ;Check this one too
334 BEQ %30tms__postFilter ;Yes -- deal with it
335 LDR R0,=&4A340 ;Button pressed message
336 CMP R2,R0 ;Is that the message?
337 BEQ %50tms__postFilter ;Yes -- deal with it
338 LDR R0,=&4A341 ;Close menus
339 CMP R2,R0 ;Is that the message?
340 BEQ %60tms__postFilter ;Yes -- deal with it
341 LDMFD R13!,{R0-R3,PC}^ ;Return
342
343 ; --- Mode change message ---
344
345 30 LDR R0,tms__oldHandle ;Get idle event handler hnd
346 CMP R0,#0 ;Is there a current handler?
347 BLNE tms__cleanUp ;Yes -- clean up a bit
348 LDR R2,tms__flags ;Get the flags word
349 BIC R2,R2,#tFlag__newFont ;No font change yet
350 LDR R1,tms__fHandle ;Get the old handle
351 MOV R0,#8 ;Read the wimp font handle
352 SWI XWimp_ReadSysInfo ;Read if we can
353 MOVVS R0,#0 ;If error -- no font
354 CMP R0,R1 ;Compare the handles
355 ORRNE R2,R2,#tFlag__newFont ;If different, mark this
356 STRNE R0,tms__fHandle ;...and store new font handle
357 STR R2,tms__flags ;Store new flags
358 LDMFD R13!,{R0-R3,PC}^ ;And return
359
360 ; --- Button pressed message ---
361 ;
362 ; We must check to see if we are clicking on one of
363 ; our menus, and close our current transient if we're not
364
365 50 LDR R2,[R1,#32] ;Get the window handle
366 LDR R3,tms__currDbox ;Get the current dbox
367 CMP R3,R2 ;Is this what we clicked on?
368 BEQ %70tms__postFilter ;Yes -- return then
369 LDR R0,tms__current ;Get the current menu
370 55 CMP R0,#0 ;Is there one?
371 BEQ %60tms__postFilter ;No -- close transient then
372 LDR R1,[R0,#hHandle] ;Get the window handle
373 CMP R1,R2 ;Are they the same
374 LDMEQFD R13!,{R0-R3,PC}^ ;Yes -- return
375 LDR R0,[R0,#hSubMenu] ;Get the submenu pointer
376 CMP R0,R3 ;Is it the dbox?
377 BNE %55tms__postFilter ;No -- check the submenus
378
379 ; --- Close the transient menu then ---
380
381 60 LDR R2,tms__current ;Point to the transient
382 CMP R2,#0 ;Is there one?
383 LDREQ R2,tms__currDbox ;No -- load dbox handle
384 MOV R0,R10 ;Remember R10 value
385 MOV R10,#0 ;We're not over any menu
386 BL tms__closeMenu ;Close the menu
387 MOV R10,R0 ;Get R10 value back
388 70 LDMFD R13!,{R0-R3,PC}^ ;And return to caller
389
390 LTORG
391
392 ;----- Initialisation -------------------------------------------------------
393
394 ; --- tms_init ---
395 ;
396 ; On entry: --
397 ;
398 ; On exit: --
399 ;
400 ; Use: Initialises the tms (Tearoff Menu System) unit.
401
402 EXPORT tms_init
403 tms_init ROUT
404
405 STMFD R13!,{R0-R2,R12,R14} ;Stack some registers
406 LDR R12,=tms__wSpace ;Locate my workspace pointer
407 WSPACE [R12] ;And then my workspace
408
409 ; --- Return if we are initialised ---
410
411 LDR R1,tms__flags ;Get the flags word
412 TST R1,#tFlag__inited ;Are we initialised
413 LDMNEFD R13!,{R0-R2,R12,PC}^ ;Yes -- return
414
415 ; --- Initialise various systems ---
416
417 BL win_init ;Initialise win
418 BL wimp_init ;And wimp
419 BL heap_init ;And heap
420
421 ; --- Set up the workspace values ---
422
423 ORR R1,R1,#tFlag__inited ;We are initialised now
424 BL wimp_version ;What wimp version is this
425
426 CMP R0,#300 ;RISC OS 3?
427 ORRGE R1,R1,#tFlag__riscos3 ;Yes -- remember this fact
428 STR R1,tms__flags ;Store the flags back
429
430 MOV R0,#8 ;Read current wimp font
431 SWI XWimp_ReadSysInfo ;Read it if possible
432 MOVVS R0,#0 ;If error -- no font
433 STR R0,tms__fHandle ;Store the handle away
434 ADR R0,tms__zInit ;Point to the correct block
435 MOV R1,#tms__zSize ;Get the size of the area
436 MOV R2,#0 ;Fill with zeros
437 BL mem_set ;And do it *very* quickly
438
439 STR R11,tms__R11 ;Save scratchpad address
440
441 ; --- Set up the filters ---
442
443 ADR R0,tms__preFilter ;Point to the routine
444 MOV R1,R12 ;Use this R12 value
445 BL event_preFilter ;Add the filter
446
447 ADR R0,tms__postFilter ;Point to the routine
448 MOV R1,R12 ;Use this R12 value
449 BL event_postFilter ;Add the filter
450
451 ; --- Set up the global area, and install hook ---
452
453 LDR R0,tms__TWIN ;Load the global area name
454 MOV R1,#twin_size ;Get the required size
455 BL sapphire_global ;Find its address
456 STR R0,tms__twin ;And store in my workspace
457 MOVCC R1,#0 ;Clear the values out...
458 MOVCC R14,#0 ;...if not already done
459 STMCCIA R0,{R1,R14} ;Store the zeroes in there
460 ADR R14,tms__hookTbl ;Point to the hook table
461 STR R14,[R0,#twin_tmsHook] ;Save in the hook entry
462
463 ; --- Initialise tearSupt ---
464
465 BL tearSupport_init ;Initialise it
466
467 ; --- And return to the user ---
468
469 LDMFD R13!,{R0-R2,R12,PC}^ ;Return to caller
470
471 tms__TWIN DCB "TWIN"
472
473 tms__hookTbl B tmsh__subWaiting
474 B tmsh__openSub
475
476 LTORG
477
478 ;----- That's all, folks ----------------------------------------------------
479
480 END