home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d8xx / d834 / pinfocom.lha / PInfoCom / pinfocom-3.0.lha / amiga_clip.c next >
C/C++ Source or Header  |  1992-11-03  |  7KB  |  358 lines

  1. /* amiga_clip.c
  2.  *
  3.  *  ``pinfocom'' -- a portable Infocom Inc. data file interpreter.
  4.  *  Copyright (C) 1987-1992  InfoTaskForce
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; see the file COPYING.  If not, write to the
  18.  *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  * $Header$
  23.  */
  24.  
  25. #ifndef _AMIGA_GLOBAL_H
  26. #include "amiga_global.h"
  27. #endif    /* !_AMIGA_GLOBAL_H */
  28.  
  29.     /* ClipClose():
  30.      *
  31.      *    Close clipboard handle, stop reading.
  32.      */
  33.  
  34. VOID
  35. ClipClose()
  36. {
  37.         /* Did we allocate a clipboard handle? */
  38.  
  39.     if(ClipHandle)
  40.     {
  41.             /* Close the handle. */
  42.  
  43.         CloseIFF(ClipHandle);
  44.  
  45.             /* Close the stream. */
  46.  
  47.         if(ClipHandle -> iff_Stream)
  48.             CloseClipboard((struct ClipboardHandle *)ClipHandle -> iff_Stream);
  49.  
  50.             /* Free the handle. */
  51.  
  52.         FreeIFF(ClipHandle);
  53.  
  54.             /* Leave no traces. */
  55.  
  56.         ClipHandle = NULL;
  57.     }
  58.  
  59.         /* Did we allocate a clipboard buffer? */
  60.  
  61.     if(ClipBuffer)
  62.     {
  63.             /* Release the buffer. */
  64.  
  65.         FreeVec(ClipBuffer);
  66.  
  67.             /* Leave no traces. */
  68.  
  69.         ClipBuffer = NULL;
  70.     }
  71.  
  72.         /* Reset input source. */
  73.  
  74.     ClipInput = FALSE;
  75. }
  76.  
  77.     /* ClipSave(const STRPTR Buffer,const LONG Len):
  78.      *
  79.      *    Save text to the clipboard.
  80.      */
  81.  
  82. VOID
  83. ClipSave(const STRPTR Buffer,const LONG Len)
  84. {
  85.         /* Is iffparse.library available? */
  86.  
  87.     if(IFFParseBase)
  88.     {
  89.         struct IFFHandle *ClipHandle;
  90.  
  91.             /* Allocate iff handle. */
  92.  
  93.         if(ClipHandle = AllocIFF())
  94.         {
  95.                 /* Open the primary clipboard buffer for reading. */
  96.  
  97.             if(ClipHandle -> iff_Stream = (ULONG)OpenClipboard(PRIMARY_CLIP))
  98.             {
  99.                     /* Make it known as a clipboard handle. */
  100.  
  101.                 InitIFFasClip(ClipHandle);
  102.  
  103.                     /* Open the handle for reading. */
  104.  
  105.                 if(!OpenIFF(ClipHandle,IFFF_WRITE))
  106.                 {
  107.                         /* Push parent chunk on the stack. */
  108.  
  109.                     if(!PushChunk(ClipHandle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  110.                     {
  111.                             /* Push data chunk on the stack. */
  112.  
  113.                         if(!PushChunk(ClipHandle,0,ID_CHRS,Len))
  114.                         {
  115.                                 /* Write the data. */
  116.  
  117.                             WriteChunkBytes(ClipHandle,Buffer,Len);
  118.  
  119.                                 /* Pop the data chunk. */
  120.  
  121.                             PopChunk(ClipHandle);
  122.                         }
  123.  
  124.                             /* Pop the parent chunk. */
  125.  
  126.                         PopChunk(ClipHandle);
  127.                     }
  128.  
  129.                         /* Release the write handle. */
  130.  
  131.                     CloseIFF(ClipHandle);
  132.                 }
  133.  
  134.                     /* Close the clipboard stream. */
  135.  
  136.                 CloseClipboard((struct ClipboardHandle *)ClipHandle -> iff_Stream);
  137.             }
  138.  
  139.                 /* Free the write handle. */
  140.  
  141.             FreeIFF(ClipHandle);
  142.         }
  143.     }
  144. }
  145.  
  146.     /* ClipRead(STRPTR Buffer,LONG Len):
  147.      *
  148.      *    Read text data from clipboard and put it into the supplied buffer.
  149.      */
  150.  
  151. LONG
  152. ClipRead(STRPTR Buffer,const LONG Len)
  153. {
  154.     LONG BytesRead = 0;
  155.  
  156.         /* Is the read buffer already exhausted? */
  157.  
  158.     if(!ClipLength)
  159.     {
  160.             /* Is there still any data to read? */
  161.  
  162.         if(ClipSize)
  163.         {
  164.             LONG Size = MIN(ClipSize,CLIP_LENGTH);
  165.  
  166.                 /* Try to read the data and return failure if necessary. */
  167.  
  168.             if(ReadChunkRecords(ClipHandle,ClipBuffer,Size,1) < 1)
  169.                 return(-1);
  170.             else
  171.             {
  172.                 ClipSize    -= Size;
  173.                 ClipLength     = Size;
  174.                 ClipIndex     = ClipBuffer;
  175.             }
  176.         }
  177.         else
  178.         {
  179.                 /* We just parsed a single chunk, now go on and
  180.                  * look for another one.
  181.                  */
  182.  
  183.             if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  184.             {
  185.                 struct ContextNode *ContextNode;
  186.  
  187.                     /* Obtain the current chunk info. */
  188.  
  189.                 if(ContextNode = CurrentChunk(ClipHandle))
  190.                 {
  191.                         /* Did we find a text chunk? */
  192.  
  193.                     if(ContextNode -> cn_Type == ID_FTXT)
  194.                     {
  195.                         LONG Size;
  196.  
  197.                             /* Determine number of bytes to read. */
  198.  
  199.                         ClipSize    = ContextNode -> cn_Size;
  200.                         Size        = MIN(ClipSize,CLIP_LENGTH);
  201.  
  202.                             /* Read the data. */
  203.  
  204.                         if(ReadChunkRecords(ClipHandle,ClipBuffer,Size,1) < 1)
  205.                             return(-1);
  206.                         else
  207.                         {
  208.                                 /* Set up the data. */
  209.  
  210.                             ClipSize    -= Size;
  211.                             ClipLength     = Size;
  212.                             ClipIndex     = ClipBuffer;
  213.                         }
  214.                     }
  215.                     else
  216.                         return(-1);
  217.                 }
  218.                 else
  219.                     return(-1);
  220.             }
  221.             else
  222.                 return(-1);
  223.         }
  224.     }
  225.  
  226.         /* The following loop processes the contents of
  227.          * the clipboard buffer read. Line feeds will be
  228.          * converted into carriage returns and non-printable
  229.          * characters will be filtered out.
  230.          */
  231.  
  232.     while(ClipLength && BytesRead < Len)
  233.     {
  234.         switch(*ClipIndex)
  235.         {
  236.                 /* Convert line feed,
  237.                  * use carriage return
  238.                  * verbatim, drop out
  239.                  * immediately.
  240.                  */
  241.  
  242.             case '\r':
  243.             case '\n':    *Buffer = '\r';
  244.  
  245.                     BytesRead++;
  246.  
  247.                         /* Return number of bytes read. */
  248.  
  249.                     return(BytesRead);
  250.  
  251.                 /* Process the rest, discard
  252.                  * non-printable characters.
  253.                  */
  254.  
  255.             default:    if(*ClipIndex >= ' ' && *ClipIndex <= '~')
  256.                     {
  257.                         *Buffer++ = *ClipIndex;
  258.  
  259.                         BytesRead++;
  260.                     }
  261.  
  262.                     break;
  263.         }
  264.  
  265.             /* Skip to the next byte. */
  266.  
  267.         ClipIndex++;
  268.         ClipLength--;
  269.     }
  270.  
  271.         /* Return number of bytes read. */
  272.  
  273.     return(BytesRead);
  274. }
  275.  
  276.     /* ClipOpen():
  277.      *
  278.      *    Open the clipboard for sequential reading.
  279.      */
  280.  
  281. Bool
  282. ClipOpen()
  283. {
  284.         /* Close any open handle. */
  285.  
  286.     ClipClose();
  287.  
  288.         /* Allocate new buffer. */
  289.  
  290.     if(ClipBuffer = (STRPTR)AllocVec(CLIP_LENGTH,MEMF_ANY))
  291.     {
  292.             /* Allocate iff handle. */
  293.  
  294.         if(ClipHandle = AllocIFF())
  295.         {
  296.                 /* Open the primary clipboard buffer for reading. */
  297.  
  298.             if(ClipHandle -> iff_Stream = (ULONG)OpenClipboard(PRIMARY_CLIP))
  299.             {
  300.                     /* Make it known as a clipboard handle. */
  301.  
  302.                 InitIFFasClip(ClipHandle);
  303.  
  304.                     /* Open the handle for reading. */
  305.  
  306.                 if(!OpenIFF(ClipHandle,IFFF_READ))
  307.                 {
  308.                         /* Stop within FTXT chunks at
  309.                          * the boundaries of CHRS data.
  310.                          */
  311.  
  312.                     if(!StopChunk(ClipHandle,ID_FTXT,ID_CHRS))
  313.                     {
  314.                             /* Parse the stream, looking
  315.                              * for a chunk...
  316.                              */
  317.  
  318.                         if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  319.                         {
  320.                             struct ContextNode *ContextNode;
  321.  
  322.                                 /* Obtain current chunk information. */
  323.  
  324.                             ContextNode = CurrentChunk(ClipHandle);
  325.  
  326.                                 /* Did we find what we were looking for? */
  327.  
  328.                             if(ContextNode -> cn_Type == ID_FTXT)
  329.                             {
  330.                                     /* Set up the data. */
  331.  
  332.                                 ClipSize    = ContextNode -> cn_Size;
  333.                                 ClipLength    = 0;
  334.  
  335.                                     /* Change input source. */
  336.  
  337.                                 ClipInput = TRUE;
  338.  
  339.                                     /* Return success. */
  340.  
  341.                                 return(TRUE);
  342.                             }
  343.                         }
  344.                     }
  345.                 }
  346.             }
  347.         }
  348.     }
  349.  
  350.         /* Clean up the remaining resources. */
  351.  
  352.     ClipClose();
  353.  
  354.         /* Return failure. */
  355.  
  356.     return(FALSE);
  357. }
  358.