home *** CD-ROM | disk | FTP | other *** search
- /*
- #### # # # #
- # # # # # The FreeWare C library for
- # # ## ### # # # # ### RISC OS machines
- # # # # # # # # # # # ___________________________________
- # # #### ### ## # # # #
- # # # # # # # # # # Please refer to the accompanying
- #### ### #### # # ##### # ### documentation for conditions of use
- ________________________________________________________________________
-
- File: save.h
- Author: Copyright © 1994 Julian Smith and Jason Howat
- Version: 1.02 (18 Jun 1994)
- Purpose: Automate handling of save-as windows
- Mods: 13-Jun-1994 - JPS - Added filetype handling
- 18-Jun-1994 - JDH - See Save.c
- */
-
- #ifndef __Desk_Save_h
- #define __Desk_Save_h
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- #include <stdlib.h>
-
- #ifndef __Desk_Event_h
- #include "Desk.Event.h"
- #endif
-
-
-
- typedef Desk_bool (*Desk_save_filesaver)(char *f, void *ref);
- /*
- This type of function should save data to file given by 'f', using info
- in 'ref'. It should return Desk_bool_TRUE if it was successful. 'ref' is the (void
- *) originally passed to Desk_Save_InitSaveWindowHandler
- */
-
- typedef int (*Desk_save_ramsaver)(
- Desk_task_handle sourcetask, /* our task handle */
- void *ref,
- Desk_task_handle desttask,
- void *destbuffer,
- unsigned int buffersize,
- int progress /* how many bytes have been transfered so far */
- );
- /*
- This type of function should Desk_Wimp_TransferBlock data. Note that you can
- do this using multiple Desk_Wimp_TransferBlock's if this is more convinient.
- Should return the total number of bytes transfered into 'destbuffer' -
- if less than buffersize, then transfer has finished. If <0, error has
- occurred. 'ref' is the (void *) originally passed to
- Desk_Save_InitSaveWindowHandler
- */
-
-
-
-
- typedef enum
- {
- Desk_save_SAVEOK = 0,
- Desk_save_RECEIVERFAILED,
- Desk_save_FILESAVERFAILED,
- Desk_save_RAMSAVERFAILED
- } Desk_save_result;
-
-
- typedef void (*Desk_save_resulthandler)(Desk_save_result result, void *ref);
- /* Called after any attempt to save. */
-
- typedef struct
- {
- Desk_window_handle window; /* Window that the save icons are in */
-
- union
- {
- unsigned int value;
- struct
- {
- unsigned int Desk_is_menu : 1; /* Savewindow is part of menu */
- unsigned int Desk_is_save_window : 1; /* Close window after save? */
- unsigned int Desk_we_are_dragging : 1; /* Are we dragging file icon? */
- unsigned int Desk_quit_after_save : 1; /* Click/drag was with Select */
- unsigned int Desk_release_after : 1; /* Release all handlers when */
- /* the window/menu is closed? */
- unsigned int padding : 27;
- } data;
- } flags;
-
- Desk_icon_handle dragsprite;
- Desk_icon_handle okbutton;
- Desk_icon_handle cancelbutton;
- Desk_icon_handle filenameicon;
- Desk_save_filesaver filesaver;
- Desk_save_ramsaver ramsaver;
- Desk_save_resulthandler resulthandler;
- size_t estimatedsize;
- int filetype;
- void *ref;
- int Desk_ram_progress; /* Num of bytes ram-transfered. */
- unsigned int Desk_last_message_ref; /* So we know which incoming */
- /* messages are replies to us */
- } Desk_save_saveblock;
- /*
-
- This struct contains all the info needed to deal with saving using the
- RISC OS data transfer protocol.
-
- It is used internally by the Desk_Save_* functions - you shouldn't need to
- use it normally. It is included here because Desk_Save_InitSaveWindowHandler
- returns a pointer to it, so that you can call
- Desk_Save_ReleaseSaveWindowHandler if you are using RO2 and have to detect
- menu closing manually, and also you might want to change the field 'ref'
- if the user presses a 'Selection' button in the save window (you might
- also want to change 'filesaver' and 'ramsaver' in this case).
-
- Also, you could change 'Desk_is_menu' if a menu-leaf savewindow changes into
- to a free-standing savewindow (this will only work if you have
- .flags.data.Desk_release_after = Desk_bool_FALSE - the saveblock wil be free-ed and all
- Desk_Event_ handlers released when the menu is closed otherwise.
-
- fn 'filesaver' is called when the data needs to be saved to a file.
-
- fn 'ramsaver' is called when the data needs to be RAM transfered.
-
- 'ref' is passed to file/ramsaver - it should enable these functions to
- save the right piece of data.
-
- You can change the following things after you have called
- Desk_Save_InitSaveWindowHandler:
-
- Desk_is_menu, Desk_is_save_window, filesaver, ramsaver, resulthandler,
- estimatedsize, ref.
-
- Don't change any of the icon or window handles, as these will have been
- used with Desk_Event_Claim, so if you change them, when Desk_Save_* calls
- Desk_Event_Release, DeskLib will complain.
-
- Also, don't change any other fields (there is no reason to anyway) as
- these are used internally and are assumed to be const.
- */
-
-
-
- Desk_save_saveblock *Desk_Save_InitSaveWindowHandler(
- Desk_window_handle window, /* handle of the window to deal with */
- Desk_bool Desk_is_menu, /* is this window part of a menu? */
- /* if Desk_bool_TRUE Desk_Save_* will close it after */
- /* 'Select'-saves */
- Desk_bool Desk_is_save_window, /* is this window just a save window? */
- /* if Desk_bool_TRUE Desk_Save_* will close it after */
- /* 'Select'-saves */
- Desk_bool Desk_release_after, /* release all Desk_Save_ handlers when */
- /* window/menu is closed? */
- Desk_icon_handle dragsprite, /* handle of the dragable file-icon */
- Desk_icon_handle okbutton, /* handle of 'OK' or 'Save' button */
- Desk_icon_handle cancelbutton, /* handle of the 'Cancel' button */
- Desk_icon_handle filenameicon, /* handle of the writable fname icon */
- Desk_save_filesaver filesaver, /* fn which saves data to a file */
- Desk_save_ramsaver ramsaver, /* fn which does Desk_Wimp_TransferBlocks */
- Desk_save_resulthandler resulthandler, /* fn to report success of save to */
- size_t estimatedsize, /* size of data (estimate) */
- int filetype,
- void *ref /* ref passed to all saver functions */
- );
- /*
-
- To implement RISC OS saving, call this function - it does all the
- message handling needed, and calls 'filesaver' or 'ramsaver' when
- needed, passing 'ref' to them so that they know what needs saving.
-
- 'ismenu' should be Desk_bool_TRUE if 'window' is part of a menu tree, and Desk_bool_FALSE if
- 'window' is normal window. This is used to know when to stop handling
- the save, e.g. when menu is closed, or when save-window is closed.
-
-
- Things you need to do:
-
- Create a conventional save-window with icons for Save, Cancel, and
- dragging, and an *indirected* text icon for the filename. (e.g. put this
- in a 'Templates' file). The filename icon *must* be indirected.
-
- Put a default file/leafname in to the filename icon.
-
- Make the dragable icon be whatever file-icon is appropriate
-
- Write a function which can save the data to a file. *Required*
-
- Write a function which can Desk_Wimp_TransferBlock the data. *Optional*
-
- Write a function to be called with result of any save *Optional*
-
- Create a reference, 'ref', to the data so that the saver functions know
- what data to save.
-
- Call Desk_Save_InitSaveWindowHandler You can do this anytime - e.g. just
- before/after you create a menu that includes the save window, when you
- open the save box in response to (for e.g.) a F3 keypress, or when you
- receive a Desk_message_MENUWARNING which heralds the opening of your
- save-window.
-
-
- YOU are responsible for opening the savewindow and dealing with menu
- handling. All Desk_Save_* does is handle the sprite-drgging, button pressing
- and data transfer protocol which originate in the save window.
-
- Then, when the user tries to save the data, the only thing which you get
- to know about is that either your 'filesaver' or 'ramsaver' is called,
- with the 'ref' you originally passed to Desk_Save_InitSaveWindowHandler. If a
- save is attempted, 'resulthandler' will be called, with the
- success/failure of the save.
-
- Thats it.
-
-
- Notes:
-
- The 'filenameicon' may be altered by Desk_Save_InitSaveWindowHandler - it
- replaces the first control chr by ASCII 0, as this works with standard C
- functions, and some template text icons seem to be terminated by ASCII
- 13.
-
- if you use 'Desk_release_after = Desk_bool_FALSE', the Desk_Event_ handlers will still be in
- place after the window/menu has closed. This is so you can keep a single
- window for all saves, and register it with Desk_Save_ just once when your
- application starts up. If your application deals with different pieces
- of data, you'll have to update the 'ref' field in the Desk_Save_saveblock
- returned by Desk_Save_InitSaveWindowHandler each time the window is opened.
-
- Desk_Save_* registers a handler for when the save window is closed, which
- Desk_Event_Release's all of the Desk_Save_* handlers for drag/click/message
- handling etc. This means you can have a save window with a close icon as
- well as/instead of the 'cancel' icon, and makes the whole thing a bit
- more robust.
-
- You can miss out any of the icons in the window by using a negative icon
- handle. This will prevent any Desk_Event_Claim's for the icon.
-
- If 'ramsaver' == NULL, then 'filesaver' will always be used. If
- 'resulthandler' == NULL, a default handler will be used, which will do
- an 'Desk_Error_Report' if a save fails.
-
- If 'resulthandler' != NULL, it will be called after any attempt to save
- the data, with 'ref' and one of the following flags:
-
- Desk_save_SAVEOK = 0 receiver signals the save went OK
- Desk_save_SAVERECEIVERFAILED receiver didn't signal it has received the data
- Desk_save_SAVESAVERFAILED your 'filesaver' function signalled an error
- Desk_save_SAVERAMFAILED your 'ramsaver' function signalled an error
-
- This is so that your app doesn't go away thinking data has been saved
- when it hasn't. Note that your saver functions will not be aware of any
- problem in the second case, where the receiver fails to load the scrap
- file.
-
- If you want to implement a 'Selection' button in the save window, you
- should register a separate handler for Desk_event_CLICK on the 'Selection'
- button in the save window, and when it is pressed, modify the saveblock
- previously returned by Desk_Save_InitSaveWindowHandler, so that
- Desk_save_saveblock.ref points to the selction data. You could also change
- the writable icon contents and the 'file/ramsave' functions etc etc.
-
- */
-
-
-
- void Desk_Save_ReleaseSaveHandlers(Desk_save_saveblock *saveblock);
- /*
- You shouldn't need this normally because menu/window closing is detected
- by SaveBoxHandler, 'cos it detects Desk_message_MENUSDELEATED and
- Desk_event_CLOSE. NB, in RO2, there is no Desk_message_MENUSDELEATED, so you will
- have to call this function when you next open a menu, or something...
-
- Also, if you want to close a free-standing (i.e. not in a menu)
- save-window when <Escape> is pressed, you will need this function.
-
- */
-
- void Desk_Save_SetFiletype(Desk_save_saveblock *saveblock, int filetype);
- /*
- Sets the sprite in the savewindow to be "Desk_file_..." and also alters the
- saveblock so that the filetype is used whenever date is saved to the
- filer or another application.
-
- NB this function changes the dragsprite icon is an *undirected* sprite-
- -only icon. If it was previously an indirected icon, the pointer to the
- indirected data is lost forever!
- */
-
- #ifdef __cplusplus
- }
- #endif
-
-
- #endif
-
-