home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 1.2 / amidev_cd_12.iso / reference_library / devices / dev_examples / cbio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-20  |  13.5 KB  |  572 lines

  1. /* Cbio.c
  2.  *
  3.  * Provide standard clipboard device interface routines
  4.  *            such as Open, Close, Post, Read, Write, etc.
  5.  *
  6.  * Compile with SAS C 5.10: LC -b1 -cfistq -v -y
  7.  *
  8.  *  NOTE - These functions are useful for writing, and reading simple
  9.  *         FTXT.  Writing, and reading complex FTXT, ILBM, etc.,
  10.  *         requires more work - under 2.0 it is highly recommended that
  11.  *         you use iffparse.library.
  12.  */
  13.  
  14. #include <exec/types.h>
  15. #include <exec/ports.h>
  16. #include <exec/io.h>
  17. #include <exec/memory.h>
  18. #include <devices/clipboard.h>
  19.  
  20. #define CBIO 1
  21.  
  22. #include "cb.h"
  23.  
  24. #include <clib/exec_protos.h>
  25. #include <clib/alib_protos.h>
  26.  
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30.  
  31. /****** cbio/CBOpen *************************************************
  32. *
  33. *   NAME
  34. *       CBOpen() - Open the clipboard.device
  35. *
  36. *   SYNOPSIS
  37. *       ior = CBOpen(unit)
  38. *
  39. *       struct IOClipReq *CBOpen( ULONG )
  40. *
  41. *   FUNCTION
  42. *       Opens the clipboard.device.  A clipboard unit number
  43. *       must be passed in as an argument.  By default, the unit
  44. *       number should be 0 (currently valid unit numbers are
  45. *       0-255).
  46. *
  47. *   RESULTS
  48. *       A pointer to an initialized IOClipReq structure, or
  49. *       a NULL pointer if the function fails.
  50. *
  51. *********************************************************************/
  52.  
  53. struct IOClipReq *CBOpen(unit)
  54. ULONG unit;
  55. {
  56. struct MsgPort *mp;
  57. struct IOStdReq *ior;
  58.  
  59. if (mp = CreatePort(0L,0L))
  60.     {
  61.     if (ior=CreateExtIO(mp,sizeof(struct IOClipReq)))
  62.         {
  63.         if (!(OpenDevice("clipboard.device",unit,ior,0L)))
  64.             {
  65.             return((struct IOClipReq *)ior);
  66.             }
  67.         DeleteExtIO(ior);
  68.         }
  69.     DeletePort(mp);
  70.     }
  71. return(NULL);
  72.  
  73. }
  74.  
  75. /****** cbio/CBClose ************************************************
  76. *
  77. *   NAME
  78. *       CBClose() - Close the clipboard.device
  79. *
  80. *   SYNOPSIS
  81. *       CBClose()
  82. *
  83. *       void CBClose()
  84. *
  85. *   FUNCTION
  86. *       Close the clipboard.device unit which was opened via
  87. *       CBOpen().
  88. *
  89. *********************************************************************/
  90.  
  91. void CBClose(ior)
  92. struct IOClipReq *ior;
  93. {
  94. struct MsgPort *mp;
  95.  
  96. mp = ior->io_Message.mn_ReplyPort;
  97.  
  98. CloseDevice((struct IOStdReq *)ior);
  99. DeleteExtIO((struct IOStdReq *)ior);
  100. DeletePort(mp);
  101.  
  102. }
  103.  
  104. /****** cbio/CBWriteFTXT *********************************************
  105. *
  106. *   NAME
  107. *       CBWriteFTXT() - Write a string of text to the clipboard.device
  108. *
  109. *   SYNOPSIS
  110. *       success = CBWriteFTXT( ior, string)
  111. *
  112. *       int CBWriteFTXT(struct IOClipReq *, char *)
  113. *
  114. *   FUNCTION
  115. *       Write a NULL terminated string of text to the clipboard.
  116. *       The string will be written in simple FTXT format.
  117. *
  118. *       Note that this function pads odd length strings automatically
  119. *       to conform to the IFF standard.
  120. *
  121. *   RESULTS
  122. *       TRUE if the write succeeded, else FALSE.
  123. *
  124. *********************************************************************/
  125.  
  126. int CBWriteFTXT(ior,string)
  127. struct IOClipReq *ior;
  128. char *string;
  129. {
  130.  
  131. ULONG length, slen;
  132. BOOL odd;
  133. int success;
  134.  
  135. slen = strlen(string);
  136. odd = (slen & 1);               /* pad byte flag */
  137.  
  138. length = (odd) ? slen+1 : slen;
  139.  
  140. /* initial set-up for Offset, Error, and ClipID */
  141.  
  142. ior->io_Offset = 0;
  143. ior->io_Error  = 0;
  144. ior->io_ClipID = 0;
  145.  
  146.  
  147. /* Create the IFF header information */
  148.  
  149. WriteLong(ior, (long *) "FORM");     /* "FORM"             */
  150. length+=12L;                         /* + "[size]FTXTCHRS" */
  151. WriteLong(ior, &length);             /* total length       */
  152. WriteLong(ior, (long *) "FTXT");     /* "FTXT"             */
  153. WriteLong(ior, (long *) "CHRS");     /* "CHRS"             */
  154. WriteLong(ior, &slen);               /* string length      */
  155.  
  156. /* Write string */
  157. ior->io_Data    = (STRPTR)string;
  158. ior->io_Length  = slen;
  159. ior->io_Command = CMD_WRITE;
  160. DoIO( (struct IORequest *) ior);
  161.  
  162. /* Pad if needed */
  163. if (odd)
  164.     {
  165.     ior->io_Data   = (STRPTR)"";
  166.     ior->io_Length = 1L;
  167.     DoIO( (struct IORequest *) ior);
  168.     }
  169.  
  170. /* Tell the clipboard we are done writing */
  171.  
  172. ior->io_Command=CMD_UPDATE;
  173. DoIO( (struct IORequest *) ior);
  174.  
  175. /* Check if io_Error was set by any of the preceding IO requests */
  176. success = ior->io_Error ? FALSE : TRUE;
  177.  
  178. return(success);
  179. }
  180.  
  181. WriteLong(ior, ldata)
  182. struct IOClipReq *ior;
  183. long *ldata;
  184. {
  185.  
  186. ior->io_Data    = (STRPTR)ldata;
  187. ior->io_Length  = 4L;
  188. ior->io_Command = CMD_WRITE;
  189. DoIO( (struct IORequest *) ior);
  190.  
  191. if (ior->io_Actual == 4)
  192.     {
  193.     return( ior->io_Error ? FALSE : TRUE);
  194.     }
  195.  
  196. return(FALSE);
  197.  
  198. }
  199.  
  200.  
  201. /****** cbio/CBQueryFTXT **********************************************
  202. *
  203. *   NAME
  204. *       CBQueryFTXT() - Check to see if clipboard contains FTXT
  205. *
  206. *   SYNOPSIS
  207. *       result = CBQueryFTXT( ior )
  208. *
  209. *       int CBQueryFTXT(struct IOClipReq *)
  210. *
  211. *   FUNCTION
  212. *       Check to see if the clipboard contains FTXT.  If so,
  213. *       call CBReadCHRS() one or more times until all CHRS
  214. *       chunks have been read.
  215. *
  216. *   RESULTS
  217. *       TRUE if the clipboard contains an FTXT chunk, else FALSE.
  218. *
  219. *   NOTES
  220. *       If this function returns TRUE, you must either call
  221. *       CBReadCHRS() until CBReadCHRS() returns FALSE, or
  222. *       call CBReadDone() to tell the clipboard.device that
  223. *       you are done reading.
  224. *
  225. *
  226. *********************************************************************/
  227.  
  228. int CBQueryFTXT(ior)
  229. struct IOClipReq *ior;
  230. {
  231. ULONG cbuff[4];
  232.  
  233.  
  234. /* initial set-up for Offset, Error, and ClipID */
  235.  
  236. ior->io_Offset = 0;
  237. ior->io_Error  = 0;
  238. ior->io_ClipID = 0;
  239.  
  240. /* Look for "FORM[size]FTXT" */
  241.  
  242. ior->io_Command = CMD_READ;
  243. ior->io_Data    = (STRPTR)cbuff;
  244. ior->io_Length  = 12;
  245.  
  246. DoIO( (struct IORequest *) ior);
  247.  
  248.  
  249. /* Check to see if we have at least 12 bytes */
  250.  
  251. if (ior->io_Actual == 12L)
  252.     {
  253.     /* Check to see if it starts with "FORM" */
  254.     if (cbuff[0] == ID_FORM)
  255.         {
  256.         /* Check to see if its "FTXT" */
  257.         if (cbuff[2] == ID_FTXT)
  258.             return(TRUE);
  259.         }
  260.  
  261.     /* It's not "FORM[size]FTXT", so tell clipboard we are done */
  262.     }
  263.  
  264. CBReadDone(ior);
  265.  
  266. return(FALSE);
  267. }
  268.  
  269.  
  270. /****** cbio/CBReadCHRS **********************************************
  271. *
  272. *   NAME
  273. *       CBReadCHRS() - Reads the next CHRS chunk from clipboard
  274. *
  275. *   SYNOPSIS
  276. *       cbbuf = CBReadCHRS( ior )
  277. *
  278. *       struct cbbuf *CBReadCHRS(struct IOClipReq * )
  279. *
  280. *   FUNCTION
  281. *       Reads and returns the text in the next CHRS chunk
  282. *       (if any) from the clipboard.
  283. *
  284. *       Allocates memory to hold data in next CHRS chunk.
  285. *
  286. *   RESULTS
  287. *       Pointer to a cbbuf struct (see cb.h), or a NULL indicating
  288. *       a failure (e.g., not enough memory, or no more CHRS chunks).
  289. *
  290. *       ***Important***
  291. *
  292. *       The caller must free the returned buffer when done with the
  293. *       data by calling CBFreeBuf().
  294. *
  295. *   NOTES
  296. *       This function strips NULL bytes, however, a full reader may
  297. *       wish to perform more complete checking to verify that the
  298. *       text conforms to the IFF standard (stripping data as required).
  299. *
  300. *       Under 2.0, the AllocVec() function could be used instead of
  301. *       AllocMem() in which case the cbbuf structure may not be
  302. *       needed.
  303. *
  304. *********************************************************************/
  305.  
  306. struct cbbuf *CBReadCHRS(ior)
  307. struct IOClipReq *ior;
  308. {
  309. ULONG chunk,size;
  310. struct cbbuf *buf;
  311. int looking;
  312.  
  313. /* Find next CHRS chunk */
  314.  
  315. looking = TRUE;
  316. buf = NULL;
  317.  
  318. while (looking)
  319.       {
  320.       looking = FALSE;
  321.  
  322.       if (ReadLong(ior,&chunk))
  323.           {
  324.           /* Is CHRS chunk ? */
  325.           if (chunk == ID_CHRS)
  326.               {
  327.               /* Get size of chunk, and copy data */
  328.               if (ReadLong(ior,&size))
  329.                   {
  330.                   if (size)
  331.                       buf=FillCBData(ior,size);
  332.                   }
  333.               }
  334.  
  335.             /* If not, skip to next chunk */
  336.           else
  337.               {
  338.               if (ReadLong(ior,&size))
  339.                   {
  340.                    looking = TRUE;
  341.                    if (size & 1)
  342.                        size++;    /* if odd size, add pad byte */
  343.  
  344.                     ior->io_Offset += size;
  345.                   }
  346.               }
  347.           }
  348.       }
  349.  
  350. if (buf == NULL)
  351.     CBReadDone(ior);        /* tell clipboard we are done */
  352.  
  353. return(buf);
  354. }
  355.  
  356.  
  357. ReadLong(ior, ldata)
  358. struct IOClipReq *ior;
  359. ULONG *ldata;
  360. {
  361. ior->io_Command = CMD_READ;
  362. ior->io_Data    = (STRPTR)ldata;
  363. ior->io_Length  = 4L;
  364.  
  365. DoIO( (struct IORequest *) ior);
  366.  
  367. if (ior->io_Actual == 4)
  368.     {
  369.     return( ior->io_Error ? FALSE : TRUE);
  370.     }
  371.  
  372. return(FALSE);
  373. }
  374.  
  375. struct cbbuf *FillCBData(ior,size)
  376. struct IOClipReq *ior;
  377. ULONG size;
  378. {
  379. register UBYTE *to,*from;
  380. register ULONG x,count;
  381.  
  382. ULONG length;
  383. struct cbbuf *buf,*success;
  384.  
  385. success = NULL;
  386.  
  387. if (buf = AllocMem(sizeof(struct cbbuf),MEMF_PUBLIC))
  388.     {
  389.  
  390.     length = size;
  391.     if (size & 1)
  392.         length++;            /* if odd size, read 1 more */
  393.  
  394.     if (buf->mem = AllocMem(length+1L,MEMF_PUBLIC))
  395.         {
  396.         buf->size = length+1L;
  397.  
  398.         ior->io_Command = CMD_READ;
  399.         ior->io_Data    = (STRPTR)buf->mem;
  400.         ior->io_Length  = length;
  401.  
  402.         to = buf->mem;
  403.         count = 0L;
  404.  
  405.         if (!(DoIO( (struct IOStdReq *) ior)))
  406.             {
  407.             if (ior->io_Actual == length)
  408.                 {
  409.                 success = buf;      /* everything succeeded */
  410.  
  411.                 /* strip NULL bytes */
  412.                 for (x=0, from=buf->mem ;x<size;x++)
  413.                      {
  414.                      if (*from)
  415.                          {
  416.                          *to = *from;
  417.                          to++;
  418.                          count++;
  419.                          }
  420.  
  421.                      from++;
  422.                      }
  423.                 *to=0x0;            /* Null terminate buffer */
  424.                 buf->count = count; /* cache count of chars in buf */
  425.                 }
  426.             }
  427.  
  428.         if (!(success))
  429.             FreeMem(buf->mem,buf->size);
  430.         }
  431.     if (!(success))
  432.         FreeMem(buf,sizeof(struct cbbuf));
  433.     }
  434.  
  435. return(success);
  436. }
  437.  
  438. /****** cbio/CBReadDone **********************************************
  439. *
  440. *   NAME
  441. *       CBReadDone() - Tell clipboard we are done reading
  442. *
  443. *   SYNOPSIS
  444. *       CBReadDone( ior )
  445. *
  446. *       void CBReadDone(struct IOClipReq * )
  447. *
  448. *   FUNCTION
  449. *       Reads past end of clipboard file until io_Actual is equal to 0.
  450. *       This is tells the clipboard that we are done reading.
  451. *
  452. *********************************************************************/
  453.  
  454. void CBReadDone(ior)
  455. struct IOClipReq *ior;
  456. {
  457. char buffer[256];
  458.  
  459. ior->io_Command = CMD_READ;
  460. ior->io_Data    = (STRPTR)buffer;
  461. ior->io_Length  = 254;
  462.  
  463.  
  464. /* falls through immediately if io_Actual == 0 */
  465.  
  466. while (ior->io_Actual)
  467.       {
  468.       if (DoIO( (struct IORequest *) ior))
  469.           break;
  470.       }
  471. }
  472.  
  473. /****** cbio/CBFreeBuf **********************************************
  474. *
  475. *   NAME
  476. *       CBFreeBuf() - Free buffer allocated by CBReadCHRS()
  477. *
  478. *   SYNOPSIS
  479. *       CBFreeBuf( buf )
  480. *
  481. *       void CBFreeBuf( struct cbbuf * )
  482. *
  483. *   FUNCTION
  484. *       Frees a buffer allocated by CBReadCHRS().
  485. *
  486. *********************************************************************/
  487.  
  488. void CBFreeBuf(buf)
  489. struct cbbuf *buf;
  490. {
  491. FreeMem(buf->mem, buf->size);
  492. FreeMem(buf, sizeof(struct cbbuf));
  493. }
  494.  
  495.  
  496. *************************************************************************
  497. *        Hookface.asm
  498. *        assembly routines for Chtest
  499. *
  500. *        Assemble with Adapt  hx68 hookface.a to hookface.o
  501. *        Link with Changehook_Test.o as shown in Changehook_Test.c header
  502. *
  503. *************************************************************************
  504.         INCDIR  'include:'
  505.         INCLUDE 'exec/types.i'
  506.         INCLUDE 'utility/hooks.i'
  507.         xdef    _callHook
  508.         xdef    _callHookPkt
  509.         xdef    _hookEntry
  510.         xdef    _stubReturn
  511. *************************************************************************
  512. * new hook standard
  513. * use struct Hook (with minnode at the top)
  514. *
  515. * *** register calling convention: ***
  516. *       A0 - pointer to hook itself
  517. *       A1 - pointer to parameter packed ("message")
  518. *       A2 - Hook specific address data ("object," e.g, gadget )
  519. *
  520. * ***  C conventions: ***
  521. * Note that parameters are in unusual register order: a0, a2, a1.
  522. * This is to provide a performance boost for assembly language
  523. * programming (the object in a2 is most frequently untouched).
  524. * It is also no problem in "register direct" C function parameters.
  525. *
  526. * calling through a hook
  527. *       callHook( hook, object, msgid, p1, p2, ... );
  528. *       callHookPkt( hook, object, msgpkt );
  529. *
  530. * using a C function:   CFunction( hook, object, message );
  531. *       hook.h_Entry = hookEntry;
  532. *       hook.h_SubEntry = CFunction;
  533. *************************************************************************
  534. * C calling hook interface for prepared message packet
  535. _callHookPkt:
  536.         movem.l a2/a6,-(sp)     ; protect
  537.         move.l  12(sp),a0       ; hook
  538.         move.l  16(sp),a2       ; object
  539.         move.l  20(sp),a1       ; message
  540.         ; ------ now have registers ready, invoke function
  541.         pea.l   hreturn(pc)
  542.         move.l  h_Entry(a0),-(sp)       ; old rts-jump trick
  543.         rts
  544. hreturn:
  545.         movem.l (sp)+,a2/a6
  546.         rts
  547.  
  548. * C calling hook interface for "varargs message packet"
  549. _callHook:
  550.         movem.l a2/a6,-(sp)     ; protect
  551.         move.l  12(sp),a0       ; hook
  552.         move.l  16(sp),a2       ; object
  553.         lea.l   20(sp),a1       ; message
  554.         ; ------ now have registers ready, invoke function
  555.         pea.l   hpreturn(pc)
  556.         move.l  h_Entry(a0),-(sp)       ; old rts-jump trick
  557.         rts
  558. hpreturn:
  559.         movem.l (sp)+,a2/a6
  560.         rts
  561.  
  562. * entry interface for C code (large-code, stack parameters)
  563. _hookEntry:
  564.         move.l  a1,-(sp)
  565.         move.l  a2,-(sp)
  566.         move.l  a0,-(sp)
  567.         move.l  h_SubEntry(a0),a0       ; C entry point
  568.         jsr     (a0)
  569.         lea     12(sp),sp
  570. _stubReturn:
  571.         rts
  572.