home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / wp_dtp / xdme1821.lha / XDME / clipboard.c < prev    next >
C/C++ Source or Header  |  1993-02-04  |  11KB  |  544 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     clipboard.c
  5.  
  6.     DESCRIPTION
  7.     Provide standard clipboard.device interface functions like Open,
  8.     Close, Read, Write, etc.
  9.  
  10.     This is typed from "Amiga ROM Kernel Reference Manual: Devices"
  11.     Page 50 and following.
  12.  
  13.     NOTES
  14.     These functions are usefull for writing and reading simple FTXT.
  15.     Writing and reading complex FTXT, ILBM, etc. requires more work.
  16.     Under 2.0 it is highly recommended that you use iffparse.library.
  17.  
  18.     BUGS
  19.  
  20.     TODO
  21.  
  22.     EXAMPLES
  23.  
  24.     SEE ALSO
  25.  
  26.     INDEX
  27.  
  28.     HISTORY
  29.     29. May 1992    ada created
  30.  
  31. ******************************************************************************/
  32.  
  33. /* Includes */
  34. #include <exec/types.h>
  35. #include <exec/ports.h>
  36. #include <exec/io.h>
  37. #include <exec/memory.h>
  38. #include <devices/clipboard.h>
  39. #include "clipboard.h"
  40. #include <clib/exec_protos.h>
  41. #include <clib/alib_protos.h>
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include <string.h>
  45.  
  46. /* Globale Variable */
  47.  
  48. /* Interne Defines & Strukturen */
  49. /*#define DEBUG*/
  50.  
  51. /* Interne Variable */
  52.  
  53. /* Interne Prototypes */
  54. static int          ReadLong     (struct IOClipReq *, ULONG *);
  55. static struct cbbuf * FillCBData (struct IOClipReq *, ULONG);
  56.  
  57.  
  58. /*****************************************************************************
  59.  
  60.     NAME
  61.     CBOpen - Open the clipboard.device
  62.  
  63.     PARAMETER
  64.     ULONG unit;
  65.  
  66.     RESULT
  67.  
  68.     RETURN
  69.     struct IOClipReq * ior;     Initialized IOClipReq-structure or NULL
  70.  
  71.     DESCRIPTION
  72.     Opens the clipboard.device. A clipboard unit number must be passed in
  73.     as an argument. By default, the unit number should be 0 (currently
  74.     valid unit numbers are 0-255).
  75.  
  76.     NOTES
  77.  
  78.     BUGS
  79.  
  80.     EXAMPLES
  81.  
  82.     SEE ALSO
  83.  
  84.     INTERNALS
  85.  
  86.     HISTORY
  87.     29. May 1992    ada created
  88.  
  89. ******************************************************************************/
  90.  
  91. struct IOClipReq * CBOpen (ULONG unit)
  92. {
  93.     struct MsgPort * mp;
  94.     struct IOStdReq * ior;
  95.  
  96.     if (mp = CreatePort (NULL, NULL)) {
  97.     if (ior = (struct IOStdReq *)CreateExtIO (mp,
  98.         sizeof (struct IOClipReq))) {
  99.         if (!(OpenDevice ((STRPTR)"clipboard.device", unit,
  100.             (struct IORequest *)ior, NULL))) {
  101. #ifdef DEBUG
  102.     printf ("Open of clipboard.device unit %d successful\n", unit);
  103. #endif
  104.         return ((struct IOClipReq *)ior);
  105.         }
  106.     }
  107.     }
  108.  
  109. #ifdef DEBUG
  110.     printf ("No clipboard.device unit %d\n", unit);
  111. #endif
  112.  
  113.     return (NULL);
  114. } /* CBOpen */
  115.  
  116.  
  117. /*****************************************************************************
  118.  
  119.     NAME
  120.     CBClose - Close the clipboard.device
  121.  
  122.     PARAMETER
  123.     struct IOClipReq * ior;
  124.  
  125.     RESULT
  126.  
  127.     RETURN
  128.     void
  129.  
  130.     DESCRIPTION
  131.     Close the clipboard.device unit which was opened via CBOpen().
  132.  
  133.     NOTES
  134.  
  135.     BUGS
  136.  
  137.     EXAMPLES
  138.  
  139.     SEE ALSO
  140.  
  141.     INTERNALS
  142.  
  143.     HISTORY
  144.     29. May 1992    ada created
  145.  
  146. ******************************************************************************/
  147.  
  148. void CBClose (struct IOClipReq * ior)
  149. {
  150.     struct MsgPort * mp;
  151.  
  152.     mp = ior->io_Message.mn_ReplyPort;
  153.  
  154.     CloseDevice ((struct IORequest *)ior);
  155.     DeleteExtIO ((struct IORequest *)ior);
  156.     DeletePort (mp);
  157. } /* CBClose */
  158.  
  159.  
  160. /*****************************************************************************
  161.  
  162.     NAME
  163.     CBWriteFTXT - Write a string of text to the clipboard
  164.  
  165.     PARAMETER
  166.     struct IOClipReq * ior;
  167.     char         * string;
  168.  
  169.     RESULT
  170.  
  171.     RETURN
  172.     int success;        TRUE/FALSE
  173.  
  174.     DESCRIPTION
  175.     Write a NULL terminated string of text to the clipboard. The string
  176.     will be written in simple FTXT format.
  177.  
  178.     Note that this function pads odd length strings automatically to
  179.     conform to the IFF standard.
  180.  
  181.     NOTES
  182.  
  183.     BUGS
  184.  
  185.     EXAMPLES
  186.  
  187.     SEE ALSO
  188.  
  189.     INTERNALS
  190.  
  191.     HISTORY
  192.     29. May 1992    ada created
  193.  
  194. ******************************************************************************/
  195.  
  196. int CBWriteFTXT (struct IOClipReq * ior, char * string)
  197. {
  198.     ULONG length;    /* EVEN string-length */
  199.     ULONG slen;     /* length of string */
  200.     BOOL  odd;        /* ODD(slen) */
  201.     static ULONG IFF_header[] = {
  202.     ID_FORM,
  203.     0,
  204.     ID_FTXT,
  205.     ID_CHRS,
  206.     0
  207.     };
  208.  
  209.     slen = strlen (string);
  210.     odd  = slen & 1;
  211.  
  212.     length = odd ? slen+1 : slen;
  213.  
  214.     /* initial setup for Offset, Error and ClipID */
  215.     ior->io_Offset  = 0;
  216.     ior->io_Error   = 0;
  217.     ior->io_ClipID  = 0;
  218.  
  219.     /* Create the IFF-header information and write it */
  220.     IFF_header[1] = length + 12;
  221.     IFF_header[4] = slen;
  222.  
  223.     ior->io_Data    = (STRPTR)IFF_header;
  224.     ior->io_Length  = sizeof (IFF_header);
  225.     ior->io_Command = CMD_WRITE;
  226.     DoIO ((struct IORequest *)ior);
  227.  
  228.     /* write string itself */
  229.     ior->io_Data    = (STRPTR)string;
  230.     ior->io_Length  = length;           /* We can write slen+1 Bytes since
  231.                       a C-String always has a '\0'-Byte
  232.                       at his end. */
  233.     ior->io_Command = CMD_WRITE;
  234.     DoIO ((struct IORequest *)ior);
  235.  
  236.     /* Tell the clipboard we are done writing */
  237.     ior->io_Command = CMD_UPDATE;
  238.     DoIO ((struct IORequest *)ior);
  239.  
  240.     return (ior->io_Error ? FALSE : TRUE);
  241. } /* CBWriteFTXT */
  242.  
  243.  
  244. /*****************************************************************************
  245.  
  246.     NAME
  247.     CBQueryFTXT
  248.  
  249.     PARAMETER
  250.     struct IOClipReq * ior;
  251.  
  252.     RESULT
  253.  
  254.     RETURN
  255.     int result;        TRUE/FALSE
  256.  
  257.     DESCRIPTION
  258.     Check if the clipboard contains a FTXT.
  259.  
  260.     NOTES
  261.     If this function returns TRUE, you MUST either call CBReadCHRS()
  262.     until it returns FALSE or CBReadDone() to tell the clipboard.device
  263.     that we are done reading.
  264.  
  265.     BUGS
  266.  
  267.     EXAMPLES
  268.  
  269.     SEE ALSO
  270.  
  271.     INTERNALS
  272.  
  273.     HISTORY
  274.     29. May 1992    ada created
  275.  
  276. ******************************************************************************/
  277.  
  278. int CBQueryFTXT (struct IOClipReq * ior)
  279. {
  280.     ULONG cbuff[3];
  281.  
  282.     /* initial setup for Offset, Error and ClipID */
  283.     ior->io_Offset  = 0;
  284.     ior->io_Error   = 0;
  285.     ior->io_ClipID  = 0;
  286.  
  287.     /* Look for "FORM[size]FTXT" */
  288.     ior->io_Data    = (STRPTR)cbuff;
  289.     ior->io_Length  = 12;        /* 3*4 Bytes */
  290.     ior->io_Command = CMD_READ;
  291.     DoIO ((struct IORequest *)ior);
  292.  
  293.     /* Have we at least 12 bytes and a valid IFF-Header ? */
  294.     if (ior->io_Actual == 12L && cbuff[0] == ID_FORM && cbuff[2] == ID_FTXT) {
  295. #ifdef DEBUG
  296.     printf ("FTXT ok\n");
  297. #endif
  298.     return (TRUE);
  299.     }
  300.  
  301. #ifdef DEBUG
  302.     printf ("No FTXT\n");
  303. #endif
  304.  
  305.     CBReadDone (ior);
  306.     return (FALSE);
  307. } /* CBQueryFTXT */
  308.  
  309.  
  310. /*****************************************************************************
  311.  
  312.     NAME
  313.     CBReadCHRS
  314.  
  315.     PARAMETER
  316.     struct IOClipReq * ior;
  317.  
  318.     RESULT
  319.  
  320.     RETURN
  321.     struct cbbuf * cbbuf;        NULL on failure (out-of-memory or
  322.                     no more CHRS-chunks).
  323.  
  324.     DESCRIPTION
  325.     Reads and returns the text in the next CHRS chunk (if any) from the
  326.     clipboard.
  327.  
  328.     Allocates memory to hold data in next CHRS chunk.
  329.  
  330.     NOTES
  331.     The caller must free the returned buffer when done via CBFreeBuf().
  332.  
  333.     BUGS
  334.  
  335.     EXAMPLES
  336.  
  337.     SEE ALSO
  338.  
  339.     INTERNALS
  340.  
  341.     HISTORY
  342.     29. May 1992    ada created
  343.  
  344. ******************************************************************************/
  345.  
  346. struct cbbuf * CBReadCHRS (struct IOClipReq * ior)
  347. {
  348.     ULONG chunk;
  349.     ULONG size;
  350.     struct cbbuf * buf;
  351.  
  352.     /* Find next CHRS chunk */
  353.     buf = NULL;
  354.  
  355.     for (;;) {
  356.     if (!(ReadLong (ior, &chunk)) )
  357.         break;
  358.  
  359.     if (!(ReadLong (ior, &size)) )
  360.         break;
  361.  
  362.     /* if it is a CHRS-hunk */
  363.     if (chunk == ID_CHRS) {
  364. #ifdef DEBUG
  365.     printf ("Found CHRS\n");
  366. #endif
  367. #ifdef DEBUG
  368.     printf ("CHRS length = %d\n", size);
  369. #endif
  370.         if (size) { /* Read data */
  371.         buf = FillCBData (ior, size);
  372.         break;
  373.         }
  374.     } else { /* else skip this hunk */
  375.         if (size & 1)
  376.         size ++;
  377.  
  378.         ior->io_Offset += size;
  379.     }
  380.     }
  381.  
  382.     /* tell clipboard we are done */
  383.     if (!buf)
  384.     CBReadDone (ior);
  385.  
  386. #ifdef DEBUG
  387.     printf ("Found '%s'\n", buf->mem);
  388. #endif
  389.  
  390.     return (buf);
  391. } /* CBReadCHRS */
  392.  
  393.  
  394. static int ReadLong (struct IOClipReq * ior, ULONG * ldata)
  395. {
  396.     ior->io_Data    = (STRPTR)ldata;
  397.     ior->io_Length  = 4;
  398.     ior->io_Command = CMD_READ;
  399.  
  400.     DoIO ((struct IORequest *)ior);
  401.  
  402.     if (ior->io_Actual == 4 && !ior->io_Error)
  403.     return (TRUE);
  404.  
  405.     return (FALSE);
  406. }
  407.  
  408.  
  409. static struct cbbuf * FillCBData (struct IOClipReq * ior, ULONG size)
  410. {
  411.     register UBYTE * to;
  412.     register UBYTE * from;
  413.     register ULONG   t;
  414.     register ULONG   count;
  415.     struct cbbuf   * buf;
  416.  
  417.     if (!size)
  418.     return (NULL);
  419.  
  420.     if (size & 1)
  421.     size ++;
  422.  
  423.     if (buf = AllocMem (sizeof (struct cbbuf) + size, MEMF_PUBLIC)) {
  424.     buf->size = sizeof (struct cbbuf) + size;
  425.  
  426.     ior->io_Data    = (STRPTR)buf->mem;
  427.     ior->io_Length    = size;
  428.     ior->io_Command = CMD_READ;
  429.  
  430.     to = (UBYTE *)buf->mem;
  431.     count = NULL;
  432.  
  433.     if (!(DoIO ((struct IORequest *)ior)) && ior->io_Actual == size) {
  434.         for (t=0, from=to; t<size; t++) {
  435.         if (*from) {
  436.             *to ++ = * from;
  437.             count ++;
  438.         }
  439.  
  440.         from ++;
  441.         } /* for all bytes in the buffer */
  442.  
  443.         *to = 0;    /* terminate buffer with 0 */
  444.         buf->count = count;
  445.     } else { /* if DoIO && number of bytes */
  446.         FreeMem (buf, buf->size);
  447.         return (NULL);
  448.     }
  449.     }
  450.  
  451.     return (buf);
  452. } /* FillCBData */
  453.  
  454.  
  455. /*****************************************************************************
  456.  
  457.     NAME
  458.     CBReadDone - Tell clipboard we are done reading
  459.  
  460.     PARAMETER
  461.     struct IOClipReq * ior;
  462.  
  463.     RESULT
  464.  
  465.     RETURN
  466.     void
  467.  
  468.     DESCRIPTION
  469.     Reads past end of clipboard file until io_Actual is equal to 0. This
  470.     tells the clipboard that we are done reading.
  471.  
  472.     NOTES
  473.  
  474.     BUGS
  475.  
  476.     EXAMPLES
  477.  
  478.     SEE ALSO
  479.  
  480.     INTERNALS
  481.  
  482.     HISTORY
  483.     29. May 1992    ada created
  484.  
  485. ******************************************************************************/
  486.  
  487. void CBReadDone (struct IOClipReq * ior)
  488. {
  489.     char tmp_buffer[64];
  490.  
  491.     ior->io_Data    = (STRPTR)tmp_buffer;
  492.     ior->io_Length  = sizeof(tmp_buffer);
  493.     ior->io_Command = CMD_READ;
  494.  
  495.     /* falls through immediately if io_Actual == 0 */
  496.     while (ior->io_Actual) {
  497.     if (DoIO ((struct IORequest *)ior))
  498.         break;
  499.     }
  500.  
  501. } /* CBReadDone */
  502.  
  503.  
  504. /*****************************************************************************
  505.  
  506.     NAME
  507.     CBFreeBuf - Free buffer allocated by CBReadCHRS()
  508.  
  509.     PARAMETER
  510.     struct cbbuf * buf;
  511.  
  512.     RESULT
  513.  
  514.     RETURN
  515.     void
  516.  
  517.     DESCRIPTION
  518.     Frees a buffer allocated by CBReadCHRS().
  519.  
  520.     NOTES
  521.  
  522.     BUGS
  523.  
  524.     EXAMPLES
  525.  
  526.     SEE ALSO
  527.  
  528.     INTERNALS
  529.  
  530.     HISTORY
  531.     29. May 1992    ada created
  532.  
  533. ******************************************************************************/
  534.  
  535. void CBFreeBuf (struct cbbuf * buf)
  536. {
  537.     FreeMem (buf, buf->size);
  538. } /* CBFreeBuf */
  539.  
  540.  
  541. /******************************************************************************
  542. *****  ENDE clipboard.c
  543. ******************************************************************************/
  544.