; ; xfer.saveAs.s ; ; Implementation of a save as dialogue box (MDW) ; ; © 1994 Straylight ; ;----- Standard header ------------------------------------------------------ GET libs:header GET libs:swis ;----- External dependencies ------------------------------------------------ GET sapphire:dbox GET sapphire:help GET sapphire:msgs GET sapphire:note GET sapphire:sapphire GET sapphire:dbx.dbx GET sapphire:dbx.fileIcon GET sapphire:xfer.save ;----- Main code ------------------------------------------------------------ AREA |Sapphire$$Code|,CODE,READONLY ; --- saveAs --- ; ; On entry: R0 == estimated size of data ; R1 == file type of the data ; R2 == pointer to name of the file ; R3 == pointer to handler block ; R4 == value to pass to handlers in R10 ; R5 == value to pass to handlers in R12 ; ; On exit: May return an error ; ; Use: Displays a save as dialogue box for you to save some data. EXPORT saveAs saveAs ROUT STMFD R13!,{R0-R6,R12,R14} ;Save some registers WSPACE sa__wSpace ;Find my workspace address ; --- Find the end of the string --- MOV R6,R3 ;Take a copy of the title tag 00saveAs LDRB R14,[R3],#1 ;Load a byte from the table CMP R14,#32 ;Is it the end yet? BGE %00saveAs ;No -- go round again then ADD R3,R3,#3 ;Add on a little bit BIC R3,R3,#3 ;And word align the result ; --- Save the fixed information away --- STMIA R12,{R0-R5} ;Save the stuff in workspace ; --- Now create a dialogue box --- ADR R0,sa__dbName ;Point to my dialogue name BL dbox_create ;Try to create the dialogue BVS %99saveAs ;If it failed, tidy up STR R0,sa__dbox ;Save the dialogue handle ADR R1,sa__dbHandler ;Point to my handler routine MOV R2,R0 ;Pass dialogue handle in R10 MOV R3,R12 ;And workspace in R12 please BL dbox_eventHandler ;Set up the event handler ADR R1,sa__dbxDef ;Point to my dialogue def BL dbx_declare ;Let dbx handle the dialogue ; --- Set up the dialogue --- MOV R1,#saIcon__write ;Get the writable icon handle LDR R2,[R13,#8] ;Get the default filename BL dbox_setField ;Write it into the icon MOV R3,R0 ;Save the dialogue handle MOV R0,R6 ;Get the title string tag BL msgs_lookup ;Translate it nicely MOV R2,R0 ;Copy it into R2 now MOV R0,R3 ;Restore the dialogue handle MOV R1,#-1 ;Fill in the title bar BL dbox_setField ;And fill in the title ; --- Now display it and return --- MOV R1,#dbOpen_trans :OR: dbOpen_pointer BL dbox_open ;Open the dialogue box LDMFD R13!,{R0-R6,R12,R14} ;Restore all the registers BICS PC,R14,#V_flag ;And don't return any errors ; --- Couldn't create the dialogue box --- 99saveAs ADD R13,R13,#4 ;Don't restore R0 on exit LDMFD R13!,{R1-R6,R12,R14} ;Restore the other registers ORRS PC,R14,#V_flag ;And return the error sa__dbName DCB "save",0 sa__dbxDef FILEICN saIcon__file,R12,:INDEX: sa__fileType DBXEND LTORG ; --- sa__dbHandler --- ; ; On entry: R0 == dialogue box event code ; R1-R9 == event-dependent information ; ; On exit: -- ; ; Use: Handles events for the save dialogue box. sa__dbHandler ROUT CMP R0,#saIcon__ok ;Is it the OK button clicked? CMPNE R0,#dbEvent_OK ;Or maybe a return key? BEQ %10sa__dbHandler ;Either -- handle it CMP R0,#dbEvent_close ;Has the window been closed? BEQ %20sa__dbHandler ;Yes -- deal with this then CMP R0,#fIcon_event ;Or is it the fileicon drag? BEQ %30sa__dbHandler ;Yes -- deal with that CMP R0,#dbEvent_help ;Is it a help request? BEQ %40sa__dbHandler ;Yes -- send some help along MOVS PC,R14 ;Return -- unknown event ; --- Deal with a click on the OK button --- 10sa__dbHandler STMFD R13!,{R0-R3,R10,R12,R14} ;Save some registers MOV R3,R1 ;Keep the button status safe ; --- Slab the OK button --- MOV R0,R10 ;Get my dialogue handle MOV R1,#saIcon__ok ;And the OK button handle BL dbox_slab ;Slab the icon in nicely ; --- Try to find a `.' character --- MOV R1,#saIcon__write ;Find the writable icon BL dbox_getField ;Read the string value MOV R0,R2 ;Keep pointer to string 13sa__dbHandler LDRB R14,[R2],#1 ;Load a byte from it CMP R14,#32 ;Is it a control character? BLO %17sa__dbHandler ;Yes -- tell user he's silly CMP R14,#'.' ;Is it a dot character? BNE %13sa__dbHandler ;No -- loop round again ; --- Tell the client to save the file --- MOV R1,#1 ;Say that the file's safe ADR R2,sa__entries ;Find the entry point block LDMIA R2,{R2,R10,R12} ;Load all the client stuff MOV R14,PC ;Set up the return address ADD PC,R2,#saEntry__save ;Try to send the file BVC %19sa__dbHandler ;If it worked, skip to end ; --- Handle an error from the client --- MOV R1,#1 ;Set icon count for errorBox MOV R14,PC ;Set up the return address ADD PC,R2,#saEntry__failed ;Tell client it failed MOV R3,#1 ;Don't close the dialogue B %19sa__dbHandler ;And skip to the end ; --- Display a note about dragging the icon --- 17sa__dbHandler MOV R3,#1 ;Don't close the dialogue ADR R0,sa__noteMsg ;Point to the note message BL msgs_lookup ;Translate the note string BL note ;And display it in a window ; --- Wrap everything up nice and tight --- 19sa__dbHandler CMP R3,#1 ;Was it an Adjust click? LDR R0,[R13,#16] ;Load my dialogue handle BLNE dbox_close ;No -- close the dialogue BL dbox_unslab ;Unslab the OK button BLNE sa__close ;And close the dialogue box LDMFD R13!,{R0-R3,R10,R12,PC}^ ;Return to caller sa__noteMsg DCB "saDRAGICN",0 ; --- Handle a close event for the window --- 20sa__dbHandler B sa__close ;Just close the window ; --- Handle an icon drag for the window --- 30sa__dbHandler STMFD R13!,{R0-R8,R14} ;Save a load of registers ; --- Find the filename string --- MOV R0,R10 ;Get the dialogue box handle MOV R1,#saIcon__write ;Get the writable icon handle BL dbox_getField ;Read the text string MOV R8,R2 ;Keep a pointer to it ; --- Set up the other arguments --- ADD R14,R13,#8 ;Point to saved window/icon LDMIA R14,{R0,R1} ;Load them into registers LDMIA R12,{R2-R7} ;Load the other arguments ORR R3,R3,#&80000000 ;Set the extended args flag MOV R4,R8 ;Point to new file name ADD R5,R5,#saEntry__save ;Point at save handlers ADR R8,sa__extraHnd ;Point to my extra handlers BL save ;Start the save operation LDMFD R13!,{R0-R8,PC}^ ;Return to caller sa__extraHnd B sa__success ;The save attempt succeeded B sa__failed ;The save attempt failed 40sa__dbHandler STMFD R13!,{R0,R14} ;Save some registers ADR R0,sa__dbHelp ;Point to the message string BL msgs_lookup ;Translate the message BL help_add ;Add it to the help text BL dbox_help ;Read help from the icon LDMFD R13!,{R0,PC}^ ;Return to caller sa__dbHelp DCB "sahDB",0 LTORG ; --- sa__close --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Closes the save as dialogue box sa__close ROUT STMFD R13!,{R0,R10,R12,R14} ;Save some registers away ; --- Close the dialogue box --- WSPACE sa__wSpace ;Locate my workspace LDR R0,sa__dbox ;Load the dialogue box handle BL dbox_destroy ;Destroy the dialogue BL fileIcon_closed ;Tell fileIcon it's closed ; --- Tell the client we've done this thing --- ADR R14,sa__entries ;Point to the entry table LDMIA R14,{R0,R10,R12} ;Load the client data LDR R14,[R0,#saEntry__closed] ;Find the closed entry word CMP R14,#0 ;Is there an entry defined? MOV R14,PC ;Set up the return address ADDNE PC,R0,#saEntry__closed ;If defined, call the entry LDMFD R13!,{R0,R10,R12,PC}^ ;Return to caller LTORG ; --- sa__success --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Handles a successful icon drag-save operation. sa__success ROUT STMFD R13!,{R0-R3,R12,R14} ;Save a few registers ; --- Send a close event to the dialogue --- WSPACE sa__wSpace ;Find my workspace pointer LDR R0,sa__dbox ;Get the dialogue box handle BL dbox_window ;Get its window handle STR R0,[R13,#-4]! ;Store it on the stack MOV R2,R0 ;Get the window handle in R2 MOV R1,R13 ;Point to the close block MOV R0,#3 ;And send a close event SWI Wimp_SendMessage ;Add it to my event queue ADD R13,R13,#4 ;Reclaim that microblock LDMFD R13!,{R0-R3,R12,PC}^ ;Return to caller LTORG ; --- sa__failed --- ; ; On entry: R0 == pointer to an error, or 0 ; R1 == 1 ; ; On exit: -- ; ; Use: Deals with an abortive to save data. sa__failed ROUT B fileIcon_reAppear ;Make the file icon reappear LTORG sa__wSpace DCD 0 ;----- The SaveAs handler block --------------------------------------------- ; ; The block begins with the message tag for the dialogue title, followed by ; an align to word boundary and then branch instructions or 0 for: ^ 0 saEntry__closed # 4 ;Save dialogue has closed ;Entry: ; -- ;Exit: ; -- saEntry__save # 4 ;Write to a file ;Entry: ; R0 == pointer to file name ; R1 == 0 if file unsafe, ; non-0 if safe ;Exit: ; -- saEntry__send # 4 ;Send a block of data ;Entry: ; -- ;Exit: ; R0 == pointer to block ; R1 == size of block ; CS if this is the last one saEntry__success # 4 ;Data transfer has finished ;Entry: ; -- ;Exit: ; -- saEntry__failed # 4 ;Data transfer failed ;Entry: ; R0 == 0 or ptr to error ; R1 == 1 ;Exit: ; -- ;----- Icon numbers --------------------------------------------------------- saIcon__write EQU 1 saIcon__file EQU 2 saIcon__ok EQU 3 ;----- Workspace ------------------------------------------------------------ ^ 0,R12 sa__wStart # 0 sa__estSize # 4 ;Estimated size of data sa__fileType # 4 ;Filetype of data to save sa__fileName # 4 ;Pointer to default name sa__entries # 4 ;Pointer to branch table sa__R10 # 4 ;Caller's value of R10 sa__R12 # 4 ;Caller's value of R12 sa__dbox # 4 ;My dialogue box handle sa__wSize EQU {VAR}-sa__wStart AREA |Sapphire$$LibData|,CODE,READONLY DCD sa__wSize DCD sa__wSpace DCD 0 DCD 0 ;----- That's all, folks ---------------------------------------------------- END