home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 1 / RISC_DISC_1.iso / pd_share / code / gcc / !GCC / patches / DeskLib / h / Save < prev    next >
Encoding:
Text File  |  1994-10-03  |  11.3 KB  |  281 lines

  1. /*
  2.     ####             #    #     # #
  3.     #   #            #    #       #          The FreeWare C library for
  4.     #   #  ##   ###  #  # #     # ###             RISC OS machines
  5.     #   # #  # #     # #  #     # #  #   ___________________________________
  6.     #   # ####  ###  ##   #     # #  #
  7.     #   # #        # # #  #     # #  #    Please refer to the accompanying
  8.     ####   ### ####  #  # ##### # ###    documentation for conditions of use
  9.     ________________________________________________________________________
  10.  
  11.     File:    save.h
  12.     Author:  Copyright © 1994 Julian Smith
  13.     Version: 1.00 (24 Apr 1994)
  14.     Purpose: Automate handling of save-as windows
  15. */
  16.  
  17. #ifndef __dl_save_h
  18. #define __dl_save_h
  19.  
  20. #ifndef __dl_event_h
  21. #include "Event.h"
  22. #endif
  23.  
  24. #include <stdio.h>
  25.  
  26. #ifdef __cplusplus
  27. extern "C" {
  28. #endif
  29.  
  30. typedef BOOL (*save_filesaver)( FILE *f, void *ref);
  31.   /*  This type of function should save data to file stream 'f', using info in
  32.    *  'ref'. It should return TRUE if an error occurred.
  33.    *  'ref' is the (void *) originally passed to Save_InitSaveWindowHandler
  34.    */
  35.  
  36. typedef int (*save_ramsaver)(
  37.   task_handle  sourcetask,                  /* our task handle */
  38.   void         *ref,
  39.   task_handle  desttask,
  40.   void         *destbuffer,
  41.   unsigned int buffersize,
  42.   int          progress       /* how many bytes have been transfered so far  */
  43.   );
  44.  
  45.   /* This type of function should Wimp_TransferBlock data. Note that you can do
  46.    * this using multiple Wimp_TransferBlock's if this is more convinient.
  47.    * Should return the total number of bytes transfered into 'destbuffer' - if
  48.    * less than buffersize, then transfer has finished. If <0, error has
  49.    * occurred.
  50.    * 'ref' is the (void *) originally passed to Save_InitSaveWindowHandler
  51.    */
  52.  
  53.  
  54.  
  55.  
  56. typedef enum
  57. {
  58.   save_SAVEOK    = 0,
  59.   save_RECEIVERFAILED,
  60.   save_FILESAVERFAILED,
  61.   save_RAMSAVERFAILED
  62. } save_result;
  63.  
  64.  
  65. typedef void (*save_resulthandler)( save_result result, void *ref);
  66.   /* Called after any attempt to save. */
  67.  
  68. typedef struct
  69. {
  70.   window_handle    window;        /*  Window that the save icons are in */
  71.  
  72.   union
  73.   {
  74.     unsigned int  value;
  75.     struct
  76.     {
  77.       unsigned int  is_menu         : 1;  /* Savewindow is part of menu  */
  78.       unsigned int  is_save_window  : 1;  /* Close window after save?    */
  79.       unsigned int  we_are_dragging : 1;  /* Are we dragging file icon?  */
  80.       unsigned int  quit_after_save : 1;  /* Click/drag was with Select  */
  81.       unsigned int  release_after   : 1;  /* Release all handlers when   */
  82.                                           /* the window/menu is closed?  */
  83.       unsigned int  padding         : 27;
  84.     } data;
  85.   } flags;
  86.  
  87.   icon_handle         dragsprite;
  88.   icon_handle         okbutton;
  89.   icon_handle         cancelbutton;
  90.   icon_handle         filenameicon;
  91.   save_filesaver      filesaver;
  92.   save_ramsaver       ramsaver;
  93.   save_resulthandler  resulthandler;
  94.   size_t              estimatedsize;
  95.   void                *ref;
  96.   int                 ram_progress;          /* Num of bytes ram-transfered. */
  97.   unsigned int        last_message_ref;      /* So we know which incoming    */
  98.                                              /* messages are replies to us   */
  99. } save_saveblock;
  100.  
  101.  
  102.   /*
  103.   ********************************************************************
  104.  
  105.   This struct contains all the info needed to deal with saving using
  106.   the RISC OS data transfer protocol.
  107.  
  108.   It is used internally by the Save_* functions - you shouldn't need
  109.   to use it normally. It is included here because
  110.   Save_InitSaveWindowHandler returns a pointer to it, so that you can
  111.   call Save_ReleaseSaveWindowHandler if you are using RO2 and have to
  112.   detect menu closing manually, and also you might want to change the
  113.   field 'ref' if the user presses a 'Selection' button in the save
  114.   window (you might also want to change 'filesaver' and 'ramsaver' in
  115.   this case).
  116.  
  117.   Also, you could change 'is_menu' if a menu-leaf savewindow changes
  118.   into to a free-standing savewindow (this will only work if you have
  119.   .flags.data.release_after = FALSE - the saveblock wil be free-ed and
  120.   all Event_ handlers released when the menu is closed otherwise.
  121.  
  122.   fn 'filesaver' is called when the data needs to be saved to a file.
  123.  
  124.   fn 'ramsaver' is called when the data needs to be RAM transfered.
  125.  
  126.   'ref' is passed to file/ramsaver - it should enable these functions
  127.   to save the right piece of data.
  128.  
  129.   You can change the following things after you have called
  130.   Save_InitSaveWindowHandler:
  131.  
  132.     is_menu,
  133.     is_save_window,
  134.     filesaver,
  135.     ramsaver,
  136.     resulthandler,
  137.     estimatedsize,
  138.     ref.
  139.  
  140.   Don't change any of the icon or window handles, as these will have
  141.   been used with Event_Claim, so if you change them, when Save_* calls
  142.   Event_Release, DeskLib will complain.
  143.  
  144.   Also, don't change any other fields (there is no reason to anyway)
  145.   as these are used internally and are assumed to be const.
  146.   *********************************************************************
  147.   */
  148.  
  149.  
  150.  
  151. save_saveblock *Save_InitSaveWindowHandler(
  152.   window_handle      window,           /* handle of the window to deal with  */
  153.   BOOL               is_menu,          /* is this window part of a menu?     */
  154.                                        /* if TRUE Save_* will close it after */
  155.                                        /* 'Select'-saves                     */
  156.   BOOL               is_save_window,   /* is this window just a save window? */
  157.                                        /* if TRUE Save_* will close it after */
  158.                                        /* 'Select'-saves                     */
  159.   BOOL               release_after,    /* release all Save_ handlers when    */
  160.                                        /* window/menu is closed?             */
  161.   icon_handle        dragsprite,       /* handle of the dragable file-icon   */
  162.   icon_handle        okbutton,         /* handle of 'OK' or 'Save' button    */
  163.   icon_handle        cancelbutton,     /* handle of the 'Cancel' button      */
  164.   icon_handle        filenameicon,     /* handle of the writable fname icon  */
  165.   save_filesaver     filesaver,        /* fn which saves data to a file      */
  166.   save_ramsaver      ramsaver,         /* fn which does Wimp_TransferBlocks  */
  167.   save_resulthandler resulthandler,    /* fn to report success of save to    */
  168.   size_t      estimatedsize,           /* size of data  (estimate)           */
  169.   void      *ref                       /* ref passed to all saver functions  */
  170.   );
  171.  
  172.   /*
  173.   ****************************************************************************
  174.  
  175.   To implement RISC OS saving, call this function - it does all the message
  176.   handling needed, and calls 'filesaver' or 'ramsaver' when needed, passing
  177.   'ref' to them so that they know what needs saving.
  178.  
  179.   'ismenu' should be TRUE if 'window' is part of a menu tree, and FALSE if
  180.   'window' is normal window. This is used to know when to stop handling the
  181.   save.
  182.   e.g. when menu is closed, or when save-window is closed.
  183.  
  184.  
  185.   Things you need to do:
  186.  
  187.   1  Create a conventional save-window with icons for Save, Cancel, and
  188.      dragging, and an *indirected* text icon for the filename.
  189.      (e.g. put this in a 'Templates' file).
  190.      The filename icon *must* be indirected.
  191.   2  Put a default file/leafname in to the filename icon.
  192.   3  Make the dragable icon be whatever file-icon is appropriate
  193.   4  Write a function which can save the data to a file.  *Required*
  194.   5  Write a function which can Wimp_TransferBlock the data.  *Optional*
  195.   6  Write a function to be called with result of any save  *Optional*
  196.   7  Create a reference, 'ref', to the data so that the saver functions
  197.      know what data to save.
  198.   8  Call Save_InitSaveWindowHandler
  199.      You can do this anytime - e.g. just before/after you create a menu that
  200.      includes the save window, when you open the save box in response to
  201.      (for e.g.) a F3 keypress, or when you receive a message_MENUWARNING which
  202.      heralds the opening of your save-window.
  203.  
  204.   YOU are responsible for opening the savewindow and dealing with menu
  205.   handling. All Save_* does is handle the sprite-drgging, button pressing and
  206.   data transfer protocol which originate in the save window.
  207.  
  208.   Then, when the user tries to save the data, the only thing which you get to
  209.   know about is that either your 'filesaver' or 'ramsaver' is called, with the
  210.   'ref' you originally passed to Save_InitSaveWindowHandler.
  211.   If a save is attempted, 'resulthandler' will be called, with the
  212.   success/failure of the save.
  213.  
  214.   Thats it.
  215.  
  216.   Notes:
  217.   The 'filenameicon' may be altered by Save_InitSaveWindowHandler - it
  218.   replaces the first control chr by ASCII 0, as this works with standard C
  219.   functions, and some template text icons seem to be terminated by ASCII 13.
  220.  
  221.   if you use 'release_after = FALSE', the Event_ handlers will still be in
  222.   place after the window/menu has closed. This is so you can keep a single
  223.   window for all saves, and register it with Save_ just once when your
  224.   application starts up.
  225.   If your application deals with different pieces of data, you'll have to
  226.   update the 'ref' field in the Save_saveblock returned by
  227.   Save_InitSaveWindowHandler each time the window is opened.
  228.  
  229.   Save_* registers a handler for when the save window is closed, which
  230.   Event_Release's all of the Save_* handlers for drag/click/message handling
  231.   etc. This means you can have a save window with a close icon as well
  232.   as/instead of the 'cancel' icon, and makes the whole thing a bit more robust.
  233.  
  234.   You can miss out any of the icons in the window by using a negative icon
  235.   handle. This will prevent any Event_Claim's for the icon.
  236.  
  237.   If 'ramsaver' == NULL, then 'filesaver' will always be used.
  238.   If 'resulthandler' == NULL, a default handler will be used, which will do an
  239.   'Error_Report' if a save fails.
  240.  
  241.   if 'resulthandler' != NULL, it will be called after any attempt to save the
  242.   data, with 'ref' and one of the following flags:
  243.  
  244.   save_SAVEOK = 0    receiver signals the save went OK
  245.   save_SAVERECEIVERFAILED  receiver didn't signal it has received the data
  246.   save_SAVESAVERFAILED  your 'filesaver' function signalled an error
  247.   save_SAVERAMFAILED  your 'ramsaver'  function signalled an error
  248.  
  249.   This is so that your app doesn't go away thinking data has been saved when
  250.   it hasn't. Note that your saver functions will not be aware of any problem
  251.   in the second case, where the receiver fails to load the scrap file.
  252.  
  253.   If you want to implement a 'Selection' button in the save window, you should
  254.   register a separate handler for event_CLICK on the 'Selection' button in the
  255.   save window, and when it is pressed, modify the saveblock previously
  256.   returned by Save_InitSaveWindowHandler, so that save_saveblock.ref points to
  257.   the selction data. You could also change the writable icon contents and the
  258.   'file/ramsave' functions etc etc.
  259.  
  260.   ****************************************************************************
  261.   */
  262.  
  263.  
  264.  
  265. void Save_ReleaseSaveHandlers(save_saveblock *saveblock);
  266.   /* You shouldn't need this normally because menu/window closing is detected
  267.    * by SaveBoxHandler, 'cos it detects message_MENUSDELEATED and event_CLOSE.
  268.    * NB, in RO2, there is no message_MENUSDELEATED, so you will have to call
  269.    * this function when you next open a menu, or something...
  270.    *
  271.    * Also, if you want to close a free-standing (i.e. not in a menu)
  272.    * save-window when <Escape> is pressed, you will need this function.
  273.    */
  274.  
  275. #ifdef __cplusplus
  276.            }
  277. #endif
  278.  
  279. #endif
  280.  
  281.