chiark / gitweb /
JPEG support and other fixes from Nick Clark
[ssr] / StraySrc / Libraries / Sapphire / s / writable
1 ;
2 ; writable.s
3 ;
4 ; Writable dialogue boxes (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:dbox
35                 GET     sapphire:fastMove
36                 GET     sapphire:msgs
37                 GET     sapphire:sapphire
38                 GET     sapphire:string
39
40 ;----- Main code ------------------------------------------------------------
41
42                 AREA    |Sapphire$$Code|,CODE,READONLY
43
44 ; --- writable ---
45 ;
46 ; On entry:     R0 == pointer to writable dialogue block
47 ;               R1 == pointer to default string to display, or 0 for null
48 ;               R2 == pointer to routine to call when string set
49 ;               R3 == value to pass to routine in R10
50 ;               R4 == value to pass to routine in R12
51 ;
52 ; On exit:      R0 == dialogue handle of created dialogue box
53 ;               May return an error
54 ;
55 ; Use:          Displays a writable dialogue box, i.e. one with a writable
56 ;               icon and OK button, used instead of writable menu items,
57 ;               for reasons to do with caret blinking and pointer changing.
58 ;
59 ;               The writable dialogue block consists of:
60 ;
61 ;               Size    Meaning
62 ;               ~~~~    ~~~~~~~
63 ;               4       Flags (see below)
64 ;               n       Validation string to use, may be null
65 ;               m       Title string (message tag) to display
66 ;
67 ;               The flags are:
68 ;
69 ;               Bit     Meaning
70 ;               ~~~     ~~~~~~~
71 ;               0-7     Maximum string length
72 ;               8       Right align text in writable icon
73 ;               9-31    Reserved; must be 0
74 ;
75 ;               The routine returns a dialogue handle because you may want
76 ;               to attach a numWrite control to the writable icon, which
77 ;               is icon number 0.
78 ;
79 ;               The handler routine is passed:
80 ;
81 ;               R0 == pointer to string typed in
82 ;               R1 == dialogue box handle (for numWrite again)
83 ;               R10, R12 as set up here
84 ;
85 ;               It must preserve all registers.  If the carry flag is set
86 ;               on exit, the dialogue box will not be closed.  If it is
87 ;               clear, the dialogue may be closed depending on the button
88 ;               status.
89 ;
90 ;               Note that this routine does *not* require a template --
91 ;               a suitable window is generated at run-time.
92
93                 EXPORT  writable
94 writable        ROUT
95
96                 STMFD   R13!,{R1-R3,R12,R14}    ;Save some registers away
97                 WSPACE  wrt__wSpace             ;Find my workspace pointer
98
99                 ; --- Save the handler information ---
100
101                 ADR     R14,wrt__proc           ;Point to the handler stuff
102                 STMIA   R14,{R2-R4}             ;Save the handler info away
103                 MOV     R3,R0                   ;Keep the description block
104
105                 ; --- Save the default string away ---
106
107                 ADR     R0,wrt__buffer          ;Point to writable buffer
108                 CMP     R1,#0                   ;Is there a default string?
109                 STREQB  R1,[R0,#0]              ;No -- save a null string
110                 BLNE    str_cpy                 ;Otherwise copy the string
111
112                 ; --- Set up the dialogue box sizes ---
113
114                 LDR     R1,[R3,#0]              ;Load the string length/flags
115                 AND     R0,R1,#&FF              ;Just get the bottom byte
116                 ADD     R0,R0,#1                ;Allow for the terminator
117                 STR     R0,wrt__dbDef+wOff__writeData+8
118                 CMP     R0,#41                  ;Is the string really big?
119                 MOVGT   R0,#41                  ;Yes -- make it sane at least
120                 MOV     R0,R0,LSL #4            ;Multiply up to pixels
121                 ADD     R0,R0,#106              ;Get the left of the icon
122                 RSB     R0,R0,#0                ;And make it negative
123                 STR     R0,wrt__dbDef+wOff__writeBox
124                 SUB     R0,R0,#24               ;Get left side of the window
125                 STR     R0,wrt__dbDef+wOff__open
126                 STR     R0,wrt__dbDef+wOff__extent
127
128                 ; --- Fix up string alignment ---
129
130                 LDR     R14,wrt__dbDef+wOff__writeFlag
131                 TST     R1,#wrtFlag_rAlign      ;Do we right align text?
132                 ORRNE   R14,R14,#&200           ;Yes -- set the bit then
133                 BICEQ   R14,R14,#&200           ;No -- clear it instead
134                 STR     R14,wrt__dbDef+wOff__writeFlag
135
136                 ; --- Fill in the validation string ---
137
138                 ADR     R0,wrt__valid           ;Point to validation buffer
139                 ADR     R1,wrt__x7              ;Point to base validation
140                 BL      str_cpy                 ;Copy it onto the end
141                 ADD     R1,R3,#4                ;Point to validation string
142                 LDRB    R14,[R1],#1             ;Load the first byte
143                 CMP     R14,#32                 ;Is this an empty string?
144                 BLO     %20writable             ;Yes -- miss this bit out
145
146                 MOV     R2,#';'                 ;Put a delimiter string in
147                 STRB    R2,[R0],#1              ;Save in validation buffer
148 10writable      STRB    R14,[R0],#1             ;Save the valid character
149                 LDRB    R14,[R1],#1             ;Load another byte
150                 CMP     R14,#32                 ;Is this the string end?
151                 BHS     %10writable             ;No -- go round again
152                 MOV     R14,#0                  ;Null terminate nicely
153                 STRB    R14,[R0],#1             ;Save it in the buffer
154
155                 ; --- Finally, fill in the title string ---
156
157 20writable      MOV     R0,R1                   ;Point to title message tag
158                 BL      msgs_lookup             ;Find the message string
159                 MOV     R1,R0                   ;Point to the message
160                 ADR     R0,wrt__title           ;Point to the title buffer
161                 BL      str_cpy                 ;And copy that over nicely
162
163                 ; --- Build the dialogue box ---
164
165                 ADR     R0,wrt__dbDef           ;Point to the dialogue defn
166                 BL      dbox_fromDefn           ;Create a dialogue box
167                 BVS     %90writable             ;Return if it failed
168
169                 ADR     R1,wrt__handler         ;Point to the handler
170                 MOV     R2,R0                   ;Pass dialogue handle in R10
171                 MOV     R3,R12                  ;Pass workspace in R12
172                 BL      dbox_eventHandler       ;Set up the event handler
173
174                 MOV     R1,#dbOpen_pointer+dbOpen_trans
175                 BL      dbox_open               ;Display the dialogue box
176                 LDMFD   R13!,{R1-R3,R12,R14}    ;Restore all the registers
177                 BICS    PC,R14,#V_flag          ;Return without an error
178
179                 ; --- Couldn't create the dialogue box ---
180
181 90writable      LDMFD   R13!,{R1-R3,R12,R14}    ;Restore all the registers
182                 ORRS    PC,R14,#V_flag          ;Return the error pointer
183
184 wrt__x7         DCB     "x7",0                  ;Tim's neat writable border
185
186                 LTORG
187
188 ; --- wrt__handler ---
189 ;
190 ; On entry:     R0 == dialogue box event code
191 ;               R1-R7 == depend on the event type
192 ;               R10 == dialogue box handle
193 ;               R12 == pointer to my workspace
194 ;
195 ; On exit:      --
196 ;
197 ; Use:          Handles events for the writable dialogue box.
198
199 wrt__handler    ROUT
200
201                 CMP     R0,#dbEvent_close       ;Someone closed my dialogue?
202                 BEQ     %10wrt__handler         ;Yes -- destroy it then
203                 CMP     R0,#dbEvent_OK          ;Is it an OK click?
204                 CMPNE   R0,#wrtIcon__ok         ;Or a click on the OK button?
205                 MOVNES  PC,R14                  ;No -- then return to caller
206
207                 ; --- Handle an OK click ---
208
209                 STMFD   R13!,{R0-R3,R10,R12,R14} ;Save loads of registers
210                 MOV     R2,R1                   ;Look after the button state
211                 MOV     R0,R10                  ;Get the dialogue handle
212                 MOV     R1,#wrtIcon__ok         ;And the OK button handle
213                 BL      dbox_slab               ;Slab the button in
214
215                 ; --- Call the user's handler ---
216
217                 ADR     R0,wrt__buffer          ;Point to the string
218                 MOV     R1,R10                  ;Get the dialogue box handle
219                 ADR     R14,wrt__proc           ;Find his event handler
220                 LDMIA   R14,{R3,R10,R12}        ;Load all the handler stuff
221                 ADDS    R0,R0,#0                ;Clear C flag cunningly
222                 MOV     R14,PC                  ;Set up return address
223                 MOV     PC,R3                   ;And call the handler
224
225                 ; --- Find out what to do next ---
226
227                 TSTCS   R2,#0                   ;Set Z flag if carry set
228                 TSTCC   R2,#1                   ;Otherwise, test Adjustness
229                 MOV     R0,R1                   ;Get the dialogue handle
230                 BLEQ    dbox_close              ;If Select then close dbox
231                 BL      dbox_unslab             ;Unslab the OK button
232                 BLEQ    dbox_destroy            ;If Select then trash dbox
233                 LDMFD   R13!,{R0-R3,R10,R12,PC}^ ;And return to caller
234
235                 ; --- The dialogue box closed ---
236
237 10wrt__handler  STMFD   R13!,{R0,R14}           ;Save some registers
238                 MOV     R0,R10                  ;Get the dialogue handle
239                 BL      dbox_destroy            ;Kill the dialogue box
240                 LDMFD   R13!,{R0,PC}^           ;Return to caller
241
242                 LTORG
243
244 ; --- wrt_init ---
245 ;
246 ; On entry:     --
247 ;
248 ; On exit:      --
249 ;
250 ; Use:          Initialises the writable dialogue box for use.
251
252                 EXPORT  wrt_init
253 wrt_init        ROUT
254
255                 STMFD   R13!,{R12,R14}          ;Save some registers
256                 WSPACE  wrt__wSpace             ;Load my workspace pointer
257                 LDR     R14,wrt__flags          ;Load the flags word nicely
258                 TST     R14,#wFlag__inited      ;Have we done this already?
259                 LDMNEFD R13!,{R12,PC}^          ;Yes -- return to caller
260
261                 ; --- Set up the flags nicely ---
262
263                 STMFD   R13!,{R0-R2}            ;Save some more registers
264                 ORR     R14,R14,#wFlag__inited  ;Set the initialised flag
265                 STR     R14,wrt__flags          ;Save the flags back again
266                 BL      dbox_init               ;Make sure dboxes are going
267
268                 ; --- Now copy the window definition over ---
269
270                 ADR     R0,wrt__dbDef           ;Point to the workspace block
271                 ADR     R1,wrt__window          ;Point to the window def
272                 MOV     R2,#wrt__windSize       ;Get the size of the block
273                 BL      fastMove                ;Copy the block over nicely
274
275                 ; --- Fill in bits of the window definition ---
276
277                 ADR     R14,wrt__title          ;Point to the title buffer
278                 STR     R14,[R0,#wOff__titleData]
279                 ADR     R14,wrt__buffer
280                 STR     R14,[R0,#wOff__writeData]
281                 ADR     R14,wrt__valid
282                 STR     R14,[R0,#wOff__writeData+4]
283
284                 LDMFD   R13!,{R0-R2,R12,PC}^    ;Return to caller
285
286                 LTORG
287
288 wrt__wSpace     DCD     0
289
290 ;----- Constants ------------------------------------------------------------
291
292                 ; --- Icon numbers ---
293
294 wrtIcon__write  EQU     0                       ;The writable icon
295 wrtIcon__ok     EQU     1                       ;The OK button
296
297                 ; --- Flags ---
298
299 wrtFlag_rAlign  EQU     (1<<8)                  ;Align text to right side
300
301 ;----- Window definition ----------------------------------------------------
302
303 ; --- Note ---
304 ;
305 ; The main window definition here gets copied into workspace so that I can
306 ; modify it nicely at runtime, to change the width of the window etc.
307
308 ; --- Macro: WOFF ---
309 ;
310 ; Arguments:    label == symbol to assign with current offset into window def
311 ;
312 ; Use:          Sets a symbol to an offset in the window definition
313
314                 MACRO
315 $label          WOFF
316 $label          EQU     {PC}-wrt__window
317                 MEND
318
319                 ; --- The main window block ---
320
321 wrt__window
322
323 wOff__open      WOFF
324                 DCD     -324,-96,0,0            ;Width dynamically adjusted
325                 DCD     0,0                     ;Window doesn't scroll (hope)
326                 DCD     -1                      ;Always open on the top
327                 DCD     &84170002               ;Window flags word (various)
328                 DCB     7,2,7,1,3,1,2,0         ;Window colours words
329
330 wOff__extent    WOFF
331                 DCD     -324,-96,0,0            ;Dynamically adjust width
332                 DCD     &00000109               ;Window title bar flags
333                 DCD     &00000000               ;Work area button type
334                 DCD     1                       ;Wimp sprite area, I think
335                 DCD     0                       ;Default minimum sizes
336
337 wOff__titleData WOFF
338                 DCD     0,-1,24                 ;Title bar icon data
339                 DCD     2                       ;2 icons following
340
341                 ; --- The writable area icon ---
342
343 wOff__writeBox  WOFF
344                 DCD     -300,-68,-110,-28       ;24 in from the left
345
346 wOff__writeFlag WOFF
347                 DCD     &0700F131               ;Icon flags word
348
349 wOff__writeData WOFF
350                 DCD     0,0,0                   ;Fill in all the data later
351
352                 ; --- The OK button ---
353
354                 DCD     -72,-72,-24,-24         ;Icon bounding box
355                 DCD     &17003139               ;Icon flags word
356                 DCD     wrt__ok,wrt__x2,3       ;Icon data strings
357
358 wrt__windSize   WOFF
359
360                 ; --- Indirected text for OK button ---
361
362 wrt__ok         DCB     "OK",0                  ;Button text string
363 wrt__x2         DCB     "x2",0                  ;Button border command
364
365 ;----- Workspace ------------------------------------------------------------
366
367                 ^       0,R12
368 wrt__wStart     #       0
369
370 wrt__flags      #       4                       ;Various flags
371
372                 ; --- The user's handler routine ---
373
374 wrt__proc       #       4                       ;The routine to call
375 wrt__R10        #       4                       ;Value to pass in R10
376 wrt__R12        #       4                       ;Value to pass in R12
377
378                 ; --- The copy of the window definition ---
379
380 wrt__dbDef      #       wrt__windSize           ;The window definition copy
381 wrt__valid      #       24                      ;Icon validation string
382 wrt__title      #       24                      ;Window title text string
383 wrt__buffer     #       256                     ;The actual data string
384
385 wrt__wSize      EQU     {VAR}-wrt__wStart
386
387 wFlag__inited   EQU     (1<<0)                  ;Have we initialised yet?
388
389                 AREA    |Sapphire$$LibData|,CODE,READONLY
390
391                 DCD     wrt__wSize
392                 DCD     wrt__wSpace
393                 DCD     0
394                 DCD     wrt_init
395
396 ;----- That's all, folks ----------------------------------------------------
397
398                 END