home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 426.lha / ClipFile_v1.02 / src / cbio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-07  |  6.8 KB  |  306 lines

  1. /* cbio.c
  2.  * Clipboard routines.
  3.  * Copyright (C) 1990 Commodore-Amiga, Inc.
  4.  * Modified extensively by David N. Junod
  5.  *
  6.  */
  7.  
  8. #include <exec/types.h>
  9. #include <exec/memory.h>
  10. #include <exec/ports.h>
  11. #include <exec/io.h>
  12. #include <devices/clipboard.h>
  13. #include <clib/macros.h>
  14. #include <clib/alib_protos.h>
  15. #include <clib/exec_protos.h>
  16. #include <string.h>
  17. #include "cf.h"
  18.  
  19. /* little macro to force a number to even */
  20. #define    FEVEN(a) (((a)&1)?(++(a)):(a))
  21.  
  22. extern ULONG SysBase, DOSBase;
  23.  
  24. struct IOClipReq *clipIO;
  25. struct MsgPort *clip_port;
  26.  
  27. LONG CBOpen (LONG unit)
  28. {
  29.     LONG retval = -1L;
  30.  
  31.     /* Create a message port for clip messages */
  32.     if (clip_port = CreatePort (0L, 0L))
  33.     {
  34.     /* Create IO request for clipboard communications */
  35.     if (clipIO = (struct IOClipReq *)
  36.           CreateExtIO (clip_port, sizeof (struct IOClipReq)))
  37.     {
  38.         /* Open the clipboard device */
  39.         if ((retval = OpenDevice ("clipboard.device", unit, clipIO, 0)) == 0L)
  40.         {
  41.         /* Return success */
  42.         return (retval);
  43.         }
  44.  
  45.         /* Free the clipboard IO request */
  46.         DeleteExtIO (clipIO);
  47.         clipIO = NULL;
  48.     }
  49.  
  50.     /* Delete the clipboard message port */
  51.     DeletePort (clip_port);
  52.     clip_port = NULL;
  53.     }
  54.  
  55.     /* return failure */
  56.     return (retval);
  57. }
  58.  
  59. VOID CBClose ()
  60. {
  61.     /* Close the clipboard device */
  62.     CloseDevice (clipIO);
  63.  
  64.     /* Free the clipboard IO request */
  65.     DeleteExtIO (clipIO);
  66.     clipIO = NULL;
  67.  
  68.     /* Delete the clipboard message port */
  69.     DeletePort (clip_port);
  70.     clip_port = NULL;
  71. }
  72.  
  73. LONG CBWrite (struct Buffer * buff)
  74. {
  75.     if (buff->b_Type == 0)
  76.     return (CBWriteFTXT ((STRPTR) buff->b_Buff));
  77.     else
  78.     return (CBWriteA (buff->b_Buff, (buff->b_Size - sizeof (struct Buffer))));
  79. }
  80.  
  81. LONG CBWriteFTXT (STRPTR string)
  82. {
  83.     LONG length, slen = strlen (string);
  84.     BOOL odd = (slen & 1);    /* pad byte flag */
  85.     LONG error = 0L;
  86.  
  87.     /* Reset the clip id */
  88.     clipIO->io_ClipID = 0;
  89.  
  90.     length = (odd) ? slen + 1 : slen;
  91.     clipIO->io_Offset = 0;
  92.     error = writeLong ((LONG *) "FORM");/* "FORM" */
  93.  
  94.     length += 12;
  95.     error = writeLong (&length);    /* #  */
  96.     error = writeLong ((LONG *) "FTXT");/* "FTXT" for example */
  97.     error = writeLong ((LONG *) "CHRS");/* "CHRS" for example */
  98.     error = writeLong (&slen);        /* #  (length of string) */
  99.  
  100.     clipIO->io_Command = CMD_WRITE;
  101.     clipIO->io_Error = 0;
  102.     clipIO->io_Data = (char *) string;
  103.     clipIO->io_Length = slen;        /* length of string */
  104.     error = (LONG) DoIO (clipIO);    /* text string */
  105.  
  106.     /* Write the pad byte */
  107.     if (odd)
  108.     {
  109.     clipIO->io_Command = CMD_WRITE;
  110.     clipIO->io_Error = 0;
  111.     clipIO->io_Data = NULL;
  112.     clipIO->io_Length = 1;
  113.     error = (LONG) DoIO (clipIO);
  114.     }
  115.  
  116.     /* Indicate that we're done reading from the clipboard */
  117.     clipIO->io_Command = CMD_UPDATE;
  118.     clipIO->io_Error = 0;
  119.     error = (LONG) DoIO (clipIO);
  120.  
  121.     return (error);
  122. }
  123.  
  124. LONG CBWriteA (STRPTR stream, LONG length)
  125. {
  126.     /* Write the block to the clipboard */
  127.     clipIO->io_Command = CMD_WRITE;
  128.     clipIO->io_Error = 0;
  129.     clipIO->io_Data = stream;
  130.     clipIO->io_Length = length;
  131.     clipIO->io_Offset = 0;
  132.     clipIO->io_ClipID = 0;
  133.     DoIO (clipIO);
  134.  
  135.     /* Indicate that we're done reading from the clipboard */
  136.     clipIO->io_Command = CMD_UPDATE;
  137.     clipIO->io_Error = 0;
  138.     return ( (LONG) DoIO (clipIO) );
  139. }
  140.  
  141. VOID CBClear (VOID)
  142. {
  143.     CBWriteA (NULL, 0L);
  144. }
  145.  
  146. STRPTR PrintID (LONG id, STRPTR buff)
  147. {
  148.     UBYTE *c;
  149.     WORD i, j;
  150.  
  151.     /* Initialize the character pointer */
  152.     c = (UBYTE *) &id;
  153.  
  154.     /* Build up the little buffer */
  155.     for (i = 4, j = 0; i--; c++)
  156.     buff[j++] = *c;
  157.  
  158.     /* Mark the end of the ID string */
  159.     buff[j]=0;
  160.  
  161.     return (buff);
  162. }
  163.  
  164. struct Buffer *CBRead (BOOL cook)
  165. {
  166.     struct Buffer *buff = NULL;
  167.     LONG cbuff[5] = {NULL};
  168.     LONG buff_type = 0;
  169.     LONG length = 0L;
  170.     LONG msize;
  171.  
  172.     /* Read clipboard header */
  173.     clipIO->io_Command = CMD_READ;
  174.     clipIO->io_Error = 0;
  175.     clipIO->io_ClipID = 0;
  176.     clipIO->io_Offset = 0;
  177.     clipIO->io_Data = (char *) cbuff;
  178.     clipIO->io_Length = 20;
  179.     DoIO (clipIO);
  180.  
  181.     /* Make sure something was read */
  182.     if ((clipIO->io_Actual) > 0L)
  183.     {
  184.     /* Make sure it was IFF FORM */
  185.     if (cbuff[0] == ID_FORM)
  186.     {
  187.         /* If we're cooking, see if it was an FTXT form */
  188.         if (cook && (cbuff[2] == ID_FTXT))
  189.         {
  190.         LONG offset = clipIO->io_Offset;
  191.         LONG maxoff = cbuff[1] + 8L;
  192.         LONG chunk = cbuff[3];
  193.         LONG clen = cbuff[4];
  194.  
  195.         if (chunk != ID_CHRS)
  196.         {
  197.             /* Back up to the beginning of the first chunk */
  198.             offset -= 8L;
  199.  
  200.             /* Try to find a CHRS chunk */
  201.             while ((offset < maxoff) && (chunk != ID_CHRS))
  202.             {
  203.             /* Seek to the next chunk */
  204.             offset += ( FEVEN(clen) + 8L );
  205.  
  206.             /* Read in the chunk type and length */
  207.             clipIO->io_Offset = offset;
  208.             DoIO (clipIO);
  209.  
  210.             /* Get the information we're interested in */
  211.             chunk = cbuff[0];
  212.             clen = cbuff[1];
  213.             }
  214.  
  215.             /* Jump past the chunk type and length */
  216.             offset += 8L;
  217.         }
  218.  
  219.         /* See if we can handle it */
  220.         if (offset < maxoff)
  221.         {
  222.             /* Align at the beginning of the CHRS chunk */
  223.             clipIO->io_Offset = offset;
  224.  
  225.             /* Set the length to read */
  226.             length = clen;
  227.         }
  228.         }
  229.         else
  230.         {
  231.         /*
  232.          * The entire length of the clipboard contents, plus the
  233.          * ID_FORM and first chunk
  234.          */
  235.         length = cbuff[1] + 8L;
  236.  
  237.         /* Buffer type is main IFF chunk type */
  238.         buff_type = cbuff[2];
  239.  
  240.         /* Realign at the beginning of the clip */
  241.         clipIO->io_Offset = 0;
  242.         }
  243.  
  244.         /* Make sure we have something to return... */
  245.         if (length > 0L)
  246.         {
  247.         /* Compute the length of our memory allocation */
  248.         msize = sizeof (struct Buffer) + length;
  249.  
  250.         /* Allocate our buffer */
  251.         if (buff = (struct Buffer *) AllocMem (msize, MEMF_CLEAR))
  252.         {
  253.             /* set up the buffer variables */
  254.             buff->b_Size = msize;
  255.             buff->b_Type = buff_type;
  256.             buff->b_ClipID = clipIO->io_ClipID;
  257.  
  258.             /* Point the buffer at the right place */
  259.             buff->b_Buff = (VOID *) ((buff) + 1);
  260.  
  261.             /* read in the text string */
  262.             clipIO->io_Data = (char *) buff->b_Buff;
  263.             clipIO->io_Length = length;
  264.             DoIO (clipIO);
  265.         }
  266.         }
  267.     }
  268.  
  269.     /* indicate that we're done reading */
  270.     clipIO->io_Offset = 0x7FFFFFF0;
  271.     clipIO->io_Length = 1;
  272.     clipIO->io_Data = NULL;
  273.     DoIO (clipIO);
  274.     }
  275.  
  276.     return (buff);
  277. }
  278.  
  279. LONG writeLong (LONG * ldata)
  280. {
  281.     clipIO->io_Command = CMD_WRITE;
  282.     clipIO->io_Error = 0;
  283.     clipIO->io_Data = (char *) ldata;
  284.     clipIO->io_Length = 4L;
  285.     return ( (LONG) DoIO (clipIO) );
  286. }
  287.  
  288. VOID freebuffer (struct Buffer * buff)
  289. {
  290.     /* Make sure that buffer is a pointer, not an error */
  291.     if ((LONG) buff > 0L)
  292.     {
  293.     /* Free the author buffer, if we allocated it */
  294.     if (buff->b_ASize > 0L)
  295.         FreeMem ((APTR) buff->b_Author, buff->b_ASize);
  296.  
  297.     /* Free the project buffer, if we allocated it */
  298.     if (buff->b_PSize > 0L)
  299.         FreeMem ((APTR) buff->b_Project, buff->b_PSize);
  300.  
  301.     /* Free the entire buffer */
  302.     FreeMem ((APTR) buff, buff->b_Size);
  303.     }
  304. }
  305.  
  306.