home *** CD-ROM | disk | FTP | other *** search
- /*
- * Drag & drop sample code.
- * Copyright 1992 Atari Corporation
- *
- * global variables used:
- * gl_apid: our AES application id
- *
- * BUGS/CAVEATS:
- * This code is not re-entrant (it uses a static
- * variable for the pipe name and for saving the
- * SIGPIPE signal handler).
- *
- * While doing the drag and drop, the SIGPIPE
- * signal (write on an empty pipe) is ignored
- */
- #include <string.h>
-
- #ifdef __MINT__
- #include <mint/atarierr.h>
- #include <signal.h>
- static __Sigfunc oldpipesig;
- #else
- #include <atarierr.h>
- static long oldpipesig;
- #endif
-
- #include "intern.h"
-
- static char pipename[] = "u:\\pipe\\dragdrop.aa";
-
-
- /* Code for originator */
-
-
- /*
- * ddcreate: create a pipe for doing the drag & drop,
- * and send an AES message to the receipient
- * application telling it about the drag & drop
- * operation.
- *
- * Input Parameters:
- * apid: AES id of the window owner
- * winid: target window (0 for background)
- * msx, msy: mouse X and Y position
- * (or -1, -1 if a fake drag & drop)
- * kstate: shift key state at time of event
- *
- * Output Parameters:
- * exts: A 32 byte buffer into which the
- * receipient's 8 favorite
- * extensions will be copied.
- *
- * Returns:
- * A positive file descriptor (of the opened
- * drag & drop pipe) on success.
- * -1 if the receipient doesn't respond or
- * returns DD_NAK
- * -2 if appl_write fails
- */
- int dd_create(int apid, int winid, int msx, int msy, int kstate, char *exts)
- {
- int fd, i;
- short msg[8];
- long fd_mask;
- char c;
-
- pipename[17] = pipename[18] = 'A';
- fd = -1;
- do
- {
- pipename[18]++;
- if (pipename[18] > 'Z')
- {
- pipename[17]++;
- if (pipename[17] > 'Z')
- break;
- }
- /* FA_HIDDEN means "get EOF if nobody has pipe open for reading" */
- fd = (int)Fcreate(pipename, FA_HIDDEN);
- }
- while (fd == EACCDN);
-
- if (fd < 0)
- return fd;
-
- /* construct and send the AES message */
- msg[0] = AP_DRAGDROP;
- msg[1] = gl_apid;
- msg[2] = 0;
- msg[3] = winid;
- msg[4] = msx;
- msg[5] = msy;
- msg[6] = kstate;
- msg[7] = (pipename[17] << 8) | pipename[18];
- i = appl_write(apid, (int)sizeof(msg), msg);
- if (i == 0)
- {
- Fclose(fd);
- return -2;
- }
-
- /* now wait for a response */
- fd_mask = 1L << fd;
- i = Fselect(DD_TIMEOUT, &fd_mask, 0L, 0L);
- if (!i || !fd_mask) /* timeout happened */
- {
- Fclose(fd);
- return -1;
- }
-
- /* read the 1 byte response */
- i = (int)Fread(fd, 1L, &c);
- if (i != 1 || c != DD_OK)
- {
- Fclose(fd);
- return -1;
- }
-
- /* now read the "preferred extensions" */
- i = (int)Fread(fd, DD_EXTSIZE, exts);
- if (i != DD_EXTSIZE)
- {
- Fclose(fd);
- return -1;
- }
-
- #ifdef __MINT__
- oldpipesig = signal(SIGPIPE, SIG_IGN);
- #else
- oldpipesig = (long)Psignal(SIGPIPE, SIG_IGN);
- #endif
- return fd;
- }
-
-
- /*
- * ddstry: see if the receipient is willing to accept a certain
- * type of data (as indicated by "ext")
- *
- * Input parameters:
- * fd file descriptor returned from ddcreate()
- * ext pointer to the 4 byte file type
- * name pointer to the name of the data
- * size number of bytes of data that will be sent
- *
- * Output parameters: none
- *
- * Returns:
- * DD_OK if the receiver will accept the data
- * DD_EXT if the receiver doesn't like the data type
- * DD_LEN if the receiver doesn't like the data size
- * DD_NAK if the receiver aborts
- */
- int dd_stry(int fd, char *ext, char *name, long size)
- {
- short hdrlen, i;
- char c;
-
- /* 4 bytes for extension, 4 bytes for size, 1 byte for
- * trailing 0
- */
- hdrlen = 9 + strlen(name);
- i = Fwrite(fd, 2L, &hdrlen);
-
- /* now send the header */
- if (i != 2)
- return DD_NAK;
- i = Fwrite(fd, 4L, ext);
- i += Fwrite(fd, 4L, &size);
- i += Fwrite(fd, (long)strlen(name)+1, name);
- if (i != hdrlen)
- return DD_NAK;
-
- /* wait for a reply */
- i = Fread(fd, 1L, &c);
- if (i != 1)
- return DD_NAK;
- return c;
- }
-
-
- /* Code for either receipient or originator */
-
-
- /*
- * ddclose: close a drag & drop operation
- */
- void dd_close(int fd)
- {
- #ifdef __MINT__
- (void)signal(SIGPIPE, oldpipesig);
- #else
- Psignal(SIGPIPE, (void *)oldpipesig);
- #endif
- (void)Fclose(fd);
- }
-
-
-
- /* Code for receipient */
-
-
- /*
- * ddopen: open a drag & drop pipe
- *
- * Input Parameters:
- * ddnam: the pipe's name (from the last word of
- * the AES message)
- * preferext: a list of DD_NUMEXTS 4 byte extensions we understand
- * these should be listed in order of preference
- * if we like fewer than DD_NUMEXTS extensions, the
- * list should be padded with 0s
- *
- * Output Parameters: none
- *
- * Returns:
- * A (positive) file handle for the drag & drop pipe, on success
- * -1 if the drag & drop is aborted
- * A negative error number if an error occurs while opening the
- * pipe.
- */
- int dd_open(int ddnam, char *preferext)
- {
- int fd;
- char outbuf[DD_EXTSIZE+1];
-
- pipename[18] = ddnam & 0x00ff;
- pipename[17] = (ddnam & 0xff00) >> 8;
-
- fd = (int)Fopen(pipename, 2);
- if (fd < 0) return fd;
-
- outbuf[0] = DD_OK;
- strncpy(outbuf+1, preferext, DD_EXTSIZE);
-
- #ifdef __MINT__
- oldpipesig = signal(SIGPIPE, SIG_IGN);
- #else
- oldpipesig = (long)Psignal(SIGPIPE, SIG_IGN);
- #endif
-
- if (Fwrite(fd, (long)DD_EXTSIZE+1, outbuf) != DD_EXTSIZE+1)
- {
- dd_close(fd);
- return -1;
- }
-
- return fd;
- }
-
-
- /*
- * ddrtry: get the next header from the drag & drop originator
- *
- * Input Parameters:
- * fd: the pipe handle returned from ddopen()
- *
- * Output Parameters:
- * name: a pointer to the name of the drag & drop item
- * (note: this area must be at least DD_NAMEMAX bytes long)
- * whichext: a pointer to the 4 byte extension
- * size: a pointer to the size of the data
- *
- * Returns:
- * TRUE on success
- * FALSE if the originator aborts the transfer
- *
- * Note: it is the caller's responsibility to actually
- * send the DD_OK byte to start the transfer, or to
- * send a DD_NAK, DD_EXT, or DD_LEN reply with ddreply().
- */
- int dd_rtry(int fd, char *name, char *whichext, long *size)
- {
- short hdrlen;
- int i;
- char buf[80];
-
- i = (int)Fread(fd, 2L, &hdrlen);
- if (i != 2)
- return FALSE;
- if (hdrlen < 9) /* this should never happen */
- return FALSE;
- i = (int)Fread(fd, 4L, whichext);
- if (i != 4)
- return FALSE;
- whichext[4] = 0;
- i = (int)Fread(fd, 4L, size);
- if (i != 4)
- return FALSE;
- hdrlen -= 8;
- if (hdrlen > DD_NAMEMAX)
- i = DD_NAMEMAX;
- else
- i = hdrlen;
- if (Fread(fd, (long)i, name) != i)
- return FALSE;
- hdrlen -= i;
-
- /* skip any extra header */
- while (hdrlen > 80)
- {
- Fread(fd, 80L, buf);
- hdrlen -= 80;
- }
- if (hdrlen > 0)
- Fread(fd, (long)hdrlen, buf);
-
- return TRUE;
- }
-
-
- /*
- * ddreply: send a 1 byte reply to the drag & drop originator
- *
- * Input Parameters:
- * fd: file handle returned from ddopen()
- * ack: byte to send (e.g. DD_OK)
- *
- * Output Parameters:
- * none
- *
- * Returns: TRUE on success, FALSE on failure
- * in the latter case the file descriptor is closed
- */
- int dd_reply(int fd, int ack)
- {
- char c = ack;
-
- if (Fwrite(fd, 1L, &c) == 1L)
- return TRUE;
- else
- Fclose(fd);
- return FALSE;
- }
-