home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Internet / Web / URLScan.lha / cbio.c < prev    next >
C/C++ Source or Header  |  1992-09-03  |  13KB  |  528 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(unit)
  89. ULONG unit;
  90. {
  91. struct MsgPort *mp;
  92. struct IOStdReq *ior;
  93.  
  94. if (mp = CreatePort(0L,0L))
  95.     {
  96.     if (ior=(struct IOStdReq *)CreateExtIO(mp,sizeof(struct IOClipReq)))
  97.         {
  98.         if (!(OpenDevice("clipboard.device",unit,ior,0L)))
  99.             {
  100.             return((struct IOClipReq *)ior);
  101.             }
  102.         DeleteExtIO(ior);
  103.         }
  104.     DeletePort(mp);
  105.     }
  106. return(NULL);
  107.  
  108. }
  109.  
  110. /****** cbio/CBClose ************************************************
  111. *
  112. *   NAME
  113. *       CBClose() -- Close the clipboard.device
  114. *
  115. *   SYNOPSIS
  116. *       CBClose()
  117. *
  118. *       void CBClose()
  119. *
  120. *   FUNCTION
  121. *       Close the clipboard.device unit which was opened via
  122. *       CBOpen().
  123. *
  124. *********************************************************************/
  125.  
  126. void CBClose(ior)
  127. struct IOClipReq *ior;
  128. {
  129. struct MsgPort *mp;
  130.  
  131. mp = ior->io_Message.mn_ReplyPort;
  132.  
  133. CloseDevice((struct IOStdReq *)ior);
  134. DeleteExtIO((struct IOStdReq *)ior);
  135. DeletePort(mp);
  136.  
  137. }
  138.  
  139. /****** cbio/CBWriteFTXT *********************************************
  140. *
  141. *   NAME
  142. *       CBWriteFTXT() -- Write a string of text to the clipboard.device
  143. *
  144. *   SYNOPSIS
  145. *       success = CBWriteFTXT( ior, string)
  146. *
  147. *       int CBWriteFTXT(struct IOClipReq *, char *)
  148. *
  149. *   FUNCTION
  150. *       Write a NULL terminated string of text to the clipboard.
  151. *       The string will be written in simple FTXT format.
  152. *
  153. *       Note that this function pads odd length strings automatically
  154. *       to conform to the IFF standard.
  155. *
  156. *   RESULTS
  157. *       TRUE if the write succeeded, else FALSE.
  158. *
  159. *********************************************************************/
  160.  
  161. int CBWriteFTXT(ior,string)
  162. struct IOClipReq *ior;
  163. char *string;
  164. {
  165.  
  166. ULONG length, slen;
  167. BOOL odd;
  168. int success;
  169.  
  170. slen = strlen(string);
  171. odd = (slen & 1);               /* pad byte flag */
  172.  
  173. length = (odd) ? slen+1 : slen;
  174.  
  175. /* initial set-up for Offset, Error, and ClipID */
  176.  
  177. ior->io_Offset = 0;
  178. ior->io_Error  = 0;
  179. ior->io_ClipID = 0;
  180.  
  181.  
  182. /* Create the IFF header information */
  183.  
  184. WriteLong(ior, (long *) "FORM");     /* "FORM"             */
  185. length+=12L;                         /* + "[size]FTXTCHRS" */
  186. WriteLong(ior, &length);             /* total length       */
  187. WriteLong(ior, (long *) "FTXT");     /* "FTXT"             */
  188. WriteLong(ior, (long *) "CHRS");     /* "CHRS"             */
  189. WriteLong(ior, &slen);               /* string length      */
  190.  
  191. /* Write string */
  192. ior->io_Data    = (STRPTR)string;
  193. ior->io_Length  = slen;
  194. ior->io_Command = CMD_WRITE;
  195. DoIO( (struct IORequest *) ior);
  196.  
  197. /* Pad if needed */
  198. if (odd)
  199.     {
  200.     ior->io_Data   = (STRPTR)"";
  201.     ior->io_Length = 1L;
  202.     DoIO( (struct IORequest *) ior);
  203.     }
  204.  
  205. /* Tell the clipboard we are done writing */
  206.  
  207. ior->io_Command=CMD_UPDATE;
  208. DoIO( (struct IORequest *) ior);
  209.  
  210. /* Check if io_Error was set by any of the preceding IO requests */
  211. success = ior->io_Error ? FALSE : TRUE;
  212.  
  213. return(success);
  214. }
  215.  
  216. WriteLong(ior, ldata)
  217. struct IOClipReq *ior;
  218. long *ldata;
  219. {
  220.  
  221. ior->io_Data    = (STRPTR)ldata;
  222. ior->io_Length  = 4L;
  223. ior->io_Command = CMD_WRITE;
  224. DoIO( (struct IORequest *) ior);
  225.  
  226. if (ior->io_Actual == 4)
  227.     {
  228.     return( ior->io_Error ? FALSE : TRUE);
  229.     }
  230.  
  231. return(FALSE);
  232.  
  233. }
  234.  
  235. /****** cbio/CBQueryFTXT **********************************************
  236. *
  237. *   NAME
  238. *       CBQueryFTXT() -- Check to see if clipboard contains FTXT
  239. *
  240. *   SYNOPSIS
  241. *       result = CBQueryFTXT( ior )
  242. *
  243. *       int CBQueryFTXT(struct IOClipReq *)
  244. *
  245. *   FUNCTION
  246. *       Check to see if the clipboard contains FTXT.  If so,
  247. *       call CBReadCHRS() one or more times until all CHRS
  248. *       chunks have been read.
  249. *
  250. *   RESULTS
  251. *       TRUE if the clipboard contains an FTXT chunk, else FALSE.
  252. *
  253. *   NOTES
  254. *       If this function returns TRUE, you must either call
  255. *       CBReadCHRS() until CBReadCHRS() returns FALSE, or
  256. *       call CBReadDone() to tell the clipboard.device that
  257. *       you are done reading.
  258. *
  259. *********************************************************************/
  260.  
  261. int CBQueryFTXT(ior)
  262. struct IOClipReq *ior;
  263. {
  264. ULONG cbuff[4];
  265.  
  266.  
  267. /* initial set-up for Offset, Error, and ClipID */
  268.  
  269. ior->io_Offset = 0;
  270. ior->io_Error  = 0;
  271. ior->io_ClipID = 0;
  272.  
  273. /* Look for "FORM[size]FTXT" */
  274.  
  275. ior->io_Command = CMD_READ;
  276. ior->io_Data    = (STRPTR)cbuff;
  277. ior->io_Length  = 12;
  278.  
  279. DoIO( (struct IORequest *) ior);
  280.  
  281.  
  282. /* Check to see if we have at least 12 bytes */
  283.  
  284. if (ior->io_Actual == 12L)
  285.     {
  286.     /* Check to see if it starts with "FORM" */
  287.     if (cbuff[0] == ID_FORM)
  288.         {
  289.         /* Check to see if its "FTXT" */
  290.         if (cbuff[2] == ID_FTXT)
  291.             return(TRUE);
  292.         }
  293.  
  294.     /* It's not "FORM[size]FTXT", so tell clipboard we are done */
  295.     }
  296.  
  297. CBReadDone(ior);
  298.  
  299. return(FALSE);
  300. }
  301.  
  302.  
  303. /****** cbio/CBReadCHRS **********************************************
  304. *
  305. *   NAME
  306. *       CBReadCHRS() -- Reads the next CHRS chunk from clipboard
  307. *
  308. *   SYNOPSIS
  309. *       cbbuf = CBReadCHRS( ior )
  310. *
  311. *       struct cbbuf *CBReadCHRS(struct IOClipReq * )
  312. *
  313. *   FUNCTION
  314. *       Reads and returns the text in the next CHRS chunk
  315. *       (if any) from the clipboard.
  316. *
  317. *       Allocates memory to hold data in next CHRS chunk.
  318. *
  319. *   RESULTS
  320. *       Pointer to a cbbuf struct (see cb.h), or a NULL indicating
  321. *       a failure (e.g., not enough memory, or no more CHRS chunks).
  322. *
  323. *       ***Important***
  324. *
  325. *       The caller must free the returned buffer when done with the
  326. *       data by calling CBFreeBuf().
  327. *
  328. *   NOTES
  329. *       This function strips NULL bytes, however, a full reader may
  330. *       wish to perform more complete checking to verify that the
  331. *       text conforms to the IFF standard (stripping data as required).
  332. *
  333. *       Under 2.0, the AllocVec() function could be used instead of
  334. *       AllocMem() in which case the cbbuf structure may not be
  335. *       needed.
  336. *
  337. *********************************************************************/
  338.  
  339. struct cbbuf *CBReadCHRS(ior)
  340. struct IOClipReq *ior;
  341. {
  342. ULONG chunk,size;
  343. struct cbbuf *buf;
  344. int looking;
  345.  
  346. /* Find next CHRS chunk */
  347.  
  348. looking = TRUE;
  349. buf = NULL;
  350.  
  351. while (looking)
  352.       {
  353.       looking = FALSE;
  354.  
  355.       if (ReadLong(ior,&chunk))
  356.           {
  357.           /* Is CHRS chunk ? */
  358.           if (chunk == ID_CHRS)
  359.               {
  360.               /* Get size of chunk, and copy data */
  361.               if (ReadLong(ior,&size))
  362.                   {
  363.                   if (size)
  364.                       buf=FillCBData(ior,size);
  365.                   }
  366.               }
  367.  
  368.             /* If not, skip to next chunk */
  369.           else
  370.               {
  371.               if (ReadLong(ior,&size))
  372.                   {
  373.                    looking = TRUE;
  374.                    if (size & 1)
  375.                        size++;    /* if odd size, add pad byte */
  376.  
  377.                     ior->io_Offset += size;
  378.                   }
  379.               }
  380.           }
  381.       }
  382.  
  383. if (buf == NULL)
  384.     CBReadDone(ior);        /* tell clipboard we are done */
  385.  
  386. return(buf);
  387. }
  388.  
  389.  
  390. ReadLong(ior, ldata)
  391. struct IOClipReq *ior;
  392. ULONG *ldata;
  393. {
  394. ior->io_Command = CMD_READ;
  395. ior->io_Data    = (STRPTR)ldata;
  396. ior->io_Length  = 4L;
  397.  
  398. DoIO( (struct IORequest *) ior);
  399.  
  400. if (ior->io_Actual == 4)
  401.     {
  402.     return( ior->io_Error ? FALSE : TRUE);
  403.     }
  404.  
  405. return(FALSE);
  406. }
  407.  
  408.  
  409. struct cbbuf *FillCBData(ior,size)
  410. struct IOClipReq *ior;
  411. ULONG size;
  412. {
  413. register UBYTE *to,*from;
  414. register ULONG x,count;
  415.  
  416. ULONG length;
  417. struct cbbuf *buf,*success;
  418.  
  419. success = NULL;
  420.  
  421. if (buf = AllocMem(sizeof(struct cbbuf),MEMF_PUBLIC))
  422.     {
  423.  
  424.     length = size;
  425.     if (size & 1)
  426.         length++;            /* if odd size, read 1 more */
  427.  
  428.     if (buf->mem = AllocMem(length+1L,MEMF_PUBLIC))
  429.         {
  430.         buf->size = length+1L;
  431.  
  432.         ior->io_Command = CMD_READ;
  433.         ior->io_Data    = (STRPTR)buf->mem;
  434.         ior->io_Length  = length;
  435.  
  436.         to = buf->mem;
  437.         count = 0L;
  438.  
  439.         if (!(DoIO( (struct IOStdReq *) ior)))
  440.             {
  441.             if (ior->io_Actual == length)
  442.                 {
  443.                 success = buf;      /* everything succeeded */
  444.  
  445.                 /* strip NULL bytes */
  446.                 for (x=0, from=buf->mem ;x<size;x++)
  447.                      {
  448.                      if (*from)
  449.                          {
  450.                          *to = *from;
  451.                          to++;
  452.                          count++;
  453.                          }
  454.  
  455.                      from++;
  456.                      }
  457.                 *to=0x0;            /* Null terminate buffer */
  458.                 buf->count = count; /* cache count of chars in buf */
  459.                 }
  460.             }
  461.  
  462.         if (!(success))
  463.             FreeMem(buf->mem,buf->size);
  464.         }
  465.     if (!(success))
  466.         FreeMem(buf,sizeof(struct cbbuf));
  467.     }
  468.  
  469. return(success);
  470. }
  471.  
  472. /****** cbio/CBReadDone **********************************************
  473. *
  474. *   NAME
  475. *       CBReadDone() -- Tell clipboard we are done reading
  476. *
  477. *   SYNOPSIS
  478. *       CBReadDone( ior )
  479. *
  480. *       void CBReadDone(struct IOClipReq * )
  481. *
  482. *   FUNCTION
  483. *       Reads past end of clipboard file until io_Actual is equal to 0.
  484. *       This is tells the clipboard that we are done reading.
  485. *
  486. *********************************************************************/
  487.  
  488. void CBReadDone(ior)
  489. struct IOClipReq *ior;
  490. {
  491. char buffer[256];
  492.  
  493. ior->io_Command = CMD_READ;
  494. ior->io_Data    = (STRPTR)buffer;
  495. ior->io_Length  = 254;
  496.  
  497.  
  498. /* falls through immediately if io_Actual == 0 */
  499.  
  500. while (ior->io_Actual)
  501.       {
  502.       if (DoIO( (struct IORequest *) ior))
  503.           break;
  504.       }
  505. }
  506.  
  507. /****** cbio/CBFreeBuf **********************************************
  508. *
  509. *   NAME
  510. *       CBFreeBuf() -- Free buffer allocated by CBReadCHRS()
  511. *
  512. *   SYNOPSIS
  513. *       CBFreeBuf( buf )
  514. *
  515. *       void CBFreeBuf( struct cbbuf * )
  516. *
  517. *   FUNCTION
  518. *       Frees a buffer allocated by CBReadCHRS().
  519. *
  520. *********************************************************************/
  521.  
  522. void CBFreeBuf(buf)
  523. struct cbbuf *buf;
  524. {
  525. FreeMem(buf->mem, buf->size);
  526. FreeMem(buf, sizeof(struct cbbuf));
  527. }
  528.