4 ; Supplies underlying tms workings -- filters, window creation etc. (TMA)
9 ;----- Standard Header ------------------------------------------------------
16 ;----- External dependencies ------------------------------------------------
18 GET libs:tearSupt.sh.tearSupt
29 ; --- Internal header files ----
31 GET sapphire:_tms.tmsGlobal
32 GET sapphire:_tms.tmsMain
34 ;----- Main code ------------------------------------------------------------
36 AREA |Sapphire$$Code|,CODE,READONLY
38 ;----- Window creation ------------------------------------------------------
40 ; --- tms__calcHeight ---
42 ; On entry: R10 == pointer to menu
44 ; On exit: R0 == The height of the menu, including tearoff bar (-ve)
46 ; Use: Calculates the height of the window, and also sets up
47 ; the yCoord fields in the items
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
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
78 ; --- tms__createWindow ---
80 ; On entry: R0 == the menu height (-ve)
81 ; R10 == pointer to the menu
83 ; On exit: V and R0 == The standard error block, if an error occured
84 ; R0 == the window handle
86 ; Use: This call will create a window for the given menu. The
87 ; block pointed to by R10 will be filled in appropriately
90 EXPORT tms__createWindow
91 tms__createWindow ROUT
93 BIC R14,R14,#V_flag ;Assume no error yet
94 STMFD R13!,{R1-R9,R14} ;Stack some registers
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
132 ; --- Add a scroll bar if we need to ---
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
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
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
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
189 ;----- Pre and Post fileters ------------------------------------------------
193 ; On entry: R0 == pointer to menu to open
197 ; Use: Opens the given tearoff menu in the right place
201 STMFD R13!,{R0-R3,R10,R14} ;Stack some registers
203 ; --- Create the window ---
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
212 ; --- Set up an event handler for the menu ---
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
219 ; --- Now, open the window ---
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
228 ; --- Fill in any extra information ---
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
243 ; --- And return to the caller ---
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
251 ; --- tms__preFilter ---
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
260 ; Use: Called as an event pre-filter. Its purpose is to open
261 ; a previously created menu in the right place.
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
270 ; --- Open a menu if we need to ---
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
278 ; --- Fake a NULL event ---
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
290 ; --- tms__postFilter ---
292 ; On entry: R0 == wimp event
293 ; R1 == the Wimp_Poll block
297 ; Use: Called as a post handle by event to look out for clever
298 ; things such as button clicks
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
313 ; --- Deal with button click ---
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
327 ; --- It was a message ---
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
343 ; --- Mode change message ---
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
360 ; --- Button pressed message ---
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
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
379 ; --- Close the transient menu then ---
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
392 ;----- Initialisation -------------------------------------------------------
400 ; Use: Initialises the tms (Tearoff Menu System) unit.
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
409 ; --- Return if we are initialised ---
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
415 ; --- Initialise various systems ---
417 BL win_init ;Initialise win
418 BL wimp_init ;And wimp
419 BL heap_init ;And heap
421 ; --- Set up the workspace values ---
423 ORR R1,R1,#tFlag__inited ;We are initialised now
424 BL wimp_version ;What wimp version is this
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
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
439 STR R11,tms__R11 ;Save scratchpad address
441 ; --- Set up the filters ---
443 ADR R0,tms__preFilter ;Point to the routine
444 MOV R1,R12 ;Use this R12 value
445 BL event_preFilter ;Add the filter
447 ADR R0,tms__postFilter ;Point to the routine
448 MOV R1,R12 ;Use this R12 value
449 BL event_postFilter ;Add the filter
451 ; --- Set up the global area, and install hook ---
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
463 ; --- Initialise tearSupt ---
465 BL tearSupport_init ;Initialise it
467 ; --- And return to the user ---
469 LDMFD R13!,{R0-R2,R12,PC}^ ;Return to caller
473 tms__hookTbl B tmsh__subWaiting
478 ;----- That's all, folks ----------------------------------------------------