Initial revision
[ssr] / StraySrc / Libraries / Sapphire / s / menu
1 ;
2 ; menu.s
3 ;
4 ; RISC OS menu handling facilities (TMA)
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 ;----- External dependencies ------------------------------------------------
33
34 GET sapphire:event
35 GET sapphire:libOpts
36 GET sapphire:sapphire
37 GET sapphire:string
38 GET sapphire:fastMove
39 GET sapphire:msgs
40 GET sapphire:help
41
42 ;----- Useful values --------------------------------------------------------
43
44 mFlag_tearoff EQU (1<<1) ;Menu has a tearoff bar
45 mFlag_makeMe EQU (1<<2) ;Recreate menu on adjust
46 mFlag_maxHeight EQU (1<<3) ;Menu has a maximum height
47
48 mFlag_indirect EQU (1<<0) ;Item text is indirected
49 mFlag_shortcut EQU (1<<1) ;Item has a keyboard shortcut
50 mFlag_iShortcut EQU (1<<2) ;Item has an indirected S/C
51 mFlag_shade EQU (1<<3) ;Item is shadable
52 mFlag_iShade EQU (1<<4) ;Item is inverse shadable
53 mFlag_switch EQU (1<<5) ;Item is a switch
54 mFlag_radio EQU (1<<6) ;Item is a radio item
55 mFlag_sprite EQU (1<<7) ;Menu item has a sprite
56 mFlag_halfSize EQU (1<<8) ;Sprite is halfsize
57 mFlag_subWarn EQU (1<<9) ;Warn client if submenu warn
58 mFlag_subMenu EQU (1<<10) ;Item has menu to be opened
59
60 mFlag_R12 EQU (1<<16) ;Use R12 for runtime data
61 mFlag_noWarn EQU (1<<17) ;Don't warn on shaded items
62 mFlag_ruleOff EQU (1<<18) ;Put a ruleoff after item
63 mFlag_noTrans EQU (1<<19) ;Don't translate messages
64
65 mFlag_end EQU (1<<31) ;No more items
66
67 ; --- Event types ---
68
69 mEvent_select EQU 0 ;Normal menu selection
70 ; R1 == index of item
71 mEvent_arrow EQU 1 ;Sub menu warning
72 ; R1 == index of item
73 mEvent_deleted EQU 2 ;Menu has been deleted
74 mEvent_help EQU 3 ;Menu help requested
75 ; R1 == ndex of item
76 ; R2 == ptr to packed itmdef
77
78 ;----- Main code ------------------------------------------------------------
79
80 AREA |Sapphire$$Code|,CODE,READONLY
81
82 ; --- menu__createTitle ---
83 ;
84 ; On entry: R0 == pointer to menu title definition
85 ; R1 == event handler to use (not used here)
86 ; R2 == R10 value to use
87 ; R3 == R12 value to use
88 ; R4 == pointer to menu stack area
89 ; R5 == pointer into stack to build definition
90 ; R9 == workspace pointer
91 ;
92 ; On exit: R0 == points to first word after table
93 ; R1-R4 == preserved
94 ; R5 == next free word in stack after defintion
95 ;
96 ; Use: This call creates the title part of a WIMP menu from
97 ; a menu definition table (assuming that it has a menu
98 ; title definition).
99
100 menu__createTitle ROUT
101
102 STMFD R13!,{R1-R4,R6-R8,R14} ;Stack some registers
103
104 STMDB R4,{R0-R3} ;Store information in stack
105 LDR R7,[R0],#4 ;Get flags
106 MOV R8,R2 ;Use R10 for runtime data
107 TST R7,#mFlag_R12 ;Should we use R12?
108 MOVNE R8,R3 ;Yes, set R8 = R3 then
109 TST R7,#mFlag_indirect ;Is the title indirected
110 LDRNE R6,[R0],#4 ;Yes -- load the offset
111 LDRNE R6,[R6,R8] ;...find new pointer
112 BNE %05 ;...and jump the next bit
113
114 MOV R6,R0 ;Get the text pointer
115 00 LDRB R8,[R0],#1 ;Get a byte
116 CMP R8,#0 ;Was it the last character?
117 BNE %00 ;No -- keep looking
118 ADD R0,R0,#3 ;Word align
119 BIC R0,R0,#3 ;Oh yes indeedy
120
121 05 MOV R2,R0 ;Remember this pointer
122 MOV R0,R6 ;Point to the message
123 TST R7,#mFlag_noTrans ;Do we translate the string?
124 BLEQ msgs_lookup ;Yes -- lookup the message
125 MOV R6,R0 ;Remember new pointer
126 BL str_len ;Get the length of the text
127 STRGT R0,menu__maxLen ;Yes -- store new length
128 TST R7,#mFlag_makeMe ;Is the menu recreatable?
129 LDMNEIA R2!,{R8} ;Yes -- read it
130 TST R7,#mFlag_maxHeight ;Is there a maximum height
131 LDMNEIA R2!,{R8} ;Yes -- read it
132
133 ; --- Now enter data into stack ---
134
135 BL menu__checkOverflow ;Make sure there's room
136 MOV R0,R5 ;Copy to here...
137 MOV R1,R6 ;...this string
138 BL str_cpy ;Do the copy
139 ADD R5,R5,#12 ;Point past 12 bytes
140 MOV R0,R2 ;Get the pointer back
141 LDR R4,=&00070207 ;Colours
142 MOV R6,#40 ;Don't know width yet
143 MOV R7,#44 ;Item height
144 MOV R8,#0 ;Gap between items
145 STMIA R5!,{R4,R6-R8} ;Store information
146
147 ; --- Return thankfully ---
148
149 LDMFD R13!,{R1-R4,R6-R8,PC}^
150
151 LTORG
152
153 ; --- menu_create ---
154 ;
155 ; On entry: R0 == pointer to menu definition table
156 ; R1 == event handler to use
157 ; R2 == R10 value for handler
158 ; R3 == R12 value for handler
159 ;
160 ; On exit: --
161 ;
162 ; Use: Creates a menu from the given menu definition
163 ; table. If this call is called more than once before
164 ; a menu is opened then the menu definiton are concatenated
165 ; into a large menu. Only the first menu title read is
166 ; taken notice of. Notice therefore, that the call doesn't
167 ; actually open a menu.
168
169 EXPORT menu_create
170 menu_create ROUT
171
172 STMFD R13!,{R0-R12,R14} ;Stack some registers
173 WSPACE menu__wSpace,R9 ;Find my workspace
174
175 MOV R12,#0 ;Number of items so far
176
177 ; --- Do we need to read the menu title? ---
178
179 LDR R4,menu__flags ;Get the flags word
180 TST R4,#mFlag__creating ;Is this the first menu
181 BEQ %00menu_create ;Yes -- set up things
182
183 ; --- We are already creating a menu ---
184
185 LDR R6,menu__begin ;Get beginning of real menu
186 TST R4,#mFlag__tOnly ;Has just the title been done
187 SUBNE R4,R6,#24 ;Yes -- block already there
188 LDR R5,menu__end ;Get the end marker
189 LDMNEIA R13,{R0-R3} ;Reclaim useful values
190 STMNEFD R13!,{R0} ;Pointer to item definitions
191 BNE %05menu_create ;Now read the items
192
193 SUB R1,R6,#4 ;Copy from here..
194 ADD R0,R1,#20 ;...to here
195 SUB R2,R5,R1 ;...this much
196 BL fastMove ;Do the copy
197 ADD R5,R5,#20 ;Increment end pointer
198 MOV R4,R1 ;Write header here
199 ADD R6,R6,#20 ;The new beginning
200 STR R6,menu__begin ;Store new value
201 LDMIA R13,{R0-R3} ;Reclaim useful values
202 STMFD R13!,{R0} ;Pointer to item definitions
203 B %05menu_create ;Go through the items
204
205 ; --- We are creating a new menu ---
206
207 00menu_create STR R12,menu__maxLen ;Max length so far
208 TST R4,#mFlag__wasSub ;Was last event a submenu?
209 LDREQ R4,menu__stack ;No -- Get the stack address
210 LDRNE R4,menu__prevMenu ;Yes - start of previous menu
211 LDRNE R5,[R4] ;...get length of menu
212 ADDNE R4,R4,R5 ;Start new menu here
213 STR R4,menu__start ;The menu start (incl. defn)
214
215 ADD R5,R4,#44 ;Where to start adding defns
216 ADD R4,R4,#20 ;Where to write the header
217 MOV R6,#0 ;The last header marker
218 STR R6,[R5,#-4] ;Store it nicely
219 STR R5,menu__begin ;Store the begin pointer
220 BL menu__createTitle ;Create the title
221 STMFD R13!,{R0} ;Pointer to item definitions
222
223 ; --- Now go through the menu items ---
224 ;
225 ; At this point, R4 points to the menu header to write to,
226 ; R5 points into the stack at the position that the next
227 ; items should be written to. R0 points to the next menu
228 ; item.
229
230 05menu_create LDR R7,[R0],#4 ;Get flags
231 TST R7,#mFlag_end ;Any more items?
232 BNE %40menu_create ;Nope -- branch ahead
233 MOV R8,R2 ;Use R10 for runtime data
234 TST R7,#mFlag_R12 ;Should we use R12?
235 MOVNE R8,R3 ;Yes, set R8 = R3 then
236 TST R7,#mFlag_indirect ;Is the text indirected
237 LDRNE R6,[R0],#4 ;Yes -- load the offset
238 LDRNE R6,[R6,R8] ;...find new pointer
239 BNE %07menu_create ;...and jump the next bit
240
241 MOV R6,R0 ;Point to the string
242 06menu_create LDRB R1,[R0],#1 ;Get a byte
243 CMP R1,#0 ;Was it the last character?
244 BNE %06menu_create ;No -- keep looking
245 ADD R0,R0,#3 ;Word align
246 BIC R0,R0,#3 ;Oh yes indeedy
247
248 ; --- So, we have an item ---
249
250 07menu_create MOV R2,R0 ;Remember this pointer
251 MOV R0,R6 ;Point to the message
252 TST R7,#mFlag_noTrans ;Do we translate the string?
253 BLEQ msgs_lookup ;Yes -- lookup the message
254 MOV R6,R0 ;Remember new pointer
255 BL str_len ;Get the length of the text
256 TST R7,#mFlag_sprite ;Is there a sprite too?
257 ADDNE R0,R0,#2 ;Yes -- add 42 to the length
258 LDR R1,menu__maxLen ;Get maximum length so far
259 CMP R0,R1 ;Is new text longer?
260 STRGT R0,menu__maxLen ;Yes -- store new length
261 MOV R0,R2 ;Get the offset back
262 MOV R1,#24 ;The WIMP item flags so far
263 LDR R2,=&7000131 ;The icon flags so far
264
265 TST R7,#mFlag_shade ;Is it shadable?
266 BEQ %10menu_create ;No -- jump this code
267 BL %99 ;Do a bit specification
268 ORRCS R2,R2,#(1<<22) ;Set the 'shaded' bit
269
270 10menu_create TST R7,#mFlag_iShade ;Is it inverse shadable?
271 BEQ %15menu_create ;No -- jump this code
272 BL %99 ;Do a bit specification
273 ORRCC R2,R2,#(1<<22) ;Set the 'shaded' bit
274
275 15menu_create TST R7,#mFlag_switch ;Is it a switch?
276 BEQ %20menu_create ;No -- jump this code
277 BL %99 ;Do a bit specification
278 ORRCS R1,R1,#1 ;Set the tick flag
279
280 20menu_create TST R7,#mFlag_radio ;Is is a radio type?
281 BEQ %23menu_create ;No -- try next type
282 LDMIA R0!,{R10,R14} ;Get offset and selector
283 ADD R10,R10,R8 ;Get real offset
284 LDR R10,[R10] ;Get the word there
285 CMP R10,R14 ;It is the same as selector?
286 ORREQ R1,R1,#1 ;Yes -- set the tick flag
287
288 23menu_create TST R7,#mFlag_sprite ;Does item contain a sprite?
289 BEQ %25menu_create ;No -- try next type
290 LDR R10,[R0],#4 ;Get the sprite name pointer
291 ORR R2,R2,#2 ;Set the 'sprite' bit
292 STR R10,menu__sprite ;Store the sprite pointer
293
294 25menu_create TST R7,#mFlag_halfSize ;Make sprite half size?
295 ORRNE R2,R2,#(1<<11) ;Yeap -- set the bit
296
297 TST R7,#mFlag_noWarn ;Don't open subs if shaded?
298 BICNE R1,R1,#16 ;Clear relevant bit
299
300 TST R7,#mFlag_ruleOff ;Put a rule off here?
301 ORRNE R1,R1,#2 ;Yes -- set the bit up
302
303 ; --- Now store this information in the block ---
304
305 BL menu__checkOverflow ;Make sure there's room
306 MOV R10,R2 ;Put the icon flags in R10
307 MOV R2,#-1 ;No submenu yet
308 TST R7,#mFlag_subMenu ;Automatic sub menu?
309 LDMNEIA R0!,{R2,R14} ;Yes -- get menu pointer
310 TST R7,#mFlag_subWarn ;Submenu warning required
311 MOVNE R2,#1 ;Yeap -- put non -1 value in
312 STMIA R5!,{R1,R2,R10} ;Splodge!
313 TST R10,#2 ;Is the sprite bit set?
314 MOVEQ R10,#-1 ;No -- no validation
315 LDRNE R10,menu__sprite ;Yes -- point to sprite name
316 MOV R14,#255 ;Buffer length
317 STMIA R5!,{R6,R10,R14} ;Icon data -- splodge!
318
319 ; --- Now, keep searching for icons ---
320
321 ADD R12,R12,#1 ;Increment item count
322 ADD R1,R13,#8 ;Point to useful values
323 LDMIA R1,{R1-R3} ;Load back useful values
324 B %05menu_create ;Keep looking
325
326 ; --- All the icons have been found, tidy up ---
327
328 40menu_create LDR R0,menu__flags ;Get my flags word
329 CMP R12,#0 ;Did we create any items?
330 ORREQ R0,R0,#mFlag__tOnly ;Yes -- set the flag
331 BICNE R0,R0,#mFlag__tOnly ;No -- clear the flag
332 ORR R0,R0,#mFlag__creating ;We are creating a menu
333 STR R0,menu__flags ;Store updated flags
334 STR R12,[R4],#4 ;Store number of items
335 STR R5,menu__end ;The end pointer
336 LDR R6,menu__start ;Get the start
337 SUB R7,R5,R6 ;Get the length
338 STR R7,[R6] ;Store in the header
339 LDMFD R13!,{R5} ;First item pointer
340 LDMFD R13!,{R0-R3} ;Load some stuff
341 MOV R14,R0 ;Remember user R0
342 MOV R0,R5 ;Pointer to first item defn
343 STMIA R4!,{R0-R3} ;Store them in the header
344 MOV R0,R14 ;Preserve R0
345
346 ; --- And return to the client ---
347
348 LDMFD R13!,{R4-R12,PC}^ ;Return to client
349
350 ; --- Do a bit specification ---
351
352 99 STMFD R13!,{R14} ;Save a register
353 LDR R10,[R0],#4 ;Get the next word
354 ADD R14,R8,R10,LSR#5 ;Get the offset
355 LDR R14,[R14] ;And the byte there
356 AND R10,R10,#31 ;Clear bit we don't want
357 ADD R10,R10,#1 ;Correct for shifting
358 MOVS R14,R14,LSR R10 ;Shift that bit into carry
359 LDMFD R13!,{PC} ;And return to caller
360
361 LTORG
362
363 ; --- menu__checkOverflow ---
364 ;
365 ; On entry: R5 == offset in menu stack for creating next item
366 ;
367 ; On exit: --
368 ;
369 ; Use: Checks to see if there's enough room in the menu stack for
370 ; a new menu item or header.
371
372 menu__checkOverflow ROUT
373
374 STMFD R13!,{R14} ;Save some registers
375 LDR R14,menu__stackEnd ;Find the end of the stack
376 SUB R14,R14,#64 ;Allow a nice bit of space
377 CMP R14,R5 ;Do we have enough space?
378 LDMGEFD R13!,{PC}^ ;Yes -- return then
379
380 LDR R14,menu__flags ;Get my flags word
381 AND R14,R14,#mFlag__inited ;Reset all the flags
382 STR R14,menu__flags ;Store updated flags
383 MOV R1,#-1 ;An invalid menu pointer
384 SWI XWimp_CreateMenu ;Close the current menu tree
385 ADR R0,menu__noMem ;Point to error message
386 BL msgs_error ;Translate the error message
387 SWI OS_GenerateError ;And generate the error
388
389 menu__noMem DCD 1
390 DCB "mSOVF",0
391
392 LTORG
393
394 ; --- menu__recreate ---
395 ;
396 ; On entry: R1 == pointer to list of menu hits
397 ; R9 == pointer to workspace
398 ;
399 ; On exit: --
400 ;
401 ; Use: Called to recreate the menu definition after an adjust
402 ; click was made on a menu.
403
404 menu__recreate ROUT
405
406 STMFD R13!,{R0-R12,R14} ;Stack some registers
407
408 MOV R10,R1 ;We need this list
409 LDR R12,menu__stack ;Point to first menu header
410 00 LDR R0,[R10],#4 ;Load a menu hit (ignore 1st)
411 CMP R0,#-1 ;Is this the end?
412 BEQ %90 ;Yes -- finish
413
414 LDR R0,[R12,#4] ;Get the title defn pointer
415 LDR R2,[R0],#4 ;Get the flags word
416 MOV R6,R0 ;Point to the text
417 TST R2,#mFlag_R12 ;Do we use R12?
418 LDREQ R7,[R12,#12] ;No -- use R10 value
419 LDRNE R7,[R12,#16] ;Yes -- use R12 value
420
421 TST R2,#mFlag_indirect ;Is the text indirected?
422 LDRNE R6,[R0] ;Yes -- get the offset
423 LDRNE R6,[R7,R6] ;...load indirected pointer
424 BL menu__skipText ;Skip past the text
425 STMFD R13!,{R10} ;Save this R10 value
426 TST R2,#mFlag_makeMe ;Is it a 'makeme' type
427 BEQ %01 ;No -- skip this bit
428 LDR R5,[R10] ;Get the next hit
429 CMP R5,#-1 ;Are we at the last menu
430 BNE %01 ;No -- ignore this function
431 LDR R5,[R0],#4 ;Get the 'make me' function
432
433 ; --- Recreate the menu over the top of the old one ---
434
435 MOV R6,#0 ;Set the new length
436 STR R6,[R12] ;Store this length in field
437 LDR R6,menu__flags ;Get my flags word
438 ORR R6,R6,#mFlag__wasSub ;Fool menu_create
439 STR R6,menu__flags ;Store the modified flags
440 STR R12,menu__prevMenu ;Make this the previous menu
441 MOV R14,PC ;Set up the return address
442 MOV PC,R5 ;Branch to the function
443 ORR R6,R6,#mFlag__recreating ;We're recreating
444 STR R6,menu__flags ;Store the modified flags
445 STR R12,menu__start ;Update this menu
446 MOV R2,R6 ;Put the flags in R2
447 BL menu__open ;Set the menu up properley
448 BIC R6,R6,#mFlag__creating ;We're not really creating
449 STR R6,menu__flags ;Store the modified flags
450 B %90 ;Tidy up and return
451
452 01 MOV R0,R6 ;Point to the text
453 TST R2,#mFlag_noTrans ;Do we translate the string?
454 BLEQ msgs_lookup ;Yes -- lookup the message
455 MOV R6,R0 ;Remember new pointer
456 BL str_len ;Get the length of the text
457 STR R0,menu__maxLen ;Store max length
458
459 ; --- Go through the items changing the flags ---
460 ;
461 ; We have to use three pointers, one to keep track of
462 ; the real WIMP icon so that we can alter it, one
463 ; to keep track of our position in the users block, and
464 ; one to keep track of which header we are using!
465
466 ; --- Find the first real item ---
467
468 MOV R0,R12 ;Point to menu defn
469 BL menu__locateFirst ;Locate the first item
470 MOV R3,R0 ;Use R3 instead
471 STMFD R13!,{R3} ;Stack this pointer
472 SUB R0,R3,#28 ;Point the the menu header
473 MOV R1,R6 ;The text string
474 BL str_cpy ;Copy the title across
475 MOV R14,#7 ;Might have trashed colour
476 STRB R14,[R3,#12-28] ;So store colour back ;-)
477
478 ; --- Set up the pointer to the first header ---
479
480 ADD R1,R12,#20 ;Point to first header
481 05 LDR R8,[R1,#12] ;Get the R10 value
482 LDR R10,[R1,#16] ;Get the R12 value
483
484 ; --- Finally locate the users definition ---
485
486 LDR R0,[R1,#4] ;Get the pointer
487
488 ; --- Now go through the list ---
489
490 06 LDR R2,[R0],#4 ;Get the flags word
491 TST R2,#mFlag_end ;No more items?
492 BNE %20 ;No -- try for more
493 LDR R4,[R3,#0] ;Load the item flags
494 MOV R7,R8 ;Use R10 value
495 TST R2,#mFlag_R12 ;Do we use R12?
496 MOVNE R7,R10 ;Yes -- set up R7
497 MOV R5,R0 ;Pointer to the text
498 TST R2,#mFlag_indirect ;Is the text indirected?
499 LDRNE R0,[R0] ;Yes -- get the offset
500 LDRNE R0,[R7,R0] ;...load indirected pointer
501 TST R2,#mFlag_noTrans ;Do we translate the string?
502 BLEQ msgs_lookup ;Yes -- lookup the message
503 STR R0,[R3,#12] ;Store the new text pointer
504 BL str_len ;Get the length
505 TST R2,#mFlag_sprite ;Is there a sprite?
506 ADDNE R0,R0,#2 ;Yes -- allow for it
507 LDR R6,menu__maxLen ;Get the current max length
508 CMP R0,R6 ;Is new length longer?
509 STRGT R0,menu__maxLen ;Yes, store this
510 MOV R0,R5 ;Get current offset back
511 BL menu__skipText ;Skip the text part
512 07 TST R2,#mFlag_shade ;Is it shadable?
513 BEQ %10 ;No -- jump this code
514 BL %99 ;Do a bit specification
515 LDR R5,[R3,#8] ;Get the icon flags
516 ORRCS R5,R5,#(1<<22) ;Set the 'shaded' bit
517 BICCC R5,R5,#(1<<22) ;Or maybe clear it
518 STR R5,[R3,#8] ;Put them back
519
520 10 TST R2,#mFlag_iShade ;Is it inverse shadable?
521 BEQ %11 ;No -- jump this code
522 BL %99 ;Do a bit specification
523 LDR R5,[R3,#8] ;Get the icon flags
524 ORRCC R5,R5,#(1<<22) ;Set the 'shaded' bit
525 BICCS R5,R5,#(1<<22) ;Or maybe clear it
526 STR R5,[R3,#8] ;Put them back
527
528 11 TST R2,#mFlag_switch ;Is it a switch
529 BEQ %12 ;No -- jump this code
530 BL %99 ;Do a bit specification
531 ORRCS R4,R4,#1 ;Set the tick flag
532 BICCC R4,R4,#1 ;Or maybe clear it
533
534 12 TST R2,#mFlag_radio ;Is is a radio type?
535 BEQ %13 ;No -- jump this code
536 LDMIA R0!,{R5,R6} ;Get offset and selector
537 ADD R5,R5,R7 ;Get real offset
538 LDR R5,[R5] ;Get the word there
539 CMP R5,R6 ;It is the same as selector?
540 ORREQ R4,R4,#1 ;Yes -- set the tick flag
541 BICNE R4,R4,#1 ;No -- clear it
542
543 13 TST R2,#mFlag_sprite ;Is there a sprite?
544 ADDNE R0,R0,#4 ;Yes -- skip the pointer
545
546 TST R2,#mFlag_subMenu ;Automatic submenu?
547 ADDNE R0,R0,#8 ;Yes -- skip those fields
548
549 STR R4,[R3,#0] ;Store the item flags back
550 ADD R3,R3,#24 ;Point to next real icon
551 B %06 ;Try another icon
552
553 ; --- Try more items from next header ---
554
555 20 ADD R1,R1,#20 ;Point to next header
556 LDR R0,[R1] ;Get the item count
557 CMP R0,#0 ;Is there one?
558 BNE %05 ;...and do it
559
560 ; --- Now move onto next menu ---
561
562 LDMFD R13!,{R3} ;Get the first item pointer
563 LDR R0,menu__maxLen ;Get the menu with
564 ADD R0,R0,#1 ;Add a character width
565 MOV R0,R0,LSL#4 ;Multiply width by 16
566 STR R0,[R3,#-12] ;Store in menu width field
567 LDR R0,[R12] ;Get the length
568 ADD R12,R12,R0 ;Point to the next menu
569 LDMFD R13!,{R10} ;Load menu hit pointer
570 B %00 ;And keep looking
571
572 ; --- We have apparently finished now ---
573
574 90 LDMFD R13!,{R0-R12,PC}^ ;Return to caller
575
576 ; --- Calculate a bit specification ---
577
578 99 LDR R5,[R0],#4 ;Get the next word
579 ADD R6,R7,R5,LSR#5 ;Get the offset
580 LDR R6,[R6] ;And the byte there
581 AND R5,R5,#31 ;Clear bits we don't want
582 ADD R5,R5,#1 ;Correct for shifting
583 MOVS R6,R6,LSR R5 ;Shift that bit into carry
584 MOV PC,R14 ;Return from subroutine
585
586 LTORG
587
588 ; --- menu__locateFirst ---
589 ;
590 ; On entry: R0 == pointer to my menu defn
591 ;
592 ; On exit: R0 == pointer to first item in menu
593 ; R1 == Number of items in menu
594 ;
595 ; Use: Given a pointer to a menu definition (my type, not
596 ; WIMP), it returns a pointer to the first item, and
597 ; a count of the number of items in the menu.
598
599 menu__locateFirst
600 ROUT
601
602 STMFD R13!,{R2-R6,R14} ;Stack some registers
603
604 MOV R1,#0 ;Item count
605 ADD R0,R0,#20 ;Point past length/re-create
606 00 LDMIA R0!,{R2,R3,R4,R5,R6} ;Load menu data
607 CMP R2,#0 ;Is this the last item?
608 ADDNE R1,R1,R2 ;No -- increment item count
609 BNE %00 ;Keep searching
610 ADD R0,R0,#12 ;Point to the first item
611 LDMFD R13!,{R2-R6,PC}^ ;Return to caller
612
613 LTORG
614
615 ; --- menu__height ---
616 ;
617 ; On entry: R1 == pointer to real menu block
618 ;
619 ; On exit: R0 == height of menu
620 ;
621 ; Use: Calculates the height of a WIMP menu, from its data structure
622
623 menu__height ROUT
624
625 STMFD R13!,{R1-R2,R14} ;Stack some registers
626
627 MOV R0,#0 ;The height so far
628 ADD R1,R1,#28 ;Point to the first item
629 00 ADD R0,R0,#44 ;Increment the height
630 LDR R2,[R1] ;Get the flags word
631 TST R2,#2 ;Is there a dotted line?
632 ADDNE R0,R0,#24 ;Yes -- add 24 to height
633 TST R2,#&80 ;Is this the last item?
634 ADDEQ R1,R1,#24 ;No -- point to next item
635 BEQ %00 ;...and keep counting
636
637 LDMFD R13!,{R1-R2,PC}^ ;Return to caller
638
639 LTORG
640
641 ; --- menu__open ---
642 ;
643 ; On entry: R2 == modules flags word
644 ; R9 == workspace pointer
645 ;
646 ; On exit: --
647 ;
648 ; Use: Opens the next menu in the right place
649
650 menu__open ROUT
651
652 STMFD R13!,{R0-R4,R14} ;Stack some registers
653
654 LDR R0,menu__start ;Point to current menu
655 BL menu__locateFirst ;Find the first item
656 SUB R1,R1,#1 ;0 index item count
657 MOV R1,R1,LSL#3 ;Multiple no. of items by 8
658 RSB R1,R1,R1,LSL#2 ;And the by 3
659 ADD R1,R0,R1 ;Point to last item
660 LDR R3,[R1] ;Load the flags word
661 ORR R3,R3,#&80 ;Set 'Last item' bit
662 BIC R3,R3,#2 ;No ruleoff here
663 STR R3,[R1] ;Store the flags back
664
665 SUB R1,R0,#28 ;Point to real menu structure
666 LDR R0,menu__maxLen ;Get the longest text length
667 MOV R0,R0,LSL#4 ;Multiply by 16
668 ADD R0,R0,#16 ;Add one for luck
669 STR R0,[R1,#16] ;Store the width
670 MOV R4,R2 ;Remember flags word
671 TST R4,#mFlag__recreating ;Are we recreating a menu
672 LDMNEFD R13!,{R0-R4,PC}^ ;Yes -- Return
673 ADR R2,menu__coords ;Point to coords block
674 LDMIA R2,{R2,R3} ;Get the x and y coords
675
676 ; --- Ensure Y position is correct on icon bar ---
677
678 TST R4,#mFlag__iBar ;Was it on the icon bar?
679 BLNE menu__height ;Calculate the menu height
680 ADDNE R3,R0,#96 ;This is the Y position
681
682 TST R4,#mFlag__wasSub ;Is it a submenu?
683 BEQ %90 ;No -- create a normal menu
684 LDR R0,menu__prevMenu ;Get menu from which it came
685 ADD R0,R0,#20 ;Point to the first header
686 50menu__open LDR R14,[R0],#4 ;Get the number of items
687 CMP R14,#0 ;Any more headers?
688 ADDNE R0,R0,#16 ;Yes -- point to next one
689 BNE %50menu__open ;...and keep looking
690 ADD R0,R0,#28 ;Point to first item
691 LDR R14,menu__prevItem ;Get the previous item hit
692 MOV R14,R14,LSL#3 ;Multiply item hit by 8
693 RSB R14,R14,R14,LSL#2 ;And then by 3
694 ADD R0,R0,R14 ;Point to the item
695 STR R1,[R0,#4] ;Store pointer in menu field
696 SWI Wimp_CreateSubMenu ;Create sub menu
697 LDMFD R13!,{R0-R4,PC}^ ;Return
698
699 90menu__open SUB R2,R2,#64 ;No -- correct X position
700 SWI Wimp_CreateMenu ;...create the menu
701 ORR R4,R4,#mFlag__opened ;Set the opened bit
702 STR R4,menu__flags ;Store the modified flags
703 LDMFD R13!,{R0-R4,PC}^ ;Return
704
705 LTORG
706
707 ; --- menu__skipText ---
708 ;
709 ; On entry: R0 == pointer to text field
710 ; R2 == item flags for this item
711 ;
712 ; On exit: R0 == pointer to first data field after the text
713 ;
714 ; Use: Skips text part of an icon definition
715
716 menu__skipText ROUT
717
718 STMFD R13!,{R14} ;Stack registers
719
720 TST R2,#mFlag_indirect ;Is it indirected?
721 ADDNE R0,R0,#4 ;Yes -- just skip a word
722 LDMNEFD R13!,{PC}^ ;And return
723
724 00 LDRB R14,[R0],#1 ;Get a character
725 CMP R14,#0 ;Is it a NULL
726 BNE %00 ;No, keep looking
727 ADD R0,R0,#3 ;Word align R0
728 BIC R0,R0,#3 ;Complete aligning
729 LDMFD R13!,{PC}^ ;And return
730
731 LTORG
732
733 ; --- menu__findItem ---
734 ;
735 ; On entry: R0 == pointer to menu definition (my kind)
736 ; R1 == Item number to locate
737 ;
738 ; On exit: R0 == pointer to the item definition
739 ; R1 == pointer to header entry for this item
740 ; R2 == index for this item (to pass to handler)
741 ;
742 ; Use: Locates the given item from a created menu definition,
743 ; and also finds the header entry for it
744
745 menu__findItem ROUT
746
747 STMFD R13!,{R3,R4,R14} ;Stack some registers
748
749 ADD R0,R0,#20 ;Point to first header
750 MOV R2,#0 ;Item so far
751 00 LDR R3,[R0] ;Number of items header's for
752 MOV R4,R2 ;Number so far
753 ADD R2,R2,R3 ;Increment my count
754 CMP R1,R2 ;Is this the relevant header?
755 ADDGE R0,R0,#20 ;No -- point to next header
756 BGE %00 ;...and keep looking
757
758 ; --- We have located the relevant header ---
759
760 SUBS R3,R1,R4 ;Calculate item index
761 STMFD R13!,{R3} ;Store it on the stack
762 MOV R1,R0 ;Point to header for user
763 LDR R0,[R1,#4] ;Find definition pointer
764 10 LDMEQFD R13!,{R2-R4,PC}^ ;Yes -- return to caller
765 LDR R2,[R0],#4 ;Load the flags
766 BL menu__skipText ;Skip the text
767 TST R2,#mFlag_shade ;Is there a shade field
768 ADDNE R0,R0,#4 ;Yes -- skip it
769 TST R2,#mFlag_iShade ;Is there a ishade field
770 ADDNE R0,R0,#4 ;Yes -- skip it
771 TST R2,#mFlag_switch ;Is there a switch field
772 ADDNE R0,R0,#4 ;Yes -- skip it
773 TST R2,#mFlag_radio ;Are there radio fields
774 ADDNE R0,R0,#8 ;Yes -- skip them
775 TST R2,#mFlag_sprite ;Is there a sprite pointer?
776 ADDNE R0,R0,#4 ;Yes -- skip it
777 TST R2,#mFlag_subMenu ;Automatic submenu?
778 ADDNE R0,R0,#8 ;Yes -- skip fields
779 SUBS R3,R3,#1 ;Decrement the count
780 B %10 ;Keep searching
781
782 LTORG
783
784 ; --- menu__dispatch ---
785 ;
786 ; On entry: R0 == event type to send
787 ; R1 == pointer to menu hits
788 ;
789 ; On exit: --
790 ;
791 ; Use: Called to dispatch a menu hit event
792
793 menu__dispatch ROUT
794
795 STMFD R13!,{R0-R3,R10,R12,R14}
796
797 MOV R3,R0 ;Remember event to send
798 LDR R0,menu__stack ;Point to first menu header
799 00 LDR R2,[R1,#4]! ;Load a menu hit (ignore 1st)
800 CMP R2,#-1 ;Is this the end?
801 BEQ %10 ;Yes -- branch ahead
802 LDR R2,[R0] ;Get the length
803 ADD R0,R0,R2 ;Point to the next menu
804 B %00 ;And keep looking
805 10 LDR R1,[R1,#-4] ;Get the item number
806 BL menu__findItem ;Point to item and header
807 MOV R14,R0 ;Keep the item pointer
808 ADD R1,R1,#8 ;Point to the event handler
809 MOV R0,R3 ;Get the event type
810 LDMFD R1,{R3,R10,R12} ;Get the values
811 MOV R1,R2 ;The indexed item number
812 MOV R2,R14 ;Pass item address in R2
813 CMP R3,#0 ;Sanity check
814 MOV R14,PC ;Set up return address
815 MOVNE PC,R3 ;Jump to the event handler
816
817 LDMFD R13!,{R0-R3,R10,R12,PC}^ ;Return
818
819 LTORG
820
821 ; --- menu__preFilter ---
822 ;
823 ; On entry: R0 == event mask and flags
824 ; R1 == pointer to block to use
825 ; R2 == earliest time to return with NULL event
826 ; R3 == pointer to poll word
827 ;
828 ; On exit: --
829 ;
830 ; Use: Call as an event pre-filter. Its purpose is to open
831 ; a previously created menu in the right place.
832
833 menu__preFilter ROUT
834
835 STMFD R13!,{R0-R2,R9,R14} ;Stack some registers
836 MOV R9,R12 ;Get workspace pointer in R9
837
838 LDR R2,menu__flags ;Get my flags word
839 TST R2,#mFlag__creating ;Are we creating a menu?
840 BEQ %90menu__preFilter ;No -- return then
841 TST R2,#mFlag__wasSub ;Is this from a sub menu?
842 BNE %70menu__preFilter ;Yes -- just open the menu
843
844 ; --- Set up menu coordinates and things ---
845
846 BL event_last ;Get the last event
847 CMP R0,#6 ;Mouse click?
848 BEQ %50menu__preFilter ;Yes -- deal with it
849
850 ; --- Open over the mouse pointer then ---
851
852 MOV R14,R2 ;Preserve flags word
853 SUB R13,R13,#20 ;Get a block for me
854 MOV R1,R13 ;Point to the block
855 SWI Wimp_GetPointerInfo ;Get pointer information
856 LDMIA R1,{R0,R1} ;Get coords out of block
857 ADR R2,menu__coords ;Point to coords block
858 STMIA R2,{R0,R1} ;Store them in the block
859 ADD R13,R13,#20 ;Get stack back
860 MOV R2,R14 ;Get flags back
861 B %70menu__preFilter ;Open the menu
862
863 ; --- Deal with button click ---
864
865 50 MOV R14,R2 ;Preserve flags word
866 LDR R0,[R1,#12] ;Get the window handle
867 CMP R0,#-2 ;Is it the icon bar
868 BNE %60menu__preFilter ;No -- jump
869 ORR R14,R14,#mFlag__iBar ;Set relevent bit
870 STR R14,menu__flags ;Store the flags back
871 60 ADR R2,menu__coords ;Point to coords block
872 LDMIA R1,{R0,R1} ;Get x and y coords
873 STMIA R2,{R0,R1} ;Store them in the block
874 MOV R2,R14 ;Get flags word back
875
876 ; --- Open the menu,then ---
877
878 70 BL menu__open ;Yes -- open the menu
879 90 LDR R2,menu__flags ;Get new flags
880 AND R2,R2,#mFlag__inited+mFlag__opened
881 STR R2,menu__flags ;Store the new flags
882 LDMFD R13!,{R0-R2,R9,PC}^ ;Return to caller
883
884 LTORG
885
886 ; --- menu__postFilter ---
887 ;
888 ; On entry: R0 == wimp event
889 ; R1 == pointer to block
890 ;
891 ; On exit: --
892 ;
893 ; Use: Called as an event post filter to catch menu related events
894
895 menu__postFilter
896 ROUT
897
898 ; --- Are we at all interested? ---
899
900 STMFD R13!,{R9,R14} ;Store R9 value
901 MOV R9,R12 ;Get the workspace pointer
902 LDR R14,menu__flags ;Get the menu flags
903 TST R14,#mFlag__opened ;Do we have a menu open?
904 LDMEQFD R13!,{R9,PC}^ ;No -- ignore it then
905
906 CMP R0,#9 ;Menu click?
907 BEQ %20 ;Yes -- deal with that
908 CMP R0,#17 ;User_Message
909 CMPNE R0,#18 ;User_Message_Recorded
910 BNE %90 ;No -- tidy up a bit
911
912 ; --- It was a message, are we interested? ---
913 ;
914 ; Note that we are allowed to corrupt R12
915
916 STMFD R13!,{R0-R2} ;Stack some registers
917 LDR R0,=&400C0 ;Menu warning
918 LDR R12,[R1,#16] ;Get the message type
919 CMP R0,R12 ;Is it menu warning?
920 BEQ %05 ;Yes -- deal with it
921 LDR R0,=&400C9 ;Menus deleted
922 CMP R0,R12 ;Is that the message?
923 BEQ %03 ;Yes -- deal with it
924 LDR R0,=&502 ;Help request
925 CMP R0,R12 ;Is that the message?
926 LDMNEFD R13!,{R0-R2} ;No -- Get registers
927 BNE %90 ;...and tidy up a bit
928
929 ; --- There was a help request ---
930
931 STMFD R13!,{R3,R10,R12} ;We need these
932 SUB R13,R13,#40 ;Get a buffer
933 MOV R0,#1 ;Get state give window/icon
934 ADD R1,R1,#32 ;Point to window/icon handle
935 LDMIA R1,{R2,R3} ;Get them
936 LDR R14,menu__twin ;Get the dbmn address
937 LDR R14,[R14,#twin_trans] ;Get the transient dbox
938 CMP R14,R2 ;Are they the same
939 BEQ %02 ;Yes -- forget it
940 MOV R1,R13 ;Use this buffer
941 SWI XWimp_GetMenuState ;Get the menu state
942 BVS %02 ;If failed, return
943 LDR R0,[R1,#0] ;First first menu index
944 CMP R0,#-1 ;Is it on our menu?
945 BEQ %02 ;No -- skip forward
946 MOV R0,#mEvent_help ;Set the event type
947 BL menu__dispatch ;Dispatch the event
948
949 ; --- Return to caller ---
950
951 02 ADD R13,R13,#40 ;Reclaim my stack
952 LDMFD R13!,{R3,R10,R12} ;Get these values back
953 LDMFD R13!,{R0-R2} ;Get registers
954 B %90 ;...and tidy up a bit
955
956 ; --- There was a menus deleted message ---
957
958 03 STMFD R13!,{R10,R12} ;We need these
959 LDR R0,menu__flags ;Get the flags word
960 BIC R0,R0,#mFlag__opened ;Well,it's closed now
961 STR R0,menu__flags ;Store the flags back
962 LDR R0,menu__stack ;Find the top level menu
963 ADD R0,R0,#8 ;Point to the handler
964 LDMIA R0,{R2,R10,R12} ;Get handler and R10/R12
965 MOV R0,#mEvent_deleted ;Set the event type
966 CMP R2,#0 ;Sanity check
967 MOV R14,PC ;Set the return address
968 MOVNE PC,R2 ;Call the handler
969 04 LDMFD R13!,{R10,R12} ;Get these values back
970 LDMFD R13!,{R0-R2} ;Get registers
971 B %90 ;...and tidy up a bit
972
973 ; --- It was a submenu warning ---
974
975 05 LDR R0,menu__flags ;Get the flags
976 ORR R0,R0,#mFlag__wasSub ;It was a menu warning
977 STR R0,menu__flags ;Put the flags back
978 ADR R0,menu__coords ;Point to my coords block
979 ADD R1,R1,#24 ;Point to the (x,y) to use
980 LDMIA R1!,{R2,R12} ;Load x and y
981 STMIA R0,{R2,R12} ;And store them usefully
982
983 ; --- We now need to find the menu in question ---
984
985 LDR R0,menu__stack ;Point to first menu header
986 05 LDR R2,[R1,#4]! ;Load a menu hit (ignore 1st)
987 CMP R2,#-1 ;Is this the end?
988 BEQ %10 ;Yes -- branch ahead
989 LDR R2,[R0] ;Get the length
990 ADD R0,R0,R2 ;Point to the next menu
991 B %05 ;And keep looking
992 10 STR R0,menu__prevMenu ;Store this pointer
993 LDR R1,[R1,#-4] ;Get the item number
994 STR R1,menu__prevItem ;Store the item number
995
996 ; --- Now we need to create the submenu if we need to ---
997
998 BL menu__findItem ;Point to the item definition
999 LDR R2,[R0],#4 ;Get the flags word
1000 TST R2,#mFlag_subMenu ;Automatic menu?
1001 BNE %15 ;Yes -- deal with it
1002
1003 ; --- Here we must just tell the user ---
1004 ;
1005 ; R0 == pointer to the menu item definition+4
1006 ; R1 == pointer to the menu header for this item
1007 ; R2 == item flags
1008
1009 MOV R0,#mEvent_arrow ;Set the event type
1010 LDR R1,[R13,#4] ;Get the message block
1011 ADD R1,R1,#32 ;Point to the menu hit list
1012 BL menu__dispatch ;Dispatch the event
1013 LDMFD R13!,{R0-R2,R9,PC}^ ;Return to caller
1014
1015 ; --- We must automatically open the menu ---
1016
1017 15 BL menu__skipText ;Skip the item text
1018 TST R2,#mFlag_switch ;Is there a switch field
1019 ADDNE R0,R0,#4 ;Yes -- skip it
1020 TST R2,#mFlag_shade ;Is there a shade field
1021 ADDNE R0,R0,#4 ;Yes -- skip it
1022 TST R2,#mFlag_iShade ;Is there a ishade field
1023 ADDNE R0,R0,#4 ;Yes -- skip it
1024 TST R2,#mFlag_radio ;Are there radio fields
1025 ADDNE R0,R0,#8 ;Yes -- skip them
1026 TST R2,#mFlag_sprite ;Is there a sprite?
1027 ADDNE R0,R0,#4 ;Yes -- skip pointer
1028 ADD R1,R1,#12 ;Point to R10,R12 for item
1029 LDMIA R1,{R2,R3} ;Use these values again
1030 LDMIA R0,{R0,R1} ;Get menu pointer & handler
1031 BL menu_create ;Create this menu
1032
1033 LDMFD R13!,{R0-R2,R9,PC}^ ;Return to caller
1034
1035 ; --- Deal with menu selection ---
1036
1037 20 STMFD R13!,{R0-R2} ;Stack some registers
1038 BIC R14,R14,#mFlag__opened ;Say the menu just closed
1039 STR R14,menu__flags ;Save these flags back
1040
1041 ; --- Set up the dbmn flag word ---
1042
1043 LDR R2,menu__twin ;Locate dbmn area
1044 LDR R14,[R2,#twin_flags] ;Get the flags word
1045 ORR R14,R14,#twinFlag_recrt ;We are going to recreate it
1046 STR R14,[R2,#twin_flags] ;Store the flags back
1047
1048 ; --- Dispatch the event ---
1049
1050 MOV R0,#mEvent_select ;Set the event type
1051 BL menu__dispatch ;Dispatch the event
1052
1053 LDR R14,[R2,#twin_flags] ;Get the flags word back
1054 TST R14,#twinFlag_recrt ;Do we still need to recreate
1055 LDMEQFD R13!,{R0-R2} ;No -- get registers back
1056 BEQ %90 ;...and tidy up
1057
1058 ; --- Recreate the menu if we need to ---
1059
1060 SUB R13,R13,#20 ;Get a block
1061 MOV R1,R13 ;Point to it
1062 SWI Wimp_GetPointerInfo ;Get pointer information
1063 LDR R1,[R1,#8] ;Get the button state
1064 TST R1,#1 ;Was Adjust clicked?
1065 ADD R13,R13,#20 ;Get the stack back
1066 LDMEQFD R13!,{R0-R2} ;No -- get registers back
1067 BEQ %90 ;...and tidy up
1068 LDMIB R13,{R1} ;Get the menu hit list back
1069 BL menu__recreate ;Recreate the menu
1070 LDR R1,menu__stack ;Get the stack pointer
1071 ADD R1,R1,#20 ;Point to the first header
1072 25 LDR R0,[R1],#4 ;Get the number of items
1073 CMP R0,#0 ;Any more headers?
1074 ADDNE R1,R1,#16 ;Yes -- point to next one
1075 BNE %25 ;...and keep looking
1076 SWI Wimp_CreateMenu ;Recreate the menu
1077 LDR R14,menu__flags ;Load the menu flags again
1078 ORR R14,R14,#mFlag__opened ;The menu is still open
1079 STR R14,menu__flags ;Save the flags back
1080
1081 LDMFD R13!,{R0-R2} ;Get registers back
1082 B %90 ;And tidy up
1083
1084 ; --- Tidy up on a non-submenu warning event ---
1085
1086 90 LDR R12,menu__flags ;Get the flags
1087 BIC R12,R12,#mFlag__wasSub ;It was not a menu warning
1088 STR R12,menu__flags ;Put the flags back
1089 LDMFD R13!,{R9,PC}^ ;Return to caller
1090
1091 LTORG
1092
1093 ; --- menu_help ---
1094 ;
1095 ; On entry: R0 == pointer to base message tag
1096 ; R1 == index of menu item
1097 ;
1098 ; On exit: --
1099 ;
1100 ; Use: Adds a string to the help message found by adding the menu
1101 ; item number to the base message tag.
1102
1103 EXPORT menu_help
1104 menu_help ROUT
1105
1106 CMP R1,#0 ;Is the menu item sane?
1107 MOVLTS PC,R14 ;No -- don't trust Tim
1108 STMFD R13!,{R0-R2,R14} ;Save some registers
1109 MOV R1,R0 ;Point to base message tag
1110 MOV R0,R11 ;Point to scratchpad
1111 BL str_cpy ;Add the string in there
1112 MOV R1,R0 ;Point to terminating null
1113 MOV R2,#25 ;Should be 25 bytes left over
1114 LDR R0,[R13,#4] ;Get his item number
1115 SWI OS_ConvertInteger4 ;Tack it on the end
1116 MOV R0,R11 ;Point to the message tag
1117 BL msgs_lookup ;Translate it nicely
1118 BL help_add ;Add it to the help string
1119 LDMFD R13!,{R0-R2,PC}^ ;Return to caller
1120
1121 LTORG
1122
1123 ; --- menu_init ---
1124 ;
1125 ; On entry: --
1126 ;
1127 ; On exit: --
1128 ;
1129 ; Use: Initialises the menu system.
1130
1131 EXPORT menu_init
1132 menu_init ROUT
1133
1134 STMFD R13!,{R0-R3,R9,R14} ;Stack some registers
1135 WSPACE menu__wSpace,R9 ;Locate my workspace
1136
1137 ; --- Are we already initialised? ---
1138
1139 LDR R0,menu__flags ;Get my flags
1140 TST R0,#mFlag__inited ;Are we initialised?
1141 LDMNEFD R13!,{R0-R3,R9,PC}^ ;Yes -- return
1142
1143 ORR R0,R0,#mFlag__inited ;Set initialised flag
1144 STR R0,menu__flags ;And store them back
1145
1146 ; --- Ensure that event is initialised ---
1147
1148 BL event_init ;Initialise it
1149
1150 ; --- Set up my menu stack ---
1151
1152 LDR R0,menu__optName ;Get the option block name
1153 BL libOpts_find ;Try to find the block
1154 LDRCS R3,[R0,#0] ;If found, load stack size
1155 MOVCC R3,#2048 ;Otherwise use default 2K
1156 MOV R0,#2 ;Allocate memory
1157 BL sapphire_heapAddr ;Find the heap address
1158 SWI OS_Heap ;Allocate the stack
1159 STR R2,menu__stack ;Store this value
1160 ADD R3,R3,R2 ;The end of the menu stack
1161 STR R3,menu__stackEnd ;The menu stack end
1162
1163 ; --- Set up the filters ---
1164
1165 ADR R0,menu__preFilter ;Point to the filter
1166 MOV R1,R9 ;Use this workspace
1167 BL event_preFilter ;Add the pre filter
1168
1169 ADR R0,menu__postFilter ;Point to the filter
1170 MOV R1,R9 ;Use this workspace
1171 BL event_postFilter ;Add the post filter
1172
1173 ; --- Locate the TWIN global area ---
1174
1175 LDR R0,menu__TWIN ;Load the global area name
1176 MOV R1,#twin_size ;Load the area's size
1177 BL sapphire_global ;Find the area's address
1178 STR R0,menu__twin ;Store the address away
1179
1180 MOVCC R1,#0 ;Clear the global area
1181 MOVCC R2,#0
1182 MOVCC R14,#0
1183 STMCCIA R0,{R1,R2,R14} ;Store zeroes all over it
1184
1185 ; --- And return peacefully ---
1186
1187 LDMFD R13!,{R0-R3,R9,PC}^ ;Return to caller
1188
1189 menu__optName DCB "MENU"
1190 menu__TWIN DCB "TWIN"
1191
1192 LTORG
1193
1194 menu__wSpace DCD 0
1195
1196 ;----- Global area layouts --------------------------------------------------
1197
1198 ; --- TWIN global area ---
1199 ;
1200 ; See transWin for more details
1201
1202 ^ 0
1203 twin_flags # 4 ;Various flags for things
1204 twin_trans # 4 ;Handle of transient window
1205 twin_tmsHook # 4 ;Hook for TMS
1206 twin_size # 4
1207
1208 twinFlag_recrt EQU (1<<0) ;Do we want to recreate?
1209
1210 ;----- Workspace ------------------------------------------------------------
1211
1212 ^ 0,R9
1213 menu__wStart # 0
1214
1215 menu__flags # 4 ;Flags word
1216
1217 mFlag__inited EQU (1<<0) ;We are initialised
1218 mFlag__creating EQU (1<<1) ;We are creating a menu
1219 mFlag__wasSub EQU (1<<2) ;Last event was sub menu warn
1220 mFlag__tOnly EQU (1<<4) ;Only the title has been done
1221 mFlag__iBar EQU (1<<5) ;The click was on icon bar
1222 mFlag__recreating EQU (1<<6) ;We are recreating a menu
1223 mFlag__opened EQU (1<<7) ;I have a menu opened
1224
1225 menu__stack # 4 ;Pointer to the menu stack
1226 menu__stackEnd # 4 ;The end of the menu stack
1227 menu__start # 4 ;Start of current menu defn
1228 menu__begin # 4 ;Pointer to real menu
1229 menu__end # 4 ;The end of the menu
1230
1231 menu__maxLen # 4 ;Maximum length of items
1232 menu__sprite # 4 ;Pointer to a sprite name
1233 menu__coords # 8 ;(x,y) coords to open menu at
1234 menu__prevMenu # 4 ;Menu from which warning came
1235 menu__prevItem # 4 ;Menu from which warning came
1236 menu__twin # 4 ;Pointer to DBMN global area
1237
1238 menu__wSize EQU {VAR}-menu__wStart
1239
1240 AREA |Sapphire$$LibData|,CODE,READONLY
1241
1242 DCD menu__wSize ;Workspace size
1243 DCD menu__wSpace ;Workspace pointer
1244 DCD 0 ;Scratchpad size
1245 DCD menu_init ;Initialisation
1246
1247 ;----- That's all, folks ----------------------------------------------------
1248
1249 END