home *** CD-ROM | disk | FTP | other *** search
- /*
- ** PGP5GUI - A GUI using Magic User Interface v3.8
- **
- ** Copyright 23-JUNE-1998 by Stefan Zakarias, All Rights Reserved.
- **
- ** This source code is released as FREEWARE - Use it for whatever you like,
- ** as long as NO financial reward is gained by you for such usage.
- **
- ** If you use any parts of the this source code for anything, give ME credit
- ** wherever credit is due, please ;-)
- */
-
- #include <exec/types.h>
- #include <exec/ports.h>
- #include <exec/io.h>
- #include <exec/memory.h>
- #include <devices/clipboard.h>
- #include <libraries/dosextens.h>
- #include <libraries/dos.h>
-
- #include <proto/muimaster.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- #include <string.h>
-
- #include "PGP5GUI.h"
-
- #define MAKE_ID(a,b,c,d) ((a<<24L) | (b<<16L) | (c<<8L) | d)
-
- #define ID_FORM MAKE_ID('F','O','R','M')
- #define ID_FTXT MAKE_ID('F','T','X','T')
- #define ID_CHRS MAKE_ID('C','H','R','S')
-
- /* prototypes */
- struct IOClipReq *CBOpen( ULONG );
- void CBClose(struct IOClipReq *);
- int CBWriteFTXT(struct IOClipReq *, char *);
- int CBQueryFTXT(struct IOClipReq *);
- UBYTE *CBReadCHRS(struct IOClipReq *);
- void CBReadDone(struct IOClipReq *);
-
- /* routines which are meant to be used internally by routines in cbio.c */
- int WriteLong(struct IOClipReq *, long *);
- int ReadLong(struct IOClipReq *, ULONG *);
- UBYTE *FillCBData(struct IOClipReq *, ULONG);
-
- extern char *warning_str;
- extern char *OK_str;
-
- /*
- ** Opens the clipboard.device. A clipboard unit number must be passed in
- ** as an argument. By default, the unit number should be 0.
- ** (currently valid unit numbers are 0-255, if we decide to go that way ;-)
- **
- ** Returns a pointer to an initialized IOClipReq structure, or a
- ** NULL pointer if the function fails.
- */
- struct IOClipReq *
- CBOpen(ULONG unit)
- {
- struct MsgPort *mp;
- struct IOStdReq *ior;
-
- if (mp = CreatePort(0L, 0L))
- {
- if (ior = (struct IOStdReq *) CreateExtIO(mp, sizeof(struct IOClipReq)))
- {
- if (!(OpenDevice("clipboard.device", unit, (struct IORequest *) ior, 0L)))
- {
- return ((struct IOClipReq *) ior);
- }
-
- DeleteExtIO((struct IORequest *) ior);
- }
-
- DeletePort(mp);
- }
-
- return (NULL);
- }
-
- /*
- ** Close the clipboard.device unit which was opened via CBOpen().
- */
- void
- CBClose(struct IOClipReq *ior)
- {
- struct MsgPort *mp;
-
- mp = ior->io_Message.mn_ReplyPort;
-
- CloseDevice((struct IORequest *) ior);
- DeleteExtIO((struct IORequest *) ior);
- DeletePort(mp);
- }
-
- /*
- ** Write a NULL terminated string of text to the clipboard.
- ** The string will be written in simple FTXT format.
- **
- ** Note that this function pads odd length strings automatically
- ** to conform to the IFF standard.
- **
- ** Returns TRUE if the write succeeded, else FALSE.
- */
- int
- CBWriteFTXT(struct IOClipReq *ior, char *string)
- {
-
- ULONG length, slen;
- BOOL odd;
- int success;
-
- slen = strlen(string);
- odd = (slen & 1); /* pad byte flag */
-
- length = (odd) ? slen + 1 : slen;
-
- /* initial set-up for Offset, Error, and ClipID */
- ior->io_Offset = 0;
- ior->io_Error = 0;
- ior->io_ClipID = 0;
-
-
- /* Create the IFF header information */
- WriteLong(ior, (long *) "FORM"); /* "FORM" */
- length += 12L; /* + "[size]FTXTCHRS" */
-
- WriteLong(ior, (long *) &length); /* total length */
- WriteLong(ior, (long *) "FTXT"); /* "FTXT" */
- WriteLong(ior, (long *) "CHRS"); /* "CHRS" */
- WriteLong(ior, (long *) &slen); /* string length */
-
- /* Write string */
- ior->io_Data = (STRPTR) string;
- ior->io_Length = slen;
- ior->io_Command = CMD_WRITE;
-
- DoIO((struct IORequest *) ior);
-
- /* Pad if needed */
- if (odd)
- {
- ior->io_Data = (STRPTR) "";
- ior->io_Length = 1L;
- DoIO((struct IORequest *) ior);
- }
-
- /* Tell the clipboard we are done writing */
- ior->io_Command = CMD_UPDATE;
-
- DoIO((struct IORequest *) ior);
-
- /* Check if io_Error was set by any of the preceding IO requests */
- success = ior->io_Error ? FALSE : TRUE;
-
- return (success);
- }
-
- int
- WriteLong(struct IOClipReq *ior, long *ldata)
- {
- ior->io_Data = (STRPTR) ldata;
- ior->io_Length = 4L;
- ior->io_Command = CMD_WRITE;
- DoIO((struct IORequest *) ior);
-
- if (ior->io_Actual == 4)
- {
- return (ior->io_Error ? FALSE : TRUE);
- }
-
- return (FALSE);
- }
-
- /*
- ** Check to see if the clipboard contains FTXT. If so,
- ** call CBReadCHRS() one or more times until all CHRS
- ** chunks have been read.
- **
- ** Returns TRUE if the clipboard contains an FTXT chunk, else FALSE.
- **
- ** NOTES
- ** If function returns TRUE, you must call either CBReadCHRS() until CBReadCHRS()
- ** returns FALSE, or call CBReadDone() to tell the clipboard.device that you are
- ** finished reading.
- */
- int
- CBQueryFTXT(ior)
- struct IOClipReq *ior;
- {
- ULONG cbuff[4];
-
- /* initial set-up for Offset, Error, and ClipID */
- ior->io_Offset = 0;
- ior->io_Error = 0;
- ior->io_ClipID = 0;
-
- /* Look for "FORM[size]FTXT" */
- ior->io_Command = CMD_READ;
- ior->io_Data = (STRPTR) cbuff;
- ior->io_Length = 12;
-
- DoIO((struct IORequest *) ior);
-
-
- /* Check to see if we have at least 12 bytes */
- if (ior->io_Actual == 12L)
- {
- /* Check to see if it starts with "FORM" */
- if (cbuff[0] == ID_FORM)
- {
- /* Check to see if its "FTXT" */
- if (cbuff[2] == ID_FTXT)
- return (TRUE);
- }
-
- /* It's not "FORM[size]FTXT", so tell clipboard we are done */
- }
-
- CBReadDone(ior);
-
- return (FALSE);
- }
-
- /*
- ** Reads and returns the text in the next CHRS chunk (if any) from the clipboard.
- ** Allocates memory to hold data in next CHRS chunk.
- **
- ** Returns a pointer to a UBYTE pointer, or a NULL indicating a failure
- ** (e.g., no memory, no more CHRS chunks, etc).
- **
- ** The calling function must free the returned buffer when done with the data by
- ** calling FreeVec().
- **
- ** This function strips NULL bytes, however, a full reader may wish to perform more
- ** complete checking to verify that the text conforms to the IFF standard
- ** (stripping data as required).
- */
- UBYTE *
- CBReadCHRS(struct IOClipReq *ior)
- {
- ULONG chunk, size;
- UBYTE *buf;
- int looking;
-
- /* Find next CHRS chunk */
- looking = TRUE;
- buf = NULL;
-
- while (looking)
- {
- looking = FALSE;
-
- if (ReadLong(ior, &chunk))
- {
- /* Is CHRS chunk ? */
- if (chunk == ID_CHRS)
- {
- /* Get size of chunk, and copy data */
- if (ReadLong(ior, &size))
- {
- if (size)
- buf = FillCBData(ior, size);
- }
- }
- /* If not, skip to next chunk */
- else
- {
- if (ReadLong(ior, &size))
- {
- looking = TRUE;
-
- if (size & 1)
- size++; /* if odd size, add pad byte */
-
- ior->io_Offset += size;
- }
- }
- }
- }
-
- if (buf == NULL)
- CBReadDone(ior); /* tell clipboard we are done */
-
- return (buf);
- }
-
- int
- ReadLong(struct IOClipReq *ior, ULONG *ldata)
- {
- ior->io_Command = CMD_READ;
- ior->io_Data = (STRPTR) ldata;
- ior->io_Length = 4L;
-
- DoIO((struct IORequest *) ior);
-
- if (ior->io_Actual == 4)
- {
- return (ior->io_Error ? FALSE : TRUE);
- }
-
- return (FALSE);
- }
-
-
- UBYTE *
- FillCBData(struct IOClipReq *ior, ULONG size)
- {
- register UBYTE *to, *from;
- register ULONG x;
-
- ULONG length;
- UBYTE *buf, *success;
-
- success = NULL;
-
- length = size;
-
- if (size & 1)
- length++; /* if odd size, read 1 more */
-
- if (buf = AllocVec(length + 1L, MEMF_PUBLIC|MEMF_CLEAR))
- {
- ior->io_Command = CMD_READ;
- ior->io_Data = (STRPTR) buf;
- ior->io_Length = length;
-
- to = buf;
-
- if (!(DoIO((struct IORequest *) ior)))
- {
- if (ior->io_Actual == length)
- {
- success = buf; /* everything succeeded */
-
- /* strip NULL bytes */
- for (x = 0, from = buf; x < size; x++)
- {
- if (*from)
- {
- *to = *from;
- to++;
- }
-
- from++;
- }
-
- *to = '\0'; /* Null terminate buffer */
- }
- }
- }
-
- if (!(success))
- FreeVec(buf);
-
- return (success);
- }
-
- /*
- ** Reads past end of clipboard file until io_Actual is equal to 0.
- ** This tells the clipboard we are done reading.
- */
- void
- CBReadDone(struct IOClipReq *ior)
- {
- char buffer[256];
-
- ior->io_Command = CMD_READ;
- ior->io_Data = (STRPTR) buffer;
- ior->io_Length = 254;
-
-
- /* falls through immediately if io_Actual == 0 */
- while (ior->io_Actual)
- {
- if (DoIO((struct IORequest *) ior))
- break;
- }
- }
-
- /*
- ** Read FTXT in the clipboard to file.
- ** Returns TRUE for no error, FALSE for error - couldn't open clipboard, no FTXT,
- ** or couldn't open temp. file.
- */
- BOOL
- ReadClipToFile(char *outname, struct ObjApp *App)
- {
- BPTR filehandle;
- BOOL ret = TRUE;
- ULONG fsize;
-
- struct IOClipReq *ior;
- UBYTE *buf;
-
- /* Open clipboard.device unit 0 */
- if (ior=CBOpen(0L))
- {
- /* Look for FTXT in clipboard */
- if (CBQueryFTXT(ior))
- {
- filehandle = Open(outname, MODE_NEWFILE);
-
- /* Did DOS give us the O.K. to read it? */
- if (filehandle)
- {
- /* Obtain a copy of the contents of each CHRS chunk */
- while (buf = CBReadCHRS(ior))
- {
- /* Get size of string to write */
- fsize = strlen(buf);
-
- /* Write file */
- Write(filehandle, buf, fsize);
-
- /* Free buffer allocated by CBReadCHRS() */
- FreeVec(buf);
- }
-
- /* Make sure clipboard knows we are finished with the clip */
- CBReadDone(ior);
-
- /* Close the file */
- Close(filehandle);
- }
- else
- {
- MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
- "Couldn't open temporary file for writing!\n");
- ret = FALSE;
- }
- }
- else
- {
- MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
- "No 'FTXT' in clipboard!\n");
- ret = FALSE;
- }
-
- /* Close the clipboard device */
- CBClose(ior);
- }
- else
- {
- MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
- "Open 'clipboard.device' failed!\n");
- ret = FALSE;
- }
-
- /* Return error flag: TRUE = OK, FALSE = Error */
- return(ret);
- }
-
- /*
- ** Write a file to the clipboard in FTXT format.
- ** Returns TRUE for no error, FALSE for error - couldn't open clipboard, couldn't
- ** open temp. file, or no memory could be allocated for transfer.
- */
- BOOL
- WriteFileToClip(char *inname, struct ObjApp *App)
- {
- struct IOClipReq *ior;
- ULONG fsize;
- char *string;
- BPTR filelock, filehandle;
-
- BOOL ret = TRUE;
-
- /* Quick-check to see if the file exists! */
- filelock = Lock(inname, ACCESS_READ);
-
- /* Did we get a lock on that file? */
- if (filelock)
- {
- /* File was found... We can (have to?) unlock it now */
- UnLock(filelock);
-
- /* Open the file for our use */
- filehandle = Open(inname, MODE_OLDFILE);
-
- /* Did DOS give us the O.K. to read it? */
- if (filehandle)
- {
- /* DOS says it's OK to use! Get size of the file */
- Seek(filehandle, 0, OFFSET_END);
-
- /* Reset the file 'cursor' */
- fsize = Seek(filehandle, 0, OFFSET_BEGINNING);
-
- /* Open clipboard.device unit 0 */
- if (ior = CBOpen(0L))
- {
- /* Get some memory for the incoming file */
- string = AllocVec(fsize+1, MEMF_PUBLIC|MEMF_CLEAR);
-
- /* Did we get some memory allocated for us? */
- if (string)
- {
- /* Read the file into the (string) buffer */
- Read(filehandle, string, fsize);
-
- /* Write the string to the clipboard */
- if (!(CBWriteFTXT(ior,string)))
- {
- MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
- "Error writing to clipboard!\n");
- ret = FALSE;
- }
-
- /* Done with string... Free memory */
- FreeVec(string);
- }
- else
- {
- MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
- "Read 'AllocVec()' failed!\n");
- ret = FALSE;
- }
-
- /* Close the clipboard device */
- CBClose(ior);
- }
- else
- {
- MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
- "Open 'clipboard.device' failed!\n");
- ret = FALSE;
- }
-
- /* Close the file */
- Close(filehandle);
- }
- }
- else
- {
- MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
- "Couldn't lock temporary file for reading!\n");
- ret = FALSE;
- }
-
- /* Return error flag: TRUE = OK, FALSE = Error */
- return(ret);
- }
-