; ; tmsGlue.s ; ; Supplies underlying tms workings -- filters, window creation etc. (TMA) ; ; © 1994 Straylight ; ;----- Standard Header ------------------------------------------------------ GET libs:header GET libs:swis GET libs:stream ;----- External dependencies ------------------------------------------------ GET libs:tearSupt.sh.tearSupt GET sapphire:event GET sapphire:errorBox GET sapphire:heap GET sapphire:mem GET sapphire:sapphire GET sapphire:screen GET sapphire:wimp GET sapphire:win ; --- Internal header files ---- GET sapphire:_tms.tmsGlobal GET sapphire:_tms.tmsMain ;----- Main code ------------------------------------------------------------ AREA |Sapphire$$Code|,CODE,READONLY ;----- Window creation ------------------------------------------------------ ; --- tms__calcHeight --- ; ; On entry: R10 == pointer to menu ; ; On exit: R0 == The height of the menu, including tearoff bar (-ve) ; ; Use: Calculates the height of the window, and also sets up ; the yCoord fields in the items tms__calcHeight ROUT STMFD R13!,{R1-R3,R14} ;Stack registers MOV R14,R10 ;Keep this pointer MOV R0,#0 ;The height so far LDR R3,[R14,#hFlags] ;Get the flags word TST R3,#hFlag__tearable ;Is there a tearoff bar? SUBNE R0,R0,#tms__barHeight ;Yes -- allow for it LDR R14,[R14,#hItems] ;Point to the items 00 CMP R14,#0 ;Are we at the end RSBEQ R1,R0,#0 ;Get +ve height STREQ R1,[R10,#hHeight] ;And store in height field LDMEQFD R13!,{R1-R3,PC}^ ;Yes -- return LDR R1,[R14,#iNumber] ;Get number of items in block ADD R2,R14,#iHdrSize ;Point to the first item 01 LDR R3,[R2,#iFlags] ;Get the item flags STR R0,[R2,#iyCoord] ;Store this coordinate SUB R0,R0,#44 ;The size of one item TST R3,#iFlag__dotted ;Is there a dotted line? SUBNE R0,R0,#24 ;Yes -- allow for it SUBS R1,R1,#1 ;Decrement item count ADDNE R2,R2,#iItemSize ;Point to the next item BNE %01tms__calcHeight ;...and count it LDR R14,[R14,#iItems] ;If at end -- point to next B %00tms__calcHeight ;...and count the next block LTORG ; --- tms__createWindow --- ; ; On entry: R0 == the menu height (-ve) ; R10 == pointer to the menu ; ; On exit: V and R0 == The standard error block, if an error occured ; R0 == the window handle ; ; Use: This call will create a window for the given menu. The ; block pointed to by R10 will be filled in appropriately ; with the handle. EXPORT tms__createWindow tms__createWindow ROUT BIC R14,R14,#V_flag ;Assume no error yet STMFD R13!,{R1-R9,R14} ;Stack some registers SUB R13,R13,#88 ;Create a block MOV R9,R13 ;Point to the block MOV R5,R0 ;The menu height LDR R6,[R10,#hMaxHeight] ;Get the maximum height CMP R6,#0 ;Is there one? BEQ %05tms__createWindow ;No -- jump this bit CMN R6,R5 ;Is actual height greater? MVNLE R5,R6 ;Yes -- make it maxHeight 05 ADR R0,tms__coords ;Point to the coords LDMIA R0,{R0,R3} ;And get them LDR R6,tms__flags ;Get the flags TST R6,#tFlag__iBar ;Is menu from icon bar ADDEQ R1,R3,R5 ;No -- miny = maxy-height MOVNE R1,#96 ;Yes -- miny = 96 SUBNE R3,R1,R5 ;...maxy = miny+height BNE %10tms__createWindow ;Jump the next text LDR R6,[R10,#hFlags] ;Get the header flags TST R6,#hFlag__tearable ;Is there a tearoff bar? ADDNE R1,R1,#tms__barHeight ;Yes -- shift up menu ADDNE R3,R3,#tms__barHeight ;Up, up, up we go 10 LDR R2,[R10,#hSprWidth] ;The sprite width LDR R4,[R10,#hTextWidth] ;The text width LDR R5,[R10,#hKeyWidth] ;The shortcut width ADD R2,R2,R4 ;Calculate the width ADD R2,R2,R5 ;Oh yes... Pleeeease! ADD R2,R2,#64 ;Left/Right edges+16 for luck LDR R14,[R10,#hTitleWidth] ;Get the title width CMP R14,R2 ;Is this greater? MOVGT R2,R14 ;Yes -- use this later STR R2,[R10,#hTotWidth] ;Remember this value ADD R2,R2,R0 ;And offset from x0 MOV R4,#0 ;Scroll x offset MOV R5,#0 ;Scroll y offset MOV R6,#-1 ;The behind value LDR R7,=&84000002 ;The wimp flags ; --- Add a scroll bar if we need to --- LDR R14,[R10,#hFlags] ;Get the flags word TST R14,#hFlag__folded ;Is the menu folded? BNE %17tms__createWindow ;Yes -- no bar needed LDR R8,[R10,#hHeight] ;Get the actual height LDR R14,[R10,#hMaxHeight] ;Get the maximum height CMP R14,#0 ;Is there one? BEQ %12tms__createWindow ;No -- compare to screen hght CMP R8,R14 ;Is it greater than max? BGT %15tms__createWindow ;Yes -- add scroll bar 12 ADD R8,R8,#50 ;Add 50 to actual STMFD R13!,{R0} ;preserve R0 BL screen_getInfo ;Get screen information LDR R0,[R0,#screen_height] ;Get the screen height CMP R8,R0 ;Is menu taller than screen? LDMFD R13!,{R0} ;Get R0 back BLE %17tms__createWindow ;No -- don't add bar 15 ORR R7,R7,#(1<<28) ;Give window a scroll bar LDR R14,[R10,#hFlags] ;Get the menu flags ORR R14,R14,#hFlag__scrBar ;There is a scroll bar STR R14,[R10,#hFlags] ;Store the flags back B %20tms__createWindow ;Jump ahead a bit 17 LDR R14,[R10,#hFlags] ;Get the menu flags BIC R14,R14,#hFlag__scrBar ;There is a scroll bar STR R14,[R10,#hFlags] ;Store the flags back 20 LDR R8,=&00070207 ;Colours LDR R14,=&000c0103 ;More colours STMIA R9!,{R0-R8,R14} ;Store in the block SUB R2,R2,R0 ;Get the real width back MOV R0,#0 ;Workarea x0 LDR R1,[R10,#hHeight] ;Get the actual height RSB R1,R1,#0 ;Make it -ve MOV R3,#0 ;y1 as for above LDR R4,=&00000139 ;The title bar flags LDR R5,=&00003000 ;The workarea button type MOV R6,#1 ;The sprite area to use MOV R7,#0 ;Minimum width/height STMIA R9!,{R0-R7} ;Store in the block LDR R0,[R10,#hText] ;Point to the text MOV R1,#-1 ;no validation string MOV R2,#&ff ;The buffer length MOV R3,#0 ;No items yet STMIA R9!,{R0-R3} ;Store this data MOV R1,R13 ;Point to the block SWI XWimp_CreateWindow ;Try to create the window ADD R13,R13,#88 ;Get my block back LDMVSFD R13!,{R1-R9,R14} ;On error, get the registers ORRVSS PC,R14,#V_flag ;...and return with error STR R0,[R10,#hHandle] ;Store the handle in menu LDMFD R13!,{R1-R9,PC}^ ;And return to caller LTORG ;----- Pre and Post fileters ------------------------------------------------ ; --- tms__open --- ; ; On entry: R0 == pointer to menu to open ; ; On exit: --- ; ; Use: Opens the given tearoff menu in the right place tms__open ROUT STMFD R13!,{R0-R3,R10,R14} ;Stack some registers ; --- Create the window --- MOV R10,R0 ;Keep pointer to the menu BL tms__calcHeight ;Work out the height of menu BL tms__createWindow ;Create the window MOVVS R1,#1 ;On error -- show 1 icon BLVS errorBox ;...display the error BVS %99tms__open ;...and return to caller ; --- Set up an event handler for the menu --- LDR R1,=tms__eventHandler ;Point to the event handler MOV R2,R10 ;The handle of the menu MOV R3,R12 ;R12 value to call with BL win_eventHandler ;Add the handler ; --- Now, open the window --- SUB R13,R13,#36 ;Get a block STR R0,[R13,#0] ;Store the handle in block MOV R1,R13 ;Point to the block SWI Wimp_GetWindowState ;Get the window state SWI Wimp_OpenWindow ;Open the window ADD R13,R13,#36 ;Get my block back ; --- Fill in any extra information --- LDR R0,tms__current ;Get the current transient CMP R0,#0 ;Is there one STREQ R10,tms__current ;No -- store this one then BLEQ wimp_taskHandle ;...get the task handle BLEQ tearSupport_opened ;...start tearoffsupt sending LDR R0,tms__prevLevel ;Point to the previous menu CMP R0,#0 ;Is there one? STRNE R10,[R0,#hSubMenu] ;Yes -- store in sub menu ptr STR R0,[R10,#hPrevMenu] ;Yes -- Point back to it MOV R0,#0 ;Time to set some values STR R0,[R10,#hSelected] ;No item selected yet STR R0,[R10,#hSubMenu] ;No current submenu either ; --- And return to the caller --- 99tms__open MOV R0,#0 ;We are no longer creating STR R0,tms__creating ;So say that! LDMFD R13!,{R0-R3,R10,PC}^ ;Return LTORG ; --- tms__preFilter --- ; ; On entry: R0 == event mask and flags ; R1 == pointer to block to use ; R2 == earliest time to return with NULL event ; R3 == pointer to fxp_poll word ; ; On exit: -- ; ; Use: Called as an event pre-filter. Its purpose is to open ; a previously created menu in the right place. tms__preFilter ROUT STMFD R13!,{R0,R14} ;Stack some registers LDR R0,tms__flags ;Get the main flags word TST R0,#tFlag__doFake ;Should we fake a NULL? BNE %10tms__preFilter ;Yes -- jump ahead then ; --- Open a menu if we need to --- LDR R0,tms__creating ;Point to menu being created CMP R0,#0 ;Is there one? LDMEQFD R13!,{R0,PC}^ ;No -- return BL tms__open ;Open the menu LDMFD R13!,{R0,PC}^ ;And return to the caller ; --- Fake a NULL event --- 10 BIC R0,R0,#tFlag__doFake ;Don't fake again ORR R0,R0,#tFlag__faking ;Remember that we're faking STR R0,tms__flags ;Store back the flags MOV R0,#0 ;Return event 0 (NULL) ADD R13,R13,#4 ;Skip over old event code LDMFD R13!,{R14} ;Load the link back ORRS PC,R14,#C_flag ;And return with carry set LTORG ; --- tms__postFilter --- ; ; On entry: R0 == wimp event ; R1 == the Wimp_Poll block ; ; On exit: -- ; ; Use: Called as a post handle by event to look out for clever ; things such as button clicks tms__postFilter ROUT STMFD R13!,{R0-R3,R14} ;Stack some regisr CMP R0,#6 ;Was it a button click? BEQ %10tms__postFilter ;Yes -- deal with it LDR R2,tms__flags ;Get the flags BIC R2,R2,#tFlag__iBar ;It wasn't a click on ibar STR R2,tms__flags ;Store the flags back CMP R0,#17 ;User_Message? CMPNE R0,#18 ;User_Message_Recorded? BEQ %20tms__postFilter ;Yes -- check it out LDMFD R13!,{R0-R3,PC}^ ;Return ; --- Deal with button click --- 10 LDR R0,[R1,#12] ;Get the window handle CMP R0,#-2 ;Is it the icon bar LDR R0,tms__flags ;Get the flags ORREQ R0,R0,#tFlag__iBar ;Yes -- set relevent bit BICNE R0,R0,#tFlag__iBar ;No -- clear it then STR R0,tms__flags ;Store the flags back ADR R2,tms__coords ;Point to coords block LDMIA R1,{R0,R1} ;Get x and y coords SUB R0,R0,#64 ;Correct the x coord STMIA R2,{R0,R1} ;Store them in the block LDMFD R13!,{R0-R3,PC}^ ;Return ; --- It was a message --- 20 LDR R2,[R1,#16] ;Get the message type LDR R0,=&400C1 ;Mode change CMP R2,R0 ;Is that the message? LDRNE R0,=&400CF ;Fonts changed CMPNE R2,R0 ;Check this one too BEQ %30tms__postFilter ;Yes -- deal with it LDR R0,=&4A340 ;Button pressed message CMP R2,R0 ;Is that the message? BEQ %50tms__postFilter ;Yes -- deal with it LDR R0,=&4A341 ;Close menus CMP R2,R0 ;Is that the message? BEQ %60tms__postFilter ;Yes -- deal with it LDMFD R13!,{R0-R3,PC}^ ;Return ; --- Mode change message --- 30 LDR R0,tms__oldHandle ;Get idle event handler hnd CMP R0,#0 ;Is there a current handler? BLNE tms__cleanUp ;Yes -- clean up a bit LDR R2,tms__flags ;Get the flags word BIC R2,R2,#tFlag__newFont ;No font change yet LDR R1,tms__fHandle ;Get the old handle MOV R0,#8 ;Read the wimp font handle SWI XWimp_ReadSysInfo ;Read if we can MOVVS R0,#0 ;If error -- no font CMP R0,R1 ;Compare the handles ORRNE R2,R2,#tFlag__newFont ;If different, mark this STRNE R0,tms__fHandle ;...and store new font handle STR R2,tms__flags ;Store new flags LDMFD R13!,{R0-R3,PC}^ ;And return ; --- Button pressed message --- ; ; We must check to see if we are clicking on one of ; our menus, and close our current transient if we're not 50 LDR R2,[R1,#32] ;Get the window handle LDR R3,tms__currDbox ;Get the current dbox CMP R3,R2 ;Is this what we clicked on? BEQ %70tms__postFilter ;Yes -- return then LDR R0,tms__current ;Get the current menu 55 CMP R0,#0 ;Is there one? BEQ %60tms__postFilter ;No -- close transient then LDR R1,[R0,#hHandle] ;Get the window handle CMP R1,R2 ;Are they the same LDMEQFD R13!,{R0-R3,PC}^ ;Yes -- return LDR R0,[R0,#hSubMenu] ;Get the submenu pointer CMP R0,R3 ;Is it the dbox? BNE %55tms__postFilter ;No -- check the submenus ; --- Close the transient menu then --- 60 LDR R2,tms__current ;Point to the transient CMP R2,#0 ;Is there one? LDREQ R2,tms__currDbox ;No -- load dbox handle MOV R0,R10 ;Remember R10 value MOV R10,#0 ;We're not over any menu BL tms__closeMenu ;Close the menu MOV R10,R0 ;Get R10 value back 70 LDMFD R13!,{R0-R3,PC}^ ;And return to caller LTORG ;----- Initialisation ------------------------------------------------------- ; --- tms_init --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Initialises the tms (Tearoff Menu System) unit. EXPORT tms_init tms_init ROUT STMFD R13!,{R0-R2,R12,R14} ;Stack some registers LDR R12,=tms__wSpace ;Locate my workspace pointer WSPACE [R12] ;And then my workspace ; --- Return if we are initialised --- LDR R1,tms__flags ;Get the flags word TST R1,#tFlag__inited ;Are we initialised LDMNEFD R13!,{R0-R2,R12,PC}^ ;Yes -- return ; --- Initialise various systems --- BL win_init ;Initialise win BL wimp_init ;And wimp BL heap_init ;And heap ; --- Set up the workspace values --- ORR R1,R1,#tFlag__inited ;We are initialised now BL wimp_version ;What wimp version is this CMP R0,#300 ;RISC OS 3? ORRGE R1,R1,#tFlag__riscos3 ;Yes -- remember this fact STR R1,tms__flags ;Store the flags back MOV R0,#8 ;Read current wimp font SWI XWimp_ReadSysInfo ;Read it if possible MOVVS R0,#0 ;If error -- no font STR R0,tms__fHandle ;Store the handle away ADR R0,tms__zInit ;Point to the correct block MOV R1,#tms__zSize ;Get the size of the area MOV R2,#0 ;Fill with zeros BL mem_set ;And do it *very* quickly STR R11,tms__R11 ;Save scratchpad address ; --- Set up the filters --- ADR R0,tms__preFilter ;Point to the routine MOV R1,R12 ;Use this R12 value BL event_preFilter ;Add the filter ADR R0,tms__postFilter ;Point to the routine MOV R1,R12 ;Use this R12 value BL event_postFilter ;Add the filter ; --- Set up the global area, and install hook --- LDR R0,tms__TWIN ;Load the global area name MOV R1,#twin_size ;Get the required size BL sapphire_global ;Find its address STR R0,tms__twin ;And store in my workspace MOVCC R1,#0 ;Clear the values out... MOVCC R14,#0 ;...if not already done STMCCIA R0,{R1,R14} ;Store the zeroes in there ADR R14,tms__hookTbl ;Point to the hook table STR R14,[R0,#twin_tmsHook] ;Save in the hook entry ; --- Initialise tearSupt --- BL tearSupport_init ;Initialise it ; --- And return to the user --- LDMFD R13!,{R0-R2,R12,PC}^ ;Return to caller tms__TWIN DCB "TWIN" tms__hookTbl B tmsh__subWaiting B tmsh__openSub LTORG ;----- That's all, folks ---------------------------------------------------- END