/* Copyright 1996 Acorn Computers Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /************************************************************************/ /* © Acorn Computers Ltd, 1992. */ /* */ /* This file forms part of an unsupported source release of RISC_OSLib. */ /* */ /* It may be freely used to create executable images for saleable */ /* products but cannot be sold in source form or as an object library */ /* without the prior written consent of Acorn Computers Ltd. */ /* */ /* If this file is re-distributed (even if modified) it should retain */ /* this copyright notice. */ /* */ /************************************************************************/ /* Title: c.xferrecv * Purpose: general purpose import of data by dragging icon * History: IDJ: 07-Feb-92: prepared for source release * */ #include #include #include "trace.h" #include "os.h" #include "bbc.h" #include "wimp.h" #include "wimpt.h" #include "win.h" #include "dbox.h" #include "typdat.h" #include "xfersend.h" #include "fileicon.h" #include "werr.h" #include "menu.h" #include "event.h" #include "xferrecv.h" #include "msgs.h" #include "VerIntern/messages.h" #define OS_ReadVarVal 0x23 typedef enum { xferrecv_state_Ask, xferrecv_state_Talk, xferrecv_state_Done, xferrecv_state_Broken } xferrecv_stateval ; static wimp_t xferrecv_sendertask ; #ifdef SHARED_C_LIBRARY static wimp_msgstr xferrecv_ack = {0}; #else static wimp_msgstr xferrecv_ack; #endif static xferrecv_buffer_processor xferrecv_processbuff ; static char *xferrecv_buffer ; static int xferrecv_buffersize ; static int xferrecv_state ; static int xferrecv_msgid ; static int scrap_ref = 0 ; static int xferrecv__fileissafe ; int xferrecv_checkinsert(char **filename) { wimp_eventstr *e = wimpt_last_event(); if ((e->e==wimp_ESENDWANTACK || e->e == wimp_ESEND) && (e->data.msg.hdr.action == wimp_MDATALOAD || e->data.msg.hdr.action == wimp_MDATAOPEN)) { tracef4("xferrecv_checkinsert returning filetype %x: %d %d %d\n", e->data.msg.data.dataload.type, scrap_ref,e->data.msg.hdr.your_ref,e->data.msg.hdr.my_ref) ; xferrecv__fileissafe = e->data.msg.hdr.your_ref != scrap_ref || scrap_ref==0 ; xferrecv_ack.hdr.action = wimp_MDATALOADOK ; xferrecv_ack.hdr.size = sizeof(wimp_msghdr) ; xferrecv_sendertask = e->data.msg.hdr.task ; xferrecv_ack.hdr.your_ref = e->data.msg.hdr.my_ref ; *filename = e->data.msg.data.dataload.name ; return e->data.msg.data.dataload.type ; } else return -1 ; } void xferrecv_insertfileok(void) { /* An insert has been completed successfully. This sends an acknowledge back to the original application. */ tracef0("xferrecv_insertfileok\n") ; if (!xferrecv__fileissafe) { tracef0("Must delete scrap file\n") ; os_cli("%remove ") ; } scrap_ref = 0 ; (void) wimp_sendmessage(wimp_ESEND, &xferrecv_ack, xferrecv_sendertask); } int xferrecv_checkprint(char **filename) { wimp_eventstr *e = wimpt_last_event(); if ((e->e==wimp_ESENDWANTACK || e->e == wimp_ESEND) && (e->data.msg.hdr.action == wimp_MPrintTypeOdd)) { tracef4("xferrecv_checkprint returning filetype %x: %d %d %d\n", e->data.msg.data.print.type, scrap_ref,e->data.msg.hdr.your_ref,e->data.msg.hdr.my_ref) ; xferrecv__fileissafe = 0 ; xferrecv_ack.hdr.action = wimp_MPrintTypeKnown ; xferrecv_ack.hdr.size = sizeof(wimp_msghdr)+sizeof(wimp_msgprint) ; xferrecv_sendertask = e->data.msg.hdr.task ; xferrecv_ack.hdr.your_ref = e->data.msg.hdr.my_ref ; *filename = e->data.msg.data.print.name ; return e->data.msg.data.print.type ; } else return -1 ; } void xferrecv_printfileok(int type) { xferrecv_ack.data.print.type = type ; (void) wimp_sendmessage(wimp_ESEND, &xferrecv_ack, xferrecv_sendertask); } int xferrecv_checkimport(int *estsize) { wimp_eventstr *e = wimpt_last_event(); if ((e->e==wimp_ESENDWANTACK || e->e == wimp_ESEND) && e->data.msg.hdr.action == wimp_MDATASAVE) { xferrecv_ack.hdr.size = sizeof(wimp_msghdr) + sizeof(wimp_msgdatasaveok) ; xferrecv_sendertask = e->data.msg.hdr.task ; xferrecv_ack.hdr.your_ref = e->data.msg.hdr.my_ref ; xferrecv_ack.hdr.action = wimp_MDATASAVEOK ; xferrecv_ack.data.datasaveok.w = e->data.msg.data.datasave.w ; xferrecv_ack.data.datasaveok.i = e->data.msg.data.datasave.i ; xferrecv_ack.data.datasaveok.x = e->data.msg.data.datasave.x ; xferrecv_ack.data.datasaveok.y = e->data.msg.data.datasave.y ; xferrecv_ack.data.datasaveok.type = e->data.msg.data.datasave.type ; *estsize = xferrecv_ack.data.datasaveok.estsize = e->data.msg.data.datasave.estsize ; tracef2("xferrecv_checkimport returning filetype %x from %d\n", e->data.msg.data.datasave.type,xferrecv_sendertask) ; return xferrecv_ack.data.datasaveok.type = e->data.msg.data.datasave.type ; } else return -1 ; } static void xferrecv_sendRAMFETCH(void) { char *addr = xferrecv_ack.data.ramfetch.addr ; int size = xferrecv_ack.data.ramfetch.nbytes ; int action = xferrecv_ack.hdr.action ; tracef2("xferrecv_sendRAMFETCH with buffer %x, size %d :", (int) xferrecv_buffer,xferrecv_buffersize) ; xferrecv_ack.hdr.action = wimp_MRAMFETCH ; xferrecv_ack.data.ramfetch.addr = xferrecv_buffer ; xferrecv_ack.data.ramfetch.nbytes = xferrecv_buffersize ; (void) wimp_sendmessage(wimp_ESENDWANTACK, &xferrecv_ack, xferrecv_sendertask); xferrecv_msgid = xferrecv_ack.hdr.my_ref ; tracef1(" ramfetch msg id %d\n",xferrecv_msgid) ; xferrecv_ack.data.ramfetch.addr=addr ; xferrecv_ack.data.ramfetch.nbytes=size ; xferrecv_ack.hdr.action = action ; } static BOOL xferrecv_unknown_events(wimp_eventstr *e, void *handle) { handle = handle ; #if TRACE tracef("xferrecv_unknown_events %d %d %d %d %d\n",e->e, e->data.msg.hdr.action,e->data.msg.hdr.my_ref, e->data.msg.hdr.your_ref,xferrecv_msgid) ; #endif if ((e->e == wimp_ESEND || e->e == wimp_ESENDWANTACK) && e->data.msg.hdr.your_ref == xferrecv_msgid && e->data.msg.hdr.action == wimp_MRAMTRANSMIT) { tracef2("xferrecv got ramtransmit of %d into %d\n", e->data.msg.data.ramtransmit.nbyteswritten,xferrecv_buffersize) ; if (e->data.msg.data.ramtransmit.nbyteswritten == xferrecv_buffersize && e->data.msg.data.ramtransmit.nbyteswritten != 0) { /* other end has filled our buffer; better try and allocate some more space */ if (xferrecv_processbuff(&xferrecv_buffer, &xferrecv_buffersize)) { /* can go on */ tracef2("users buffer processor set buffer %x, size %d\n", (int) xferrecv_buffer, xferrecv_buffersize) ; xferrecv_ack.hdr.your_ref = e->data.msg.hdr.my_ref ; xferrecv_sendRAMFETCH() ; xferrecv_state = xferrecv_state_Talk ; } else { tracef0("users buffer processor failed: break down\n") ; xferrecv_state = xferrecv_state_Broken ; } } else { tracef0("xferrecv had final ramtransmit; set done state\n") ; xferrecv_buffersize = e->data.msg.data.ramtransmit.nbyteswritten ; xferrecv_state = xferrecv_state_Done ; } } else if (e->e == wimp_EACK && e->data.msg.hdr.my_ref == xferrecv_msgid) { tracef0("xferrecv ramfetch bounced: ") ; /* got our message back */ if (xferrecv_state == xferrecv_state_Ask) { os_regset r ; tracef0("ask for Wimp$Scrap transfer\n") ; /* first check that variable exists */ r.r[0] = (int) "Wimp$Scrap" ; r.r[1] = NULL ; r.r[2] = -1 ; r.r[3] = 0 ; r.r[4] = 0 ; /* don't use 3 cos buffer size unsigned for macro expansion (fixed in 4.15) */ os_swix(OS_ReadVarVal+os_X, &r) ; if (r.r[2]==0) werr(0,msgs_lookup(MSGS_xferrecv1)) ; else { strcpy(xferrecv_ack.data.datasaveok.name, "") ; xferrecv_ack.data.datasaveok.estsize = -1 ; /* file is not safe with us */ (void) wimp_sendmessage(wimp_ESEND, &xferrecv_ack, xferrecv_sendertask); scrap_ref = xferrecv_ack.hdr.my_ref ; } } else { tracef0("tell the user the protocol fell down\n") ; werr(0, msgs_lookup(MSGS_xferrecv2)) ; } xferrecv_state = xferrecv_state_Broken ; } else return FALSE ; return TRUE ; } int xferrecv_doimport(char *buf, int size, xferrecv_buffer_processor p) { /* Receives data into the buffer; calls the buffer processor if the buffer given becomes full. Returns TRUE if the transaction completed sucessfully. */ win_add_unknown_event_processor(xferrecv_unknown_events, 0) ; tracef0("xferrecv_doimport entered\n") ; xferrecv_processbuff = p ; xferrecv_buffer = buf ; xferrecv_buffersize = size ; xferrecv_sendRAMFETCH() ; xferrecv_state = xferrecv_state_Ask ; xferrecv__fileissafe = FALSE ; do { event_process() ; } while (xferrecv_state < xferrecv_state_Done) ; win_remove_unknown_event_processor(xferrecv_unknown_events, 0) ; return (xferrecv_state == xferrecv_state_Done ? xferrecv_buffersize : -1 ) ; } BOOL xferrecv_file_is_safe() { return xferrecv__fileissafe ; } /* end */