home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d8xx / d832 / term.lha / Term / term-3.1-Source.lha / termClip.c < prev    next >
C/C++ Source or Header  |  1993-02-18  |  8KB  |  478 lines

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