Initial revision
[ssr] / StraySrc / Libraries / Sapphire / s / ibicon
1 ;
2 ; ibicon.s
3 ;
4 ; Icon bar icon handling (TMA)
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sapphire library.
12 ;
13 ; Sapphire is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Sapphire is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sapphire. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29 GET libs:header
30 GET libs:swis
31
32 ;----- External dependencies ------------------------------------------------
33
34 GET sapphire:msgs
35 GET sapphire:suballoc
36 GET sapphire:sapphire
37 GET sapphire:string
38 GET sapphire:resspr
39 GET sapphire:wimp
40 GET sapphire:win
41
42 ;----- Event types ----------------------------------------------------------
43
44 ^ 0
45 ibEvent_select # 1
46 ibEvent_menu # 1
47 ibEvent_adjust # 1
48 ibEvent_save # 1
49 ibEvent_load # 1
50 ibEvent_help # 1
51
52 ;----- Main code ------------------------------------------------------------
53
54 AREA |Sapphire$$Code|,CODE,READONLY
55
56 ; --- ibicon__addToList ---
57 ;
58 ; On entry: R0 == icon handle
59 ; R1 == pointer to routine to call
60 ; R2 == pointer to icon data
61 ; R3 == pointer to validation string
62 ; R4 == R10 value to call routine
63 ; R5 == R12 value to call routine with
64 ; R6 == pointer to list head to use
65 ;
66 ; On exit: R0-R6 preserved
67 ;
68 ; Use: Adds a rountine to the given list. Later added
69 ; routines are called first
70
71 ibicon__addToList
72 ROUT
73
74 STMFD R13!,{R0-R6,R14} ;Stack some registers
75
76 ; --- Allocate a block ---
77
78 MOV R0,#list__size ;Size to allocate
79 BL sub_alloc ;Allocate the block
80 BVS %01 ;Branch ahead if error
81
82 ; --- Fill the block in ---
83
84 LDR R1,[R6] ;Get the list head
85 STR R1,[R0,#list__next] ;Store in next field
86 STR R0,[R6] ;Store new block at head
87
88 LDMIA R13,{R1-R6} ;Get parameters
89 STMIB R0,{R1-R6} ;Store them in the block
90
91 ; --- And return to user ---
92
93 LDMFD R13!,{R0-R6,R14} ;Load back link
94 BICS PC,R14,#V_flag ;Return without error
95
96 ; --- Barf if an error occured ---
97
98 01 ADD R13,R13,#4 ;Skip over R0
99 LDMFD R13!,{R1-R6,R14} ;Branch if error
100 ORRS PC,R14,#V_flag ;Return with error
101
102 LTORG
103
104 ; --- ibicon__removeFromList ---
105 ;
106 ; On entry: R0 == ibicon pointer
107 ; R1 == pointer to list head to use
108 ;
109 ; On exit: All registers/flags preserved
110 ;
111 ; Use: Removes a routine from the given list. All values are
112 ; compared.
113
114 ibicon__removeFromList
115 ROUT
116
117 STMFD R13!,{R0-R4,R14}
118
119 ; --- Find the block ---
120
121 MOV R2,R1 ;The previous pointer
122 LDR R1,[R1] ;Get the head of the list
123 01 TEQ R1,#0 ;Are we at the end?
124 LDMEQFD R13!,{R0-R4,PC}^ ;Yes -- return
125 LDR R4,[R1] ;Get the next pointer
126 CMP R1,R0 ;Are pointers the same?
127 MOVNE R2,R1 ;If no, remember previous
128 MOVNE R1,R4 ;...get list pointer
129 BNE %01 ;...and keep looking
130
131 ; --- So now the block has been found ---
132
133 MOV R0,R1 ;Put the block in R0
134 MOV R1,#list__size ;Get the size
135 BL sub_free ;Free the block
136 STR R4,[R2,#0] ;Store in prev next ^
137
138 ; --- And return to the user ---
139
140 LDMFD R13!,{R0-R4,PC}^
141
142 LTORG
143
144 ; --- ibicon__size ---
145 ;
146 ; On entry: R0 == pointer to block to use
147 ; R1 == sprite area to use
148 ; R2 == pointer to sprite name
149 ;
150 ; On exit: --
151 ;
152 ; Use: Determines the size of the given icon, and fills in the
153 ; block appropriatly (x0,y0,x1,y1)
154
155 ibicon__size ROUT
156
157 STMFD R13!,{R0-R6} ;Stack some registers
158
159 MOV R0,#40 ;Get sprite info
160 CMP R1,#1 ;Is it WIMP area?
161 ORRNE R0,R0,#&100 ;No -- use user area
162 SWINE XOS_SpriteOp ;...do the SpriteOp
163 SWIEQ Wimp_SpriteOp ;Yes, SpriteOp on WIMP area
164 LDMVSFD R13!,{R0-R6} ;Recover registers on error
165 ORRVSS PC,R14,#V_flag ;...and return with an error
166
167 MOV R0,R6 ;Get info on sprite's mode
168 MOV R1,#4 ;Read XEigFactor
169 SWI OS_ReadModeVariable ;Get the Eig Factor
170 MOV R3,R3,LSL R2 ;Get the width in OS units
171 MOV R1,#5 ;Read yEigFactor
172 SWI OS_ReadModeVariable ;Get the Eig Factor
173 MOV R4,R4,LSL R2 ;Get the height in OS units
174 MOV R0,#0 ;x0 coordinate
175 MOV R1,#0 ;y0 coordinate
176 LDR R2,[R13,#0] ;Get the block to use
177 STMIA R2,{R0,R1,R3,R4} ;Store the size info
178
179 LDMFD R13!,{R0-R6} ;Recover registers
180 MOVS PC,R14 ;And return
181
182 ; --- ibicon_create ---
183 ;
184 ; On entry: R0 == pointer to sprite name
185 ; R1 == pointer to text buffer (must be writable if you
186 ; intend to change the text)
187 ; R2 == icon bar position indicator (`window handle')
188 ; R3 == icon bar priority/icon handle
189 ; R4 == pointer to event handler
190 ; R5 == value to pass in R10
191 ; R6 == value to pass in R12
192 ;
193 ; On exit: R0 == ibicon icon handle
194 ; May return an error
195 ;
196 ; Use: Places an icon on the icon bar. Your handler is called when
197 ; an event occurs on the icon. On entry to the handler, R10
198 ; and R12 are set up as for above, R0 is the event type, and
199 ; R1 is the ibicon pointer.
200
201 EXPORT ibicon_create
202 ibicon_create ROUT
203
204 ; --- Stack registers, locate workspace etc. ---
205
206 STMFD R13!,{R1-R7,R9,R10,R12,R14} ;Stack loads of registers
207 WSPACE ibicon__wSpace,R9 ;Find a bit of workspace
208
209 ; --- Stuff useful values into high registers ---
210
211 MOV R12,R0 ;Keep the sprite name safe
212 MOV R10,R1 ;Keep the text pointer safe
213 MOV R7,R2 ;Keep position thingy
214
215 ; --- Now create buffers for the sprite name ---
216
217 MOV R0,#16 ;Size for sprite buffer
218 BL sub_alloc ;Get a block (PDQ)
219 BVS %99ibicon_create ;And zip ahead if it failed
220
221 ; --- Build the sprite name in the buffer ---
222
223 MOV R2,R0 ;Keep the pointer for a while
224 CMP R10,#0 ;Is there any text?
225 MOVNE R1,#'S' ;Yes -- stick an `S' on
226 STRNEB R1,[R0],#1 ;And insert it at the front
227 MOV R1,R12 ;Point to sprite name
228 BL str_cpy ;And build the name string
229 MOV R12,R2 ;Keep this buffer pointer now
230
231 ; --- Build the icon definition ---
232
233 SUB R13,R13,#36 ;Make space for the icon blk
234 BEQ %00ibicon_create ;If sprite only, deal with it
235
236 ; --- Deal with text+sprite icons ---
237
238 MOV R2,R1 ;Point to original sname
239 MOV R1,#1 ;Wimp sprite area
240 ADD R0,R13,#4 ;Fill in this block
241 BL ibicon__size ;Get the sprite size
242
243 LDR R1,[R0,#4] ;Get y0
244 SUB R1,R1,#16 ;y0=y0-16
245 STR R1,[R0,#4] ;Store adjusted y0
246 LDR R1,[R0,#12] ;Get y1
247 ADD R1,R1,#20 ;y1=y1+20
248 STR R1,[R0,#12] ;Store adjusted y1
249
250 STR R10,[R13,#24] ;Store text buffer ^ if text
251 STR R12,[R13,#28] ;And the validation string ^
252 MOV R0,R10 ;The text string
253 BL str_len ;How long is it?
254 STR R0,[R13,#32] ;Store the value
255 LDR R1,[R13,#12] ;Get the x1 icon size
256 CMP R1,R0,LSL#4 ;Is it less than length*16
257 MOVLT R1,R0,LSL#4 ;Yes, make it equal
258 STRLT R1,[R13,#12] ;...and store it back
259 LDR R0,=&1700312B ;The icon flags
260 STR R0,[R13,#20] ;Store them
261 B %01ibicon_create ;Jump ahead
262
263 ; --- Deal with sprite only icons ---
264
265 00ibicon_create BL resspr_area ;Get the sprite area to use
266 STR R0,[R13,#28] ;Store that in the block
267
268 MOV R10,R12 ;R10 is icon data
269 MOV R12,#0 ;No validation needed
270
271 MOV R1,R0 ;Put sprite area in R1
272 MOV R2,R10 ;Point to sprite name
273 ADD R0,R13,#4 ;Fill in this block
274 BL ibicon__size ;Get the sprite size
275 MOVVS R1,#1 ;If error -- try WIMP area
276 BLVS ibicon__size ;...try again
277 STR R10,[R13,#24] ;Store sprite name pointer
278 MOV R0,R10 ;Point to sprite name
279 BL str_len ;Get its length
280 STR R0,[R13,#32] ;And store that too
281 LDR R0,=&1700311A ;The icon flags
282 STR R0,[R13,#20] ;Store them
283
284 ; --- Create the icon ---
285
286 01ibicon_create BL wimp_version ;Get the wimp version number
287 LDR R1,=310 ;Wimp version
288 MOV R2,R7 ;Get back position thingy
289 CMP R0,R1 ;Is it less than RISC OS 3.1
290 BGE %02ibicon_create ;No -- go ahead
291
292 ; --- Ensure position word works on RISCOS 2/3.0 ---
293
294 CMP R2,#-5 ;Left, scanning from left?
295 CMPNE R2,#-6 ;Left, scanning from right?
296 MOVEQ R2,#-2 ;Yes -- put it on left
297 BEQ %02ibicon_create ;Now go ahead
298
299 CMP R2,#-7 ;Right, scanning from left?
300 CMPNE R2,#-8 ;Right, scanning from right?
301 MOVEQ R2,#-1 ;Yes -- put it on right
302
303 ; --- Actually create it ---
304
305 02ibicon_create STR R2,[R13,#0] ;The position to put icon in
306 MOV R0,R3 ;Icon handle/priority
307 MOV R1,R13 ;Point to the block
308 SWI XWimp_CreateIcon ;Create the icon
309 ADD R13,R13,#36 ;Reclaim stack
310 BVS %99ibicon_create ;Barf if error
311
312 ; --- Add the icon into the list ---
313
314 MOV R2,R10 ;Icon data
315 MOV R3,R12 ;Validation string
316 ADR R6,ibicon__icons ;The head of the list
317 ADD R1,R13,#12 ;Point to relevent parameters
318 LDMIA R1,{R1,R4,R5} ;Routine to call, R10, R12
319 BL ibicon__addToList ;Add to the list
320 BVS %99ibicon_create ;Stop if error occurred
321
322 ; --- Return to the user ---
323
324 LDR R0,ibicon__icons ;Return the ibicon pointer
325 LDMFD R13!,{R1-R7,R9,R10,R12,R14} ;Load my registers
326 BICS PC,R14,#V_flag ;Return without error
327
328 ; --- An error occurred ---
329
330 99ibicon_create LDMFD R13!,{R1-R7,R9,R10,R12,R14} ;Load my registers
331 ORRS PC,R14,#V_flag ;Return with error
332
333 LTORG
334
335 ; --- ibicon_changeSprite ---
336 ;
337 ; On entry: R0 == ibicon pointer
338 ; R1 == pointer to sprite name
339 ;
340 ; On exit: --
341 ;
342 ; Use: Changes the sprite of the ibicon passed to it.
343
344 EXPORT ibicon_changeSprite
345 ibicon_changeSprite
346 ROUT
347
348 STMFD R13!,{R0-R3,R9,R14} ;Stack some registers
349 WSPACE ibicon__wSpace,R9 ;Get my workspace
350
351 LDR R3,[R0,#list__iHandle] ;Get the icon handle
352 LDR R2,[R0,#list__valid] ;Get the validation
353 CMP R2,#0 ;Is there any?
354 LDREQ R0,[R0,#list__iData] ;No -- point to data
355 ADDNE R0,R2,#1 ;Yes -- point passed the 'S'
356 BL str_cpy ;And copy the name across
357 SUB R13,R13,#16 ;Get a block
358 MOV R0,#-2 ;The icon bar
359 MOV R1,R3 ;The icon handle
360 MOV R2,#0 ;EOR Word
361 MOV R3,#0 ;The clear word
362 STMIA R13,{R0-R3} ;Store in the block
363 MOV R1,R13 ;Point to the block
364 SWI Wimp_SetIconState ;Update the icon
365 ADD R13,R13,#16 ;Reclaim my stack
366 LDMFD R13!,{R0-R3,R9,PC}^ ;Return to the user
367
368 LTORG
369
370 ; --- ibicon_changeText ---
371 ;
372 ; On entry: R0 == ibicon pointer
373 ; R1 == pointer to new text
374 ;
375 ; On exit: --
376 ;
377 ; Use: Changes the sprite of the ibicon passed to it.
378
379 EXPORT ibicon_changeText
380 ibicon_changeText
381 ROUT
382
383 STMFD R13!,{R0-R3,R9,R14} ;Stack some registers
384 WSPACE ibicon__wSpace,R9 ;Get my workspace
385
386 LDR R3,[R0,#list__iHandle] ;Get the icon handle
387 LDR R2,[R0,#list__valid] ;Get the validation
388 CMP R2,#0 ;Is there any?
389 BEQ %00 ;No -- big time error
390 LDR R0,[R0,#list__iData] ;Point to the text buffer
391 BL str_cpy ;Copy the text across
392 SUB R13,R13,#16 ;Get a block
393 MOV R0,#-2 ;The icon bar
394 MOV R1,R3 ;The icon handle
395 MOV R2,#0 ;EOR Word
396 MOV R3,#0 ;The clear word
397 STMIA R13,{R0-R3} ;Store in the block
398 MOV R1,R13 ;Point to the block
399 SWI Wimp_SetIconState ;Update the icon
400 ADD R13,R13,#16 ;Reclaim my stack
401 LDMFD R13!,{R0-R3,R9,PC}^ ;Return to the user
402
403 ; --- We can't change the text of a sprite only icon ---
404
405 00 ADR R0,ibicon__cantDo ;Point to the error message
406 BL msgs_error ;Translate the message
407 SWI OS_GenerateError ;Cause an error
408
409 ibicon__cantDo DCD 0
410 DCB "ibCCT",0
411
412 LTORG
413
414 ; --- ibicon_remove ---
415 ;
416 ; On entry: R0 == ibicon icon handle
417 ;
418 ; On exit: --
419 ;
420 ; Use: Removes the given icon from the icon bar.
421
422 EXPORT ibicon_remove
423 ibicon_remove ROUT
424
425 STMFD R13!,{R0-R3,R9,R14} ;Stack some registers
426 WSPACE ibicon__wSpace,R9 ;Locate my workspace
427
428 ; --- Delete the icon ---
429
430 MOV R2,R0 ;Remember ibicon pointer
431 SUB R13,R13,#8 ;Get a block
432 LDR R1,[R0,#list__iHandle] ;Get the icon handle
433 MOV R0,#-2 ;The icon bar
434 STMIA R13,{R0,R1} ;Store handles in block
435 MOV R1,R13 ;Point to block
436 SWI XWimp_DeleteIcon ;Delete the icon
437 ADD R13,R13,#8 ;Reclaim the block from stack
438
439 ; --- Delete the ibicon data ---
440
441 MOV R0,R3 ;Point to the ibicon
442 LDR R1,ibicon__icons ;Remove from this list
443 BL ibicon__removeFromList ;Remove the icon
444
445 ; --- And return from whence thy came ---
446
447 LDMFD R13!,{R0-R3,R9,PC}^ ;Return to caller
448
449 LTORG
450
451 ; --- ibicon__handler ---
452 ;
453 ; On entry: R0 == event returned from Wimp_Poll
454 ; R1 == poll block
455 ; R12 == workspace
456 ;
457 ; On exit: C set if call is claimed
458 ;
459 ; Use: Called as an event handler when the wimp reports iconbar
460 ; activity
461
462 ibicon__handler ROUT
463
464 STMFD R13!,{R0-R7,R9,R10,R14} ;Stack some registers
465 MOV R9,R12 ;R9 is workspace pointer
466
467 CMP R0,#6 ;Was it a button click
468 BNE %50 ;No try messages
469 LDR R2,[R1,#8] ;Get buttons
470 TST R2,#1 ;Was it Adjust
471 MOVNE R0,#ibEvent_adjust ;Yes -- set the type
472 TST R2,#4 ;Was it select
473 MOVNE R0,#ibEvent_select ;Yes -- set the type
474 TST R2,#2 ;Was it menu
475 MOVNE R0,#ibEvent_menu ;Yes -- set the type
476 LDR R1,[R1,#16] ;Get the icon handle
477
478 10 ADDS R0,R0,#0 ;Clear carry flag
479 LDR R2,ibicon__icons ;Get my icons list
480 20 TEQ R2,#0 ;Are we at the end
481 BEQ %30 ;Yes -- jump ahead
482 MOV R7,R2 ;Remember this pointer
483 LDMIA R2,{R2-R6,R10,R12} ;Load parameters to pass
484 TEQ R1,R3 ;Are icon handles the same
485 BNE %20 ;No -- try another handler
486 TEQ R4,#0 ;Is there a handler?
487 BEQ %20 ;No -- keep trying
488 MOV R1,R7 ;Pass the pointer
489 MOV R14,PC ;Set return address
490 MOV PC,R4 ;Branch to handler
491 BCC %20 ;Try next handler
492 30 LDMFD R13!,{R0-R7,R9,R10,R14} ;Load the registers
493 BICCCS PC,R14,#C_flag ;Return with carry clear
494 ORRCSS PC,R14,#C_flag ;... or with carry set
495
496 ; --- Was the event a suitable message ---
497
498 50 CMP R0,#17 ;User_Message
499 CMPNE R0,#18 ;User_Message_Recorded
500 LDMNEFD R13!,{R0-R7,R9,R10,R14} ;No -- load the registers
501 BICNES PC,R14,#C_flag ;...and return with C clear
502
503 MOV R3,R1 ;We need R1
504 MOV R0,#-1 ;No type yet
505 LDR R2,[R3,#16] ;Get the message type
506 CMP R2,#1 ;Data Save
507 MOVEQ R0,#ibEvent_save ;Yes -- set the type
508 LDREQ R1,[R3,#24] ;...and get the icon handle
509 CMP R2,#3 ;Data Load
510 MOVEQ R0,#ibEvent_load ;Yes -- set the type
511 LDREQ R1,[R3,#24] ;...and get the icon handle
512 LDR R4,=&502 ;Help request
513 CMP R2,R4 ;Is it?
514 MOVEQ R0,#ibEvent_help ;Yes -- set the type
515 LDREQ R1,[R3,#36] ;...and get the icon handle
516
517 CMP R0,#-1 ;Was the message valid
518 BNE %10 ;Yes -- dispatch the event
519 LDMEQFD R13!,{R0-R7,R9,R10,R14} ;No -- load the registers
520 BICEQS PC,R14,#C_flag ;...and return with C clear
521
522 LTORG
523
524 ; --- ibicon_init ---
525 ;
526 ; On entry: --
527 ;
528 ; On exit: --
529 ;
530 ; Use: Initialises the ibicon unit.
531
532 EXPORT ibicon_init
533 ibicon_init ROUT
534
535 STMFD R13!,{R0-R3,R9,R14} ;Stack some registers
536 WSPACE ibicon__wSpace,R9 ;Locate my workspace
537
538 ; --- Are we already initialised? ---
539
540 LDR R0,ibicon__flags ;Get my flags
541 TST R0,#ibicon__INITED ;Are we initialised?
542 LDMNEFD R13!,{R0,R9,PC}^ ;Yes -- return
543
544 ORR R0,R0,#ibicon__INITED ;Set initialised flag
545 STR R0,ibicon__flags ;And store them back
546
547 ; --- Ensure win is initialised ---
548
549 BL win_init ;Initialise win
550
551 ; --- Initialise the workspace ---
552
553 MOV R0,#0 ;No handlers yet
554 STR R0,ibicon__icons ;No siree
555
556 ; --- Set up the event handler ---
557
558 MOV R0,#-2 ;Window is icon bar
559 ADR R1,ibicon__handler ;Routine to call
560 MOV R2,#0 ;My handle
561 MOV R3,R9 ;Pass workspace ^ to R12
562 BL win_eventHandler ;Add the handler
563 MOV R0,R1 ;Point to the handler again
564 BL win_unknownHandler ;Ooo.. An unknown one too
565
566 ; --- Return to caller ---
567
568 LDMFD R13!,{R0-R3,R9,PC}^ ;Return
569
570 LTORG
571
572 ibicon__wSpace DCD 0
573
574 ;----- Workspace ------------------------------------------------------------
575
576 ^ 0,R9
577 ibicon__wStart # 0
578
579 ibicon__flags # 4 ;Flags
580
581 ibicon__INITED EQU (1<<0) ;I've been initialised
582
583 ibicon__icons # 4 ;Event handler list
584
585 ibicon__wSize EQU {VAR}-ibicon__wStart
586
587 ; --- list structure ---
588
589 ^ 0
590 list__next # 4 ;The next block
591 list__iHandle # 4 ;The window handle
592 list__proc # 4 ;Handler code
593 list__iData # 4 ;Pointer to icon data
594 list__valid # 4 ;Pointer to validation
595 list__r10 # 4 ;R10 to call with
596 list__r12 # 4 ;R12 to call with
597
598 list__size # 0
599
600 AREA |Sapphire$$LibData|,CODE,READONLY
601
602 DCD ibicon__wSize ;Workspace size
603 DCD ibicon__wSpace ;Workspace pointer
604 DCD 0 ;Scratchpad size
605 DCD ibicon_init ;Initialisation code
606
607 ;----- That's all, folks ----------------------------------------------------
608
609 END
610