chiark / gitweb /
Initial revision
[ssr] / StraySrc / Libraries / Sapphire / s / dbox
1 ;
2 ; dbox.s
3 ;
4 ; Dialogue box handling (MDW)
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sapphire library.
12 ;
13 ; Sapphire is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Sapphire is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sapphire.  If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29                 GET     libs:header
30                 GET     libs:swis
31
32 ;----- External dependencies ------------------------------------------------
33
34                 GET     sapphire:akbd
35                 GET     sapphire:alloc
36                 GET     sapphire:event
37                 GET     sapphire:keyMap
38                 GET     sapphire:help
39                 GET     sapphire:hour
40                 GET     sapphire:msgs
41                 GET     sapphire:sapphire
42                 GET     sapphire:string
43                 GET     sapphire:subAlloc
44                 GET     sapphire:template
45                 GET     sapphire:transWin
46                 GET     sapphire:win
47                 GET     sapphire:winUtils
48
49 ;----- Creating and deleting dialogue boxes ---------------------------------
50
51                 AREA    |Sapphire$$Code|,CODE,READONLY
52
53 ; --- dbox_create ---
54 ;
55 ; On entry:     R0 == pointer to dialogue template name
56 ;
57 ; On exit:      R0 == dialogue box handle for the dialogue
58 ;               May return an error
59 ;
60 ; Use:          Creates a dialogue box from a template definition.
61
62                 EXPORT  dbox_create
63 dbox_create     ROUT
64
65                 STMFD   R13!,{R1-R3,R14}        ;Save some registers
66
67                 ; --- Locate the template and copy it ---
68
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
77
78                 ; --- Now create a dialogue box around it ---
79
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
84
85                 ; --- Tidy up aftet an error
86
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
96
97                 LTORG
98
99 ; --- dbox_fromEmbedded ---
100 ;
101 ; On entry:     R0 == pointer to an embedded template
102 ;
103 ; On exit:      R0 == dialogue box handle
104 ;               May return an error
105 ;
106 ; Use:          Creates a dialogue box from an embedded template definition.
107
108                 EXPORT  dbox_fromEmbedded
109 dbox_fromEmbedded ROUT
110
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
120
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
130
131                 LTORG
132
133 ; --- dbox_fromDefn ---
134 ;
135 ; On entry:     R0 == pointer to a window definition
136 ;
137 ; On exit:      R0 == dialogue box handle for the dialogue
138 ;               May return an error
139 ;
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
143 ;               box:
144 ;
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.
150 ;
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.
154 ;
155 ;               * The window definition and the indirected data must both
156 ;                 be writable.
157
158                 EXPORT  dbox_fromDefn
159 dbox_fromDefn   ROUT
160
161                 STMFD   R13!,{R1-R3,R10,R14}    ;Save some registers away
162
163                 ; --- Obtain a dbox block from the heap ---
164
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
170
171                 ; --- Now start filling in the structure ---
172
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
182
183                 ; --- Now we need to create a window ---
184
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
189
190                 ; --- Now register our event handler for it ---
191
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
197
198                 ; --- Now return the dialogue box handle ---
199
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
203
204                 ; --- Tidy up after unfortunate events ---
205
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
210
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
215
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
221
222 dbox__createErr DCD     1
223                 DCB     "dboxCRTERR",0
224
225 ; --- dbox_destroy ---
226 ;
227 ; On entry:     R0 == dialogue box handle
228 ;
229 ; On exit:      --
230 ;
231 ; Use:          Destroys a dialogue box, freeing all the memory it took
232 ;               up etc.
233
234                 EXPORT  dbox_destroy
235 dbox_destroy    ROUT
236
237                 STMFD   R13!,{R0,R1,R10,R14}    ;Save some registers
238                 MOV     R10,R0                  ;Get the dialogue handle
239
240                 ; --- Make sure the dialogue's been closed ---
241
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
246
247                 ; --- Remove the event handler ---
248
249                 LDR     R0,[R10,#dbox__window]  ;Find the window handle
250                 BL      win_windowDeleted       ;Window doesn't need handling
251
252                 ; --- Delete the window ---
253
254                 ADD     R1,R10,#dbox__window    ;Point to the window handle
255                 SWI     Wimp_DeleteWindow       ;Delete the window
256
257                 ; --- Free the template copy ---
258
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
263
264                 ; --- Free the dialogue block ---
265
266                 MOV     R0,R10                  ;Point to the dbox block
267                 BL      free                    ;Free its memory up
268
269                 ; --- Return to caller ---
270
271                 LDMFD   R13!,{R0,R1,R10,PC}^    ;Return to caller
272
273 ;----- The event handler ---------------------------------------------------
274
275 ; --- dbox__events ---
276 ;
277 ; On entry:     R0 == the event code that happened
278 ;               R1 == pointer to the event data
279 ;               R10 == dialogue box it happened to
280 ;
281 ; On exit:      CS if we handled the event, CC otherwise
282 ;
283 ; Use:          Handles various events for a dialogue box
284
285 dbox__events    ROUT
286
287                 ; --- Dispatch the event to the right place ---
288
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
293
294                 ; --- Event dispatch table ---
295
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
306
307                 ; --- Handle a message ---
308
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
313
314 ; --- dbox__dispatch ---
315 ;
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
319 ;
320 ; On exit:      CS or CC from the event handler
321 ;
322 ; Use:          Dispatches an event to the event handler associated with the
323 ;               dialogue box, and returns its response.
324
325 dbox__dispatch  ROUT
326
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
337
338                 LTORG
339
340 ; --- dbox__checkIcon ---
341 ;
342 ; On entry:     R1 == icon handle
343 ;               R10 == dialogue box handle
344 ;
345 ; On exit:      R1 == icon handle or -1 if it was shaded
346 ;
347 ; Use:          Translates an icon handle to the window background if it
348 ;               is shaded, for passing to event handlers.
349
350 dbox__checkIcon ROUT
351
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
360
361                 LTORG
362
363 ; --- dbox__hint ---
364 ;
365 ; On entry:     R0 == -1
366 ;               R1 == pointer to hint event block
367 ;
368 ; On exit:      C set if handled
369 ;
370 ; Use:          Sends a hint event to the dbox handler
371
372 dbox__hint      ROUT
373
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
379
380                 LTORG
381
382 ; --- dbox__redraw ---
383 ;
384 ; On entry:     R0 == 1
385 ;               R1 == pointer to window handle
386 ;
387 ; On exit:      C set
388 ;
389 ; Use:          Redraws a window using Sculptrix
390
391 dbox__redraw    ROUT
392
393                 STMFD   R13!,{R0,R2,R3,R14}     ;Save some registers
394
395                 ; --- Start the redraw operation ---
396
397                 SWI     Wimp_RedrawWindow       ;Start the redraw
398                 CMP     R0,#0                   ;Is it over already?
399                 BEQ     %10dbox__redraw         ;Yes -- skip to the end
400
401                 ; --- Set up Sculptrix's sprite area ---
402
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
406
407                 ; --- Do any bits that need doing ---
408
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
417
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
422
423                 SWI     XSculptrix_RedrawWindow ;Get Sculptrix to do its bit
424
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
428
429                 ; --- That's it, then ---
430
431 10dbox__redraw  LDMFD   R13!,{R0,R2,R3,R14}     ;Unstack all the registers
432                 ORRS    PC,R14,#C_flag          ;Set carry and return
433
434                 LTORG
435
436 ; --- dbox__open ---
437 ;
438 ; On entry:     R0 == 2
439 ;               R1 == pointer to window open block
440 ;
441 ; On exit:      C set
442 ;
443 ; Use:          This just opens the window.  Later, it may do clever things
444 ;               with panes.
445
446 dbox__open      SWI     Wimp_OpenWindow         ;Open the window
447                 ORRS    PC,R14,#C_flag          ;Set carry and return
448
449 ; --- dbox__close ---
450 ;
451 ; On entry:     R0 == 3
452 ;               R1 == pointer to the window handle
453 ;
454 ; On exit:      C set
455 ;
456 ; Use:          Passes a close event to the user dialogue box handler.
457
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
463
464 ; --- dbox__mouse ---
465 ;
466 ; On entry:     R0 == 6
467 ;               R1 == pointer to mouse status block
468 ;
469 ; On exit:      C set if we understood the event, C clear otherwise
470 ;
471 ; Use:          Passes a click event to the dbox event handler.
472
473 dbox__mouse     ROUT
474
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
484
485                 ; --- The user clicked Menu ---
486
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
492
493                 ; --- The user clicked Select or Adjust ---
494
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
501
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
505
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
509
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
519
520                 ; --- The user dragged an icon ---
521
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
529
530                 ; --- Finish everything off nicely ---
531
532 80dbox__mouse   LDMFD   R13!,{R0-R2,R9,R14}     ;Restore the registers
533                 ORRS    PC,R14,#C_flag          ;Claim the event nicely
534
535                 LTORG
536
537 ; --- dbox__enterLeave ---
538 ;
539 ; On entry:     R0 == 4 for leaving, 5 for entering
540 ;
541 ; On exit:      --
542 ;
543 ; Use:          Informs dialogue handlers that pointer has entered or left
544 ;               a window.
545
546 dbox__enterLeave ROUT
547
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
552
553                 LTORG
554
555 ; --- dbox__keyPress ---
556 ;
557 ; On entry:     R0 == 8
558 ;               R1 == pointer to caret block
559 ;
560 ; On exit:      C clear
561 ;
562 ; Use:          Handles key events for a dialogue box
563
564 dbox__keyPress  ROUT
565
566                 STMFD   R13!,{R0-R3,R14}        ;Save some registers
567
568                 ; --- Send the event to the user ---
569
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
578
579                 ; --- Now see if it's one of ours ---
580
581                 CMP     R1,#&100                ;Is it an extended code?
582                 BGE     %20dbox__keyPress       ;Yes -- skip forward
583
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
590
591 00              LDMFD   R13!,{R0-R3,PC}^        ;Forget it -- don't know
592
593                 ; --- Send a key event on ---
594
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...
598
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...
602
603                 ; --- Handle an extended key ---
604
605 20              AND     R2,R1,#&FF              ;Leave the bottom byte
606
607                 ; --- Straight cursor keys ---
608
609                 MOV     R0,#0
610
611                 CMP     R2,#key_kEnter-256
612                 MOVEQ   R0,#dbEvent_OK
613                 BEQ     %10dbox__keyPress
614
615                 CMP     R2,#key_sReturn-256
616                 CMPNE   R2,#key_skEnter-256
617                 MOVEQ   R0,#dbEvent_OK
618                 BEQ     %11dbox__keyPress
619
620                 CMP     R2,#key_sEsc-256
621                 MOVEQ   R0,#dbEvent_cancel
622                 BEQ     %11dbox__keyPress
623
624                 CMP     R2,#key_Up-256
625                 CMPNE   R2,#key_sTab-256
626                 MOVEQ   R1,#-1
627                 BEQ     %40dbox__keyPress
628
629                 CMP     R2,#key_Down-256
630                 CMPNE   R2,#key_Tab-256
631                 MOVEQ   R1,#+1
632                 BEQ     %40dbox__keyPress
633
634                 ; --- Control cursor keys ---
635
636                 MOV     R0,#1
637
638                 CMP     R2,#key_cUp-256
639                 MOVEQ   R1,#+1
640                 BEQ     %40dbox__keyPress
641
642                 ; --- Cursor up ---
643
644                 CMP     R2,#key_cDown-256
645                 MOVEQ   R1,#-1
646                 BEQ     %40dbox__keyPress
647
648                 ; --- Nothing worth knowing about ---
649
650                 B       %00dbox__keyPress
651
652                 ; --- Actually do a cursor move ---
653
654 40              BL      dbox__moveCaret         ;Do the cursor move
655
656                 ; --- Return and claim the keypress ---
657
658 50              LDMFD   R13!,{R0-R3,R14}
659                 ORRS    PC,R14,#C_flag
660
661                 LTORG
662
663 ; --- dbox__message ---
664 ;
665 ; On entry:     R0 == 17 or 18
666 ;               R1 == pointer to message data
667 ;
668 ; On exit:      C set if the event was handled, or clear otherwise
669 ;
670 ; Use:          Handles messages sent to dialogue boxes.
671
672 dbox__message   ROUT
673
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
684
685                 ; --- Handle help requests for the dbox ---
686
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
692
693                 ; --- Handle save and load events ---
694
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
705
706                 ; --- We did something, so claim event ---
707
708 80dbox__message LDMFD   R13!,{R0-R4,R9,R14}     ;Restore all the registers
709                 ORRS    PC,R14,#C_flag          ;Return, claiming the event
710
711                 LTORG
712
713 ;----- Locating icons -------------------------------------------------------
714
715 ; --- dbox__find ---
716 ;
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
721 ;                     very odd)
722 ;               R10 == dialogue box handle
723 ;
724 ; On exit:      R0 == icon number of found icon or -1
725 ;               Other registers preserved
726 ;
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
730 ;               current state.
731 ;
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.
736 ;
737 ;               The return value is the number of the first icon that
738 ;               matched the specification, or -1 if none of them matched.
739
740 dbox__find      ROUT
741
742                 STMFD   R13!,{R4-R6,R14}        ;Save some registers
743
744                 ; --- Find the cached window defintion ---
745
746                 LDR     R4,[R10,#dbox__defn]    ;Locate the definition
747
748                 ; --- Work out a sensible scanning start position ---
749
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
757
758                 ; --- Now work out when to stop scanning ---
759
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
764
765                 ; --- A few other pre-scan bits ---
766
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
770
771                 ; --- The main scanning loop ---
772                 ;
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
778                 ; can be done in 6.
779                 ;
780                 ; Rather oddly, we start with the termination condition.
781
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
788
789                 ; --- Now see if we got a match ---
790
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
795
796                 ; --- Set up for the next one ---
797
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
801
802                 ; --- We failed to find it -- return -1 ---
803
804 02dbox__find    MOV     R0,#-1                  ;Return funny failure value
805                 LDMFD   R13!,{R4-R6,PC}^        ;Return to caller
806
807                 LTORG
808
809 ; --- dbox__icon ---
810 ;
811 ; On entry:     R0 == icon number wanted
812 ;               R10 == dialogue box block pointer
813 ;
814 ; On exit:      R0 == pointer to numbered icon's definition
815 ;
816 ; Use:          Locates an icon definition given its number
817
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
823
824 ;----- Main initialisation --------------------------------------------------
825
826 ; --- dbox_init ---
827 ;
828 ; On entry:     --
829 ;
830 ; On exit:      --
831 ;
832 ; Use:          Initialises the dbox system.
833
834                 EXPORT  dbox_init
835 dbox_init       ROUT
836
837                 STMFD   R13!,{R12,R14}          ;Save a load of registers
838                 WSPACE  dbox__wSpace            ;Find my workspace
839
840                 ; --- Make sure I'm not running yet ---
841
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
845
846                 ; --- Set up the flags nicely ---
847
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
855
856                 LTORG
857
858 dbox__wSpace    DCD     0
859
860 ;----- Opening and closing dialogue boxes -----------------------------------
861
862 ; --- dbox_open ---
863 ;
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
868 ;
869 ; On exit:      --
870 ;
871 ; Use:          Displays the dialogue box on the screen in the given manner.
872
873                 EXPORT  dbox_open
874 dbox_open       ROUT
875
876                 STMFD   R13!,{R0-R6,R10,R12,R14}
877                 WSPACE  dbox__wSpace            ;Locate my workspace
878                 MOV     R10,R0                  ;Move the dbox handle away
879
880                 ; --- Is this a submenu request? ---
881
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
886
887                 ; --- Now work out how to open it ---
888
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
894
895                 ; --- Read the dialogue's position ---
896
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
902
903                 ; --- Move the dialogue box to the right position ---
904
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
909
910                 ; --- Open a persistent dialogue box ---
911
912                 SWI     Wimp_OpenWindow         ;Open the window
913                 ADD     R13,R13,#36             ;Reclaim the stack space
914
915                 ; --- If the window was already open, quit now ---
916
917                 TST     R6,#dbFlag__open        ;Is the dialogue box open
918                 BNE     %80dbox_open            ;Yes -- skip past this bit
919
920                 ; --- Now find out if there's a caret to handle ---
921
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
930
931                 ; --- Read the old caret position ---
932
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
938                 ORR     R2,R2,#&00ff0000
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
944
945                 ; --- That's it, so finish things off ---
946
947 10dbox_open     B       %80dbox_open            ;Perform wrapping-up actions
948
949                 ; --- Open as a transient menu ---
950
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
958
959                 ; --- Open in the correct submenu position ---
960
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
965
966                 ; --- Wrap everything up now ---
967
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}^
974
975                 LTORG
976
977 ; --- dbox_close ---
978 ;
979 ; On entry:     R0 == dialogue box handle
980 ;
981 ; On exit:      --
982 ;
983 ; Use:          Closes a dialogue box, by clearing the current menu if
984 ;               necessary.
985
986                 EXPORT  dbox_close
987 dbox_close      ROUT
988
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
992
993                 ; --- First things first -- check it's open ---
994
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
998
999                 ; --- Now restore the caret if needs be ---
1000                 ;
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.
1004
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
1010
1011                 ; --- Now handle transientness properly ---
1012
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
1018
1019                 BIC     R6,R6,#dbFlag__open :OR: dbFlag__rCaret
1020                 STR     R6,[R10,#dbox__flags]   ;Store flags away again
1021
1022                 ; --- Send a lifecycle warning ---
1023
1024                 MOV     R0,#dbEvent_lifeCycle   ;Get the event code
1025                 MOV     R1,#dblc_close          ;Box has closed
1026                 BL      dbox__dispatch          ;Send the event
1027
1028 80dbox_close    LDMFD   R13!,{R0-R6,R10,R12,PC}^ ;Return to caller
1029
1030                 LTORG
1031
1032 ; --- dbox_writePos ---
1033 ;
1034 ; On entry:     R0 == dialogue box handle
1035 ;
1036 ; On exit:      --
1037 ;
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.
1043
1044                 EXPORT  dbox_writePos
1045 dbox_writePos   ROUT
1046
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
1062
1063                 LTORG
1064
1065 ;----- Caret handling functions ---------------------------------------------
1066
1067 ; --- dbox__viewIcon ---
1068 ;
1069 ; On entry:     R0 == an icon number
1070 ;               R10 == dialogue box handle
1071 ;
1072 ; On exit:      --
1073 ;
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.
1077 ;
1078 ;               This is translated fairly literally from the STEEL code
1079 ;               in dbox__nextWritable.
1080
1081 dbox__viewIcon  ROUT
1082
1083                 STMFD   R13!,{R0-R9,R14}        ;Save a load of registers
1084
1085                 ; --- Locate the icon definition ---
1086
1087                 BL      dbox__icon              ;Find the icon position
1088                 MOV     R9,R0                   ;Keep a pointer to it
1089
1090                 ; --- Find the window position ---
1091
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
1097
1098                 ; --- Now read the window scroll positions ---
1099
1100                 LDMIB   R13,{R0-R5}             ;Load window visible coords
1101
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
1108
1109                 LDMIA   R9,{R6-R8,R14}          ;Load icon coordinates nicely
1110
1111                 SUB     R6,R6,#24               ;Add a bit of extra around
1112                 SUB     R7,R7,#24
1113                 ADD     R8,R8,#24
1114                 ADD     R14,R14,#24
1115
1116                 ; --- Bodge the scroll positions until icon is visible ---
1117                 ;
1118                 ; This section is fairly self-explanatory, and the comments
1119                 ; are very dull.
1120
1121                 CMP     R7,R3
1122                 ADDLT   R5,R7,R1
1123                 CMP     R14,R5
1124                 MOVGT   R5,R14
1125                 CMP     R6,R4
1126                 MOVLT   R4,R6
1127                 CMP     R8,R2
1128                 SUBGT   R4,R8,R0
1129
1130                 ; --- Now store the scroll offsets back and reopen ---
1131
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
1136
1137                 ; --- Reclaim the stack and return ---
1138
1139                 ADD     R13,R13,#36
1140                 LDMFD   R13!,{R0-R9,PC}^        ;Return to caller
1141
1142                 LTORG
1143
1144 ; --- dbox__moveCaret ---
1145 ;
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
1150 ;
1151 ; On exit:      --
1152 ;
1153 ; Use:          Moves the caret between writable icons, responding to cursor
1154 ;               key presses.
1155
1156 dbox__moveCaret ROUT
1157
1158                 STMFD   R13!,{R0-R5,R14}        ;Save a few registers
1159
1160                 ; --- Find out where the cursor is ---
1161
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
1165
1166                 ; --- Check this is the right window ---
1167
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
1173
1174                 ; --- Now set up a search for the icon ---
1175
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
1180
1181                 ; --- Load the icon flags to search for ---
1182
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
1188
1189                 ; --- Now it's come up with the goods ---
1190
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
1194
1195                 ; --- Scroll to make icon visible ---
1196
1197                 BL      dbox__viewIcon          ;Scroll the window nicely
1198
1199                 ; --- Set the caret position nicely ---
1200
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
1207
1208                 LDMFD   R13!,{R0-R5,PC}^        ;Return to caller at last
1209
1210                 LTORG
1211
1212 ;----- Selecting and shading icons ------------------------------------------
1213
1214 ; --- dbox_select ---
1215 ;
1216 ; On entry:     R0 == dialogue box handle
1217 ;               R1 == icon number
1218 ;               R2 == 0 to deselect the icon, 1 to select it, 2 to toggle
1219 ;                     its current selected state
1220 ;
1221 ; On exit:      --
1222 ;
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.
1226
1227                 EXPORT  dbox_select
1228 dbox_select     ROUT
1229
1230                 STMFD   R13!,{R0-R2,R14}        ;Save some registers away
1231
1232                 ; --- Find the old state ---
1233
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
1239
1240                 ; --- Find out the current selection state ---
1241
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
1248
1249                 ; --- Make sure we need to do something ---
1250
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
1254
1255                 ; --- Now change the icon state ---
1256
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
1261
1262                 ADD     R13,R13,#40             ;Restore the stack nicely
1263                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
1264
1265                 LTORG
1266
1267 ; --- dbox_shade ---
1268 ;
1269 ; On entry:     R0 == dialogue box handle
1270 ;               R1 == icon number
1271 ;               R2 == 0 to unshade the icon, 1 to shade it, 2 to toggle its
1272 ;                     current shaded state
1273 ;
1274 ; On exit:      --
1275 ;
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
1279 ;               out for:
1280 ;
1281 ;               * Don't use any other method of shading icons
1282 ;
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
1287 ;                 icon is shaded.
1288 ;
1289 ;               This routine has been written so that it only flickers icons
1290 ;               when they actually need it.
1291
1292                 EXPORT  dbox_shade
1293 dbox_shade      ROUT
1294
1295                 STMFD   R13!,{R0-R6,R10,R14}    ;Save a load of registers
1296
1297                 ; --- Make sure we need to do something ---
1298
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
1305
1306                 ; --- Work out what needs to be done ---
1307
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
1312
1313                 ; --- Now quit if there's nothing to do ---
1314
1315                 CMP     R2,R5                   ;Are they the same now?
1316                 LDMEQFD R13!,{R0-R6,R10,PC}^    ;Yes -- return right now
1317
1318                 ; --- Find the old state from the icon ---
1319
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
1326
1327                 ; --- Now process the cached flags nicely ---
1328                 ;
1329                 ; We can just flip the bit now, because we know it must be
1330                 ; different to its old state.
1331
1332                 EOR     R6,R6,#&00400000        ;Toggle the flag
1333                 STR     R6,[R4,#16]             ;Store it back in the block
1334
1335                 ; --- Now work out exactly what we have to do ---
1336
1337                 TST     R6,#&00400000           ;Are we meant to be shading?
1338                 BEQ     %50dbox_shade           ;No -- unshade nicely
1339
1340                 ; --- Lots of messing about with bitmasks ---
1341                 ;
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.
1348
1349                 MOV     R0,#8                   ;Read the font handle
1350                 SWI     XWimp_ReadSysInfo       ;Read the handle then
1351                 MOVVS   R0,#0                   ;Unknown -- not supported
1352
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
1358
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
1366
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
1372
1373                 ; --- Now make sure the caret's not in it ---
1374
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
1381
1382                 ; --- Now kick the caret into cyberspace ---
1383
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
1390
1391                 ; --- Now handle unshading -- this is easy :-/ ---
1392
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
1396
1397                 BIC     R5,R5,#&0f500000        ;Clear another load of bits
1398                 BIC     R5,R5,#&000ff000        ;And the last load of bits
1399
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
1405
1406                 ; --- Tidy everything up finally ---
1407
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
1416
1417                 LTORG
1418
1419 ; --- dbox_selectMany ---
1420 ;
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)
1424 ;
1425 ; On exit:      --
1426 ;
1427 ; Use:          Changes the select state of a group of icons.
1428
1429                 EXPORT  dbox_selectMany
1430 dbox_selectMany ROUT
1431
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
1439
1440                 LTORG
1441
1442 ; --- dbox_shadeMany ---
1443 ;
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)
1447 ;
1448 ; On exit:      --
1449 ;
1450 ; Use:          Changes the shade state of a group of icons.
1451
1452                 EXPORT  dbox_shadeMany
1453 dbox_shadeMany  ROUT
1454
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
1462
1463                 LTORG
1464
1465 ; --- dbox_isSelected ---
1466 ;
1467 ; On entry:     R0 == dialogue box handle
1468 ;               R1 == icon number
1469 ;
1470 ; On exit:      CS if the icon is selected, CC otherwise
1471 ;
1472 ; Use:          Returns whether an icon is currently selected.
1473
1474                 EXPORT  dbox_isSelected
1475 dbox_isSelected ROUT
1476
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
1489
1490                 LTORG
1491
1492 ; --- dbox_radio ---
1493 ;
1494 ; On entry:     R0 == dialogue box handle
1495 ;               R1 == icon handle
1496 ;
1497 ; On exit:      --
1498 ;
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
1502 ;               this ESG.
1503
1504                 EXPORT  dbox_radio
1505 dbox_radio      ROUT
1506
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
1510
1511                 ; --- Locate the icon and check it's a radio button ---
1512
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
1522
1523                 ; --- The ESG is now in R4 -- process it ---
1524
1525                 MOV     R0,#-1                  ;Start from the beginning
1526
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
1541
1542                 LTORG
1543
1544 ;----- Clicking and unclicking icons ----------------------------------------
1545
1546 ; --- dbox_slab ---
1547 ;
1548 ; On entry:     R0 == dialogue box handle
1549 ;               R1 == icon handle
1550 ;
1551 ; On exit:      May return an error
1552 ;
1553 ; Use:          Slabs an icon in properly, to give visual feedback when you
1554 ;               click it.
1555
1556                 EXPORT  dbox_slab
1557 dbox_slab       ROUT
1558
1559                 STMFD   R13!,{R0-R2,R12,R14}    ;Save some registers away
1560                 WSPACE  dbox__wSpace            ;Find my workspace pointer
1561
1562                 ; --- Allocate a new block ---
1563
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
1567
1568                 ; --- Link the block into the list ---
1569
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
1573
1574                 ; --- Now actually slab the icon ---
1575
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
1581
1582                 ; --- Tidy up after an error ---
1583
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
1587
1588                 LTORG
1589
1590 ; --- dbox_unslab ---
1591 ;
1592 ; On entry:     --
1593 ;
1594 ; On exit:      CS if there are no more slabbed icons after this one, CC
1595 ;               if there are more left.
1596 ;
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:
1602 ;
1603 ;                               BL      dbox_unslab
1604 ;                               SUBCC   PC,PC,#12       ;Avoids a label!
1605 ;
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.
1609 ;
1610 ;                               LDR     R0,my_dbox
1611 ;                               BL      dbox_close
1612 ;                               BL      dbox_unslab
1613 ;                               BL      dbox_destroy
1614
1615                 EXPORT  dbox_unslab
1616 dbox_unslab     ROUT
1617
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
1621
1622                 ; --- Get the descriptor to free ---
1623
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
1627
1628                 ; --- Unslab the icon and unlink the block ---
1629                 ;
1630                 ; Make sure the hourglass stays off all this time.
1631
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
1641
1642                 ; --- Free the block now ---
1643
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
1647
1648                 ; --- Now return the status to the user ---
1649
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
1654
1655                 LTORG
1656
1657 ;----- Messing with dialogue box fields -------------------------------------
1658
1659 ; --- dbox__fieldLen ---
1660 ;
1661 ; On entry:     R1 == icon number
1662 ;               R10 == dialogue box handle
1663 ;
1664 ; On exit:      R0 == length of the text in the icon
1665 ;
1666 ; Use:          Returns the length of the field in the given icon
1667
1668 dbox__fieldLen  ROUT
1669
1670                 STMFD   R13!,{R1,R14}           ;Save some registers
1671
1672                 ; --- Find the icon definition ---
1673
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
1679
1680                 ; --- Get the icon flags and find the data ---
1681
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
1685
1686                 ; --- Handle indirectedness ---
1687
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
1692
1693                 ; --- Handle nonindirectedness ---
1694                 ;
1695                 ; We know at this point that R0 is 0, because we used ANDS
1696                 ; not TST above.  This is a pointless optimisation.
1697
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
1705
1706                 ; --- Return the calculated length ---
1707
1708 12              ADD     R13,R13,#40             ;Reclaim the stack again
1709                 LDMFD   R13!,{R1,PC}^           ;Return to caller
1710
1711                 LTORG
1712
1713 ; --- dbox_setField ---
1714 ;
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
1720 ;
1721 ; On exit:      --
1722 ;
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
1728 ;               justify flag.
1729 ;
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.
1735 ;
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.
1740
1741                 EXPORT  dbox_setField
1742 dbox_setField   ROUT
1743
1744                 STMFD   R13!,{R0-R5,R14}        ;Stash registers away
1745
1746                 ; --- Handle the title bar nicely ---
1747
1748                 CMP     R1,#-1                  ;Does he want the title?
1749                 BEQ     %30dbox_setField        ;Yes -- jump ahead to do it
1750
1751                 ; --- Find out about the icon ---
1752
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
1760
1761                 ; --- Make sure we can change the text ---
1762
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
1766
1767                 ; --- Now find how much we actually have to copy ---
1768
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
1779
1780                 ; --- Copy the text into the buffer ---
1781
1782 00dbox_setField LDR     R0,[R13,#28]            ;Find the buffer address
1783                 MOV     R3,#0                   ;Count the length too
1784
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
1791
1792                 ; --- Handle ellipsis generation ---
1793
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
1801
1802                 ; --- Return to normality ---
1803
1804 15dbox_setField LDRB    R14,[R0],#1             ;Get one from the buffer
1805                 CMP     R14,#' '                ;Same for the buffer char
1806                 MOVLO   R14,#0
1807
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
1811
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
1815
1816                 ; --- We've copied the string -- now update the icon ---
1817
1818                 TST     R4,#2                   ;Is the string different?
1819                 BEQ     %20dbox_setField        ;No -- skip ahead
1820
1821                 MOV     R1,#0
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
1826
1827                 ; --- Now check for the caret ---
1828
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
1837
1838                 ; --- Push the caret back a little ---
1839
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
1843
1844                 ; --- Now put the caret in the right place ---
1845
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
1850
1851                 ; --- Return nicely ---
1852
1853 20dbox_setField ADD     R13,R13,#40             ;Reclaim that temporary space
1854                 LDMFD   R13!,{R0-R5,PC}^        ;Return to caller
1855
1856                 ; --- Caller wants to update the title bar ---
1857
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
1862
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
1868
1869                 ; --- Icon wasn't indirected ---
1870
1871 80dbox_setField ADR     R0,dbox__nind           ;Point to error
1872                 BL      msgs_error              ;Translate the message
1873                 SWI     OS_GenerateError
1874
1875 dbox__nind      DCD     1
1876                 DCB     "dboxNIND",0
1877
1878                 LTORG
1879
1880 ; --- dbox_getField ---
1881 ;
1882 ; On entry:     R0 == dialogue box handle
1883 ;               R1 == icon number to interrogate
1884 ;
1885 ; On exit:      R0, R1 preserved
1886 ;               R2 == pointer to the icon text
1887 ;
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.
1897 ;
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.
1902 ;
1903 ;               Note: The indirected case is immensely quick -- just load a
1904 ;               pointer.  The non-indirected case has been optimised as much
1905 ;               as possible.
1906
1907                 EXPORT  dbox_getField
1908 dbox_getField   ROUT
1909
1910                 STMFD   R13!,{R0,R1,R10,R14}    ;Save some registers
1911
1912                 ; --- Find the icon defintion ---
1913
1914                 MOV     R10,R0                  ;Keep dialogue box handle
1915                 MOV     R0,R1                   ;Put icon handle in R0
1916                 BL      dbox__icon              ;Find icon definition
1917
1918                 ; --- Find out about indirectedness ---
1919
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
1924
1925                 ; --- Copy the text to the scratchpad ---
1926
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
1934
1935                 LTORG
1936
1937 ;---- Other utility functions -----------------------------------------------
1938
1939 ; --- dbox_eventHandler ---
1940 ;
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
1945 ;
1946 ; On exit:      R0 preserved
1947 ;               R1 == pointer to old handler
1948 ;               R2 == old R10 value
1949 ;               R3 == old R12 value
1950 ;
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.
1954
1955                 EXPORT  dbox_eventHandler
1956 dbox_eventHandler
1957                 ROUT
1958
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
1970
1971                 LTORG
1972
1973 ; --- dbox_renderTitle ---
1974 ;
1975 ; On entry:     R0 == dialogue box handle
1976 ;               R1 == pointer to redraw block
1977 ;
1978 ; On exit:      --
1979 ;
1980 ; Use:          Renders a dialogue box's embedded title if there is one.
1981
1982                 EXPORT  dbox_renderTitle
1983 dbox_renderTitle
1984                 ROUT
1985
1986                 STMFD   R13!,{R0-R3,R10,R14}    ;Save a load of registers
1987
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
1992
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
1998
1999                 LDMFD   R13!,{R0-R3,R10,PC}^    ;Return to caller now
2000
2001                 LTORG
2002
2003 ; --- dbox_setEmbeddedTitle ---
2004 ;
2005 ; On entry:     R0 == dialogue box handle
2006 ;               R1 == icon which should contain the embedded title
2007 ;
2008 ; On exit:      --
2009 ;
2010 ; Use:          Declares a given dialogue box as requiring an embedded title
2011 ;               (rather than the one the WindowManager put on).
2012
2013                 EXPORT  dbox_setEmbeddedTitle
2014 dbox_setEmbeddedTitle
2015                 STR     R1,[R0,#dbox__title]    ;Store the icon number
2016                 MOVS    PC,R14
2017
2018 ; --- dbox_setClickDrag ---
2019 ;
2020 ; On entry:     R0 == dialogue box handle
2021 ;
2022 ; On exit:      --
2023 ;
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
2026 ;               bar.
2027
2028                 EXPORT  dbox_setClickDrag
2029 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
2035
2036 ; --- dbox_hasTitle ---
2037 ;
2038 ; On entry:     R0 == dialogue box handle
2039 ;
2040 ; On exit:      CS if the dialogue box has a title bar, CC if not
2041 ;
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.
2045
2046                 EXPORT  dbox_hasTitle
2047 dbox_hasTitle   ROUT
2048
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
2056
2057 10dbox_hasTitle TST     R14,#1<<0               ;Test the old-fashioned bit
2058
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
2062
2063                 LTORG
2064
2065 ; --- dbox_window ---
2066 ;
2067 ; On entry:     R0 == dialogue box handle
2068 ;
2069 ; On exit:      R0 == the dialogue box's window handle
2070 ;
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.
2074
2075                 EXPORT  dbox_window
2076 dbox_window     LDR     R0,[R0,#dbox__window]   ;Load the window handle
2077                 MOVS    PC,R14                  ;Return to caller
2078
2079 ; --- dbox_help ---
2080 ;
2081 ; On entry:     --
2082 ;
2083 ; On exit:      --
2084 ;
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.
2088
2089                 EXPORT  dbox_help
2090 dbox_help       ROUT
2091
2092                 STMFD   R13!,{R0-R4,R10,R12,R14} ;Save some registers
2093                 WSPACE  dbox__wSpace            ;Find my workspace quickly
2094
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
2099
2100                 ; --- Locate the validation string ---
2101
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
2107
2108                 ; --- Copy the message tag to scratchpad ---
2109
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
2113
2114 10dbox_help     LDRB    R14,[R2],#1             ;Get the next byte
2115
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
2120
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
2129
2130                 ; --- Send the message to !Help ---
2131
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
2135
2136 99dbox_help     LDMFD   R13!,{R0-R4,R10,R12,PC}^ ;No -- return right now
2137
2138                 LTORG
2139
2140 ;----- Useful constants -----------------------------------------------------
2141
2142 ; --- Ways of opening dialogue boxes ---
2143
2144                 ^       0
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
2150
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
2154
2155 ; --- Dialogue box event codes ---
2156
2157 dbEvent_close   EQU     -2                      ;The user closed the dialogue
2158                                                 ;C flag ignored on exit
2159
2160 dbEvent_help    EQU     -3                      ;The user wants some help
2161                                                 ;R1 == icon number
2162                                                 ;C flag ignored on exit
2163
2164 dbEvent_OK      EQU     -4                      ;The user clicked OK
2165                                                 ;R1 == mouse button status
2166                                                 ;C flag ignored on exit
2167
2168 dbEvent_cancel  EQU     -5                      ;The user clicked Cancel
2169                                                 ;R1 == mouse button status
2170                                                 ;C flag ignored on exit
2171
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
2176
2177 dbEvent_menu    EQU     -7                      ;User clicked Menu button
2178                                                 ;R1 == icon handle clicked
2179                                                 ;C flag ignored on exit
2180
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
2185
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
2192
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
2199
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
2205
2206 dbEvent_hint    EQU     -12                     ;Received a hint message
2207                                                 ;R2 == pointer to hint string
2208
2209 dbEvent_enter   EQU     -13                     ;Pointer has entered window
2210
2211 dbEvent_leave   EQU     -14                     ;Pointer has left window
2212
2213 dbEvent_lifeCycle EQU   -15                     ;Interesting points in cycle
2214                                                 ;R1 == life cycle code
2215
2216 ; --- Life cycle codes ---
2217
2218                 ^       0
2219 dblc_create     #       1                       ;Creation (used by dbx)
2220 dblc_open       #       1                       ;Opening
2221 dblc_close      #       1                       ;Closing
2222 dblc_destroy    #       1                       ;Destruction
2223
2224 ; --- Other values ---
2225
2226 dbFlag_dots     EQU     (1<<31)                 ;Add dots if text overflows
2227                                                 ;  in dbox_setField
2228
2229 ;----- Dialogue box data structure ------------------------------------------
2230
2231                 ^       0
2232
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
2242
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
2247
2248 dbox__blockSize #       0                       ;Size of the above block
2249
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
2254
2255 ;----- Workspace ------------------------------------------------------------
2256
2257                 ^       0,R12
2258 dbox__wStart    #       0
2259
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
2264
2265 dbFlag__inited  EQU     (1<<0)                  ;The dbox system is running
2266
2267 dbox__wSize     EQU     {VAR}-dbox__wStart
2268
2269                 AREA    |Sapphire$$LibData|,CODE,READONLY
2270
2271                 DCD     dbox__wSize
2272                 DCD     dbox__wSpace
2273                 DCD     16
2274                 DCD     dbox_init
2275
2276 ;----- That's all, folks ----------------------------------------------------
2277
2278                 END