; ; transWin.s ; ; Transient window handling (MDW) ; ; © 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 GET libs:stream ;----- External dependencies ------------------------------------------------ GET sapphire:event GET sapphire:sapphire ;----- Main code ------------------------------------------------------------ AREA |Sapphire$$Code|,CODE,READONLY ; --- transWin_subWaiting --- ; ; On entry: -- ; ; On exit: CS if a submenu is waiting to be opened, CC otherwise ; ; Use: Informs the caller whether the menu system is waiting for ; a submenu to be attached. EXPORT transWin_subWaiting transWin_subWaiting ROUT ORR R14,R14,#C_flag ;Assume there is one waiting STMFD R13!,{R0,R1,R12,R14} ;Save some registers WSPACE tw__wSpace ;Find my workspace ; --- First, try asking TMS --- LDR R1,tw__twin ;Load the global area address LDR R1,[R1,#twin_tmsHook] ;Load the hook address CMP R1,#1 ;Has the hook been set up? MOVCS R14,PC ;Yes -- set up return address ADDCS PC,R1,#tmsh__subWaiting ;And call the routine LDMCSFD R13!,{R0,R1,R12,PC}^ ;Return true ; --- Now find out about the normal WIMP --- BL event_last ;Find the last event CMP R0,#17 ;Is it some kind of message? CMPNE R0,#18 ;Either type of message? LDREQ R0,[R1,#16] ;Get the message code MOVEQ R14,#&40000 ;The message base number ORREQ R14,R14,#&000C0 ;We're looking for submenus CMPEQ R0,R14 ;Do they match? LDMEQFD R13!,{R0,R1,R12,PC}^ ;Return true LDMFD R13!,{R0,R1,R12,R14} ;Unstack some registers BICS PC,R14,#C_flag ;Return false LTORG ; --- transWin_openSub --- ; ; On entry: R0 == window handle to open ; ; On exit: -- ; ; Use: Opens the given window as a submenu. EXPORT transWin_openSub transWin_openSub ROUT STMFD R13!,{R0-R3,R12,R14} ;Save some registers WSPACE tw__wSpace ;Find my workspace ; --- First of all, try TMS --- LDR R1,tw__twin ;Load the global area address LDR R1,[R1,#twin_tmsHook] ;Load the hook address CMP R1,#1 ;Has the hook been set up? MOVCS R14,PC ;Yes -- set up return address ADDCS PC,R1,#tmsh__subWaiting ;And call the routine MOVCS R14,PC ;If it is waiting... ADDCS PC,R1,#tmsh__openSub ;...get it to open the menu BCS %90transWin_openSub ;And then return to caller ; --- Now try the normal system --- MOV R2,R0 ;Look after the window handle BL event_last ;Find the last event CMP R0,#17 ;Is it some kind of message? CMPNE R0,#18 ;Either type of message? LDREQ R0,[R1,#16] ;Get the message code MOVEQ R14,#&40000 ;The message base number ORREQ R14,R14,#&000C0 ;We're looking for submenus CMPEQ R0,R14 ;Do they match? BNE %99transWin_openSub ;No -- return then ; --- Open as a normal submenu --- ADD R14,R1,#24 ;Point to the coordinates MOV R1,R2 ;Get the window handle back LDMIA R14,{R2,R3} ;Read the coordinates SWI Wimp_CreateSubMenu ;Display the menu nicely MOV R0,R1 ;Get window handle in R0 ; --- Register the transient menu 90 BL transWin_register ;Register the window 99 LDMFD R13!,{R0-R3,R12,PC}^ ;And return to caller LTORG ; --- transWin_register --- ; ; On entry: R0 == window handle to register ; ; On exit: -- ; ; Use: Registers a window as being the current transient window. EXPORT transWin_register transWin_register ROUT STMFD R13!,{R12,R14} ;Save some registers WSPACE tw__wSpace ;Find my workspace LDR R12,tw__twin ;Find the global area STR R0,[R12,#twin_trans] ;Save the transient window LDR R14,[R12,#twin_flags] ;Load the TWIN flags word BIC R14,R14,#twinFlag_recrt ;Don't recreate the menu STR R14,[R12,#twin_flags] ;Save the flags back again LDMFD R13!,{R12,PC}^ ;And return to caller LTORG ; --- transWin_close --- ; ; On entry: R0 == window handle to close ; ; On exit: -- ; ; Use: Closes the current transient window. EXPORT transWin_close transWin_close ROUT STMFD R13!,{R0,R1,R10,R12,R14} ;Save some registers WSPACE tw__wSpace ;Find my workspace LDR R14,tw__flags ;Load my flags word TST R14,#twFlag__wimpCls ;Did the WIMP close it? MOVEQ R1,#-1 ;No -- kill the whole menu SWIEQ Wimp_CreateMenu ;Using this neat trick MOV R1,R13 ;Point at caller's handle SWI Wimp_CloseWindow ;Close the window LDR R0,[R13,#0] ;Load his window again LDR R12,tw__twin ;Find the global area LDR R14,[R12,#twin_trans] ;Load the current transient SUBS R14,R0,R14 ;Do they match nicely? STREQ R14,[R12,#twin_trans] ;Yes -- zero the current one LDMFD R13!,{R0,R1,R10,R12,PC}^ ;And return to caller LTORG ; --- tw__faker --- ; ; On entry: R0 == event code ; R1 == pointer to event data ; ; On exit: CS and new event set up, or CC and registers preserved ; ; Use: Generates dummy close events for transient windows. tw__faker ROUT ; --- Ignore redraw events --- CMP R0,#1 ;Is it a redraw event? MOVEQS PC,R14 ;Yes -- return right now ; --- Start up the faking business --- STMFD R13!,{R9,R10,R14} ;Save some registers LDR R14,tw__flags ;Load my flags word BIC R14,R14,#twFlag__wimpCls ;Wimp hasn't closed it STR R14,tw__flags ;Save the flags back again LDR R10,tw__twin ;Find the global area LDR R9,[R10,#twin_trans] ;Load the transient window CMP R9,#0 ;Is there one defined? LDMEQFD R13!,{R9,R10,PC}^ ;No -- return right now ; --- See if the window's still open --- CMP R0,#9 ;Is this a menu hit event? BEQ %10tw__faker ;Yes -- window will close STMFD R13!,{R0,R1} ;Save some more registers SUB R13,R13,#36 ;Make some stack space STR R9,[R13,#0] ;Save window handle in there MOV R1,R13 ;Point at the block SWI Wimp_GetWindowState ;Read the window information LDR R14,[R13,#32] ;Load the window flags TST R14,#&00010000 ;Is the window open still? ADD R13,R13,#36 ;Reclaim the stack space? LDMNEFD R13!,{R0,R1,R9,R10,PC}^ ;Yes -- return to caller LDMFD R13!,{R0,R1} ;Restore those registers ; --- Fake the event --- LDR R14,tw__flags ;Load my flags word ORR R14,R14,#twFlag__wimpCls ;Wimp has closed the window STR R14,tw__flags ;Save the flags back again 10tw__faker STR R9,[R1,#0] ;Save window handle in block MOV R0,#3 ;It's a close event LDMFD R13!,{R9,R10,R14} ;Unstack the registers ORRS PC,R14,#C_flag ;And return with C set LTORG ; --- transWin_init --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Initialises the transWin system. EXPORT transWin_init transWin_init ROUT STMFD R13!,{R12,R14} ;Save some registers WSPACE tw__wSpace ;Find my workspace ; --- Make sure I'm not already running --- LDR R14,tw__flags ;Load my flags word TST R14,#twFlag__inited ;Is my initialised flag set? LDMNEFD R13!,{R12,PC}^ ;Yes -- return to caller MOV R14,#twFlag__inited ;Set the intialised flag STR R14,tw__flags ;And save the flags back ; --- Set up the TWIN global area --- STMFD R13!,{R0-R2} ;Save some more registers LDR R0,tw__TWIN ;Load the global name word MOV R1,#twin_size ;And the size value BL sapphire_global ;Find the global area STR R0,tw__twin ;Save the address of this BCS %10transWin_init ;If already created, skip on MOV R1,#0 ;No flags set currently MOV R2,#0 ;No transient window set up MOV R14,#0 ;TMS hasn't registered itself STMIA R0,{R1,R2,R14} ;Save them in the area ; --- Now set up my fake event handler --- 10transWin_init BL event_init ;Make sure event is awake ADR R0,tw__faker ;Point to the fake handler MOV R1,R12 ;Pass it my workspace address BL event_fakeHandler ;Register the handler LDMFD R13!,{R0-R2,R12,PC}^ ;And return to caller tw__TWIN DCB "TWIN" LTORG tw__wSpace DCD 0 ;----- Workspace ------------------------------------------------------------ ; --- TWIN global area layout --- ; ; This global area is intended to allow communication ; between transWin and menu system providers. ; ; The TMS hook is set by TMS to point to a pair of branch ; instructions to routines tmsh_subWaiting and tmsh_openSub ; respectively. ; ; tmsh_subWaiting should return CS if TMS is waiting to open ; a submenu, and CC otherwise. tmsh_openSub is passed a ; window handle in R0, which it should open as a submenu in ; whatever way it sees fit. ; ; If the tmsHook pointer is zero, transWin will assume that ; TMS is not available. ^ 0 twin_flags # 4 ;Various useful flags twin_trans # 4 ;The current transient window twin_tmsHook # 4 ;A hook to the TMS system twin_size # 0 ;The size of the global area twinFlag_recrt EQU (1<<0) ;Menu will be recreated tmsh__subWaiting EQU 0 tmsh__openSub EQU 4 ; --- Workspace --- ^ 0,R12 tw__wStart # 0 tw__flags # 4 ;Various useful flags tw__twin # 4 ;Pointer to the TWIN global tw__wSize EQU {VAR}-tw__wStart twFlag__inited EQU (1<<0) ;We have been initialised twFlag__wimpCls EQU (1<<1) ;Wimp closed last dbox AREA |Sapphire$$LibData|,CODE,READONLY DCD tw__wSize DCD tw__wSpace DCD 0 DCD transWin_init ;----- That's all, folks ---------------------------------------------------- END