4 ; Dialogue box handling (MDW)
6 ; © 1994-1998 Straylight
9 ;----- Licensing note -------------------------------------------------------
11 ; This file is part of Straylight's Sapphire library.
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)
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.
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.
27 ;----- Standard header ------------------------------------------------------
32 ;----- External dependencies ------------------------------------------------
49 ;----- Creating and deleting dialogue boxes ---------------------------------
51 AREA |Sapphire$$Code|,CODE,READONLY
55 ; On entry: R0 == pointer to dialogue template name
57 ; On exit: R0 == dialogue box handle for the dialogue
60 ; Use: Creates a dialogue box from a template definition.
65 STMFD R13!,{R1-R3,R14} ;Save some registers
67 ; --- Locate the template and copy it ---
69 MOV R3,R0 ;Keep name pointer safe
70 MOV R1,#0 ;No template created yet
71 BL template_find ;Find the actual definition
72 MOVVC R2,R0 ;Keep this pointer
73 MOVVS R2,#1 ;Otherwise assume shared rsc
74 MOV R0,R3 ;Point at the name again
75 BL template_copy ;And create the copy I use
76 MOVVC R1,R0 ;Look after the copy
78 ; --- Now create a dialogue box around it ---
80 BLVC dbox_fromDefn ;Create dbox from window def
81 STRVC R2,[R0,#dbox__template] ;Store the template pointer
82 LDMVCFD R13!,{R1-R3,R14} ;Unstack the registers
83 BICVCS PC,R14,#V_flag ;And return errorless
85 ; --- Tidy up aftet an error
87 MOV R2,R0 ;Look after this
88 MOVS R0,R1 ;Get the template pointer
89 BLNE template_free ;Maybe we free it
90 MOVNE R0,R2 ;If not, get error back
91 ADDEQ R2,R2,#4 ;Otherwise find error text
92 ADREQ R0,dbox__createErr ;Point to my skeleton error
93 BLEQ msgs_error ;Translate and substitute
94 LDMFD R13!,{R1-R3,R14} ;Restore registers
95 ORRS PC,R14,#V_flag ;Return the error
99 ; --- dbox_fromEmbedded ---
101 ; On entry: R0 == pointer to an embedded template
103 ; On exit: R0 == dialogue box handle
104 ; May return an error
106 ; Use: Creates a dialogue box from an embedded template definition.
108 EXPORT dbox_fromEmbedded
109 dbox_fromEmbedded ROUT
111 STMFD R13!,{R1,R2,R14} ;Save some registers
112 MOV R1,#0 ;Clear template pointer
113 BL template_embedded ;Copy the template
114 MOVVC R1,R0 ;Look after this
115 BLVC dbox_fromDefn ;Create the dialogue box
116 MOVVC R14,#1 ;Mark as a template
117 STRVC R14,[R0,#dbox__template] ;So it gets freed properly
118 LDMVCFD R13!,{R1,R2,R14} ;Restore registers
119 BICVCS PC,R14,#V_flag ;And return with no error
121 MOV R2,R0 ;Look after this
122 MOVS R0,R1 ;Get the template pointer
123 BLNE template_free ;Maybe we free it
124 MOVNE R0,R2 ;If not, get error back
125 ADDEQ R2,R2,#4 ;Otherwise find error text
126 ADREQ R0,dbox__createErr ;Point to my skeleton error
127 BLEQ msgs_error ;Translate and substitute
128 LDMFD R13!,{R1,R2,R14} ;Restore registers
129 ORRS PC,R14,#V_flag ;Return the error
133 ; --- dbox_fromDefn ---
135 ; On entry: R0 == pointer to a window definition
137 ; On exit: R0 == dialogue box handle for the dialogue
138 ; May return an error
140 ; Use: Creates a dialogue box from an immediate window definition,
141 ; rather than a template. There are several things you need
142 ; to be aware of when you use this call to create a dialogue
145 ; * The window definition is not copied, but used directly
146 ; for the duration the dialogue box exists. It must
147 ; not move for this duration. When the dialogue is
148 ; destroyed, you can release the memory for the definition,
149 ; although this is your responsibility.
151 ; * The indirected data is not copied either, so you'll have
152 ; to copy it yourself if you want multiple dialogues from
153 ; the same window definition.
155 ; * The window definition and the indirected data must both
161 STMFD R13!,{R1-R3,R10,R14} ;Save some registers away
163 ; --- Obtain a dbox block from the heap ---
165 MOV R3,R0 ;Look after the definition
166 MOV R0,#dbox__blockSize ;Find out how much I need
167 BL alloc ;Allocate the memory
168 BLCS alloc_error ;If it failed, find error msg
169 BCS %99dbox_fromDefn ;... and quit if no memory
171 ; --- Now start filling in the structure ---
173 STR R3,[R0,#dbox__defn] ;Store the copy pointer away
174 MOV R2,#0 ;Start zeroing things
175 STR R2,[R0,#dbox__proc] ;No event handler yet
176 STR R2,[R0,#dbox__flags] ;Dialogue box has no flags
177 STR R2,[R0,#dbx__defn] ;Dbox not nabbed by dbx yet
178 STR R2,[R0,#dbox__template] ;No template definition
179 MOV R2,#-1 ;No embedded title icon
180 STR R2,[R0,#dbox__title] ;So store it away
181 MOV R10,R0 ;Keep this pointer safe
183 ; --- Now we need to create a window ---
185 MOV R1,R3 ;Point to the window defn
186 SWI XWimp_CreateWindow ;Create the window
187 BVS %98dbox_fromDefn ;If it failed, tidy up
188 STR R0,[R10,#dbox__window] ;Store the window handle
190 ; --- Now register our event handler for it ---
192 ADR R1,dbox__events ;Point to my event handler
193 MOV R2,R10 ;Pass the dialogue box handle
194 WSPACE dbox__wSpace,R3 ;And my workspace pointer
195 BL win_eventHandler ;Register the event handler
196 BVS %97dbox_fromDefn ;If that failed, tidy up
198 ; --- Now return the dialogue box handle ---
200 MOV R0,R10 ;Return pointer to my block
201 LDMFD R13!,{R1-R3,R10,R14} ;Restore the registers
202 BICS PC,R14,#V_flag ;Return with no errors
204 ; --- Tidy up after unfortunate events ---
206 97dbox_fromDefn MOV R3,R0 ;Keep error pointer
207 ADD R1,R10,#dbox__window ;Point to the window handle
208 SWI Wimp_DeleteWindow ;Delete the duff window
209 MOV R0,R3 ;Restore error pointer
211 98dbox_fromDefn MOV R2,R0 ;Keep error pointer
212 MOV R0,R10 ;Point to the block
213 BL free ;Free it up -- it's useless
214 MOV R0,R2 ;Restore error pointer
216 99dbox_fromDefn ADD R2,R0,#4 ;Point to the error message
217 ADR R0,dbox__createErr ;Point to my skeleton error
218 BL msgs_error ;Translate and substitute
219 LDMFD R13!,{R1-R3,R10,R14} ;Restore registers
220 ORRS PC,R14,#V_flag ;Return the error
222 dbox__createErr DCD 1
225 ; --- dbox_destroy ---
227 ; On entry: R0 == dialogue box handle
231 ; Use: Destroys a dialogue box, freeing all the memory it took
237 STMFD R13!,{R0,R1,R10,R14} ;Save some registers
238 MOV R10,R0 ;Get the dialogue handle
240 ; --- Make sure the dialogue's been closed ---
242 BL dbox_close ;Close the dialogue box
243 MOV R0,#dbEvent_lifeCycle ;Send a lifecycle message
244 MOV R1,#dblc_destroy ;Dialogue will be destroyed
245 BL dbox__dispatch ;Send the message
247 ; --- Remove the event handler ---
249 LDR R0,[R10,#dbox__window] ;Find the window handle
250 BL win_windowDeleted ;Window doesn't need handling
252 ; --- Delete the window ---
254 ADD R1,R10,#dbox__window ;Point to the window handle
255 SWI Wimp_DeleteWindow ;Delete the window
257 ; --- Free the template copy ---
259 LDR R14,[R10,#dbox__template] ;Load the template address
260 CMP R14,#0 ;Is there one defined?
261 LDRNE R0,[R10,#dbox__defn] ;Point to the template copy
262 BLNE template_free ;Free it up now
264 ; --- Free the dialogue block ---
266 MOV R0,R10 ;Point to the dbox block
267 BL free ;Free its memory up
269 ; --- Return to caller ---
271 LDMFD R13!,{R0,R1,R10,PC}^ ;Return to caller
273 ;----- The event handler ---------------------------------------------------
275 ; --- dbox__events ---
277 ; On entry: R0 == the event code that happened
278 ; R1 == pointer to the event data
279 ; R10 == dialogue box it happened to
281 ; On exit: CS if we handled the event, CC otherwise
283 ; Use: Handles various events for a dialogue box
287 ; --- Dispatch the event to the right place ---
289 STR R10,dbox__eventDbox ;Remember this handle
290 CMP R0,#9 ;Is it a sensible event?
291 BGE %00dbox__events ;No -- check for messages
292 ADD PC,PC,R0,LSL #2 ;Yes -- dispatch to handler
294 ; --- Event dispatch table ---
296 B dbox__hint ;Hint for the hint bar
297 MOVS PC,R14 ;Null event
298 B dbox__redraw ;Redraw window request
299 B dbox__open ;Open window request
300 B dbox__close ;Close window request
301 B dbox__enterLeave ;Pointer leaving window
302 B dbox__enterLeave ;Pointer entering window
303 B dbox__mouse ;Mouse clicked
304 MOVS PC,R14 ;Drag event
305 B dbox__keyPress ;Key pressed
307 ; --- Handle a message ---
309 00dbox__events CMP R0,#17 ;User message
310 CMPNE R0,#18 ;Rubber message (bouncy!)
311 MOVNES PC,R14 ;No -- return unhandled
312 B dbox__message ;Handle the message event
314 ; --- dbox__dispatch ---
316 ; On entry: R0 == the (dbox-style) event code to dispatch
317 ; R1-R7 == any additional arguments that want passing along
318 ; R10 == the dialogue box to send the event to
320 ; On exit: CS or CC from the event handler
322 ; Use: Dispatches an event to the event handler associated with the
323 ; dialogue box, and returns its response.
327 STMFD R13!,{R8-R10,R12,R14} ;Save lots of registers
328 MOV R9,R10 ;Pass dialogue handle in R9
329 ADDS R0,R0,#0 ;Clear the carry flag
330 LDMIB R10,{R8,R10,R12} ;Get the event handler stuff
331 TEQ R8,#0 ;Is there an event handler?
332 MOVNE R14,PC ;Set up return address
333 MOVNE PC,R8 ;Call the event handler
334 LDMFD R13!,{R8-R10,R12,R14} ;Restore the registers
335 ORRCSS PC,R14,#C_flag ;Return CS if it returned CS
336 BICCCS PC,R14,#C_flag ;Return CC if it returned CC
340 ; --- dbox__checkIcon ---
342 ; On entry: R1 == icon handle
343 ; R10 == dialogue box handle
345 ; On exit: R1 == icon handle or -1 if it was shaded
347 ; Use: Translates an icon handle to the window background if it
348 ; is shaded, for passing to event handlers.
352 STMFD R13!,{R0,R14} ;Save some registers
353 MOV R0,R1 ;Move icon handle along
354 BL dbox__icon ;Find the icon definition
355 LDR R14,[R0,#16] ;Load the icon flags
356 TST R14,#&00400000 ;Is the icon shaded?
357 MOVNE R1,#-1 ;Yes -- return background
358 STR R1,dbox__eventIcon ;Store in workspace
359 LDMFD R13!,{R0,PC}^ ;Return to caller
366 ; R1 == pointer to hint event block
368 ; On exit: C set if handled
370 ; Use: Sends a hint event to the dbox handler
374 STMFD R13!,{R0-R2,R14} ;Save some registers
375 MOV R0,#dbEvent_hint ;The event code
376 ADD R2,R1,#4 ;Point to the string
377 BL dbox__dispatch ;Send it to the handler
378 LDMFD R13!,{R0-R2,PC} ;Return with its flags
382 ; --- dbox__redraw ---
385 ; R1 == pointer to window handle
389 ; Use: Redraws a window using Sculptrix
393 STMFD R13!,{R0,R2,R3,R14} ;Save some registers
395 ; --- Start the redraw operation ---
397 SWI Wimp_RedrawWindow ;Start the redraw
398 CMP R0,#0 ;Is it over already?
399 BEQ %10dbox__redraw ;Yes -- skip to the end
401 ; --- Set up Sculptrix's sprite area ---
403 LDR R0,[R10,#dbox__defn] ;Find the window definition
404 LDR R0,[R0,#64] ;Load the sprite area pointer
405 SWI XSculptrix_SetSpriteArea ;Set up the sprite area
407 ; --- Do any bits that need doing ---
409 00dbox__redraw LDR R2,[R1,#4] ;Get the window left position
410 ADD R0,R1,#16 ;Point to the top position
411 LDMIA R0,{R0,R3,R14} ;Load top, and scroll posns
412 SUB R2,R2,R3 ;Convert to find origin x
413 SUB R3,R0,R14 ;Convert to find origin y
414 MOV R0,#dbEvent_redraw ;Give user a redraw event
415 BL dbox__dispatch ;Send it to the handler
416 BCS %01dbox__redraw ;If it claimed it, skip ahead
418 LDR R0,[R10,#dbox__title] ;Get the embedded title icon
419 CMP R0,#-1 ;Has it been defined?
420 MOVNE R0,R10 ;Give it the dialogue box
421 BLNE dbox_renderTitle ;Yes -- render it nicely
423 SWI XSculptrix_RedrawWindow ;Get Sculptrix to do its bit
425 01dbox__redraw SWI Wimp_GetRectangle ;Get the next rectangle
426 CMP R0,#0 ;Is this the end yet?
427 BNE %00dbox__redraw ;No -- do the rest
429 ; --- That's it, then ---
431 10dbox__redraw LDMFD R13!,{R0,R2,R3,R14} ;Unstack all the registers
432 ORRS PC,R14,#C_flag ;Set carry and return
439 ; R1 == pointer to window open block
443 ; Use: This just opens the window. Later, it may do clever things
446 dbox__open SWI Wimp_OpenWindow ;Open the window
447 ORRS PC,R14,#C_flag ;Set carry and return
449 ; --- dbox__close ---
452 ; R1 == pointer to the window handle
456 ; Use: Passes a close event to the user dialogue box handler.
458 dbox__close STMFD R13!,{R0,R14} ;Save some registers
459 MOV R0,#dbEvent_close ;The close event code
460 BL dbox__dispatch ;Pass it to the handler
461 LDMFD R13!,{R0,R14} ;Unstack all the registers
462 ORRS PC,R14,#C_flag ;Set carry and return
464 ; --- dbox__mouse ---
467 ; R1 == pointer to mouse status block
469 ; On exit: C set if we understood the event, C clear otherwise
471 ; Use: Passes a click event to the dbox event handler.
475 STMFD R13!,{R0-R2,R9,R14} ;Save some registers
476 MOV R9,R1 ;Keep the event pointer
477 LDR R1,[R9,#8] ;Get the button status
478 TST R1,#&5 ;Is it Select or Adjust?
479 BNE %10dbox__mouse ;Yes -- handle it nicely
480 TST R1,#&50 ;Is it a drag event?
481 BNE %20dbox__mouse ;Yes -- handle it nicely
482 TST R1,#&2 ;Is it a menu click?
483 LDMEQFD R13!,{R0-R2,R9,PC}^ ;No -- we're clueless then
485 ; --- The user clicked Menu ---
487 LDR R1,[R9,#16] ;Get the icon handle out
488 MOV R0,#dbEvent_menu ;Give it a menu click
489 BL dbox__checkIcon ;Handle icon shadedness
490 BL dbox__dispatch ;Give it to the user
491 B %80dbox__mouse ;And return C set
493 ; --- The user clicked Select or Adjust ---
495 10dbox__mouse LDR R1,[R9,#16] ;Get the icon handle out
496 BL dbox__checkIcon ;Handle icon shadedness
497 MOV R0,R1 ;Return icon number as event
498 LDR R1,[R9,#8] ;Load the button state again
499 BL dbox__dispatch ;Dispatch the event out
500 BCS %80dbox__mouse ;If handled, skip this bit
502 MOV R1,R0 ;Get the icon handle in R1
503 MOV R0,R10 ;And dialogue handle in R0
504 BL dbox_radio ;Handle magic radio buttons
506 LDR R0,[R10,#dbox__flags] ;Get this dialogue's flags
507 TST R0,#dbFlag__drag ;Is the move on drag bit on?
508 BEQ %80dbox__mouse ;No -- skip this bit out
510 SUB R13,R13,#56 ;Make a drag info block
511 LDR R0,[R10,#dbox__window] ;Get the window handle
512 STR R0,[R13,#0] ;Store the window handle
513 MOV R0,#1 ;Move the window
514 STR R0,[R13,#4] ;Store the drag type
515 MOV R1,R13 ;Point to the block
516 SWI Wimp_DragBox ;Start the window moving
517 ADD R13,R13,#56 ;Reclaim the stack space
518 B %80dbox__mouse ;Skip ahead to claim event
520 ; --- The user dragged an icon ---
522 20dbox__mouse LDR R1,[R9,#16] ;Get the icon handle out
523 BL dbox__checkIcon ;Handle shadiness nicely
524 MOV R2,R1 ;Move handle to right place
525 LDR R1,[R9,#8] ;Load button status again
526 MOV R0,#dbEvent_drag ;Give handler a drag event
527 BL dbox__dispatch ;And pass it to the handler
528 B %80dbox__mouse ;And claim the event
530 ; --- Finish everything off nicely ---
532 80dbox__mouse LDMFD R13!,{R0-R2,R9,R14} ;Restore the registers
533 ORRS PC,R14,#C_flag ;Claim the event nicely
537 ; --- dbox__enterLeave ---
539 ; On entry: R0 == 4 for leaving, 5 for entering
543 ; Use: Informs dialogue handlers that pointer has entered or left
546 dbox__enterLeave ROUT
548 STMFD R13!,{R0,R14} ;Save some registers
549 ADD R0,R0,#dbEvent_leave-4 ;Convert to appropriate event
550 BL dbox__dispatch ;Send it to the handler
551 LDMFD R13!,{R0,PC}^ ;And return to caller
555 ; --- dbox__keyPress ---
558 ; R1 == pointer to caret block
562 ; Use: Handles key events for a dialogue box
566 STMFD R13!,{R0-R3,R14} ;Save some registers
568 ; --- Send the event to the user ---
570 LDR R2,[R1,#4] ;Get the icon handle
571 STR R2,dbox__eventIcon ;Store it in workspace
572 LDR R0,[R1,#24] ;Get the key code
573 BL akbd_translate ;Mangle for extended keyset
574 MOV R1,R0 ;Move into right register
575 MOV R0,#dbEvent_key ;Key event code
576 BL dbox__dispatch ;Send it to the user
577 BCS %50dbox__keyPress ;If processed, skip ahead
579 ; --- Now see if it's one of ours ---
581 CMP R1,#&100 ;Is it an extended code?
582 BGE %20dbox__keyPress ;Yes -- skip forward
584 CMP R1,#key_Return ;Is it a return?
585 MOVEQ R0,#dbEvent_OK ;Yes -- give out an OK event
586 BEQ %10dbox__keyPress ;Send it on its way
587 CMP R1,#key_Esc ;Or maybe an escape
588 MOVEQ R0,#dbEvent_cancel ;Yes -- give a Cancel event
589 BEQ %10dbox__keyPress ;Send it on its way
591 00 LDMFD R13!,{R0-R3,PC}^ ;Forget it -- don't know
593 ; --- Send a key event on ---
595 10 MOV R1,#4 ;Pretend Select was pressed
596 BL dbox__dispatch ;Send it to the client
597 B %50dbox__keyPress ;Now we've done the deed...
599 11 MOV R1,#1 ;Pretend Adjust was pressed
600 BL dbox__dispatch ;Send it to the client
601 B %50dbox__keyPress ;Now we've done the deed...
603 ; --- Handle an extended key ---
605 20 AND R2,R1,#&FF ;Leave the bottom byte
607 ; --- Straight cursor keys ---
611 CMP R2,#key_kEnter-256
613 BEQ %10dbox__keyPress
615 CMP R2,#key_sReturn-256
616 CMPNE R2,#key_skEnter-256
618 BEQ %11dbox__keyPress
621 MOVEQ R0,#dbEvent_cancel
622 BEQ %11dbox__keyPress
625 CMPNE R2,#key_sTab-256
627 BEQ %40dbox__keyPress
630 CMPNE R2,#key_Tab-256
632 BEQ %40dbox__keyPress
634 ; --- Control cursor keys ---
640 BEQ %40dbox__keyPress
644 CMP R2,#key_cDown-256
646 BEQ %40dbox__keyPress
648 ; --- Nothing worth knowing about ---
652 ; --- Actually do a cursor move ---
654 40 BL dbox__moveCaret ;Do the cursor move
656 ; --- Return and claim the keypress ---
658 50 LDMFD R13!,{R0-R3,R14}
663 ; --- dbox__message ---
665 ; On entry: R0 == 17 or 18
666 ; R1 == pointer to message data
668 ; On exit: C set if the event was handled, or clear otherwise
670 ; Use: Handles messages sent to dialogue boxes.
674 STMFD R13!,{R0-R4,R9,R14} ;Save some registers
675 MOV R9,R1 ;Point to the event block
676 LDR R14,[R9,#16] ;Get the message type number
677 CMP R14,#1 ;Is it a save message?
678 CMPNE R14,#3 ;Or a load message?
679 BEQ %10dbox__message ;Yes -- handle them the same
680 MOV R0,#&500 ;&502 is a help request
681 ORR R0,R0,#&002 ;Build the full number
682 CMP R14,R0 ;Is it a help request?
683 LDMNEFD R13!,{R0-R4,R9,PC}^ ;No -- we don't understand
685 ; --- Handle help requests for the dbox ---
687 LDR R1,[R9,#36] ;Obtain the icon handle
688 BL dbox__checkIcon ;Handle icon shadiness
689 MOV R0,#dbEvent_help ;Pass a help request on
690 BL dbox__dispatch ;Send it to the client
691 B %80dbox__message ;Skip on and claim the event
693 ; --- Handle save and load events ---
695 10dbox__message CMP R14,#1 ;Is it a save message?
696 MOVEQ R0,#dbEvent_save ;Yes -- give a save event
697 MOVNE R0,#dbEvent_load ;No -- give a load event
698 LDR R1,[R9,#24] ;Get the icon handle
699 BL dbox__checkIcon ;Handle icon shadiness
700 LDR R2,[R9,#40] ;Get filetype in R2
701 ADD R3,R9,#44 ;Point to filename with R3
702 LDR R4,[R9,#36] ;Estimated size in R4
703 BL dbox__dispatch ;Send the message on
704 B %80dbox__message ;Skip on and claim the event
706 ; --- We did something, so claim event ---
708 80dbox__message LDMFD R13!,{R0-R4,R9,R14} ;Restore all the registers
709 ORRS PC,R14,#C_flag ;Return, claiming the event
713 ;----- Locating icons -------------------------------------------------------
717 ; On entry: R0 == icon number to start from or -1
718 ; R1 == AND mask for flags
719 ; R2 == flags word to match
720 ; R3 == direction to scan in (either +1 or -1 unless you're
722 ; R10 == dialogue box handle
724 ; On exit: R0 == icon number of found icon or -1
725 ; Other registers preserved
727 ; Use: Locates an icon within a window with flags that match the
728 ; ones given. Note that icon definitions within the cached
729 ; window definition are scanned, not icons in their actual
732 ; Searching from icon `-1' means to start from one end and
733 ; keep looking until you've gone through all of them.
734 ; Otherwise, the scan starts from the icon *after* the one
735 ; specified in R0 on entry.
737 ; The return value is the number of the first icon that
738 ; matched the specification, or -1 if none of them matched.
742 STMFD R13!,{R4-R6,R14} ;Save some registers
744 ; --- Find the cached window defintion ---
746 LDR R4,[R10,#dbox__defn] ;Locate the definition
748 ; --- Work out a sensible scanning start position ---
750 CMP R0,#-1 ;Extremity requested?
751 ADDNE R0,R0,R3 ;No -- skip over start icon
752 BNE %00dbox__find ;And skip past this bit
753 CMP R3,#0 ;Is the increment positive?
754 MOVGT R0,#0 ;Yes -- start from 0
755 LDRLT R0,[R4,#84] ;No -- load the icon count
756 SUBLT R0,R0,#1 ;And bump down -- zero index
758 ; --- Now work out when to stop scanning ---
760 00dbox__find CMP R3,#0 ;What's the increment again?
761 BEQ %02dbox__find ;If it's silly, find nothing
762 LDRGT R5,[R4,#84] ;Positive -- stop at the
763 SUBGT R5,R5,#1 ;...number of icons -1
765 ; --- A few other pre-scan bits ---
767 AND R2,R2,R1 ;Make sure flags aren't silly
768 ADD R6,R4,#88 ;Point to icon number 0
769 ADD R6,R6,R0,LSL #5 ;Point to the right icon
771 ; --- The main scanning loop ---
773 ; The comparison at the end is slightly tricky. It works
774 ; on the basis that if R3>0, the condition is that R0>R5,
775 ; and if R3<0, the condition is that R0<0. Each of these
776 ; double-barrelled conditions can be done in two ARM
777 ; instructions, and both together, complete with branches
780 ; Rather oddly, we start with the termination condition.
782 01dbox__find CMP R3,#0 ;What's the increment like?
783 CMPLT R0,#0 ;Check not gone too low
784 BLT %02dbox__find ;Yes -- exit the loop
785 CMP R3,#0 ;Check increment again
786 CMPGT R0,R5 ;Check not gone too high
787 BGT %02dbox__find ;Yes -- exit the loop
789 ; --- Now see if we got a match ---
791 LDR R14,[R6,#16] ;Get icon flags for this one
792 AND R14,R14,R1 ;Apply the AND mask to them
793 CMP R14,R2 ;Is this a match?
794 LDMEQFD R13!,{R4-R6,PC}^ ;Yes -- return to caller
796 ; --- Set up for the next one ---
798 ADD R0,R0,R3 ;Move the icon number on
799 ADD R6,R6,R3,LSL #5 ;And bump icon pointer too
800 B %01dbox__find ;Jump back to the loop start
802 ; --- We failed to find it -- return -1 ---
804 02dbox__find MOV R0,#-1 ;Return funny failure value
805 LDMFD R13!,{R4-R6,PC}^ ;Return to caller
811 ; On entry: R0 == icon number wanted
812 ; R10 == dialogue box block pointer
814 ; On exit: R0 == pointer to numbered icon's definition
816 ; Use: Locates an icon definition given its number
818 dbox__icon STMFD R13!,{R14} ;Save link register a bit
819 LDR R14,[R10,#dbox__defn] ;Find window definition
820 ADD R14,R14,#88 ;Point to the first icon
821 ADD R0,R14,R0,LSL #5 ;Add R0*32 to point to icon
822 LDMFD R13!,{PC}^ ;Return to caller nicely
824 ;----- Main initialisation --------------------------------------------------
832 ; Use: Initialises the dbox system.
837 STMFD R13!,{R12,R14} ;Save a load of registers
838 WSPACE dbox__wSpace ;Find my workspace
840 ; --- Make sure I'm not running yet ---
842 LDR R14,dbox__wFlags ;Get hold of my flags word
843 TST R14,#dbFlag__inited ;Am I running yet?
844 LDMNEFD R13!,{R12,PC}^ ;Yes -- return immediately
846 ; --- Set up the flags nicely ---
848 MOV R14,#dbFlag__inited ;I am initialised now
849 STR R14,dbox__wFlags ;Save my flags back again
850 MOV R14,#0 ;Zero some workspace bits
851 STR R14,dbox__clickList ;Nothing on the click list
852 BL win_init ;Make sure win's awake
853 BL transWin_init ;And also for transWin
854 LDMFD R13!,{R12,PC}^ ;Return to caller
860 ;----- Opening and closing dialogue boxes -----------------------------------
864 ; On entry: R0 == dialogue box handle
865 ; R1 == how to open the dialogue box
866 ; Other registers depend on R1, and are described at the end
867 ; of this header file
871 ; Use: Displays the dialogue box on the screen in the given manner.
876 STMFD R13!,{R0-R6,R10,R12,R14}
877 WSPACE dbox__wSpace ;Locate my workspace
878 MOV R10,R0 ;Move the dbox handle away
880 ; --- Is this a submenu request? ---
882 ADDS R0,R0,#0 ;Clear the C flag
883 TST R1,#dbOpen_nonSub ;Do we ignore this?
884 BLEQ transWin_subWaiting ;No -- waiting for a submenu?
885 BCS %60dbox_open ;Yes -- open as a submenu
887 ; --- Now work out how to open it ---
889 LDR R6,[R10,#dbox__flags] ;Get the dialogue's flags
890 TST R1,#dbOpen_persist ;Is this a persistent dbox?
891 BICEQ R6,R6,#dbFlag__static ;No -- clear static flag
892 ORRNE R6,R6,#dbFlag__static ;Yes -- set static flag
893 MOV R4,R1 ;Look after open style
895 ; --- Read the dialogue's position ---
897 SUB R13,R13,#36 ;Enough for a window block
898 LDR R0,[R10,#dbox__window] ;Get the window handle
899 STR R0,[R13,#0] ;Store it in the block
900 MOV R1,R13 ;Point to the window handle
901 SWI Wimp_GetWindowState ;Read in the information
903 ; --- Move the dialogue box to the right position ---
905 BIC R0,R4,#dbOpen_persist + dbOpen_nonSub
906 BL winUtils_setPosition ;Position the window nicely
907 TST R6,#dbFlag__static ;Is it static?
908 BEQ %40dbox_open ;No -- skip ahead a bit
910 ; --- Open a persistent dialogue box ---
912 SWI Wimp_OpenWindow ;Open the window
913 ADD R13,R13,#36 ;Reclaim the stack space
915 ; --- If the window was already open, quit now ---
917 TST R6,#dbFlag__open ;Is the dialogue box open
918 BNE %80dbox_open ;Yes -- skip past this bit
920 ; --- Now find out if there's a caret to handle ---
922 MOV R0,#-1 ;Start searching from start
923 MOV R1,#&0000E000 ;Find all Writable icons
924 MOV R2,#&0000E000 ;Only check button type bits
925 MOV R3,#+1 ;Search forwards
926 BL dbox__find ;Find the icon
927 CMP R0,#-1 ;Is there a writable icon?
928 BICEQ R6,R6,#dbFlag__rCaret ;Don't have to restore caret
929 BEQ %10dbox_open ;No -- skip ahead
931 ; --- Read the old caret position ---
933 ADD R1,R10,#dbox__oldCaret ;Point to old caret block
934 SWI Wimp_GetCaretPosition ;Read the current position
935 LDR R0,[R10,#dbox__window] ;Get the dialogue window
936 MOV R1,#-1 ;In no particular icon
937 MOV R2,#&ff000000 ;Quite a long way away
939 MOV R3,#0 ;Doesn't really matter
940 MOV R4,#&02000000 ;Hide caret, make it small
941 MOV R5,#-1 ;No index into icon, please
942 SWI Wimp_SetCaretPosition ;Set the caret's position
943 ORR R6,R6,#dbFlag__rCaret ;Remember to restore caret
945 ; --- That's it, so finish things off ---
947 10dbox_open B %80dbox_open ;Perform wrapping-up actions
949 ; --- Open as a transient menu ---
951 40dbox_open LDR R1,[R10,#dbox__window] ;Get the window handle ready
952 SWI Wimp_CreateMenu ;Create it as a menu :-/
953 BIC R6,R6,#dbFlag__rCaret ;Don't restore the caret
954 ADD R13,R13,#36 ;Reclaim the stack we used
955 MOV R0,R1 ;Get the window handle again
956 BL transWin_register ;This is transient window
957 B %80dbox_open ;Perform wrapping-up actions
959 ; --- Open in the correct submenu position ---
961 60dbox_open LDR R0,[R10,#dbox__window] ;Load the window handle
962 BL transWin_openSub ;And display as submenu
963 LDR R6,[R10,#dbox__flags] ;Read the dialogue box flags
964 BIC R6,R6,#dbFlag__static :OR: dbFlag__rCaret
966 ; --- Wrap everything up now ---
968 80dbox_open ORR R6,R6,#dbFlag__open ;The window is at last open
969 STR R6,[R10,#dbox__flags] ;Store the flags away now
970 MOV R0,#dbEvent_lifeCycle ;A lifecycle event
971 MOV R1,#dblc_open ;Box has opened
972 BL dbox__dispatch ;Send a message
973 LDMFD R13!,{R0-R6,R10,R12,PC}^
979 ; On entry: R0 == dialogue box handle
983 ; Use: Closes a dialogue box, by clearing the current menu if
989 STMFD R13!,{R0-R6,R10,R12,R14} ;Save some registers away
990 WSPACE dbox__wSpace ;Locate my workspace
991 MOV R10,R0 ;Move dbox handle away
993 ; --- First things first -- check it's open ---
995 LDR R6,[R10,#dbox__flags] ;Get the dialogue's flags
996 TST R6,#dbFlag__open ;Is the open flag on?
997 BEQ %80dbox_close ;No -- skip forward
999 ; --- Now restore the caret if needs be ---
1001 ; Try not to be overly upset if we can't put the caret back.
1002 ; After all, the window may have closed by now. An X SWI
1003 ; is called for, and we ignore V on exit.
1005 TST R6,#dbFlag__rCaret ;Does caret need restoring?
1006 BEQ %00dbox_close ;No -- skip forwards
1007 ADD R0,R10,#dbox__oldCaret ;Point to old caret block
1008 LDMIA R0,{R0-R5} ;Load the old caret state
1009 SWI XWimp_SetCaretPosition ;And try to put it back
1011 ; --- Now handle transientness properly ---
1013 00dbox_close TST R6,#dbFlag__static ;Is this a static dialogue?
1014 LDREQ R0,[R10,#dbox__window] ;Yes -- find the window
1015 BLEQ transWin_close ;And close it
1016 ADDNE R1,R10,#dbox__window ;Point to the window handle
1017 SWINE Wimp_CloseWindow ;Close the window now
1019 BIC R6,R6,#dbFlag__open :OR: dbFlag__rCaret
1020 STR R6,[R10,#dbox__flags] ;Store flags away again
1022 ; --- Send a lifecycle warning ---
1024 MOV R0,#dbEvent_lifeCycle ;Get the event code
1025 MOV R1,#dblc_close ;Box has closed
1026 BL dbox__dispatch ;Send the event
1028 80dbox_close LDMFD R13!,{R0-R6,R10,R12,PC}^ ;Return to caller
1032 ; --- dbox_writePos ---
1034 ; On entry: R0 == dialogue box handle
1038 ; Use: Saves the dialogue's current position so that it will be
1039 ; opened here the next time it is created. If the dialogue
1040 ; box was created from a template, the template is updated.
1041 ; Otherwise, the new state is written back to the definition
1042 ; supplied to dbox_fromDefn.
1044 EXPORT dbox_writePos
1047 STMFD R13!,{R0-R5,R10,R14} ;Save a load of registers
1048 MOV R10,R0 ;Keep the dialogue handle
1049 SUB R13,R13,#36 ;Make space on the stack
1050 LDR R14,[R10,#dbox__window] ;Get the dialogue's window
1051 STR R14,[R13,#0] ;Save in the block
1052 MOV R1,R13 ;Point to the block
1053 SWI Wimp_GetWindowState ;Get the window's position
1054 LDMIB R13,{R0-R5} ;Load pos and scroll settings
1055 LDR R14,[R10,#dbox__template] ;Find the template address
1056 CMP R14,#0 ;Is it actually there?
1057 CMPNE R14,#1 ;Check for embedded templates
1058 LDREQ R14,[R10,#dbox__defn] ;No -- just use definition
1059 STMIA R14,{R0-R5} ;Yes -- save them for later
1060 ADD R13,R13,#36 ;Reclaim the used stack space
1061 LDMFD R13!,{R0-R5,R10,PC}^ ;Return to caller
1065 ;----- Caret handling functions ---------------------------------------------
1067 ; --- dbox__viewIcon ---
1069 ; On entry: R0 == an icon number
1070 ; R10 == dialogue box handle
1074 ; Use: Scrolls the given dialogue box so that the specified icon
1075 ; is visible. The icon is assumed to be in the same position
1076 ; as it was when it was created.
1078 ; This is translated fairly literally from the STEEL code
1079 ; in dbox__nextWritable.
1083 STMFD R13!,{R0-R9,R14} ;Save a load of registers
1085 ; --- Locate the icon definition ---
1087 BL dbox__icon ;Find the icon position
1088 MOV R9,R0 ;Keep a pointer to it
1090 ; --- Find the window position ---
1092 SUB R13,R13,#36 ;Make space for a window def
1093 LDR R14,[R10,#dbox__window] ;Find the dbox's window hnd
1094 STR R14,[R13,#0] ;Store it in the block
1095 MOV R1,R13 ;Point to the block
1096 SWI Wimp_GetWindowState ;Find the window information
1098 ; --- Now read the window scroll positions ---
1100 LDMIB R13,{R0-R5} ;Load window visible coords
1102 SUB R0,R2,R0 ;R0 == window width
1103 SUB R1,R3,R1 ;R1 == window height
1104 ADD R2,R4,R0 ;R2 == window right hand side
1105 SUB R3,R5,R1 ;R3 == window bottom edge
1106 ;R4 == window left hand side
1107 ;R5 == window top edge
1109 LDMIA R9,{R6-R8,R14} ;Load icon coordinates nicely
1111 SUB R6,R6,#24 ;Add a bit of extra around
1116 ; --- Bodge the scroll positions until icon is visible ---
1118 ; This section is fairly self-explanatory, and the comments
1130 ; --- Now store the scroll offsets back and reopen ---
1132 ADD R1,R13,#20 ;Point to scroll offsets
1133 STMIA R1,{R4,R5} ;Store them back in the block
1134 MOV R1,R13 ;Point to the block
1135 SWI Wimp_OpenWindow ;Now open the window nicely
1137 ; --- Reclaim the stack and return ---
1140 LDMFD R13!,{R0-R9,PC}^ ;Return to caller
1144 ; --- dbox__moveCaret ---
1146 ; On entry: R0 == 0 to move relative to current input focus
1147 ; 1 to move absolute (for ctrl cursor keys)
1148 ; R1 == direction to move in (+1 or -1, if you've any sense)
1149 ; R10 == dialogue box handle
1153 ; Use: Moves the caret between writable icons, responding to cursor
1156 dbox__moveCaret ROUT
1158 STMFD R13!,{R0-R5,R14} ;Save a few registers
1160 ; --- Find out where the cursor is ---
1162 SUB R13,R13,#24 ;Make way for a caret block
1163 MOV R1,R13 ;Point to it
1164 SWI Wimp_GetCaretPosition ;Find the caret nicely
1166 ; --- Check this is the right window ---
1168 LDMIA R13,{R0,R5} ;Get the input focus window
1169 LDR R14,[R10,#dbox__window] ;Get dialogue box window
1170 ADD R13,R13,#24 ;Reclaim that stack space
1171 CMP R0,R14 ;Do they match nicely?
1172 LDMNEFD R13!,{R0-R5,PC}^ ;No -- return to caller
1174 ; --- Now set up a search for the icon ---
1176 LDMIA R13,{R0,R3} ;Get the stacked start pos
1177 CMP R0,#0 ;Is it a zero?
1178 MOVNE R0,#-1 ;No -- start from one end
1179 MOVEQ R0,R5 ;Yes -- start from current
1181 ; --- Load the icon flags to search for ---
1183 MOV R2,#&0000E000 ;Find writable icons
1184 ORR R1,R2,#&00400000 ;Also check shaded bit
1185 BL dbox__find ;Find the icon nicely
1186 CMP R0,#-1 ;Did it find one?
1187 BLEQ dbox__find ;No -- search from one end
1189 ; --- Now it's come up with the goods ---
1191 CMP R0,#-1 ;Did it fail this time?
1192 CMPNE R0,R5 ;Or just come back again?
1193 LDMEQFD R13!,{R0-R5,PC}^ ;Yes -- nothing doing then
1195 ; --- Scroll to make icon visible ---
1197 BL dbox__viewIcon ;Scroll the window nicely
1199 ; --- Set the caret position nicely ---
1201 MOV R1,R0 ;Icon number to R1
1202 BL dbox__fieldLen ;Find the string length
1203 MOV R5,R0 ;This is icon text index
1204 MOV R4,#-1 ;Calculate things for me
1205 LDR R0,[R10,#dbox__window] ;Get the window handle
1206 SWI Wimp_SetCaretPosition ;Move the caret nicely now
1208 LDMFD R13!,{R0-R5,PC}^ ;Return to caller at last
1212 ;----- Selecting and shading icons ------------------------------------------
1214 ; --- dbox_select ---
1216 ; On entry: R0 == dialogue box handle
1218 ; R2 == 0 to deselect the icon, 1 to select it, 2 to toggle
1219 ; its current selected state
1223 ; Use: Selects or deselects the specified icon in the Acorn sense
1224 ; (i.e. by flipping its selected bit). The state is only
1225 ; changed if required, to reduce flicker.
1230 STMFD R13!,{R0-R2,R14} ;Save some registers away
1232 ; --- Find the old state ---
1234 SUB R13,R13,#40 ;Make space for an icon block
1235 LDR R0,[R0,#dbox__window] ;Get the window handle
1236 STMIA R13,{R0,R1} ;Save the handles away
1237 MOV R1,R13 ;Point to the block
1238 SWI Wimp_GetIconState ;Find out about the icon
1240 ; --- Find out the current selection state ---
1242 LDR R14,[R13,#24] ;Load the flags word
1243 AND R14,R14,#&00200000 ;Clear all but the select bit
1244 CMP R2,#1 ;Are we to select the icon?
1245 MOVEQ R2,#&00200000 ;Yes -- set the select bit
1246 CMP R2,#2 ;Are we to toggle it?
1247 EOREQ R2,R14,#&00200000 ;Yes -- toggle it then
1249 ; --- Make sure we need to do something ---
1251 CMP R2,R14 ;Are the states the same?
1252 ADDEQ R13,R13,#40 ;Yes -- restore the stack
1253 LDMEQFD R13!,{R0-R2,PC}^ ;And return right now
1255 ; --- Now change the icon state ---
1257 ADD R0,R13,#8 ;Point to the flags masks
1258 MOV R14,#&00200000 ;Clear only the selected bit
1259 STMIA R0,{R2,R14} ;Save the masks in the block
1260 SWI Wimp_SetIconState ;Set the state nicely
1262 ADD R13,R13,#40 ;Restore the stack nicely
1263 LDMFD R13!,{R0-R2,PC}^ ;Return to caller
1267 ; --- dbox_shade ---
1269 ; On entry: R0 == dialogue box handle
1271 ; R2 == 0 to unshade the icon, 1 to shade it, 2 to toggle its
1272 ; current shaded state
1276 ; Use: Makes the icon look dimmer, to indicate that it is not
1277 ; available. It uses its own shading algorithms, rather than
1278 ; the WindowManager's, so there are some things you must watch
1281 ; * Don't use any other method of shading icons
1283 ; * Don't assume that a shaded icon isn't going to give you
1284 ; events. At the user level, this should have been tidied
1285 ; up, but at the Sapphire level, it's still a problem.
1286 ; There is a routine in winUtils which will tell you if an
1289 ; This routine has been written so that it only flickers icons
1290 ; when they actually need it.
1295 STMFD R13!,{R0-R6,R10,R14} ;Save a load of registers
1297 ; --- Make sure we need to do something ---
1299 MOV R10,R0 ;Look after the dbox handle
1300 MOV R0,R1 ;Get the original icon handle
1301 BL dbox__icon ;Find my cached icon defn
1302 MOV R4,R0 ;Look after this pointer
1303 LDR R6,[R4,#16] ;Load the icon's flags
1304 AND R5,R6,#&00400000 ;Leave only the selected bit
1306 ; --- Work out what needs to be done ---
1308 CMP R2,#1 ;Do we have to shade it?
1309 MOVEQ R2,#&00400000 ;Yes -- set the bit
1310 CMP R2,#2 ;Do we have to toggle it?
1311 EOREQ R2,R5,#&00400000 ;Yes -- get the toggled state
1313 ; --- Now quit if there's nothing to do ---
1315 CMP R2,R5 ;Are they the same now?
1316 LDMEQFD R13!,{R0-R6,R10,PC}^ ;Yes -- return right now
1318 ; --- Find the old state from the icon ---
1320 LDR R0,[R10,#dbox__window] ;Get the window handle
1321 SUB R13,R13,#40 ;Make way for an icon block
1322 STMIA R13,{R0,R1} ;Save window and icon handles
1323 MOV R1,R13 ;Point to the block
1324 SWI Wimp_GetIconState ;Get the icon information
1325 LDR R5,[R13,#24] ;Get the current icon flags
1327 ; --- Now process the cached flags nicely ---
1329 ; We can just flip the bit now, because we know it must be
1330 ; different to its old state.
1332 EOR R6,R6,#&00400000 ;Toggle the flag
1333 STR R6,[R4,#16] ;Store it back in the block
1335 ; --- Now work out exactly what we have to do ---
1337 TST R6,#&00400000 ;Are we meant to be shading?
1338 BEQ %50dbox_shade ;No -- unshade nicely
1340 ; --- Lots of messing about with bitmasks ---
1342 ; We need to change the icon colours, the button type and
1343 ; the ESG number for text icons, and the shaded bit for
1344 ; sprite icons. If there's a sprite, or nothing at all, then
1345 ; we set the shaded bit. If there's text and a sprite, then
1346 ; we /don't/ do the text hacking if anti-aliased fonts are
1347 ; being used, since everything looks nasty.
1349 MOV R0,#8 ;Read the font handle
1350 SWI XWimp_ReadSysInfo ;Read the handle then
1351 MOVVS R0,#0 ;Unknown -- not supported
1353 AND R14,R5,#3 ;Get the contents bits
1354 TST R14,#2 ;Do we have a sprite?
1355 CMPNE R0,#0 ;And is there a font?
1356 TSTEQ R5,#&40 ;Or is the icon anti-aliased?
1357 BICNE R14,R14,#1 ;Yes -- clear text bit then
1359 CMP R14,#1 ;Is it text only?
1360 ORRNE R5,R5,#&00400000 ;No -- set the shaded bit
1361 TST R14,#1 ;Does it contain text?
1362 BICNE R5,R5,#&0f100000 ;Clear foreg colour and ESG 5
1363 BICNE R5,R5,#&000ff000 ;Clear ESG and button type
1364 ORRNE R5,R5,#&02100000 ;Set foreg and ESG bit 5
1365 ORRNE R5,R5,#&000f0000 ;Set ESG to 31, leave btype
1367 MOV R14,#-1 ;Clear all the flags bits
1368 ADD R0,R13,#8 ;Point to flags masks
1369 STMIA R0,{R5,R14} ;Store them in the block
1370 MOV R1,R13 ;Point to the block again
1371 SWI Wimp_SetIconState ;And `shade' the icon
1373 ; --- Now make sure the caret's not in it ---
1375 LDMIA R1,{R2,R3} ;Get the window and icon
1376 SWI Wimp_GetCaretPosition ;Find where the caret is
1377 LDMIA R1,{R4,R5} ;Get the focus window and icn
1378 CMP R2,R4 ;Check the windows match
1379 CMPEQ R3,R5 ;And check the icons match
1380 BNE %80dbox_shade ;If not, skip ahead a bit
1382 ; --- Now kick the caret into cyberspace ---
1384 LDMIA R1,{R0-R5} ;Load the caret registers
1385 MOV R1,#-1 ;Kick caret out of icon
1386 MOV R2,#&ff000000 ;Quite a long way away
1387 ORR R2,R2,#&00ff0000
1388 SWI Wimp_SetCaretPosition ;Set the new caret position
1389 B %80dbox_shade ;Tidy everything up
1391 ; --- Now handle unshading -- this is easy :-/ ---
1393 50dbox_shade BIC R6,R6,#&f000000f ;Clear some bits
1394 BIC R6,R6,#&00e00000 ;Clear some more bits
1395 BIC R6,R6,#&00000ff0 ;Clear yet more bits
1397 BIC R5,R5,#&0f500000 ;Clear another load of bits
1398 BIC R5,R5,#&000ff000 ;And the last load of bits
1400 ORR R5,R5,R6 ;Now merge them all together
1401 MOV R14,#-1 ;Update all of the flags
1402 ADD R0,R13,#8 ;Point to the flags masks
1403 STMIA R0,{R5,R14} ;Save the masks away
1404 SWI Wimp_SetIconState ;Now flicker the icon
1406 ; --- Tidy everything up finally ---
1408 80dbox_shade ADD R13,R13,#40 ;Restore the stack position
1409 LDR R0,[R10,#dbox__defn] ;Find the window definition
1410 LDR R0,[R0,#64] ;Load the sprite area pointer
1411 SWI XSculptrix_SetSpriteArea ;Set the sprite area up
1412 LDR R1,[R13,#4] ;Get the icon handle back
1413 LDR R0,[R10,#dbox__window] ;Get the window handle
1414 SWI XSculptrix_UpdateIcon ;And redraw the 3D border
1415 LDMFD R13!,{R0-R6,R10,PC}^ ;Return to caller
1419 ; --- dbox_selectMany ---
1421 ; On entry: R0 == dialogue box handle
1422 ; R1 == pointer to icon handle list, -1 terminated
1423 ; R2 == select action (0 == unselect, 1 == select, 2 == toggle)
1427 ; Use: Changes the select state of a group of icons.
1429 EXPORT dbox_selectMany
1430 dbox_selectMany ROUT
1432 STMFD R13!,{R1,R3,R14} ;Save some registers
1433 MOV R3,R1 ;Remember this pointer
1434 00 LDR R1,[R3],#4 ;Load next icon handle
1435 CMP R1,#-1 ;Is it the end of the list?
1436 BLNE dbox_select ;No -- then do the select
1437 BNE %b00 ;And loop round again
1438 LDMFD R13!,{R1,R3,PC}^ ;And return to caller
1442 ; --- dbox_shadeMany ---
1444 ; On entry: R0 == dialogue box handle
1445 ; R1 == pointer to icon handle list, -1 terminated
1446 ; R2 == shade action (0 == unshade, 1 == shade, 2 == toggle)
1450 ; Use: Changes the shade state of a group of icons.
1452 EXPORT dbox_shadeMany
1455 STMFD R13!,{R1,R3,R14} ;Save some registers
1456 MOV R3,R1 ;Remember this pointer
1457 00 LDR R1,[R3],#4 ;Load next icon handle
1458 CMP R1,#-1 ;Is it the end of the list?
1459 BLNE dbox_shade ;No -- then do the select
1460 BNE %b00 ;And loop round again
1461 LDMFD R13!,{R1,R3,PC}^ ;And return to caller
1465 ; --- dbox_isSelected ---
1467 ; On entry: R0 == dialogue box handle
1470 ; On exit: CS if the icon is selected, CC otherwise
1472 ; Use: Returns whether an icon is currently selected.
1474 EXPORT dbox_isSelected
1475 dbox_isSelected ROUT
1477 STMFD R13!,{R0,R1,R14} ;Save the registers away
1478 SUB R13,R13,#40 ;Make space for an icon block
1479 LDR R0,[R0,#dbox__window] ;Load the dialogue's window
1480 STMIA R13,{R0,R1} ;Store them in the block
1481 MOV R1,R13 ;Point to the block
1482 SWI Wimp_GetIconState ;Get the icon information
1483 LDR R14,[R13,#24] ;Load the icon flags
1484 ADD R13,R13,#40 ;Recover the stack space
1485 TST R14,#&00200000 ;Check the selected bit
1486 LDMFD R13!,{R0,R1,R14} ;Load the saved registers
1487 ORRNES PC,R14,#C_flag ;If flag set, return with CS
1488 BICEQS PC,R14,#C_flag ;Otherwise, clear carry
1492 ; --- dbox_radio ---
1494 ; On entry: R0 == dialogue box handle
1499 ; Use: Checks to see if the icon is a radio button as defined by
1500 ; Sapphire, i.e. button type 3 (debounced) and non-zero ESG.
1501 ; If it is, it selects it, and deselects all other icons with
1507 STMFD R13!,{R0-R4,R9,R10,R14} ;Save some registers
1508 MOV R10,R0 ;Get the dialogue handle
1509 MOV R9,R1 ;Look after the icon number
1511 ; --- Locate the icon and check it's a radio button ---
1513 MOV R0,R1 ;Icon in R0 for dbox__icon
1514 BL dbox__icon ;Find the icon definition
1515 LDR R14,[R0,#16] ;Load the icon flags
1516 AND R4,R14,#&0000f000 ;Leave only the button type
1517 CMP R4,#&00003000 ;Make sure it's Debounced
1518 LDMNEFD R13!,{R0-R4,R9,R10,PC}^ ;No -- return right now
1519 ANDS R4,R14,#&001f0000 ;Leave only the ESG
1520 CMPNE R4,#&001f0000 ;Or 31 (i.e. it's shaded)
1521 LDMEQFD R13!,{R0-R4,R9,R10,PC}^ ;Yes -- return right now
1523 ; --- The ESG is now in R4 -- process it ---
1525 MOV R0,#-1 ;Start from the beginning
1527 00dbox_radio MOV R1,#&001f0000 ;Mask out all but the ESG
1528 MOV R2,R4 ;Move ESG in to test it
1529 MOV R3,#+1 ;Search forwards nicely
1530 BL dbox__find ;Get the next matching icon
1531 CMP R0,#-1 ;None found?
1532 LDMEQFD R13!,{R0-R4,R9,R10,PC}^ ;Return to caller then
1533 MOV R1,R0 ;Icon number in R1 required
1534 MOV R0,R10 ;Dialogue box handle in R0
1535 CMP R1,R9 ;Is this the clicked icon?
1536 MOVEQ R2,#1 ;Yes -- select it
1537 MOVNE R2,#0 ;No -- deselect it
1538 BL dbox_select ;Change its selection state
1539 MOV R0,R1 ;Start search where we left
1540 B %00dbox_radio ;And loop round again
1544 ;----- Clicking and unclicking icons ----------------------------------------
1548 ; On entry: R0 == dialogue box handle
1551 ; On exit: May return an error
1553 ; Use: Slabs an icon in properly, to give visual feedback when you
1559 STMFD R13!,{R0-R2,R12,R14} ;Save some registers away
1560 WSPACE dbox__wSpace ;Find my workspace pointer
1562 ; --- Allocate a new block ---
1564 MOV R0,#20 ;Make space for a new block
1565 BL sub_alloc ;Try to allocate the block
1566 BVS %90dbox_slab ;If it failed, skip forward
1568 ; --- Link the block into the list ---
1570 LDR R14,dbox__clickList ;Load the old list head
1571 STR R0,dbox__clickList ;Store this block as new head
1572 STR R14,[R0,#0] ;And store link to next one
1574 ; --- Now actually slab the icon ---
1576 ADD R2,R0,#4 ;Point to slab descriptor
1577 LDR R0,[R13,#0] ;Get the saved dbox handle
1578 LDR R0,[R0,#dbox__window] ;Get the window handle
1579 SWI XSculptrix_SlabIcon ;Slab the icon in nicely
1580 LDMFD R13!,{R0-R2,R12,PC}^ ;Return to caller
1582 ; --- Tidy up after an error ---
1584 90dbox_slab ADD R13,R13,#4 ;Skip past stacked R0
1585 LDMFD R13!,{R1,R2,R12,R14} ;Load the saved registers
1586 ORRS PC,R14,#V_flag ;Set V flag on exit
1590 ; --- dbox_unslab ---
1594 ; On exit: CS if there are no more slabbed icons after this one, CC
1595 ; if there are more left.
1597 ; Use: Unslabs an icon slabbed with dbox_slab. Icons are unslabbed
1598 ; in reverse order to that in which they were slabbed. The
1599 ; carry flag is returned as an indication of whether there
1600 ; are any more icons left in the list -- you can unslab all
1601 ; icons in one go by doing:
1604 ; SUBCC PC,PC,#12 ;Avoids a label!
1606 ; It is recommended that, if you are going to close a window,
1607 ; you unslab icons within it *after* you close, but before you
1608 ; actually destroy it, e.g.
1618 STMFD R13!,{R0-R2,R12,R14} ;Save some registers away
1619 WSPACE dbox__wSpace ;Find my workspace pointer
1620 LDR R1,dbox__clickList ;Find the last slabbed icon
1622 ; --- Get the descriptor to free ---
1624 CMP R1,#0 ;Is there one at all?
1625 LDMEQFD R13!,{R0-R2,R12,R14} ;No -- restore the registers
1626 ORREQS PC,R14,#C_flag ;And return with C set
1628 ; --- Unslab the icon and unlink the block ---
1630 ; Make sure the hourglass stays off all this time.
1632 ADD R2,R1,#4 ;Point to the slab descriptor
1633 SUB R13,R13,#8 ;Make an hourglass status blk
1634 MOV R0,R13 ;Point to the block
1635 BL hour_suspend ;Save the old state a while
1636 SWI XSculptrix_UnslabIcon ;Unslab the icon nicely
1637 BL hour_resume ;Resume the hourglass now
1638 ADD R13,R13,#8 ;And restore the stack
1639 LDR R2,[R1,#0] ;Get the next field out
1640 STR R2,dbox__clickList ;Store it as the new head
1642 ; --- Free the block now ---
1644 MOV R0,R1 ;Point to the slab block
1645 MOV R1,#20 ;suballoc wants the size
1646 BL sub_free ;Free the block again
1648 ; --- Now return the status to the user ---
1650 CMP R2,#0 ;Was the next block null?
1651 LDMFD R13!,{R0-R2,R12,R14} ;Restore all the registers
1652 ORREQS PC,R14,#C_flag ;Yes -- return and set C
1653 BICNES PC,R14,#C_flag ;No -- return and clear C
1657 ;----- Messing with dialogue box fields -------------------------------------
1659 ; --- dbox__fieldLen ---
1661 ; On entry: R1 == icon number
1662 ; R10 == dialogue box handle
1664 ; On exit: R0 == length of the text in the icon
1666 ; Use: Returns the length of the field in the given icon
1670 STMFD R13!,{R1,R14} ;Save some registers
1672 ; --- Find the icon definition ---
1674 SUB R13,R13,#40 ;Make space for icon block
1675 LDR R0,[R10,#dbox__window] ;Get the window handle
1676 STMIA R13,{R0,R1} ;Store handles in block
1677 MOV R1,R13 ;Point at the block
1678 SWI Wimp_GetIconState ;Find the *current* icon info
1680 ; --- Get the icon flags and find the data ---
1682 LDR R0,[R13,#24] ;Load the flags word
1683 ANDS R0,R0,#1<<8 ;Check indir flag (clever)
1684 BEQ %10dbox__fieldLen ;Yes -- skip ahead a bit
1686 ; --- Handle indirectedness ---
1688 LDR R0,[R13,#28] ;Load the icon data pointer
1689 ADD R13,R13,#40 ;Reclaim the stack block
1690 LDMFD R13!,{R1,R14} ;Unstack the registers
1691 B str_len ;Find the string length
1693 ; --- Handle nonindirectedness ---
1695 ; We know at this point that R0 is 0, because we used ANDS
1696 ; not TST above. This is a pointless optimisation.
1698 10 ADD R1,R13,#28 ;Point to the data string
1699 11 LDRB R14,[R1],#1 ;Get a byte from the string
1700 CMP R14,#' ' ;Is it the end yet?
1701 BLT %12dbox__fieldLen ;Yes -- skip forward
1702 ADD R0,R0,#1 ;Bump on the counter
1703 CMP R0,#12 ;Is it maximum length yet?
1704 BLT %11dbox__fieldLen ;No -- skip back again
1706 ; --- Return the calculated length ---
1708 12 ADD R13,R13,#40 ;Reclaim the stack again
1709 LDMFD R13!,{R1,PC}^ ;Return to caller
1713 ; --- dbox_setField ---
1715 ; On entry: R0 == dialogue box handle
1716 ; R1 == icon number to write to (may be -1 for title)
1717 ; flags in top byte if not -1:
1718 ; dbFlag_dots (bit 31) == add `...' if text overflows
1719 ; R2 == pointer to string to use
1723 ; Use: Writes the string specified into the indirection buffer
1724 ; for the given icon. If the icon is not indirected, an
1725 ; error is generated. If the indirected buffer is too small,
1726 ; the string is shortened by chopping off the beginning or
1727 ; the end, according to the setting of the icon's right
1730 ; The icon is only flickered if the text has actually changed.
1731 ; The caret is moved correctly if it is within the icon to
1732 ; prevent it `falling off' the end and deleting the validation
1733 ; string, or being positioned incorrectly in centred icons if
1734 ; the length changes.
1736 ; Note that this routine requires a string to already be in
1737 ; the buffer, and doesn't perform any substitution or other
1738 ; transformations. This helps to prevent buffer full errors
1739 ; and similar problems.
1741 EXPORT dbox_setField
1744 STMFD R13!,{R0-R5,R14} ;Stash registers away
1746 ; --- Handle the title bar nicely ---
1748 CMP R1,#-1 ;Does he want the title?
1749 BEQ %30dbox_setField ;Yes -- jump ahead to do it
1751 ; --- Find out about the icon ---
1753 AND R4,R1,#&FF000000 ;Get the flag bits out
1754 BIC R1,R1,#&FF000000 ;Leave just the icon number
1755 LDR R0,[R0,#dbox__window] ;Get the dbox's window handle
1756 SUB R13,R13,#40 ;Make space for icon block
1757 STMIA R13,{R0,R1} ;Store the info in it
1758 MOV R1,R13 ;Point to the icon block
1759 SWI Wimp_GetIconState ;Get the icon's information
1761 ; --- Make sure we can change the text ---
1763 LDR R1,[R13,#24] ;Get the icon's flags
1764 TST R1,#&100 ;Check the indirected bit
1765 BEQ %80dbox_setField ;It's an error if it's clear
1767 ; --- Now find how much we actually have to copy ---
1769 LDR R5,[R13,#36] ;Get the buffer length
1770 SUB R5,R5,#1 ;Take terminator into account
1771 MOV R0,R2 ;Point to the string to copy
1772 BL str_len ;Find out how long it is
1773 SUBS R0,R0,R5 ;Find out the difference
1774 BICLE R4,R4,#(1<<31) ;If it fits, don't add dots
1775 BLE %00dbox_setField ;And skip ahead
1776 TST R1,#1<<9 ;Is it right aligned?
1777 ADDNE R2,R2,R0 ;Yes, chop off front
1778 ORRNE R4,R4,#1 ;And set a flag to remember
1780 ; --- Copy the text into the buffer ---
1782 00dbox_setField LDR R0,[R13,#28] ;Find the buffer address
1783 MOV R3,#0 ;Count the length too
1785 10dbox_setField CMP R5,R3 ;How much space left in buff?
1786 MOVLE R1,#0 ;None -- pretend null char
1787 LDRGTB R1,[R2],#1 ;Get a byte from the string
1788 CMP R1,#' ' ;Is it a control char?
1789 MOVLO R1,#0 ;Yes -- say it's a zero
1790 BLO %15dbox_setField ;And don't bother with dots
1792 ; --- Handle ellipsis generation ---
1794 TST R4,#(1<<31) ;Do we put the ellipsis in?
1795 BEQ %15dbox_setField ;No -- skip ahead then
1796 TST R4,#1 ;Are we right-justified?
1797 ADDNE R14,R3,#1 ;Yes -- just get the length
1798 SUBEQ R14,R5,R3 ;Otherwise find what's left
1799 CMP R14,#4 ;Are we within three?
1800 MOVLO R1,#'.' ;Yes -- put in a dot then
1802 ; --- Return to normality ---
1804 15dbox_setField LDRB R14,[R0],#1 ;Get one from the buffer
1805 CMP R14,#' ' ;Same for the buffer char
1808 CMP R1,R14 ;Are they different
1809 ORRNE R4,R4,#2 ;Yes -- remember this
1810 STRNEB R1,[R0,#-1] ;And store the different char
1812 CMP R1,#0 ;Is that end of the string?
1813 ADDNE R3,R3,#1 ;No -- bump the length on
1814 BNE %10dbox_setField ;And go round for another
1816 ; --- We've copied the string -- now update the icon ---
1818 TST R4,#2 ;Is the string different?
1819 BEQ %20dbox_setField ;No -- skip ahead
1822 STR R1,[R13,#8] ;The EOR mask for setstate
1823 STR R1,[R13,#12] ;The BIC mask for setstate
1824 MOV R1,R13 ;Point to the block
1825 SWI Wimp_SetIconState ;Flicker the icon nastily
1827 ; --- Now check for the caret ---
1829 SWI Wimp_GetCaretPosition ;Find out where the caret is
1830 LDMIA R13,{R2,R4} ;Get the window and icon
1831 ADD R0,R13,#40 ;Point past this block
1832 LDMIA R0,{R0,R1} ;Get the old dbox and icon
1833 LDR R0,[R0,#dbox__window] ;Get the window handle
1834 CMP R0,R2 ;Do the window handles match?
1835 CMPEQ R1,R4 ;And the icon handles?
1836 BNE %20dbox_setField ;No -- skip ahead
1838 ; --- Push the caret back a little ---
1840 LDR R5,[R13,#20] ;Get the caret index
1841 CMP R5,R3 ;Is this bigger than new len?
1842 MOVGT R5,R3 ;Yes -- trim the index
1844 ; --- Now put the caret in the right place ---
1846 MOV R2,#-1 ;Don't set the x coord
1847 MOV R3,#-1 ;Don't set the y coord
1848 MOV R4,#-1 ;Don't set the height
1849 SWI Wimp_SetCaretPosition ;Put the caret in its place
1851 ; --- Return nicely ---
1853 20dbox_setField ADD R13,R13,#40 ;Reclaim that temporary space
1854 LDMFD R13!,{R0-R5,PC}^ ;Return to caller
1856 ; --- Caller wants to update the title bar ---
1858 30dbox_setField LDR R14,[R0,#dbox__defn] ;Load the window definition
1859 LDR R5,[R14,#56] ;Load the title bar's flags
1860 TST R5,#&00000100 ;Check the indirected bit
1861 BEQ %80dbox_setField ;If clear, generate the error
1863 LDR R1,[R14,#72] ;Load the buffer pointer
1864 LDR R2,[R0,#dbox__window] ;Load the window handle
1865 LDR R0,[R13,#8] ;Load the string pointer
1866 BL winUtils_setTitle ;And set the title string
1867 LDMFD R13!,{R0-R5,PC}^ ;Return to caller
1869 ; --- Icon wasn't indirected ---
1871 80dbox_setField ADR R0,dbox__nind ;Point to error
1872 BL msgs_error ;Translate the message
1873 SWI OS_GenerateError
1880 ; --- dbox_getField ---
1882 ; On entry: R0 == dialogue box handle
1883 ; R1 == icon number to interrogate
1885 ; On exit: R0, R1 preserved
1886 ; R2 == pointer to the icon text
1888 ; Use: Returns a pointer to the text associated with an icon.
1889 ; Note that if the icon is *not* indirected, the text will
1890 ; be copied into the scratchpad. Otherwise you get a pointer
1891 ; to the actual indirected data. You shouldn't write to the
1892 ; string returned at all -- dbox_setField is specially
1893 ; designed to do that sort of thing very well (i.e. not
1894 ; flickering the text unless it has to, truncating if it's too
1895 ; long, and handling the caret correctly). You *are* allowed
1896 ; to zero terminate the string if you want to, though.
1898 ; Despite all the PRM's assurances to the contrary, chances
1899 ; are the text will be terminated by some weird control char,
1900 ; so you'll have to handle this, and not just assume it's
1901 ; going to be null-terminated.
1903 ; Note: The indirected case is immensely quick -- just load a
1904 ; pointer. The non-indirected case has been optimised as much
1907 EXPORT dbox_getField
1910 STMFD R13!,{R0,R1,R10,R14} ;Save some registers
1912 ; --- Find the icon defintion ---
1914 MOV R10,R0 ;Keep dialogue box handle
1915 MOV R0,R1 ;Put icon handle in R0
1916 BL dbox__icon ;Find icon definition
1918 ; --- Find out about indirectedness ---
1920 LDR R14,[R0,#16] ;Load the icon flags word
1921 TST R14,#1<<8 ;Is the bit set?
1922 LDRNE R2,[R0,#20] ;Yes -- load the pointer
1923 LDMNEFD R13!,{R0,R1,R10,PC}^ ;And return
1925 ; --- Copy the text to the scratchpad ---
1927 ADD R0,R0,#20 ;Point to the text string
1928 LDMIA R0,{R0,R1,R14} ;Load the 12 bytes of text
1929 STMIA R11,{R0,R1,R14} ;Store them in scratchpad
1930 MOV R0,#0 ;Zero terminate nicely
1931 STRB R0,[R11,#12] ;In case string is too long
1932 MOV R2,R11 ;Point to string in scratch
1933 LDMFD R13!,{R0,R1,R10,PC}^ ;Return to caller
1937 ;---- Other utility functions -----------------------------------------------
1939 ; --- dbox_eventHandler ---
1941 ; On entry: R0 == dialogue box handle
1942 ; R1 == pointer to handler routine
1943 ; R2 == value to pass to handler in R10
1944 ; R3 == value to pass to handler in R12
1946 ; On exit: R0 preserved
1947 ; R1 == pointer to old handler
1948 ; R2 == old R10 value
1949 ; R3 == old R12 value
1951 ; Use: Sets up an event handler for a dialogue box, and returns
1952 ; the previous one. If the pointer to handler is 0, there is
1953 ; no dialogue box event handler.
1955 EXPORT dbox_eventHandler
1959 STMFD R13!,{R4-R6,R14} ;Save some registers
1960 LDR R14,[R0,#dbx__defn] ;Load the dbx pointer
1961 CMP R14,#0 ;Is there a dbx definition?
1962 ADDEQ R14,R0,#dbox__proc ;Point to the correct user...
1963 ADDNE R14,R0,#dbx__proc ;... handler
1964 LDMIA R14,{R4-R6} ;Load the old values out
1965 STMIA R14,{R1-R3} ;Store the new ones in
1966 MOV R1,R4 ;Move the old values to...
1967 MOV R2,R5 ;... the correct registers...
1968 MOV R3,R6 ;... for returning
1969 LDMFD R13!,{R4-R6,PC}^ ;Return to caller
1973 ; --- dbox_renderTitle ---
1975 ; On entry: R0 == dialogue box handle
1976 ; R1 == pointer to redraw block
1980 ; Use: Renders a dialogue box's embedded title if there is one.
1982 EXPORT dbox_renderTitle
1986 STMFD R13!,{R0-R3,R10,R14} ;Save a load of registers
1988 MOV R10,R0 ;Move the handle into R10
1989 LDR R0,[R10,#dbox__title] ;Get the icon number out
1990 CMP R0,#-1 ;Check there really is one
1991 LDMEQFD R13!,{R0-R3,R10,PC}^ ;Return to caller if not
1993 BL dbox__icon ;Find the icon pointer
1994 MOV R2,#0 ;Group box type 0, please
1995 LDR R3,[R10,#dbox__defn] ;Find the window definition
1996 LDR R3,[R3,#72] ;Get the actual data pointer
1997 SWI XSculptrix_PlotGroupBox ;Draw the group box
1999 LDMFD R13!,{R0-R3,R10,PC}^ ;Return to caller now
2003 ; --- dbox_setEmbeddedTitle ---
2005 ; On entry: R0 == dialogue box handle
2006 ; R1 == icon which should contain the embedded title
2010 ; Use: Declares a given dialogue box as requiring an embedded title
2011 ; (rather than the one the WindowManager put on).
2013 EXPORT dbox_setEmbeddedTitle
2014 dbox_setEmbeddedTitle
2015 STR R1,[R0,#dbox__title] ;Store the icon number
2018 ; --- dbox_setClickDrag ---
2020 ; On entry: R0 == dialogue box handle
2024 ; Use: Sets a given dialogue box so that the user can move it by
2025 ; dragging from any part of the window, not just the title
2028 EXPORT dbox_setClickDrag
2030 STMFD R13!,{R14} ;Save a register
2031 LDR R14,[R0,#dbox__flags] ;Load the flags word
2032 ORR R14,R14,#dbFlag__drag ;Set the click-drag flag
2033 STR R14,[R0,#dbox__flags] ;Save the flags back again
2034 LDMFD R13!,{PC}^ ;Return to caller
2036 ; --- dbox_hasTitle ---
2038 ; On entry: R0 == dialogue box handle
2040 ; On exit: CS if the dialogue box has a title bar, CC if not
2042 ; Use: Informs the caller whether the dialogue box has a title bar.
2043 ; This is mainly useful for other library sections which
2044 ; conditionally add in embedded titles etc.
2046 EXPORT dbox_hasTitle
2049 STMFD R13!,{R14} ;Save a register
2050 LDR R14,[R0,#dbox__defn] ;Load the window definition
2051 LDR R14,[R14,#28] ;Load the window flags
2052 TST R14,#1<<31 ;Using new gadget flags?
2053 BEQ %10dbox_hasTitle ;No -- skip to handle this
2054 TST R14,#1<<26 ;Test the title bar flag
2055 B %20dbox_hasTitle ;And skip the other test
2057 10dbox_hasTitle TST R14,#1<<0 ;Test the old-fashioned bit
2059 20dbox_hasTitle LDMFD R13!,{R14} ;Restore the register I saved
2060 ORRNES PC,R14,#C_flag ;If bit set, return carry
2061 BICEQS PC,R14,#C_flag ;Otherwise clear carry
2065 ; --- dbox_window ---
2067 ; On entry: R0 == dialogue box handle
2069 ; On exit: R0 == the dialogue box's window handle
2071 ; Use: Returns the Wimp window handle associated with a dialogue
2072 ; box. This may be useful if you want to perform lowlevel
2073 ; Wimp operation on it, or to subclass it using win.
2076 dbox_window LDR R0,[R0,#dbox__window] ;Load the window handle
2077 MOVS PC,R14 ;Return to caller
2085 ; Use: Adds a help line to the current help message, read by
2086 ; scanning the icon to which the help was sent for an `H'
2087 ; validation string.
2092 STMFD R13!,{R0-R4,R10,R12,R14} ;Save some registers
2093 WSPACE dbox__wSpace ;Find my workspace quickly
2095 LDR R10,dbox__eventDbox ;Find the helpful dbox
2096 LDR R0,dbox__eventIcon ;Find the icon too
2097 CMP R0,#0 ;Is it a sensible number?
2098 BLT %99dbox_help ;No -- skip to the end
2100 ; --- Locate the validation string ---
2102 BL dbox__icon ;Find the icon definition
2103 MOV R1,#'H' ;Find `H' validation commands
2104 MOV R2,#0 ;Start from the beginning
2105 BL winUtils_findValid ;Find the validation string
2106 BCC %99dbox_help ;If not there, skip to end
2108 ; --- Copy the message tag to scratchpad ---
2110 MOV R0,R11 ;Point to scratchpad
2111 MOV R1,#0 ;We are not escaped yet
2112 ADD R2,R2,#1 ;Skip past `H' character
2114 10dbox_help LDRB R14,[R2],#1 ;Get the next byte
2116 CMP R14,#'\' ;Is it a backslash?
2117 CMPEQ R1,#0 ;Make sure it's not escaped
2118 MOVEQ R1,#1 ;Yes -- escape next char
2119 BEQ %10dbox_help ;And loop for next char
2121 CMP R14,#' ' ;Is it a control character
2122 MOVLT R14,#0 ;Yes -- terminate string
2123 CMP R14,#';' ;Is it validation string end?
2124 CMPEQ R1,#0 ;Make sure it's not escaped
2125 MOVEQ R14,#0 ;Yes -- terminate string
2126 STRB R14,[R0],#1 ;Store character in buffer
2127 CMP R14,#0 ;Was that the end?
2128 BNE %10dbox_help ;No -- try for another one
2130 ; --- Send the message to !Help ---
2132 MOV R0,R11 ;Point to buffer start again
2133 BL msgs_lookup ;Lookup the message tag
2134 BL help_add ;Add it to the help message
2136 99dbox_help LDMFD R13!,{R0-R4,R10,R12,PC}^ ;No -- return right now
2140 ;----- Useful constants -----------------------------------------------------
2142 ; --- Ways of opening dialogue boxes ---
2145 dbOpen_current # 1 ;In its current position
2146 dbOpen_centre # 1 ;Centred on the screen
2147 dbOpen_pointer # 1 ;Centred over the pointer
2148 dbOpen_givenY # 1 ;At a given height on screen
2149 ; R2 == y coordinate to open
2151 dbOpen_trans EQU &00 ;Make the dbox transient
2152 dbOpen_persist EQU &80 ;Make the dbox persistent
2153 dbOpen_nonSub EQU &40 ;Don't open as a submenu
2155 ; --- Dialogue box event codes ---
2157 dbEvent_close EQU -2 ;The user closed the dialogue
2158 ;C flag ignored on exit
2160 dbEvent_help EQU -3 ;The user wants some help
2162 ;C flag ignored on exit
2164 dbEvent_OK EQU -4 ;The user clicked OK
2165 ;R1 == mouse button status
2166 ;C flag ignored on exit
2168 dbEvent_cancel EQU -5 ;The user clicked Cancel
2169 ;R1 == mouse button status
2170 ;C flag ignored on exit
2172 dbEvent_redraw EQU -6 ;Redraw a single rectangle
2173 ;R1 == pointer to redraw blk
2174 ;R2,R3 == coords of origin
2175 ;CS => don't do default draw
2177 dbEvent_menu EQU -7 ;User clicked Menu button
2178 ;R1 == icon handle clicked
2179 ;C flag ignored on exit
2181 dbEvent_drag EQU -8 ;User dragged an icon
2182 ;R1 == mouse button status
2183 ;R2 == icon handle dragged
2184 ;C flag ignored on exit
2186 dbEvent_save EQU -9 ;User wants to import data
2187 ;R1 == icon handle dropped on
2188 ;R2 == filetype of data
2189 ;R3 == pointer to filename
2190 ;R4 == estimated file size
2191 ;C flag ignored on exit
2193 dbEvent_load EQU -10 ;User wants to load data
2194 ;R1 == icon handle dropped on
2195 ;R2 == filetype of data
2196 ;R3 == pointer to filename
2197 ;R4 == estimated file size
2198 ;C flag ignored on exit
2200 dbEvent_key EQU -11 ;User pressed a key
2201 ;R1 == key code received
2202 ;R2 == icon handle with caret
2203 ;CC => unknown keypress
2204 ;Key code has been translated
2206 dbEvent_hint EQU -12 ;Received a hint message
2207 ;R2 == pointer to hint string
2209 dbEvent_enter EQU -13 ;Pointer has entered window
2211 dbEvent_leave EQU -14 ;Pointer has left window
2213 dbEvent_lifeCycle EQU -15 ;Interesting points in cycle
2214 ;R1 == life cycle code
2216 ; --- Life cycle codes ---
2219 dblc_create # 1 ;Creation (used by dbx)
2220 dblc_open # 1 ;Opening
2221 dblc_close # 1 ;Closing
2222 dblc_destroy # 1 ;Destruction
2224 ; --- Other values ---
2226 dbFlag_dots EQU (1<<31) ;Add dots if text overflows
2229 ;----- Dialogue box data structure ------------------------------------------
2233 dbox__window # 4 ;The real window handle
2234 dbox__proc # 4 ;Pointer to event handler
2235 dbox__R10 # 4 ;Magic handle for event proc
2236 dbox__R12 # 4 ;Workspace for event proc
2237 dbox__oldCaret # 24 ;Caret position to restore
2238 dbox__defn # 4 ;Pointer to window template
2239 dbox__template # 4 ;Pointer to original template
2240 dbox__title # 4 ;Embedded title icon number
2241 dbox__flags # 4 ;Various interesting flags
2243 dbx__proc # 4 ;Pointer to user event proc
2244 dbx__R10 # 4 ;Object pointer for user proc
2245 dbx__R12 # 4 ;Workspace for user proc
2246 dbx__defn # 4 ;Pointer to control def block
2248 dbox__blockSize # 0 ;Size of the above block
2250 dbFlag__open EQU (1<<0) ;Dialogue box is on-screen
2251 dbFlag__static EQU (1<<1) ;Dialogue box is static
2252 dbFlag__rCaret EQU (1<<2) ;We have to restore the caret
2253 dbFlag__drag EQU (1<<3) ;Clicking window starts move
2255 ;----- Workspace ------------------------------------------------------------
2260 dbox__wFlags # 4 ;Various magic flags for me
2261 dbox__clickList # 4 ;List of button slabbings
2262 dbox__eventDbox # 4 ;Dbox last event happened to
2263 dbox__eventIcon # 4 ;Icon number from last event
2265 dbFlag__inited EQU (1<<0) ;The dbox system is running
2267 dbox__wSize EQU {VAR}-dbox__wStart
2269 AREA |Sapphire$$LibData|,CODE,READONLY
2276 ;----- That's all, folks ----------------------------------------------------