home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #12 / Amiga Plus CD - 2002 - No. 12.iso / AmigaOS / Aplus_Dev / AP-Website / download / pgp / pgp5gui-174b.lha / PGP5GUI-Src.lha / PGP5GUI-Src / cbio.c next >
Encoding:
C/C++ Source or Header  |  1998-06-23  |  11.6 KB  |  546 lines

  1. /*
  2. ** PGP5GUI - A GUI using Magic User Interface v3.8
  3. **
  4. ** Copyright 23-JUNE-1998 by Stefan Zakarias, All Rights Reserved.
  5. **
  6. ** This source code is released as FREEWARE - Use it for whatever you like,
  7. ** as long as NO financial reward is gained by you for such usage.
  8. **
  9. ** If you use any parts of the this source code for anything, give ME credit
  10. ** wherever credit is due, please ;-)
  11. */
  12.  
  13. #include <exec/types.h>
  14. #include <exec/ports.h>
  15. #include <exec/io.h>
  16. #include <exec/memory.h>
  17. #include <devices/clipboard.h>
  18. #include <libraries/dosextens.h>
  19. #include <libraries/dos.h>
  20.  
  21. #include <proto/muimaster.h>
  22. #include <proto/exec.h>
  23. #include <proto/dos.h>
  24.  
  25. #include <string.h>
  26.  
  27. #include "PGP5GUI.h"
  28.  
  29. #define MAKE_ID(a,b,c,d) ((a<<24L) | (b<<16L) | (c<<8L) | d)
  30.  
  31. #define ID_FORM MAKE_ID('F','O','R','M')
  32. #define ID_FTXT MAKE_ID('F','T','X','T')
  33. #define ID_CHRS MAKE_ID('C','H','R','S')
  34.  
  35. /* prototypes */
  36. struct IOClipReq *CBOpen( ULONG );
  37. void CBClose(struct IOClipReq *);
  38. int CBWriteFTXT(struct IOClipReq *, char *);
  39. int CBQueryFTXT(struct IOClipReq *);
  40. UBYTE *CBReadCHRS(struct IOClipReq *);
  41. void CBReadDone(struct IOClipReq *);
  42.  
  43. /* routines which are meant to be used internally by routines in cbio.c */
  44. int WriteLong(struct IOClipReq *, long *);
  45. int ReadLong(struct IOClipReq *, ULONG *);
  46. UBYTE *FillCBData(struct IOClipReq *, ULONG);
  47.  
  48. extern char *warning_str;
  49. extern char *OK_str;
  50.  
  51. /*
  52. ** Opens the clipboard.device.  A clipboard unit number must be passed in
  53. ** as an argument.  By default, the unit number should be 0.
  54. ** (currently valid unit numbers are 0-255, if we decide to go that way ;-)
  55. **
  56. ** Returns a pointer to an initialized IOClipReq structure, or a
  57. ** NULL pointer if the function fails.
  58. */
  59. struct IOClipReq *
  60. CBOpen(ULONG unit)
  61. {
  62.     struct MsgPort *mp;
  63.     struct IOStdReq *ior;
  64.  
  65.     if (mp = CreatePort(0L, 0L))
  66.     {
  67.         if (ior = (struct IOStdReq *) CreateExtIO(mp, sizeof(struct IOClipReq)))
  68.         {
  69.             if (!(OpenDevice("clipboard.device", unit, (struct IORequest *) ior, 0L)))
  70.             {
  71.                 return ((struct IOClipReq *) ior);
  72.             }
  73.  
  74.             DeleteExtIO((struct IORequest *) ior);
  75.         }
  76.  
  77.         DeletePort(mp);
  78.     }
  79.  
  80.     return (NULL);
  81. }
  82.  
  83. /*
  84. ** Close the clipboard.device unit which was opened via CBOpen().
  85. */
  86. void
  87. CBClose(struct IOClipReq *ior)
  88. {
  89.     struct MsgPort *mp;
  90.  
  91.     mp = ior->io_Message.mn_ReplyPort;
  92.  
  93.     CloseDevice((struct IORequest *) ior);
  94.     DeleteExtIO((struct IORequest *) ior);
  95.     DeletePort(mp);
  96. }
  97.  
  98. /*
  99. ** Write a NULL terminated string of text to the clipboard.
  100. ** The string will be written in simple FTXT format.
  101. **
  102. ** Note that this function pads odd length strings automatically
  103. ** to conform to the IFF standard.
  104. **
  105. ** Returns TRUE if the write succeeded, else FALSE.
  106. */
  107. int
  108. CBWriteFTXT(struct IOClipReq *ior, char *string)
  109. {
  110.  
  111.     ULONG length, slen;
  112.     BOOL odd;
  113.     int success;
  114.  
  115.     slen = strlen(string);
  116.     odd = (slen & 1);            /* pad byte flag */
  117.  
  118.     length = (odd) ? slen + 1 : slen;
  119.  
  120.     /* initial set-up for Offset, Error, and ClipID */
  121.     ior->io_Offset = 0;
  122.     ior->io_Error = 0;
  123.     ior->io_ClipID = 0;
  124.  
  125.  
  126.     /* Create the IFF header information */
  127.     WriteLong(ior, (long *) "FORM");    /* "FORM" */
  128.     length += 12L;                        /* + "[size]FTXTCHRS" */
  129.  
  130.     WriteLong(ior, (long *) &length);    /* total length */
  131.     WriteLong(ior, (long *) "FTXT");    /* "FTXT" */
  132.     WriteLong(ior, (long *) "CHRS");    /* "CHRS" */
  133.     WriteLong(ior, (long *) &slen);        /* string length */
  134.  
  135.     /* Write string */
  136.     ior->io_Data = (STRPTR) string;
  137.     ior->io_Length = slen;
  138.     ior->io_Command = CMD_WRITE;
  139.  
  140.     DoIO((struct IORequest *) ior);
  141.  
  142.     /* Pad if needed */
  143.     if (odd)
  144.     {
  145.         ior->io_Data = (STRPTR) "";
  146.         ior->io_Length = 1L;
  147.         DoIO((struct IORequest *) ior);
  148.     }
  149.  
  150.     /* Tell the clipboard we are done writing */
  151.     ior->io_Command = CMD_UPDATE;
  152.  
  153.     DoIO((struct IORequest *) ior);
  154.  
  155.     /* Check if io_Error was set by any of the preceding IO requests */
  156.     success = ior->io_Error ? FALSE : TRUE;
  157.  
  158.     return (success);
  159. }
  160.  
  161. int
  162. WriteLong(struct IOClipReq *ior, long *ldata)
  163. {
  164.     ior->io_Data = (STRPTR) ldata;
  165.     ior->io_Length = 4L;
  166.     ior->io_Command = CMD_WRITE;
  167.     DoIO((struct IORequest *) ior);
  168.  
  169.     if (ior->io_Actual == 4)
  170.     {
  171.         return (ior->io_Error ? FALSE : TRUE);
  172.     }
  173.  
  174.     return (FALSE);
  175. }
  176.  
  177. /*
  178. ** Check to see if the clipboard contains FTXT.  If so,
  179. ** call CBReadCHRS() one or more times until all CHRS
  180. ** chunks have been read.
  181. **
  182. ** Returns TRUE if the clipboard contains an FTXT chunk, else FALSE.
  183. **
  184. ** NOTES
  185. ** If function returns TRUE, you must call either CBReadCHRS() until CBReadCHRS()
  186. ** returns FALSE, or call CBReadDone() to tell the clipboard.device that you are 
  187. ** finished reading.
  188. */
  189. int
  190. CBQueryFTXT(ior)
  191. struct IOClipReq *ior;
  192. {
  193.     ULONG cbuff[4];
  194.  
  195.     /* initial set-up for Offset, Error, and ClipID */
  196.     ior->io_Offset = 0;
  197.     ior->io_Error = 0;
  198.     ior->io_ClipID = 0;
  199.  
  200.     /* Look for "FORM[size]FTXT" */
  201.     ior->io_Command = CMD_READ;
  202.     ior->io_Data = (STRPTR) cbuff;
  203.     ior->io_Length = 12;
  204.  
  205.     DoIO((struct IORequest *) ior);
  206.  
  207.  
  208.     /* Check to see if we have at least 12 bytes */
  209.     if (ior->io_Actual == 12L)
  210.     {
  211.         /* Check to see if it starts with "FORM" */
  212.         if (cbuff[0] == ID_FORM)
  213.         {
  214.             /* Check to see if its "FTXT" */
  215.             if (cbuff[2] == ID_FTXT)
  216.                 return (TRUE);
  217.         }
  218.  
  219.         /* It's not "FORM[size]FTXT", so tell clipboard we are done */
  220.     }
  221.  
  222.     CBReadDone(ior);
  223.  
  224.     return (FALSE);
  225. }
  226.  
  227. /*
  228. ** Reads and returns the text in the next CHRS chunk (if any) from the clipboard.
  229. ** Allocates memory to hold data in next CHRS chunk.
  230. **
  231. ** Returns a pointer to a UBYTE pointer, or a NULL indicating a failure
  232. ** (e.g., no memory, no more CHRS chunks, etc).
  233. **
  234. ** The calling function must free the returned buffer when done with the data by
  235. ** calling FreeVec().
  236. **
  237. ** This function strips NULL bytes, however, a full reader may wish to perform more
  238. ** complete checking to verify that the text conforms to the IFF standard
  239. ** (stripping data as required).
  240. */
  241. UBYTE *
  242. CBReadCHRS(struct IOClipReq *ior)
  243. {
  244.     ULONG chunk, size;
  245.     UBYTE *buf;
  246.     int looking;
  247.  
  248.     /* Find next CHRS chunk */
  249.     looking = TRUE;
  250.     buf = NULL;
  251.  
  252.     while (looking)
  253.     {
  254.         looking = FALSE;
  255.  
  256.         if (ReadLong(ior, &chunk))
  257.         {
  258.             /* Is CHRS chunk ? */
  259.             if (chunk == ID_CHRS)
  260.             {
  261.                 /* Get size of chunk, and copy data */
  262.                 if (ReadLong(ior, &size))
  263.                 {
  264.                     if (size)
  265.                         buf = FillCBData(ior, size);
  266.                 }
  267.             }
  268.             /* If not, skip to next chunk */
  269.             else
  270.             {
  271.                 if (ReadLong(ior, &size))
  272.                 {
  273.                     looking = TRUE;
  274.  
  275.                     if (size & 1)
  276.                         size++;    /* if odd size, add pad byte */
  277.  
  278.                     ior->io_Offset += size;
  279.                 }
  280.             }
  281.         }
  282.     }
  283.  
  284.     if (buf == NULL)
  285.         CBReadDone(ior);        /* tell clipboard we are done */
  286.  
  287.     return (buf);
  288. }
  289.  
  290. int
  291. ReadLong(struct IOClipReq *ior, ULONG *ldata)
  292. {
  293.     ior->io_Command = CMD_READ;
  294.     ior->io_Data = (STRPTR) ldata;
  295.     ior->io_Length = 4L;
  296.  
  297.     DoIO((struct IORequest *) ior);
  298.  
  299.     if (ior->io_Actual == 4)
  300.     {
  301.         return (ior->io_Error ? FALSE : TRUE);
  302.     }
  303.  
  304.     return (FALSE);
  305. }
  306.  
  307.  
  308. UBYTE *
  309. FillCBData(struct IOClipReq *ior, ULONG size)
  310. {
  311.     register UBYTE *to, *from;
  312.     register ULONG x;
  313.  
  314.     ULONG length;
  315.     UBYTE *buf, *success;
  316.  
  317.     success = NULL;
  318.  
  319.     length = size;
  320.  
  321.     if (size & 1)
  322.         length++;                /* if odd size, read 1 more */
  323.  
  324.     if (buf = AllocVec(length + 1L, MEMF_PUBLIC|MEMF_CLEAR))
  325.     {
  326.         ior->io_Command = CMD_READ;
  327.         ior->io_Data = (STRPTR) buf;
  328.         ior->io_Length = length;
  329.  
  330.         to = buf;
  331.  
  332.         if (!(DoIO((struct IORequest *) ior)))
  333.         {
  334.             if (ior->io_Actual == length)
  335.             {
  336.                 success = buf;    /* everything succeeded */
  337.  
  338.                 /* strip NULL bytes */
  339.                 for (x = 0, from = buf; x < size; x++)
  340.                 {
  341.                     if (*from)
  342.                     {
  343.                         *to = *from;
  344.                         to++;
  345.                     }
  346.  
  347.                     from++;
  348.                 }
  349.  
  350.                 *to = '\0';        /* Null terminate buffer */
  351.             }
  352.         }
  353.     }
  354.  
  355.     if (!(success))
  356.         FreeVec(buf);
  357.  
  358.     return (success);
  359. }
  360.  
  361. /*
  362. ** Reads past end of clipboard file until io_Actual is equal to 0.
  363. ** This tells the clipboard we are done reading.
  364. */
  365. void
  366. CBReadDone(struct IOClipReq *ior)
  367. {
  368.     char buffer[256];
  369.  
  370.     ior->io_Command = CMD_READ;
  371.     ior->io_Data = (STRPTR) buffer;
  372.     ior->io_Length = 254;
  373.  
  374.  
  375.     /* falls through immediately if io_Actual == 0 */
  376.     while (ior->io_Actual)
  377.     {
  378.         if (DoIO((struct IORequest *) ior))
  379.             break;
  380.     }
  381. }
  382.  
  383. /*
  384. ** Read FTXT in the clipboard to file.
  385. ** Returns TRUE for no error, FALSE for error - couldn't open clipboard, no FTXT,
  386. ** or couldn't open temp. file.
  387. */
  388. BOOL
  389. ReadClipToFile(char *outname, struct ObjApp *App)
  390. {
  391.     BPTR filehandle;
  392.     BOOL ret = TRUE;
  393.     ULONG fsize;
  394.  
  395.     struct IOClipReq *ior;
  396.     UBYTE *buf;
  397.  
  398.     /* Open clipboard.device unit 0 */
  399.     if (ior=CBOpen(0L))
  400.     {
  401.         /* Look for FTXT in clipboard */
  402.         if (CBQueryFTXT(ior))
  403.         {
  404.             filehandle = Open(outname, MODE_NEWFILE);
  405.  
  406.             /* Did DOS give us the O.K. to read it? */
  407.             if (filehandle)
  408.             {
  409.                 /* Obtain a copy of the contents of each CHRS chunk */
  410.                 while (buf = CBReadCHRS(ior))
  411.                 {
  412.                     /* Get size of string to write */
  413.                     fsize = strlen(buf);
  414.  
  415.                     /* Write file */
  416.                     Write(filehandle, buf, fsize);
  417.  
  418.                     /* Free buffer allocated by CBReadCHRS() */
  419.                     FreeVec(buf);
  420.                 }
  421.  
  422.                 /* Make sure clipboard knows we are finished with the clip */
  423.                 CBReadDone(ior);
  424.  
  425.                 /* Close the file */
  426.                 Close(filehandle);
  427.             }
  428.             else
  429.             {
  430.                 MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
  431.                             "Couldn't open temporary file for writing!\n");
  432.                 ret = FALSE;
  433.             }
  434.         }
  435.         else
  436.         {
  437.             MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
  438.                         "No 'FTXT' in clipboard!\n");
  439.             ret = FALSE;
  440.         }
  441.  
  442.         /* Close the clipboard device */
  443.         CBClose(ior);
  444.     }
  445.     else
  446.     {
  447.         MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
  448.                     "Open 'clipboard.device' failed!\n");
  449.         ret = FALSE;
  450.     }
  451.  
  452.     /* Return error flag: TRUE = OK, FALSE = Error */
  453.     return(ret);
  454. }
  455.  
  456. /*
  457. ** Write a file to the clipboard in FTXT format.
  458. ** Returns TRUE for no error, FALSE for error - couldn't open clipboard, couldn't
  459. ** open temp. file, or no memory could be allocated for transfer.
  460. */
  461. BOOL
  462. WriteFileToClip(char *inname, struct ObjApp *App)
  463. {
  464.     struct IOClipReq *ior;
  465.     ULONG fsize;
  466.     char *string;
  467.     BPTR filelock, filehandle;
  468.  
  469.     BOOL ret = TRUE;
  470.  
  471.     /* Quick-check to see if the file exists! */
  472.     filelock = Lock(inname, ACCESS_READ);
  473.  
  474.     /* Did we get a lock on that file? */
  475.     if (filelock)
  476.     {
  477.         /* File was found...  We can (have to?) unlock it now */
  478.         UnLock(filelock);
  479.  
  480.         /* Open the file for our use */
  481.         filehandle = Open(inname, MODE_OLDFILE);
  482.  
  483.         /* Did DOS give us the O.K. to read it? */
  484.         if (filehandle)
  485.         {
  486.             /* DOS says it's OK to use!    Get size of the file */
  487.             Seek(filehandle, 0, OFFSET_END);
  488.  
  489.             /* Reset the file 'cursor' */
  490.             fsize = Seek(filehandle, 0, OFFSET_BEGINNING);
  491.  
  492.             /* Open clipboard.device unit 0 */
  493.             if (ior = CBOpen(0L))
  494.             {
  495.                 /* Get some memory for the incoming file */
  496.                 string = AllocVec(fsize+1, MEMF_PUBLIC|MEMF_CLEAR);
  497.  
  498.                 /* Did we get some memory allocated for us? */
  499.                 if (string)
  500.                 {
  501.                     /* Read the file into the (string) buffer */
  502.                     Read(filehandle, string, fsize);
  503.  
  504.                     /* Write the string to the clipboard */
  505.                     if (!(CBWriteFTXT(ior,string)))
  506.                     {
  507.                         MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
  508.                                     "Error writing to clipboard!\n");
  509.                         ret = FALSE;
  510.                     }
  511.  
  512.                     /* Done with string...  Free memory */
  513.                     FreeVec(string);
  514.                 }
  515.                 else
  516.                 {
  517.                     MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
  518.                                 "Read 'AllocVec()' failed!\n");
  519.                     ret = FALSE;
  520.                 }
  521.  
  522.                 /* Close the clipboard device */
  523.                 CBClose(ior);
  524.             }
  525.             else
  526.             {
  527.                 MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
  528.                             "Open 'clipboard.device' failed!\n");
  529.                 ret = FALSE;
  530.             }
  531.  
  532.             /* Close the file */
  533.             Close(filehandle);
  534.         }
  535.     }
  536.     else
  537.     {
  538.         MUI_Request(App->App, App->WI_Main, 0, warning_str, OK_str,
  539.                     "Couldn't lock temporary file for reading!\n");
  540.         ret = FALSE;
  541.     }
  542.  
  543.     /* Return error flag: TRUE = OK, FALSE = Error */
  544.     return(ret);
  545. }
  546.