/* * Routine pour Drag and drop sous MultiTos * source: D&D Atari, demo OEP (Alexander Lorenz) * * Struktur OEP (oep.apid): AES-ID der Applikation * * (Tab = 4) */ #ifdef __PUREC__ #include #else #include #include #include #endif #include #include #include "windom.h" #include "dragdrop.h" #ifndef EACCDN #define EACCDN (-36) #endif #ifndef FA_HIDDEN #define FA_HIDDEN 0x02 #endif static char pipename[] = "U:\\PIPE\\DRAGDROP.AA"; static long pipesig; /* * Routinen fr den Sender */ /* * Erzeugt Pipe fr D&D * * Eingabeparameter: * pipe - Pointer auf 2 Byte Buffer fr Pipeextension * * Ausgabeparameters: * keine * * Returnwert: * >0: Filehandle der Pipe * -1: Fehler beim Erzeugen der Pipe */ short ddcreate(short *pipe) { long fd = -1; pipename[17] = 'A'; pipename[18] = 'A' - 1; do /* ouvre un pipe inoccup‚ */ { pipename[18]++; if (pipename[18] > 'Z') { pipename[17]++; if (pipename[17] > 'Z') break; else pipename[18] = 'A'; } /* FA_HIDDEN fr Pipe notwendig! */ fd = Fcreate(pipename, FA_HIDDEN); } while (fd == (long) EACCDN); if (fd < 0L) return(-1); *pipe = (pipename[17] << 8) | pipename[18]; /* Signalhandler konfigurieren */ ddgetsig(&pipesig); return((short) fd); } /* * Sendet AP_DRAGDROP an Empf„ngerapplikation * * Eingabeparameter: * apid - AES-ID der Emf„ngerapp. * fd - Filehandle der D&D-Pipe * winid - Handle des Zielfensters (0 fr Desktopfenster) * mx/my - Maus X und Y Koord. * (-1/-1 fr einen fake Drag&Drop) * kstate - Sondertastenstatus * pipename - Extension der D&D-Pipe * * Ausgabeparameter: * keine * * Returnwert: * >0: kein Fehler * -1: Empf„ngerapp. gibt DD_NAK zurck * -2: Empf„ngerapp. antwortet nicht (Timeout) * -3: Fehler bei appl_write() */ short ddmessage(short apid, short fd, short winid, short mx, short my, short kstate, short pipeid) { char c; short i, msg[8]; long fd_mask; /* AES-Message define and post */ msg[0] = AP_DRAGDROP; msg[1] = _AESapid; msg[2] = 0; msg[3] = winid; msg[4] = mx; msg[5] = my; msg[6] = kstate; msg[7] = pipeid; i = appl_write(apid, 16, msg); if (i == 0) { ddclose(fd); return(-3); } /* receiver reaction */ fd_mask = (1L << fd); i = Fselect(DD_TIMEOUT, &fd_mask, 0L, 0L); if (!i || !fd_mask) { /* Timeout eingetreten */ ddclose(fd); return(-2); } /* le recepteur refuse (lecture du pipe) */ if (Fread(fd, 1L, &c) != 1L) { ddclose(fd); return(-1); } if (c != DD_OK) { ddclose(fd); return(-1); } return(1); } /* * Liest die 8 "bevorzugten" Extensionen der Empf„ngerapplikation * * Eingabeparameter: * fd - Filehandle der D&D-Pipe * * Ausgabeparameters: * exts - 32 Bytebuffer fr die 8 bevorzugten Extensionen * der Zielapp. * * Returnwert: * >0: kein Fehler * -1: Fehler beim Lesen aus der Pipe */ short ddrexts(short fd, char *exts) { if (Fread(fd, DD_EXTSIZE, exts) != DD_EXTSIZE) { ddclose(fd); return(-1); } return(1); } /* * Testet, ob der Empf„nger einen Datentyp akzeptiert * * Eingabeparameter: * fd - Filehandle (von ddcreate()) * ext - Zeiger auf Datentyp (4 Bytes zB. "ARGS") * text - Zeiger auf Datenbeschreibung (optional, zB. "DESKTOP args") * name - Zeiger auf Datendateiname (optional, zB. "SAMPLE.TXT") * size - Anzahl Bytes der zu sendenden Daten * * Ausgabeparameter: * keine * * Returnwert: * DD_OK - Empf„nger akzeptiert Datentyp * DD_NAK - Empf„nger brach Drag&Drop ab * DD_EXT - Empf„nger lehnt Datentyp ab * DD_LEN - Empf„nger kann Datenmenge nicht verarbeiten * DD_TRASH - Drop erfolgte auf Mlleimer * DD_PRINTER - Drop erfolgte auf Drucker * DD_CLIPBOARD - Drop erfolgte auf Clipboard */ short ddstry(short fd, char *ext, char *text, char *name, long size) { char c; short hdrlen, i; /* 4 Bytes fr "ext", 4 Bytes fr "size", 2 Bytes fr Stringendnullen */ hdrlen = (short) (4 + 4 + strlen(text)+1 + strlen(name)+1); /* Header senden */ if (Fwrite(fd, 2L, &hdrlen) != 2L) return(DD_NAK); i = (short) Fwrite(fd, 4L, ext); i += (short) Fwrite(fd, 4L, &size); i += (short) Fwrite(fd, strlen(text)+1, text); i += (short) Fwrite(fd, strlen(name)+1, name); if (i != hdrlen) return(DD_NAK); /* auf die Antwort warten */ if (Fread(fd, 1L, &c) != 1L) return(DD_NAK); return(c); } /* Routinen fr Sender und Empf„nger */ /* * Pipe schliežen (Drag&Drop beenden/abbrechen) */ void ddclose(short fd) { /* Signalhandler restaurieren */ ddsetsig(pipesig); Fclose(fd); } /* * Signalhandler fr D&D konfigurieren * * Eingabeparameter: * oldsig - Zeiger auf 4 Byte Puffer fr alten Handlerwert * * Ausgabeparameter: * keine * * Returnwerte: * keine */ void ddgetsig(long *oldsig) { *oldsig = (long) Psignal(SIGPIPE, (void *) SIG_IGN); } /* * Signalhandler nach D&D restaurieren * * Eingabeparameter: * oldsig - Alter Handlerwert (von ddgetsig) * * Ausgabeparameter: * keine * * Returnwerte: * keine */ void ddsetsig(long oldsig) { if (oldsig != -32L) Psignal(SIGPIPE, (void *) oldsig); } /* Routinen fr Empf„nger */ /* * Drag&Drop Pipe ”ffnen * * Eingabeparameter: * ddnam - Extension der Pipe (letztes short von AP_DRAGDROP) * ddmsg - DD_OK oder DD_NAK * * Ausgabeparameter: * keine * * Returnwerte: * >0 - Filehandle der Drag&Drop pipe * -1 - Drag&Drop abgebrochen */ short ddopen(short ddnam, char ddmsg) { long fd; pipename[17] = (ddnam & 0xff00) >> 8; pipename[18] = ddnam & 0x00ff; fd = Fopen(pipename, 2); if (fd < 0L) return(-1); /* Signalhandler konfigurieren */ ddgetsig(&pipesig); if (Fwrite((short) fd, 1L, &ddmsg) != 1L) { ddclose((short) fd); return(-1); } return((short) fd); } /* * Schreibt die 8 "bevorzugten" Extensionen der Applikation * * Eingabeparameter: * fd - Filehandle der D&D-Pipe * exts - Liste aus acht 4 Byte Extensionen die verstanden * werden. Diese Liste sollte nach bevorzugten Datentypen * sortiert sein. Sollten weniger als DD_NUMEXTS * Extensionen untersttzt werden, muž die Liste mit * Nullen (0) aufgefllt werden! * * Ausgabeparameter: * keine * * Returnwert: * >0: kein Fehler * -1: Fehler beim Schreiben in die Pipe */ short ddsexts(short fd, char *exts) { if (Fwrite(fd, DD_EXTSIZE, exts) != DD_EXTSIZE) { ddclose(fd); return(-1); } return(1); } /* * N„chsten Header vom Sender holen * * Eingabeparameter: * fd - Filehandle der Pipe (von ddopen()) * * Ausgabeparameters: * name - Zeiger auf Buffer fr Datenbeschreibung (min. DD_NAMEMAX!) * file - Zeiger auf Buffer fr Datendateiname (min. DD_NAMEMAX!) * whichext- Zeiger auf Buffer fr Extension (4 Bytes) * size - Zeiger auf Buffer fr Datengr”že (4 Bytes) * * Returnwert: * >0: kein Fehler * -1: Sender brach Drag&Drop ab * * On lit dans le pipe qui normalement est constitu‚ de: * 1 short: taille du header * 4 CHAR: type de donn‚e (extension) * 1 long: taille des donn‚es * STRING: description des donn‚es * STRING: nom du fichiers * soit au minimun 11 octets (cas ou les string sont r‚duites … \0) * les string sont limit‚ a 128 octets */ short ddrtry(short fd, char *name, char *file, char *whichext, long *size) { char buf[DD_NAMEMAX * 2]; short hdrlen, i, len; if (Fread(fd, 2L, &hdrlen) != 2L) return(-1); if (hdrlen < 9) /* il reste au minimum 11 - 2 = 9 octets a lire */ { /* sollte eigentlich nie passieren */ return(-1); /* erreur taille incorrecte */ } if (Fread(fd, 4L, whichext) != 4L) /* lecture de l'extension */ return(-1); if (Fread(fd, 4L, size) != 4L) /* lecture de la longueurs des donn‚es */ return(-1); hdrlen -= 8; /* on a lu 8 octets */ if (hdrlen > DD_NAMEMAX*2) i = DD_NAMEMAX*2; else i = hdrlen; len = i; if (Fread(fd, (long) i, buf) != (long) i) return(-1); hdrlen -= i; strncpy(name, buf, DD_NAMEMAX); i = (short) strlen(name) + 1; if (len - i > 0) strncpy(file, buf + i, DD_NAMEMAX); else file[0] = '\0'; /* weitere Bytes im Header in den Mll */ while (hdrlen > DD_NAMEMAX*2) { if (Fread(fd, DD_NAMEMAX*2, buf) != DD_NAMEMAX*2) return(-1); hdrlen -= DD_NAMEMAX*2; } if (hdrlen > 0) { if (Fread(fd, (long) hdrlen, buf) != (long) hdrlen) return(-1); } return(1); } /* * Sendet der Senderapplikation eine 1 Byte Antwort * * Eingabeparameter: * fd - Filehandle der Pipe (von ddopen()) * ack - Byte das gesendet werden soll (zB. DD_OK) * * Ausgabeparameter: * keine * * Returnwert: * >0: kein Fehler * -1: Fehler (die Pipe wird automatisch geschlossen!) */ short ddreply(short fd, char ack) { if (Fwrite(fd, 1L, &ack) != 1L) { ddclose(fd); return(-1); } return(1); }