; ; ibicon.s ; ; Icon bar icon handling (TMA) ; ; © 1994-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; This file is part of Straylight's Sapphire library. ; ; Sapphire is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2, or (at your option) ; any later version. ; ; Sapphire is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with Sapphire. If not, write to the Free Software Foundation, ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;----- Standard header ------------------------------------------------------ GET libs:header GET libs:swis ;----- External dependencies ------------------------------------------------ GET sapphire:msgs GET sapphire:suballoc GET sapphire:sapphire GET sapphire:string GET sapphire:resspr GET sapphire:wimp GET sapphire:win ;----- Event types ---------------------------------------------------------- ^ 0 ibEvent_select # 1 ibEvent_menu # 1 ibEvent_adjust # 1 ibEvent_save # 1 ibEvent_load # 1 ibEvent_help # 1 ;----- Main code ------------------------------------------------------------ AREA |Sapphire$$Code|,CODE,READONLY ; --- ibicon__addToList --- ; ; On entry: R0 == icon handle ; R1 == pointer to routine to call ; R2 == pointer to icon data ; R3 == pointer to validation string ; R4 == R10 value to call routine ; R5 == R12 value to call routine with ; R6 == pointer to list head to use ; ; On exit: R0-R6 preserved ; ; Use: Adds a rountine to the given list. Later added ; routines are called first ibicon__addToList ROUT STMFD R13!,{R0-R6,R14} ;Stack some registers ; --- Allocate a block --- MOV R0,#list__size ;Size to allocate BL sub_alloc ;Allocate the block BVS %01 ;Branch ahead if error ; --- Fill the block in --- LDR R1,[R6] ;Get the list head STR R1,[R0,#list__next] ;Store in next field STR R0,[R6] ;Store new block at head LDMIA R13,{R1-R6} ;Get parameters STMIB R0,{R1-R6} ;Store them in the block ; --- And return to user --- LDMFD R13!,{R0-R6,R14} ;Load back link BICS PC,R14,#V_flag ;Return without error ; --- Barf if an error occured --- 01 ADD R13,R13,#4 ;Skip over R0 LDMFD R13!,{R1-R6,R14} ;Branch if error ORRS PC,R14,#V_flag ;Return with error LTORG ; --- ibicon__removeFromList --- ; ; On entry: R0 == ibicon pointer ; R1 == pointer to list head to use ; ; On exit: All registers/flags preserved ; ; Use: Removes a routine from the given list. All values are ; compared. ibicon__removeFromList ROUT STMFD R13!,{R0-R4,R14} ; --- Find the block --- MOV R2,R1 ;The previous pointer LDR R1,[R1] ;Get the head of the list 01 TEQ R1,#0 ;Are we at the end? LDMEQFD R13!,{R0-R4,PC}^ ;Yes -- return LDR R4,[R1] ;Get the next pointer CMP R1,R0 ;Are pointers the same? MOVNE R2,R1 ;If no, remember previous MOVNE R1,R4 ;...get list pointer BNE %01 ;...and keep looking ; --- So now the block has been found --- MOV R0,R1 ;Put the block in R0 MOV R1,#list__size ;Get the size BL sub_free ;Free the block STR R4,[R2,#0] ;Store in prev next ^ ; --- And return to the user --- LDMFD R13!,{R0-R4,PC}^ LTORG ; --- ibicon__size --- ; ; On entry: R0 == pointer to block to use ; R1 == sprite area to use ; R2 == pointer to sprite name ; ; On exit: -- ; ; Use: Determines the size of the given icon, and fills in the ; block appropriatly (x0,y0,x1,y1) ibicon__size ROUT STMFD R13!,{R0-R6} ;Stack some registers MOV R0,#40 ;Get sprite info CMP R1,#1 ;Is it WIMP area? ORRNE R0,R0,#&100 ;No -- use user area SWINE XOS_SpriteOp ;...do the SpriteOp SWIEQ Wimp_SpriteOp ;Yes, SpriteOp on WIMP area LDMVSFD R13!,{R0-R6} ;Recover registers on error ORRVSS PC,R14,#V_flag ;...and return with an error MOV R0,R6 ;Get info on sprite's mode MOV R1,#4 ;Read XEigFactor SWI OS_ReadModeVariable ;Get the Eig Factor MOV R3,R3,LSL R2 ;Get the width in OS units MOV R1,#5 ;Read yEigFactor SWI OS_ReadModeVariable ;Get the Eig Factor MOV R4,R4,LSL R2 ;Get the height in OS units MOV R0,#0 ;x0 coordinate MOV R1,#0 ;y0 coordinate LDR R2,[R13,#0] ;Get the block to use STMIA R2,{R0,R1,R3,R4} ;Store the size info LDMFD R13!,{R0-R6} ;Recover registers MOVS PC,R14 ;And return ; --- ibicon_create --- ; ; On entry: R0 == pointer to sprite name ; R1 == pointer to text buffer (must be writable if you ; intend to change the text) ; R2 == icon bar position indicator (`window handle') ; R3 == icon bar priority/icon handle ; R4 == pointer to event handler ; R5 == value to pass in R10 ; R6 == value to pass in R12 ; ; On exit: R0 == ibicon icon handle ; May return an error ; ; Use: Places an icon on the icon bar. Your handler is called when ; an event occurs on the icon. On entry to the handler, R10 ; and R12 are set up as for above, R0 is the event type, and ; R1 is the ibicon pointer. EXPORT ibicon_create ibicon_create ROUT ; --- Stack registers, locate workspace etc. --- STMFD R13!,{R1-R7,R9,R10,R12,R14} ;Stack loads of registers WSPACE ibicon__wSpace,R9 ;Find a bit of workspace ; --- Stuff useful values into high registers --- MOV R12,R0 ;Keep the sprite name safe MOV R10,R1 ;Keep the text pointer safe MOV R7,R2 ;Keep position thingy ; --- Now create buffers for the sprite name --- MOV R0,#16 ;Size for sprite buffer BL sub_alloc ;Get a block (PDQ) BVS %99ibicon_create ;And zip ahead if it failed ; --- Build the sprite name in the buffer --- MOV R2,R0 ;Keep the pointer for a while CMP R10,#0 ;Is there any text? MOVNE R1,#'S' ;Yes -- stick an `S' on STRNEB R1,[R0],#1 ;And insert it at the front MOV R1,R12 ;Point to sprite name BL str_cpy ;And build the name string MOV R12,R2 ;Keep this buffer pointer now ; --- Build the icon definition --- SUB R13,R13,#36 ;Make space for the icon blk BEQ %00ibicon_create ;If sprite only, deal with it ; --- Deal with text+sprite icons --- MOV R2,R1 ;Point to original sname MOV R1,#1 ;Wimp sprite area ADD R0,R13,#4 ;Fill in this block BL ibicon__size ;Get the sprite size LDR R1,[R0,#4] ;Get y0 SUB R1,R1,#16 ;y0=y0-16 STR R1,[R0,#4] ;Store adjusted y0 LDR R1,[R0,#12] ;Get y1 ADD R1,R1,#20 ;y1=y1+20 STR R1,[R0,#12] ;Store adjusted y1 STR R10,[R13,#24] ;Store text buffer ^ if text STR R12,[R13,#28] ;And the validation string ^ MOV R0,R10 ;The text string BL str_len ;How long is it? STR R0,[R13,#32] ;Store the value LDR R1,[R13,#12] ;Get the x1 icon size CMP R1,R0,LSL#4 ;Is it less than length*16 MOVLT R1,R0,LSL#4 ;Yes, make it equal STRLT R1,[R13,#12] ;...and store it back LDR R0,=&1700312B ;The icon flags STR R0,[R13,#20] ;Store them B %01ibicon_create ;Jump ahead ; --- Deal with sprite only icons --- 00ibicon_create BL resspr_area ;Get the sprite area to use STR R0,[R13,#28] ;Store that in the block MOV R10,R12 ;R10 is icon data MOV R12,#0 ;No validation needed MOV R1,R0 ;Put sprite area in R1 MOV R2,R10 ;Point to sprite name ADD R0,R13,#4 ;Fill in this block BL ibicon__size ;Get the sprite size MOVVS R1,#1 ;If error -- try WIMP area BLVS ibicon__size ;...try again STR R10,[R13,#24] ;Store sprite name pointer MOV R0,R10 ;Point to sprite name BL str_len ;Get its length STR R0,[R13,#32] ;And store that too LDR R0,=&1700311A ;The icon flags STR R0,[R13,#20] ;Store them ; --- Create the icon --- 01ibicon_create BL wimp_version ;Get the wimp version number LDR R1,=310 ;Wimp version MOV R2,R7 ;Get back position thingy CMP R0,R1 ;Is it less than RISC OS 3.1 BGE %02ibicon_create ;No -- go ahead ; --- Ensure position word works on RISCOS 2/3.0 --- CMP R2,#-5 ;Left, scanning from left? CMPNE R2,#-6 ;Left, scanning from right? MOVEQ R2,#-2 ;Yes -- put it on left BEQ %02ibicon_create ;Now go ahead CMP R2,#-7 ;Right, scanning from left? CMPNE R2,#-8 ;Right, scanning from right? MOVEQ R2,#-1 ;Yes -- put it on right ; --- Actually create it --- 02ibicon_create STR R2,[R13,#0] ;The position to put icon in MOV R0,R3 ;Icon handle/priority MOV R1,R13 ;Point to the block SWI XWimp_CreateIcon ;Create the icon ADD R13,R13,#36 ;Reclaim stack BVS %99ibicon_create ;Barf if error ; --- Add the icon into the list --- MOV R2,R10 ;Icon data MOV R3,R12 ;Validation string ADR R6,ibicon__icons ;The head of the list ADD R1,R13,#12 ;Point to relevent parameters LDMIA R1,{R1,R4,R5} ;Routine to call, R10, R12 BL ibicon__addToList ;Add to the list BVS %99ibicon_create ;Stop if error occurred ; --- Return to the user --- LDR R0,ibicon__icons ;Return the ibicon pointer LDMFD R13!,{R1-R7,R9,R10,R12,R14} ;Load my registers BICS PC,R14,#V_flag ;Return without error ; --- An error occurred --- 99ibicon_create LDMFD R13!,{R1-R7,R9,R10,R12,R14} ;Load my registers ORRS PC,R14,#V_flag ;Return with error LTORG ; --- ibicon_changeSprite --- ; ; On entry: R0 == ibicon pointer ; R1 == pointer to sprite name ; ; On exit: -- ; ; Use: Changes the sprite of the ibicon passed to it. EXPORT ibicon_changeSprite ibicon_changeSprite ROUT STMFD R13!,{R0-R3,R9,R14} ;Stack some registers WSPACE ibicon__wSpace,R9 ;Get my workspace LDR R3,[R0,#list__iHandle] ;Get the icon handle LDR R2,[R0,#list__valid] ;Get the validation CMP R2,#0 ;Is there any? LDREQ R0,[R0,#list__iData] ;No -- point to data ADDNE R0,R2,#1 ;Yes -- point passed the 'S' BL str_cpy ;And copy the name across SUB R13,R13,#16 ;Get a block MOV R0,#-2 ;The icon bar MOV R1,R3 ;The icon handle MOV R2,#0 ;EOR Word MOV R3,#0 ;The clear word STMIA R13,{R0-R3} ;Store in the block MOV R1,R13 ;Point to the block SWI Wimp_SetIconState ;Update the icon ADD R13,R13,#16 ;Reclaim my stack LDMFD R13!,{R0-R3,R9,PC}^ ;Return to the user LTORG ; --- ibicon_changeText --- ; ; On entry: R0 == ibicon pointer ; R1 == pointer to new text ; ; On exit: -- ; ; Use: Changes the sprite of the ibicon passed to it. EXPORT ibicon_changeText ibicon_changeText ROUT STMFD R13!,{R0-R3,R9,R14} ;Stack some registers WSPACE ibicon__wSpace,R9 ;Get my workspace LDR R3,[R0,#list__iHandle] ;Get the icon handle LDR R2,[R0,#list__valid] ;Get the validation CMP R2,#0 ;Is there any? BEQ %00 ;No -- big time error LDR R0,[R0,#list__iData] ;Point to the text buffer BL str_cpy ;Copy the text across SUB R13,R13,#16 ;Get a block MOV R0,#-2 ;The icon bar MOV R1,R3 ;The icon handle MOV R2,#0 ;EOR Word MOV R3,#0 ;The clear word STMIA R13,{R0-R3} ;Store in the block MOV R1,R13 ;Point to the block SWI Wimp_SetIconState ;Update the icon ADD R13,R13,#16 ;Reclaim my stack LDMFD R13!,{R0-R3,R9,PC}^ ;Return to the user ; --- We can't change the text of a sprite only icon --- 00 ADR R0,ibicon__cantDo ;Point to the error message BL msgs_error ;Translate the message SWI OS_GenerateError ;Cause an error ibicon__cantDo DCD 0 DCB "ibCCT",0 LTORG ; --- ibicon_remove --- ; ; On entry: R0 == ibicon icon handle ; ; On exit: -- ; ; Use: Removes the given icon from the icon bar. EXPORT ibicon_remove ibicon_remove ROUT STMFD R13!,{R0-R3,R9,R14} ;Stack some registers WSPACE ibicon__wSpace,R9 ;Locate my workspace ; --- Delete the icon --- MOV R2,R0 ;Remember ibicon pointer SUB R13,R13,#8 ;Get a block LDR R1,[R0,#list__iHandle] ;Get the icon handle MOV R0,#-2 ;The icon bar STMIA R13,{R0,R1} ;Store handles in block MOV R1,R13 ;Point to block SWI XWimp_DeleteIcon ;Delete the icon ADD R13,R13,#8 ;Reclaim the block from stack ; --- Delete the ibicon data --- MOV R0,R3 ;Point to the ibicon LDR R1,ibicon__icons ;Remove from this list BL ibicon__removeFromList ;Remove the icon ; --- And return from whence thy came --- LDMFD R13!,{R0-R3,R9,PC}^ ;Return to caller LTORG ; --- ibicon__handler --- ; ; On entry: R0 == event returned from Wimp_Poll ; R1 == poll block ; R12 == workspace ; ; On exit: C set if call is claimed ; ; Use: Called as an event handler when the wimp reports iconbar ; activity ibicon__handler ROUT STMFD R13!,{R0-R7,R9,R10,R14} ;Stack some registers MOV R9,R12 ;R9 is workspace pointer CMP R0,#6 ;Was it a button click BNE %50 ;No try messages LDR R2,[R1,#8] ;Get buttons TST R2,#1 ;Was it Adjust MOVNE R0,#ibEvent_adjust ;Yes -- set the type TST R2,#4 ;Was it select MOVNE R0,#ibEvent_select ;Yes -- set the type TST R2,#2 ;Was it menu MOVNE R0,#ibEvent_menu ;Yes -- set the type LDR R1,[R1,#16] ;Get the icon handle 10 ADDS R0,R0,#0 ;Clear carry flag LDR R2,ibicon__icons ;Get my icons list 20 TEQ R2,#0 ;Are we at the end BEQ %30 ;Yes -- jump ahead MOV R7,R2 ;Remember this pointer LDMIA R2,{R2-R6,R10,R12} ;Load parameters to pass TEQ R1,R3 ;Are icon handles the same BNE %20 ;No -- try another handler TEQ R4,#0 ;Is there a handler? BEQ %20 ;No -- keep trying MOV R1,R7 ;Pass the pointer MOV R14,PC ;Set return address MOV PC,R4 ;Branch to handler BCC %20 ;Try next handler 30 LDMFD R13!,{R0-R7,R9,R10,R14} ;Load the registers BICCCS PC,R14,#C_flag ;Return with carry clear ORRCSS PC,R14,#C_flag ;... or with carry set ; --- Was the event a suitable message --- 50 CMP R0,#17 ;User_Message CMPNE R0,#18 ;User_Message_Recorded LDMNEFD R13!,{R0-R7,R9,R10,R14} ;No -- load the registers BICNES PC,R14,#C_flag ;...and return with C clear MOV R3,R1 ;We need R1 MOV R0,#-1 ;No type yet LDR R2,[R3,#16] ;Get the message type CMP R2,#1 ;Data Save MOVEQ R0,#ibEvent_save ;Yes -- set the type LDREQ R1,[R3,#24] ;...and get the icon handle CMP R2,#3 ;Data Load MOVEQ R0,#ibEvent_load ;Yes -- set the type LDREQ R1,[R3,#24] ;...and get the icon handle LDR R4,=&502 ;Help request CMP R2,R4 ;Is it? MOVEQ R0,#ibEvent_help ;Yes -- set the type LDREQ R1,[R3,#36] ;...and get the icon handle CMP R0,#-1 ;Was the message valid BNE %10 ;Yes -- dispatch the event LDMEQFD R13!,{R0-R7,R9,R10,R14} ;No -- load the registers BICEQS PC,R14,#C_flag ;...and return with C clear LTORG ; --- ibicon_init --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Initialises the ibicon unit. EXPORT ibicon_init ibicon_init ROUT STMFD R13!,{R0-R3,R9,R14} ;Stack some registers WSPACE ibicon__wSpace,R9 ;Locate my workspace ; --- Are we already initialised? --- LDR R0,ibicon__flags ;Get my flags TST R0,#ibicon__INITED ;Are we initialised? LDMNEFD R13!,{R0,R9,PC}^ ;Yes -- return ORR R0,R0,#ibicon__INITED ;Set initialised flag STR R0,ibicon__flags ;And store them back ; --- Ensure win is initialised --- BL win_init ;Initialise win ; --- Initialise the workspace --- MOV R0,#0 ;No handlers yet STR R0,ibicon__icons ;No siree ; --- Set up the event handler --- MOV R0,#-2 ;Window is icon bar ADR R1,ibicon__handler ;Routine to call MOV R2,#0 ;My handle MOV R3,R9 ;Pass workspace ^ to R12 BL win_eventHandler ;Add the handler MOV R0,R1 ;Point to the handler again BL win_unknownHandler ;Ooo.. An unknown one too ; --- Return to caller --- LDMFD R13!,{R0-R3,R9,PC}^ ;Return LTORG ibicon__wSpace DCD 0 ;----- Workspace ------------------------------------------------------------ ^ 0,R9 ibicon__wStart # 0 ibicon__flags # 4 ;Flags ibicon__INITED EQU (1<<0) ;I've been initialised ibicon__icons # 4 ;Event handler list ibicon__wSize EQU {VAR}-ibicon__wStart ; --- list structure --- ^ 0 list__next # 4 ;The next block list__iHandle # 4 ;The window handle list__proc # 4 ;Handler code list__iData # 4 ;Pointer to icon data list__valid # 4 ;Pointer to validation list__r10 # 4 ;R10 to call with list__r12 # 4 ;R12 to call with list__size # 0 AREA |Sapphire$$LibData|,CODE,READONLY DCD ibicon__wSize ;Workspace size DCD ibicon__wSpace ;Workspace pointer DCD 0 ;Scratchpad size DCD ibicon_init ;Initialisation code ;----- That's all, folks ---------------------------------------------------- END