home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / YADME10.LHA / YADME10 / src / cbio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-19  |  12.6 KB  |  514 lines

  1. /*
  2.  * Copyright (c) 1992 Commodore-Amiga, Inc.
  3.  * 
  4.  * This example is provided in electronic form by Commodore-Amiga, Inc. for 
  5.  * use with the "Amiga ROM Kernel Reference Manual: Devices", 3rd Edition, 
  6.  * published by Addison-Wesley (ISBN 0-201-56775-X).
  7.  * 
  8.  * The "Amiga ROM Kernel Reference Manual: Devices" contains additional 
  9.  * information on the correct usage of the techniques and operating system 
  10.  * functions presented in these examples.  The source and executable code 
  11.  * of these examples may only be distributed in free electronic form, via 
  12.  * bulletin board or as part of a fully non-commercial and freely 
  13.  * redistributable diskette.  Both the source and executable code (including 
  14.  * comments) must be included, without modification, in any copy.  This 
  15.  * example may not be published in printed form or distributed with any
  16.  * commercial product.  However, the programming techniques and support
  17.  * routines set forth in these examples may be used in the development
  18.  * of original executable software products for Commodore Amiga computers.
  19.  * 
  20.  * All other rights reserved.
  21.  * 
  22.  * This example is provided "as-is" and is subject to change; no
  23.  * warranties are made.  All use is at your own risk. No liability or
  24.  * responsibility is assumed.
  25.  *
  26.  **************************************************************************
  27.  *
  28.  *
  29.  * Cbio.c
  30.  *
  31.  * Provide standard clipboard device interface routines
  32.  *            such as Open, Close, Post, Read, Write, etc.
  33.  *
  34.  * Compile with SAS C 5.10: LC -b1 -cfistq -v -y
  35.  *
  36.  *  NOTES: These functions are useful for writing and reading simple
  37.  *         FTXT.  Writing and reading complex FTXT, ILBM, etc.,
  38.  *         requires more work.  You should use the iffparse.library 
  39.  *         to write and read FTXT, ILBM and other IFF file types.
  40.  *
  41.  *         When this code is used with older versions of the Amiga OS 
  42.  *         (i.e., before V36) a memory loss of 536 bytes will occur due 
  43.  *         to bugs in the clipboard device.
  44.  *
  45.  */
  46.  
  47. #include <exec/types.h>
  48. #include <exec/ports.h>
  49. #include <exec/io.h>
  50. #include <exec/memory.h>
  51. #include <devices/clipboard.h>
  52.  
  53. #define CBIO 1
  54.  
  55. #include "cb.h"
  56.  
  57. #include <clib/exec_protos.h>
  58. #include <clib/alib_protos.h>
  59.  
  60. #include <stdlib.h>
  61. #include <stdio.h>
  62. #include <string.h>
  63.  
  64.  
  65. /****** cbio/CBOpen *************************************************
  66. *
  67. *   NAME
  68. *       CBOpen() -- Open the clipboard.device
  69. *
  70. *   SYNOPSIS
  71. *       ior = CBOpen(unit)
  72. *
  73. *       struct IOClipReq *CBOpen( ULONG )
  74. *
  75. *   FUNCTION
  76. *       Opens the clipboard.device.  A clipboard unit number
  77. *       must be passed in as an argument.  By default, the unit
  78. *       number should be 0 (currently valid unit numbers are
  79. *       0-255).
  80. *
  81. *   RESULTS
  82. *       A pointer to an initialized IOClipReq structure, or
  83. *       a NULL pointer if the function fails.
  84. *
  85. *********************************************************************/
  86.  
  87.  
  88.  struct IOClipReq *CBOpen(ULONG unit)
  89.   {
  90.    struct MsgPort *mp;
  91.    struct IOStdReq *ior;
  92.    
  93.    if (mp = CreatePort(0L,0L))
  94.     {
  95.      if (ior=(struct IOStdReq *)CreateExtIO(mp,sizeof(struct IOClipReq)))
  96.       {
  97.        if (!(OpenDevice("clipboard.device",unit,(struct IORequest *)ior,0L)))
  98.         {
  99.          return((struct IOClipReq *)ior);
  100.         }
  101.        DeleteExtIO((struct IORequest *)ior);
  102.       }
  103.      DeletePort(mp);
  104.     }
  105.    return(NULL);
  106.    
  107.   }
  108.  
  109. /****** cbio/CBClose ************************************************
  110. *
  111. *   NAME
  112. *       CBClose() -- Close the clipboard.device
  113. *
  114. *   SYNOPSIS
  115. *       CBClose()
  116. *
  117. *       void CBClose()
  118. *
  119. *   FUNCTION
  120. *       Close the clipboard.device unit which was opened via
  121. *       CBOpen().
  122. *
  123. *********************************************************************/
  124.  
  125.  void CBClose(struct IOClipReq *ior)
  126.   {
  127.    struct MsgPort *mp;
  128.    
  129.    mp = ior->io_Message.mn_ReplyPort;
  130.    
  131.    CloseDevice((struct IORequest *)ior);
  132.    DeleteExtIO((struct IORequest *)ior);
  133.    DeletePort(mp);
  134.    
  135.   }
  136.  
  137. /****** cbio/CBWriteFTXT *********************************************
  138. *
  139. *   NAME
  140. *       CBWriteFTXT() -- Write a string of text to the clipboard.device
  141. *
  142. *   SYNOPSIS
  143. *       success = CBWriteFTXT( ior, string)
  144. *
  145. *       int CBWriteFTXT(struct IOClipReq *, char *)
  146. *
  147. *   FUNCTION
  148. *       Write a NULL terminated string of text to the clipboard.
  149. *       The string will be written in simple FTXT format.
  150. *
  151. *       Note that this function pads odd length strings automatically
  152. *       to conform to the IFF standard.
  153. *
  154. *   RESULTS
  155. *       TRUE if the write succeeded, else FALSE.
  156. *
  157. *********************************************************************/
  158.  
  159.  int CBWriteFTXT(struct IOClipReq *ior, char *string)
  160.   {
  161.    
  162.    ULONG length, slen;
  163.    BOOL odd;
  164.    int success;
  165.    
  166.    slen = strlen(string);
  167.    odd = (slen & 1);               /* pad byte flag */
  168.    
  169.    length = (odd) ? slen+1 : slen;
  170.    
  171. /* initial set-up for Offset, Error, and ClipID */
  172.    
  173.    ior->io_Offset = 0;
  174.    ior->io_Error  = 0;
  175.    ior->io_ClipID = 0;
  176.    
  177.    
  178. /* Create the IFF header information */
  179.    
  180.    WriteLong(ior, (long *) "FORM");     /* "FORM"             */
  181.    length+=12L;                         /* + "[size]FTXTCHRS" */
  182.    WriteLong(ior, (long *)&length);             /* total length       */
  183.    WriteLong(ior, (long *) "FTXT");     /* "FTXT"             */
  184.    WriteLong(ior, (long *) "CHRS");     /* "CHRS"             */
  185.    WriteLong(ior, (long *)&slen);               /* string length      */
  186.    
  187. /* Write string */
  188.    ior->io_Data    = (STRPTR)string;
  189.    ior->io_Length  = slen;
  190.    ior->io_Command = CMD_WRITE;
  191.    DoIO( (struct IORequest *) ior);
  192.    
  193. /* Pad if needed */
  194.    if (odd)
  195.     {
  196.      ior->io_Data   = (STRPTR)"";
  197.      ior->io_Length = 1L;
  198.      DoIO( (struct IORequest *) ior);
  199.     }
  200.    
  201. /* Tell the clipboard we are done writing */
  202.    
  203.    ior->io_Command=CMD_UPDATE;
  204.    DoIO( (struct IORequest *) ior);
  205.    
  206. /* Check if io_Error was set by any of the preceding IO requests */
  207.    success = ior->io_Error ? FALSE : TRUE;
  208.    
  209.    return(success);
  210.   }
  211.  
  212.  WriteLong(struct IOClipReq *ior, long *ldata)
  213.   {
  214.    
  215.    ior->io_Data    = (STRPTR)ldata;
  216.    ior->io_Length  = 4L;
  217.    ior->io_Command = CMD_WRITE;
  218.    DoIO( (struct IORequest *) ior);
  219.    
  220.    if (ior->io_Actual == 4)
  221.     {
  222.      return( ior->io_Error ? FALSE : TRUE);
  223.     }
  224.    
  225.    return(FALSE);
  226.    
  227.   }
  228.  
  229. /****** cbio/CBQueryFTXT **********************************************
  230. *
  231. *   NAME
  232. *       CBQueryFTXT() -- Check to see if clipboard contains FTXT
  233. *
  234. *   SYNOPSIS
  235. *       result = CBQueryFTXT( ior )
  236. *
  237. *       int CBQueryFTXT(struct IOClipReq *)
  238. *
  239. *   FUNCTION
  240. *       Check to see if the clipboard contains FTXT.  If so,
  241. *       call CBReadCHRS() one or more times until all CHRS
  242. *       chunks have been read.
  243. *
  244. *   RESULTS
  245. *       TRUE if the clipboard contains an FTXT chunk, else FALSE.
  246. *
  247. *   NOTES
  248. *       If this function returns TRUE, you must either call
  249. *       CBReadCHRS() until CBReadCHRS() returns FALSE, or
  250. *       call CBReadDone() to tell the clipboard.device that
  251. *       you are done reading.
  252. *
  253. *********************************************************************/
  254.  
  255.  int CBQueryFTXT(struct IOClipReq *ior)
  256.   {
  257.    ULONG cbuff[4];
  258.    
  259.    
  260. /* initial set-up for Offset, Error, and ClipID */
  261.    
  262.    ior->io_Offset = 0;
  263.    ior->io_Error  = 0;
  264.    ior->io_ClipID = 0;
  265.    
  266. /* Look for "FORM[size]FTXT" */
  267.    
  268.    ior->io_Command = CMD_READ;
  269.    ior->io_Data    = (STRPTR)cbuff;
  270.    ior->io_Length  = 12;
  271.    
  272.    DoIO( (struct IORequest *) ior);
  273.    
  274.    
  275. /* Check to see if we have at least 12 bytes */
  276.    
  277.    if (ior->io_Actual == 12L)
  278.     {
  279.     /* Check to see if it starts with "FORM" */
  280.      if (cbuff[0] == ID_FORM)
  281.       {
  282.         /* Check to see if its "FTXT" */
  283.        if (cbuff[2] == ID_FTXT)
  284.        return(TRUE);
  285.       }
  286.      
  287.     /* It's not "FORM[size]FTXT", so tell clipboard we are done */
  288.     }
  289.    
  290.    CBReadDone(ior);
  291.    
  292.    return(FALSE);
  293.   }
  294.  
  295.  
  296. /****** cbio/CBReadCHRS **********************************************
  297. *
  298. *   NAME
  299. *       CBReadCHRS() -- Reads the next CHRS chunk from clipboard
  300. *
  301. *   SYNOPSIS
  302. *       cbbuf = CBReadCHRS( ior )
  303. *
  304. *       struct cbbuf *CBReadCHRS(struct IOClipReq * )
  305. *
  306. *   FUNCTION
  307. *       Reads and returns the text in the next CHRS chunk
  308. *       (if any) from the clipboard.
  309. *
  310. *       Allocates memory to hold data in next CHRS chunk.
  311. *
  312. *   RESULTS
  313. *       Pointer to a cbbuf struct (see cb.h), or a NULL indicating
  314. *       a failure (e.g., not enough memory, or no more CHRS chunks).
  315. *
  316. *       ***Important***
  317. *
  318. *       The caller must free the returned buffer when done with the
  319. *       data by calling CBFreeBuf().
  320. *
  321. *   NOTES
  322. *       This function strips NULL bytes, however, a full reader may
  323. *       wish to perform more complete checking to verify that the
  324. *       text conforms to the IFF standard (stripping data as required).
  325. *
  326. *       Under 2.0, the AllocVec() function could be used instead of
  327. *       AllocMem() in which case the cbbuf structure may not be
  328. *       needed.
  329. *
  330. *********************************************************************/
  331.  
  332.  struct cbbuf *CBReadCHRS(struct IOClipReq *ior)
  333.   {
  334.    ULONG chunk,size;
  335.    struct cbbuf *buf;
  336.    int looking;
  337.    
  338. /* Find next CHRS chunk */
  339.    
  340.    looking = TRUE;
  341.    buf = NULL;
  342.    
  343.    while (looking)
  344.     {
  345.      looking = FALSE;
  346.      
  347.      if (ReadLong(ior,&chunk))
  348.       {
  349.           /* Is CHRS chunk ? */
  350.        if (chunk == ID_CHRS)
  351.         {
  352.               /* Get size of chunk, and copy data */
  353.          if (ReadLong(ior,&size))
  354.           {
  355.            if (size)
  356.            buf=FillCBData(ior,size);
  357.           }
  358.         }
  359.        
  360.             /* If not, skip to next chunk */
  361.        else
  362.         {
  363.          if (ReadLong(ior,&size))
  364.           {
  365.            looking = TRUE;
  366.            if (size & 1)
  367.            size++;    /* if odd size, add pad byte */
  368.            
  369.            ior->io_Offset += size;
  370.           }
  371.         }
  372.       }
  373.     }
  374.    
  375.    if (buf == NULL)
  376.    CBReadDone(ior);        /* tell clipboard we are done */
  377.    
  378.    return(buf);
  379.   }
  380.  
  381.  
  382.  ReadLong(struct IOClipReq *ior, ULONG *ldata)
  383.   {
  384.    ior->io_Command = CMD_READ;
  385.    ior->io_Data    = (STRPTR)ldata;
  386.    ior->io_Length  = 4L;
  387.    
  388.    DoIO( (struct IORequest *) ior);
  389.    
  390.    if (ior->io_Actual == 4)
  391.     {
  392.      return( ior->io_Error ? FALSE : TRUE);
  393.     }
  394.    
  395.    return(FALSE);
  396.   }
  397.  
  398.  
  399.  struct cbbuf *FillCBData(struct IOClipReq *ior, ULONG size)
  400.   {
  401.    register UBYTE *to,*from;
  402.    register ULONG x,count;
  403.    
  404.    ULONG length;
  405.    struct cbbuf *buf,*success;
  406.    
  407.    success = NULL;
  408.    
  409.    if (buf = AllocMem(sizeof(struct cbbuf),MEMF_PUBLIC))
  410.     {
  411.      
  412.      length = size;
  413.      if (size & 1)
  414.      length++;            /* if odd size, read 1 more */
  415.      
  416.      if (buf->mem = AllocMem(length+1L,MEMF_PUBLIC))
  417.       {
  418.        buf->size = length+1L;
  419.        
  420.        ior->io_Command = CMD_READ;
  421.        ior->io_Data    = (STRPTR)buf->mem;
  422.        ior->io_Length  = length;
  423.        
  424.        to = buf->mem;
  425.        count = 0L;
  426.        
  427.        if (!(DoIO( (struct IORequest *) ior)))
  428.         {
  429.          if (ior->io_Actual == length)
  430.           {
  431.            success = buf;      /* everything succeeded */
  432.            
  433.                 /* strip NULL bytes */
  434.            for (x=0, from=buf->mem ;x<size;x++)
  435.             {
  436.              if (*from)
  437.               {
  438.                *to = *from;
  439.                to++;
  440.                count++;
  441.               }
  442.              
  443.              from++;
  444.             }
  445.            *to=0x0;            /* Null terminate buffer */
  446.            buf->count = count; /* cache count of chars in buf */
  447.           }
  448.         }
  449.        
  450.        if (!(success))
  451.        FreeMem(buf->mem,buf->size);
  452.       }
  453.      if (!(success))
  454.      FreeMem(buf,sizeof(struct cbbuf));
  455.     }
  456.    
  457.    return(success);
  458.   }
  459.  
  460. /****** cbio/CBReadDone **********************************************
  461. *
  462. *   NAME
  463. *       CBReadDone() -- Tell clipboard we are done reading
  464. *
  465. *   SYNOPSIS
  466. *       CBReadDone( ior )
  467. *
  468. *       void CBReadDone(struct IOClipReq * )
  469. *
  470. *   FUNCTION
  471. *       Reads past end of clipboard file until io_Actual is equal to 0.
  472. *       This is tells the clipboard that we are done reading.
  473. *
  474. *********************************************************************/
  475.  
  476.  void CBReadDone(struct IOClipReq *ior)
  477.   {
  478.    char buffer[256];
  479.    
  480.    ior->io_Command = CMD_READ;
  481.    ior->io_Data    = (STRPTR)buffer;
  482.    ior->io_Length  = 254;
  483.    
  484.    
  485. /* falls through immediately if io_Actual == 0 */
  486.    
  487.    while (ior->io_Actual)
  488.     {
  489.      if (DoIO( (struct IORequest *) ior))
  490.      break;
  491.     }
  492.   }
  493.  
  494. /****** cbio/CBFreeBuf **********************************************
  495. *
  496. *   NAME
  497. *       CBFreeBuf() -- Free buffer allocated by CBReadCHRS()
  498. *
  499. *   SYNOPSIS
  500. *       CBFreeBuf( buf )
  501. *
  502. *       void CBFreeBuf( struct cbbuf * )
  503. *
  504. *   FUNCTION
  505. *       Frees a buffer allocated by CBReadCHRS().
  506. *
  507. *********************************************************************/
  508.  
  509.  void CBFreeBuf(struct cbbuf *buf)
  510.   {
  511.    FreeMem(buf->mem, buf->size);
  512.    FreeMem(buf, sizeof(struct cbbuf));
  513.   }
  514.