4 ; Icon bar icon handling (TMA)
6 ; © 1994-1998 Straylight
9 ;----- Licensing note -------------------------------------------------------
11 ; This file is part of Straylight's Sapphire library.
13 ; Sapphire is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
18 ; Sapphire is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sapphire. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 ;----- Standard header ------------------------------------------------------
32 ;----- External dependencies ------------------------------------------------
42 ;----- Event types ----------------------------------------------------------
52 ;----- Main code ------------------------------------------------------------
54 AREA |Sapphire$$Code|,CODE,READONLY
56 ; --- ibicon__addToList ---
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
66 ; On exit: R0-R6 preserved
68 ; Use: Adds a rountine to the given list. Later added
69 ; routines are called first
74 STMFD R13!,{R0-R6,R14} ;Stack some registers
76 ; --- Allocate a block ---
78 MOV R0,#list__size ;Size to allocate
79 BL sub_alloc ;Allocate the block
80 BVS %01 ;Branch ahead if error
82 ; --- Fill the block in ---
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
88 LDMIA R13,{R1-R6} ;Get parameters
89 STMIB R0,{R1-R6} ;Store them in the block
91 ; --- And return to user ---
93 LDMFD R13!,{R0-R6,R14} ;Load back link
94 BICS PC,R14,#V_flag ;Return without error
96 ; --- Barf if an error occured ---
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
104 ; --- ibicon__removeFromList ---
106 ; On entry: R0 == ibicon pointer
107 ; R1 == pointer to list head to use
109 ; On exit: All registers/flags preserved
111 ; Use: Removes a routine from the given list. All values are
114 ibicon__removeFromList
117 STMFD R13!,{R0-R4,R14}
119 ; --- Find the block ---
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
131 ; --- So now the block has been found ---
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 ^
138 ; --- And return to the user ---
140 LDMFD R13!,{R0-R4,PC}^
144 ; --- ibicon__size ---
146 ; On entry: R0 == pointer to block to use
147 ; R1 == sprite area to use
148 ; R2 == pointer to sprite name
152 ; Use: Determines the size of the given icon, and fills in the
153 ; block appropriatly (x0,y0,x1,y1)
157 STMFD R13!,{R0-R6} ;Stack some registers
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
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
179 LDMFD R13!,{R0-R6} ;Recover registers
180 MOVS PC,R14 ;And return
182 ; --- ibicon_create ---
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
193 ; On exit: R0 == ibicon icon handle
194 ; May return an error
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.
204 ; --- Stack registers, locate workspace etc. ---
206 STMFD R13!,{R1-R7,R9,R10,R12,R14} ;Stack loads of registers
207 WSPACE ibicon__wSpace,R9 ;Find a bit of workspace
209 ; --- Stuff useful values into high registers ---
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
215 ; --- Now create buffers for the sprite name ---
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
221 ; --- Build the sprite name in the buffer ---
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
231 ; --- Build the icon definition ---
233 SUB R13,R13,#36 ;Make space for the icon blk
234 BEQ %00ibicon_create ;If sprite only, deal with it
236 ; --- Deal with text+sprite icons ---
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
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
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
263 ; --- Deal with sprite only icons ---
265 00ibicon_create BL resspr_area ;Get the sprite area to use
266 STR R0,[R13,#28] ;Store that in the block
268 MOV R10,R12 ;R10 is icon data
269 MOV R12,#0 ;No validation needed
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
284 ; --- Create the icon ---
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
292 ; --- Ensure position word works on RISCOS 2/3.0 ---
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
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
303 ; --- Actually create it ---
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
312 ; --- Add the icon into the list ---
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
322 ; --- Return to the user ---
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
328 ; --- An error occurred ---
330 99ibicon_create LDMFD R13!,{R1-R7,R9,R10,R12,R14} ;Load my registers
331 ORRS PC,R14,#V_flag ;Return with error
335 ; --- ibicon_changeSprite ---
337 ; On entry: R0 == ibicon pointer
338 ; R1 == pointer to sprite name
342 ; Use: Changes the sprite of the ibicon passed to it.
344 EXPORT ibicon_changeSprite
348 STMFD R13!,{R0-R3,R9,R14} ;Stack some registers
349 WSPACE ibicon__wSpace,R9 ;Get my workspace
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
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
370 ; --- ibicon_changeText ---
372 ; On entry: R0 == ibicon pointer
373 ; R1 == pointer to new text
377 ; Use: Changes the sprite of the ibicon passed to it.
379 EXPORT ibicon_changeText
383 STMFD R13!,{R0-R3,R9,R14} ;Stack some registers
384 WSPACE ibicon__wSpace,R9 ;Get my workspace
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
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
403 ; --- We can't change the text of a sprite only icon ---
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
414 ; --- ibicon_remove ---
416 ; On entry: R0 == ibicon icon handle
420 ; Use: Removes the given icon from the icon bar.
425 STMFD R13!,{R0-R3,R9,R14} ;Stack some registers
426 WSPACE ibicon__wSpace,R9 ;Locate my workspace
428 ; --- Delete the icon ---
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
439 ; --- Delete the ibicon data ---
441 MOV R0,R3 ;Point to the ibicon
442 LDR R1,ibicon__icons ;Remove from this list
443 BL ibicon__removeFromList ;Remove the icon
445 ; --- And return from whence thy came ---
447 LDMFD R13!,{R0-R3,R9,PC}^ ;Return to caller
451 ; --- ibicon__handler ---
453 ; On entry: R0 == event returned from Wimp_Poll
457 ; On exit: C set if call is claimed
459 ; Use: Called as an event handler when the wimp reports iconbar
464 STMFD R13!,{R0-R7,R9,R10,R14} ;Stack some registers
465 MOV R9,R12 ;R9 is workspace pointer
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
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
496 ; --- Was the event a suitable message ---
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
503 MOV R3,R1 ;We need R1
504 MOV R0,#-1 ;No type yet
505 LDR R2,[R3,#16] ;Get the message type
507 MOVEQ R0,#ibEvent_save ;Yes -- set the type
508 LDREQ R1,[R3,#24] ;...and get the icon handle
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
514 MOVEQ R0,#ibEvent_help ;Yes -- set the type
515 LDREQ R1,[R3,#36] ;...and get the icon handle
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
524 ; --- ibicon_init ---
530 ; Use: Initialises the ibicon unit.
535 STMFD R13!,{R0-R3,R9,R14} ;Stack some registers
536 WSPACE ibicon__wSpace,R9 ;Locate my workspace
538 ; --- Are we already initialised? ---
540 LDR R0,ibicon__flags ;Get my flags
541 TST R0,#ibicon__INITED ;Are we initialised?
542 LDMNEFD R13!,{R0,R9,PC}^ ;Yes -- return
544 ORR R0,R0,#ibicon__INITED ;Set initialised flag
545 STR R0,ibicon__flags ;And store them back
547 ; --- Ensure win is initialised ---
549 BL win_init ;Initialise win
551 ; --- Initialise the workspace ---
553 MOV R0,#0 ;No handlers yet
554 STR R0,ibicon__icons ;No siree
556 ; --- Set up the event handler ---
558 MOV R0,#-2 ;Window is icon bar
559 ADR R1,ibicon__handler ;Routine to call
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
566 ; --- Return to caller ---
568 LDMFD R13!,{R0-R3,R9,PC}^ ;Return
574 ;----- Workspace ------------------------------------------------------------
579 ibicon__flags # 4 ;Flags
581 ibicon__INITED EQU (1<<0) ;I've been initialised
583 ibicon__icons # 4 ;Event handler list
585 ibicon__wSize EQU {VAR}-ibicon__wStart
587 ; --- list structure ---
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
600 AREA |Sapphire$$LibData|,CODE,READONLY
602 DCD ibicon__wSize ;Workspace size
603 DCD ibicon__wSpace ;Workspace pointer
604 DCD 0 ;Scratchpad size
605 DCD ibicon_init ;Initialisation code
607 ;----- That's all, folks ----------------------------------------------------