home *** CD-ROM | disk | FTP | other *** search
- /* XferSend.c */
- /*
-
- ##### # #
- # # # # #
- # # #
- # ## #### #### # ## ####
- # # # # # # # # # #
- # # # # # ### # # # #
- # # # # # # # # # #
- # ### # # # #### ##### ### ####
-
- -----------------------------------------------------------------------------
-
- This is source for use with the 'DeskLib' Wimp C programming library for
- Risc OS. I currently use v1.04 of DeskLib. This source is FreeWare, which
- means you can use it to write commercial applications, but you may not charge
- *in any way* for the distribution of this source. I (Tim Browse) retain
- all copyright on this source.
-
- This source is provided 'as is' and I offer no guarantees that is useful,
- bug-free, commented, that it will compile, or even that it exists.
-
- If it breaks in half, you own both pieces.
-
- All source © Tim Browse 1993
-
- -----------------------------------------------------------------------------
-
- */
-
- /* A replacement for Acorn's xfersend, using DeskLib */
-
- /* ANSI includes */
- #include <string.h>
-
- /* Risc OS Lib includes */
- #include "werr.h"
- #include "bbc.h"
-
- /* DeskLib includes */
- #include "DeskLib.Core.h"
- #include "DeskLib.Wimp.h"
- #include "DeskLib.WimpSWIs.h"
- #include "DeskLib.Screen.h"
- #include "DeskLib.Event.h"
- #include "DeskLib.EventMsg.h"
- #include "DeskLib.Error.h"
- #include "DeskLib.Coord.h"
- #include "DeskLib.SWI.h"
-
- #include "Timslib.swis.h"
-
- #include "XferSend.h"
-
- typedef struct
- {
- int filetype;
- char *name;
- int estsize;
- xfersend_saveproc savetofile;
- void *handle;
- unsigned int myref;
- } xfersend_block;
-
- BOOL export_finished,
- export_successful;
-
- /* Forward declarations of handlers fpr claiming/releasing events */
-
- static BOOL DataSaveAckHandler(event_pollblock *event, void *handle);
- static BOOL DataLoadAckHandler(event_pollblock *event, void *handle);
- static BOOL XferFailHandler(event_pollblock *event, void *handle);
-
- static BOOL DataSaveAckHandler(event_pollblock *event, void *handle)
- {
- xfersend_block *info = (xfersend_block *) handle;
- message_block *message;
- message_destinee destinee;
-
- /* If this isn't a reply to the message we sent, ignore it */
- if (event->data.message.header.yourref != info->myref)
- return FALSE;
-
- /* We've got a filename to use, so save the data to it */
- export_successful =
- info->savetofile(event->data.message.data.datasaveack.filename, info->handle);
-
- /* Send a DataLoad message back */
- destinee.value = event->data.message.header.sender;
-
- message = &event->data.message;
- message->header.action = message_DATALOAD;
- message->header.yourref = message->header.myref;
-
- message->header.size = sizeof(message_header) + sizeof(message_dataload);
-
- Wimp_SendMessage(event_USERMESSAGERECORDED, message, destinee, 0);
-
- /* Make a note of the myref field */
- info->myref = message->header.myref;
- return TRUE;
- }
-
- static BOOL DataLoadAckHandler(event_pollblock *event, void *handle)
- {
- xfersend_block *info = (xfersend_block *) handle;
-
- /* If this isn't a reply to the message we sent, ignore it */
- if (event->data.message.header.yourref != info->myref)
- return FALSE;
-
- /* Transfer is finished */
- export_finished = TRUE;
-
- /* Release the message events we've claimed */
- EventMsg_Release(message_DATASAVEACK, event_ANY, DataSaveAckHandler);
- EventMsg_Release(message_DATALOADACK, event_ANY, DataLoadAckHandler);
- Event_Release(event_USERMESSAGEACK, event_ANY, event_ANY, XferFailHandler, handle);
-
- return TRUE;
- }
-
- static BOOL XferFailHandler(event_pollblock *event, void *handle)
- {
- /* One of our messages wasn't replied to, so abort the transfer. */
- export_finished = TRUE;
- export_successful = FALSE;
-
- /* Release the message events we've claimed */
- EventMsg_Release(message_DATASAVEACK, event_ANY, DataSaveAckHandler);
- EventMsg_Release(message_DATALOADACK, event_ANY, DataLoadAckHandler);
- Event_Release(event_USERMESSAGEACK, event_ANY, event_ANY, XferFailHandler, handle);
-
- /* If we sent a DataLoad and no reply was forthcoming, complain about lack of
- response - see Risc OS 2 PRMs p1266
- */
- if (event->data.message.header.action == message_DATALOAD)
- werr(FALSE, "Data transfer failed: Receiver died.");
-
- return TRUE;
- }
-
- static BOOL DragHandler(event_pollblock *event, void *handle)
- {
- xfersend_block *info = (xfersend_block *) handle;
- mouse_block ptr;
- message_block message;
- message_destinee destinee;
-
- /* Get end point of drag */
- Wimp_GetPointerInfo(&ptr);
-
- /* Ask for DataSaveAck and DataLoadAck messages, and UserMessageAck events
- to be sent to our handlers.
- */
- EventMsg_Claim(message_DATASAVEACK, event_ANY, DataSaveAckHandler, handle);
- EventMsg_Claim(message_DATALOADACK, event_ANY, DataLoadAckHandler, handle);
- Event_Claim(event_USERMESSAGEACK, event_ANY, event_ANY, XferFailHandler, handle);
-
- /* Set up a DataSave message to send to this end point */
-
- destinee.window = ptr.window;
-
- message.header.size = sizeof(message_header) + sizeof(message_datasave);
-
- message.header.yourref = 0; /* original message */
- message.header.action = message_DATASAVE;
-
- message.data.datasave.window = ptr.window;
- message.data.datasave.icon = ptr.icon;
- message.data.datasave.pos = ptr.pos;
- message.data.datasave.estsize = info->estsize;
- message.data.datasave.filetype = info->filetype;
- strcpy(message.data.datasave.leafname, info->name);
-
- /* Send the DataSave message */
- Wimp_SendMessage(event_USERMESSAGERECORDED, &message, destinee, 0);
-
- /* Make a note of the 'myref' field */
- info->myref = message.header.myref;
-
- return TRUE;
- }
-
-
- BOOL XferSend(int filetype, char *name, int estsize,
- xfersend_saveproc savetofile, event_pollblock *event, void *handle)
- {
- xfersend_block xfersend;
-
- icon_block icon;
- window_state state;
- drag_block drag;
-
- /* Save info for handler to get at */
- xfersend.filetype = filetype;
- xfersend.name = name;
- xfersend.estsize = estsize;
- xfersend.savetofile = savetofile;
- xfersend.handle = handle;
-
-
- /* Drag a fixed box around the screen */
- drag.type = drag_FIXEDBOX;
-
- /* Get the bounding box of the icon user is dragging */
- Error_Check(Wimp_GetIconState(event->data.mouse.window, event->data.mouse.icon,
- &icon));
-
- /* Convert to screen co-ordinates */
- Error_Check(Wimp_GetWindowState(event->data.mouse.window, &state));
- Coord_RectToScreen(&icon.workarearect, (convert_block *) &state.openblock.screenrect);
-
- /* Make this the size of the box */
- drag.screenrect = icon.workarearect;
-
- /* Constrain to whole screen (ie unconstrained) */
- drag.parent.min.x = 0;
- drag.parent.min.y = 0;
- drag.parent.max = screen_size;
-
- /* Claim drag events */
- Event_Claim(event_USERDRAG, event_ANY, event_ANY, DragHandler, (void *) &xfersend);
-
- /* Initiate drag */
- Error_Check(Wimp_DragBox(&drag));
-
- /* Keep polling until drag received by our handler and dealt with */
- export_finished = FALSE;
- export_successful = FALSE;
-
- /* Keep polling for events until the file is saved */
- while (!export_finished)
- Event_Poll();
-
- /* Release drag events */
- Event_Release(event_USERDRAG, event_ANY, event_ANY, DragHandler, (void *) &xfersend);
-
- /* Return value according to whether it worked or not... */
- return export_successful;
- }
-