home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / Clip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  8.0 KB  |  463 lines

  1. /*
  2. **    Clip.c
  3. **
  4. **    Clipboard support routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #ifndef _GLOBAL_H
  11. #include "Global.h"
  12. #endif
  13.  
  14. STATIC struct IFFHandle    *ClipHandle;
  15. STATIC STRPTR         ClipBuffer,
  16.              ClipIndex;
  17. STATIC LONG         ClipSize,
  18.              ClipLength;
  19.  
  20.     /* CloseClip():
  21.      *
  22.      *    Close clipboard handle, stop reading.
  23.      */
  24.  
  25. VOID
  26. CloseClip()
  27. {
  28.     if(ClipHandle)
  29.     {
  30.         CloseIFF(ClipHandle);
  31.  
  32.         if(ClipHandle -> iff_Stream)
  33.             CloseClipboard((struct ClipboardHandle *)ClipHandle -> iff_Stream);
  34.  
  35.         FreeIFF(ClipHandle);
  36.  
  37.         ClipHandle = NULL;
  38.     }
  39.  
  40.     FreeVecPooled(ClipBuffer);
  41.     ClipBuffer = NULL;
  42. }
  43.  
  44.     /* GetClip(STRPTR Buffer,LONG Len,BOO Filter):
  45.      *
  46.      *    Read text data from clipboard and put it into the supplied buffer.
  47.      */
  48.  
  49. LONG
  50. GetClip(STRPTR Buffer,LONG Len,BOOL Filter)
  51. {
  52.     LONG    BytesPut = 0;
  53.     LONG    c;
  54.  
  55.         /* Is the read buffer already exhausted? */
  56.  
  57.     if(!ClipLength)
  58.     {
  59.             /* Is there still any data to read? */
  60.  
  61.         if(ClipSize)
  62.         {
  63.             LONG Size = MIN(ClipSize,1024);
  64.  
  65.                 /* Try to read the data and return failure if necessary. */
  66.  
  67.             if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
  68.                 return(-1);
  69.             else
  70.             {
  71.                 ClipSize    -= Size;
  72.                 ClipLength     = Size;
  73.                 ClipIndex     = ClipBuffer;
  74.             }
  75.         }
  76.         else
  77.         {
  78.                 /* We just parsed a single chunk, now go on and
  79.                  * look for another one.
  80.                  */
  81.  
  82.             if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  83.             {
  84.                 struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
  85.  
  86.                 if(ContextNode -> cn_Type == ID_FTXT)
  87.                 {
  88.                     LONG Size;
  89.  
  90.                     ClipSize    = ContextNode -> cn_Size;
  91.                     Size        = MIN(ClipSize,1024);
  92.  
  93.                     if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
  94.                         return(-1);
  95.                     else
  96.                     {
  97.                         ClipSize    -= Size;
  98.                         ClipLength     = Size;
  99.                         ClipIndex     = ClipBuffer;
  100.                     }
  101.                 }
  102.                 else
  103.                     return(-1);
  104.             }
  105.             else
  106.                 return(-1);
  107.         }
  108.     }
  109.  
  110.     while(ClipLength && BytesPut < Len)
  111.     {
  112.         ClipLength--;
  113.  
  114.         switch(c = *ClipIndex++)
  115.         {
  116.             case '\r':
  117.  
  118.                 break;
  119.  
  120.             default:
  121.  
  122.                 if(IsPrintable[c])
  123.                 {
  124.                     *Buffer++ = c;
  125.                     BytesPut++;
  126.                 }
  127.  
  128.                 break;
  129.         }
  130.     }
  131.  
  132.     return(BytesPut);
  133. }
  134.  
  135.     /* OpenClip():
  136.      *
  137.      *    Open the clipboard for sequential reading.
  138.      */
  139.  
  140. LONG
  141. OpenClip(LONG Unit)
  142. {
  143.     LONG Error;
  144.  
  145.     CloseClip();
  146.  
  147.     if(ClipBuffer = (STRPTR)AllocVecPooled(1024,MEMF_ANY))
  148.     {
  149.         if(ClipHandle = AllocIFF())
  150.         {
  151.             if(ClipHandle -> iff_Stream = (ULONG)OpenClipboard(Unit))
  152.             {
  153.                 InitIFFasClip(ClipHandle);
  154.  
  155.                 if(!OpenIFF(ClipHandle,IFFF_READ))
  156.                 {
  157.                     if(!StopChunk(ClipHandle,ID_FTXT,ID_CHRS))
  158.                     {
  159.                         if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  160.                         {
  161.                             struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
  162.  
  163.                             if(ContextNode -> cn_Type == ID_FTXT)
  164.                             {
  165.                                 ClipSize    = ContextNode -> cn_Size;
  166.                                 ClipLength    = 0;
  167.  
  168.                                 return(CLIPERR_NONE);
  169.                             }
  170.                             else
  171.                                 Error = CLIPERR_NOTEXT;
  172.                         }
  173.                         else
  174.                             Error = CLIPERR_NOTEXT;
  175.                     }
  176.                     else
  177.                         Error = CLIPERR_IFF;
  178.                 }
  179.                 else
  180.                     Error = CLIPERR_OPEN;
  181.             }
  182.             else
  183.                 Error = CLIPERR_OPEN;
  184.         }
  185.         else
  186.             Error = CLIPERR_MEM;
  187.     }
  188.     else
  189.         Error = CLIPERR_MEM;
  190.  
  191.     CloseClip();
  192.  
  193.     return(Error);
  194. }
  195.  
  196.     /* GetClipContents(LONG Unit,APTR *Buffer,LONG *Size):
  197.      *
  198.      *    Merge text contents of the clipboard into a single string.
  199.      */
  200.  
  201. BOOL
  202. GetClipContents(LONG Unit,APTR *Buffer,LONG *Size)
  203. {
  204.     struct IFFHandle    *Handle;
  205.     LONG             Bytes = 0;
  206.     APTR             Store = NULL;
  207.  
  208.     if(Handle = AllocIFF())
  209.     {
  210.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Unit))
  211.         {
  212.             InitIFFasClip(Handle);
  213.  
  214.             if(!OpenIFF(Handle,IFFF_READ))
  215.             {
  216.                 if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  217.                 {
  218.                     struct ContextNode *Node;
  219.  
  220.                     while(!ParseIFF(Handle,IFFPARSE_SCAN))
  221.                     {
  222.                         Node = CurrentChunk(Handle);
  223.  
  224.                         if(Node -> cn_Type == ID_FTXT)
  225.                             Bytes += Node -> cn_Size;
  226.                     }
  227.                 }
  228.  
  229.                 CloseIFF(Handle);
  230.             }
  231.  
  232.             if(Bytes)
  233.             {
  234.                 if(!OpenIFF(Handle,IFFF_READ))
  235.                 {
  236.                     if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  237.                     {
  238.                         if(Store = AllocVecPooled(Bytes,MEMF_ANY))
  239.                         {
  240.                             STRPTR             Index        = Store;
  241.                             LONG             BytesRead    = 0;
  242.                             struct ContextNode    *Node;
  243.  
  244.                             while(!ParseIFF(Handle,IFFPARSE_SCAN) && BytesRead < Bytes)
  245.                             {
  246.                                 Node = CurrentChunk(Handle);
  247.  
  248.                                 if(Node -> cn_Type == ID_FTXT)
  249.                                 {
  250.                                     LONG Count = Node -> cn_Size;
  251.  
  252.                                     if(BytesRead + Count > Bytes)
  253.                                         Count = Bytes - BytesRead;
  254.  
  255.                                     if(Count > 0)
  256.                                     {
  257.                                         if((Count = ReadChunkBytes(Handle,Index,Count)) > 0)
  258.                                         {
  259.                                             Index        += Count;
  260.                                             BytesRead    += Count;
  261.                                         }
  262.                                     }
  263.                                 }
  264.                             }
  265.  
  266.                             Bytes = BytesRead;
  267.                         }
  268.                     }
  269.  
  270.                     CloseIFF(Handle);
  271.                 }
  272.             }
  273.  
  274.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  275.         }
  276.  
  277.         FreeIFF(Handle);
  278.     }
  279.  
  280.     if(Store && !Bytes)
  281.     {
  282.         FreeVecPooled(Store);
  283.  
  284.         Store = NULL;
  285.     }
  286.  
  287.     *Buffer    = Store;
  288.     *Size    = Bytes;
  289.  
  290.     return((BOOL)(Store != NULL));
  291. }
  292.  
  293.     /* AddClip(STRPTR Buffer,LONG Size):
  294.      *
  295.      *    Merge previous clipboard contents with new text,
  296.      *    then store the new string in the clipboard.
  297.      */
  298.  
  299. BOOL
  300. AddClip(STRPTR Buffer,LONG Size)
  301. {
  302.     LONG    Bytes;
  303.     APTR    Store;
  304.  
  305.     if(GetClipContents(Config -> ClipConfig -> ClipboardUnit,&Store,&Bytes))
  306.     {
  307.         struct IFFHandle    *Handle;
  308.         BOOL             Success = FALSE;
  309.  
  310.         if(Handle = AllocIFF())
  311.         {
  312.             if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  313.             {
  314.                 InitIFFasClip(Handle);
  315.  
  316.                 if(!OpenIFF(Handle,IFFF_WRITE))
  317.                 {
  318.                     if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  319.                     {
  320.                         if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  321.                         {
  322.                             if(WriteChunkBytes(Handle,Store,Bytes) == Bytes)
  323.                             {
  324.                                 if(WriteChunkBytes(Handle,Buffer,Size) == Size)
  325.                                 {
  326.                                     if(!PopChunk(Handle))
  327.                                         Success = TRUE;
  328.                                 }
  329.                             }
  330.                         }
  331.                     }
  332.  
  333.                     if(Success)
  334.                     {
  335.                         if(PopChunk(Handle))
  336.                             Success = FALSE;
  337.                     }
  338.  
  339.                     CloseIFF(Handle);
  340.                 }
  341.  
  342.                 CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  343.             }
  344.  
  345.             FreeIFF(Handle);
  346.         }
  347.  
  348.         FreeVecPooled(Store);
  349.  
  350.         return(Success);
  351.     }
  352.     else
  353.         return(SaveClip(Buffer,Size));
  354. }
  355.  
  356.     /* SaveClip(STRPTR Buffer,LONG Size):
  357.      *
  358.      *    Send a given text buffer to the clipboard.
  359.      */
  360.  
  361. BOOL
  362. SaveClip(STRPTR Buffer,LONG Size)
  363. {
  364.     BOOL Success = FALSE;
  365.  
  366.     if(Size > 0)
  367.     {
  368.         struct IFFHandle *Handle;
  369.  
  370.         if(Handle = AllocIFF())
  371.         {
  372.             if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  373.             {
  374.                 InitIFFasClip(Handle);
  375.  
  376.                 if(!OpenIFF(Handle,IFFF_WRITE))
  377.                 {
  378.                     if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  379.                     {
  380.                         if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  381.                         {
  382.                             if(WriteChunkBytes(Handle,Buffer,Size) == Size)
  383.                             {
  384.                                 if(!PopChunk(Handle))
  385.                                     Success = TRUE;
  386.                             }
  387.                         }
  388.                     }
  389.  
  390.                     if(Success)
  391.                     {
  392.                         if(PopChunk(Handle))
  393.                             Success = FALSE;
  394.                     }
  395.  
  396.                     CloseIFF(Handle);
  397.                 }
  398.  
  399.                 CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  400.             }
  401.  
  402.             FreeIFF(Handle);
  403.         }
  404.     }
  405.  
  406.     return(Success);
  407. }
  408.  
  409.     /* LoadClip(STRPTR Buffer,LONG Size):
  410.      *
  411.      *    Put the contents of the clipboard into a given
  412.      *    buffer. Note that only the first FTXT chunk will
  413.      *    be read. Since this code will only be called by
  414.      *    the clipboard server process which serves the
  415.      *    string gadget editing hook, this will hopefully
  416.      *    not be fatal. If you want more data to be read,
  417.      *    including multiple FTXT chunks, use the OpenClip(),
  418.      *    GetClip(), CloseClip() combo above.
  419.      */
  420.  
  421. LONG
  422. LoadClip(STRPTR Buffer,LONG Size)
  423. {
  424.     struct IFFHandle    *Handle;
  425.     LONG             Bytes = 0;
  426.  
  427.     if(Handle = AllocIFF())
  428.     {
  429.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  430.         {
  431.             InitIFFasClip(Handle);
  432.  
  433.             if(!OpenIFF(Handle,IFFF_READ))
  434.             {
  435.                 if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  436.                 {
  437.                     if(!ParseIFF(Handle,IFFPARSE_SCAN))
  438.                     {
  439.                         struct ContextNode *ContextNode = CurrentChunk(Handle);
  440.  
  441.                         if(ContextNode -> cn_Type == ID_FTXT)
  442.                         {
  443.                             if(Size > ContextNode -> cn_Size)
  444.                                 Size = ContextNode -> cn_Size;
  445.  
  446.                             if(ReadChunkRecords(Handle,Buffer,Size,1))
  447.                                 Bytes = Size;
  448.                         }
  449.                     }
  450.                 }
  451.  
  452.                 CloseIFF(Handle);
  453.             }
  454.  
  455.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  456.         }
  457.  
  458.         FreeIFF(Handle);
  459.     }
  460.  
  461.     return(Bytes);
  462. }
  463.