#include "proto.h" #include #ifdef __MINT_LIB__ #include #endif #ifndef EACCDN #define EACCDN -36 #endif #ifndef SIGPIPE #define SIGPIPE 13 #endif #ifndef SIG_IGN #define SIG_IGN 1L #endif #ifdef __MINT_LIB__ #define SIGNAL long #else #define SIGNAL void * #endif static char ourexts[DD_EXTSIZE] = "ARGS"; static char pipename[] = "U:\\PIPE\\DRAGDROP.AA"; static int any_ext; static long oldpipesig; int _dd_available; void SetDragDrop(int any,char *exts) { any_ext = any; strupr(strncpy(ourexts,exts,DD_EXTSIZE-1)); } static int ddcreate(int sendto,int win_id,int msx,int msy,int kstate,char exts[]) { reg int fd, msg[8]; long fd_mask; char c; pipename[17] = pipename[18] = 'A'; do { pipename[18]++; if (pipename[18]>'Z') { pipename[17]++; if (pipename[17]>'Z') break; else pipename[18] = 'A'; } fd = (int) Fcreate(pipename, FA_HIDDEN); } while (fd==EACCDN); if (fd<0) return (-2); msg[3] = win_id; msg[4] = msx; msg[5] = msy; msg[6] = kstate; msg[7] = (pipename[17]<<8)|pipename[18]; if (AvSendMsg(sendto, AP_DRAGDROP, msg)==FALSE) { Fclose(fd); return (-1); } fd_mask = 1L<>8); fd = (int) Fopen(pipename,2); if (fd<0) return (fd); outbuf[0] = DD_OK; strncpy(outbuf+1,preferext,DD_EXTSIZE); oldpipesig = (long) Psignal(SIGPIPE,(SIGNAL) SIG_IGN); if (Fwrite(fd,DD_EXTSIZE+1,outbuf)!=DD_EXTSIZE+1) { ddclose(fd); return (-1); } else return (fd); } static int ddrtry(int fd, char *name, char *whichext, long *size) { int hdrlen,i; char buf[80]; if (Fread(fd,2L,&hdrlen)!=2 || hdrlen<9) return (-1); if (Fread(fd,4L,whichext)!=4) return (-1); whichext[4] = 0; if (Fread(fd,4L,size)!=4) return (-1); hdrlen -= 8; i = min(hdrlen,DD_NAMEMAX); if (Fread(fd,i,name)!=i) return (-1); hdrlen -= i; while (hdrlen>80) { Fread(fd,80L,buf); hdrlen -= 80; } if (hdrlen>0) Fread(fd,hdrlen,buf); return (0); } static int ddreply(int fd, int ack) { char c = ack; if (Fwrite(fd,1L,&c)!=1) { ddclose(fd); return (-1); } else return (0); } void _rec_ddmsg(int *msg) { DRAG_DROP dd; char txtname[DD_NAMEMAX],*mem,ext[5]; int fd; if (strlen(ourexts)<4) return; dd.dd_originator = msg[1]; dd.dd_type = MINT_DRAG; dd.dd_win = get_window(msg[3]); dd.dd_mx = msg[4]; dd.dd_my = msg[5]; dd.dd_kstate = msg[6]; if ((fd=ddopen(msg[7],ourexts))<0) return; for(;;) { if (ddrtry(fd,txtname,ext,&dd.dd_size)) { ddclose(fd); return; } else { ext[4] = '\0'; memcpy(dd.dd_ext,ext,4); strupr(ext); } if (any_ext || strstr(ourexts,ext)) { if ((mem=Malloc(dd.dd_size+1))==NULL) { if (ddreply(fd, DD_LEN)) return; continue; } if (ddreply(fd,DD_OK)) return; if (Fread(fd,dd.dd_size,mem)!=dd.dd_size) { ddclose(fd); return; } mem[dd.dd_size] = 0; ddclose(fd); if (!strncmp(ext,"ARGS",4)) { dd.dd_args = mem; dd.dd_ext[0] = '\0'; dd.dd_mem = NULL; dd.dd_size = 0; } else { dd.dd_args = NULL; dd.dd_mem = mem; } dd.dd_name = txtname; _send_msg(&dd,0,OBJC_DRAGGED,0,0); Mfree(mem); return; } else if (ddreply(fd, DD_EXT)) return; } } int SendDragDrop(int msx,int msy,int kstate,char *name,char *sp_ext,long size,char *data) { int fd,sendto,win_id,dummy; char recexts[DD_EXTSIZE],exts[5]; if (!_dd_available) return (NO_DD); memcpy(exts,sp_ext,4); exts[4] = '\0'; strupr(exts); if ((win_id=wind_find(msx,msy))<=0 || !wind_xget(win_id,WF_OWNER,&sendto,&dummy,&dummy,&dummy) || sendto==ap_id) return (NO_RECEIVER); switch (fd=ddcreate(sendto,win_id,msx,msy,kstate,recexts)) { case -2: return (NO_DD); case -1: return (DD_NAK); } if ((dummy=ddstry(fd,exts,name,size))!=DD_OK) { ddclose(fd); return (dummy); } dummy = (Fwrite(fd,size,data)==size); ddclose(fd); return ((dummy) ? DD_OK : DD_LEN); }