home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / emacs-19.28-src.tgz / tar.out / fsf / emacs / src / amiga_clipboard.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  6KB  |  250 lines

  1. /* Amiga clipboard support
  2.    Copyright (C) 1994 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU Emacs.
  5.  
  6. GNU Emacs 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, or (at your option)
  9. any later version.
  10.  
  11. GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* CHFIXME: check if this file is uptodate */
  21.  
  22. #include "config.h"
  23. #include "lisp.h"
  24. #include "termchar.h"
  25. #include "amiga.h"
  26.  
  27. #include <stdio.h>
  28. #include <internal/devices.h>
  29.  
  30. #undef LONGBITS
  31.  
  32. #include <exec/types.h>
  33. #include <exec/io.h>
  34. #include <devices/clipboard.h>
  35. #include <libraries/iffparse.h>
  36. #include <utility/hooks.h>
  37.  
  38. #include <proto/exec.h>
  39. #include <proto/iffparse.h>
  40.  
  41. #ifdef USE_PROTOS
  42. #include "protos.h"
  43. #endif
  44.  
  45. #define  ID_FTXT    MAKE_ID('F','T','X','T')
  46. #define  ID_CHRS    MAKE_ID('C','H','R','S')
  47.  
  48. /*
  49.  * Text error messages for possible IFFERR_#? returns from various
  50.  * IFF routines.  To get the index into this array, take your IFFERR code,
  51.  * negate it, and subtract one.
  52.  *  idx = -error - 1;
  53.  */
  54. static char *far ifferrormsgs[] = {
  55.     "End of file (not an error).",
  56.     "End of context (not an error).",
  57.     "No lexical scope.",
  58.     "Insufficient memory.",
  59.     "Stream read error.",
  60.     "Stream write error.",
  61.     "Stream seek error.",
  62.     "File is corrupt.",
  63.     "IFF syntax error.",
  64.     "Not an IFF file.",
  65.     "Required call-back hook missing.",
  66.     "Return to client.  You should never see this."
  67. };
  68.  
  69. Lisp_Object amiga_new_clip;
  70. static struct IFFHandle *far iff;
  71. struct Library *IFFParseBase;
  72.  
  73. static struct IOClipReq *far ClipRequest;
  74. static struct Hook cliphook;
  75.  
  76. /* added __interrupt flag this disables stack checking for this function
  77.  * so we can compile with stack checking on.  -ch3/19/93. */
  78. static ULONG __saveds __asm __interrupt
  79. clip_change(    register __a0 struct Hook    *hook,
  80.         register __a2 VOID        *object,
  81.         register __a1 ULONG        *message )
  82. {
  83.     amiga_new_clip = 1;
  84.     return 0;
  85. }
  86.  
  87. static Lisp_Object clip_unwind(Lisp_Object dummy)
  88. {
  89.     CloseIFF (iff);
  90.     CloseClipboard ((struct ClipboardHandle *) iff->iff_Stream);
  91.  
  92.     return Qnil;
  93. }
  94.  
  95. static int clip_protect(void)
  96. {
  97.     int count = specpdl_ptr - specpdl;
  98.  
  99.     record_unwind_protect(clip_unwind, Qnil);
  100.  
  101.     return count;
  102. }
  103.  
  104. static long clip_check(long err)
  105. {
  106.     if(err) error ("Clipboard IO failed, error %ld: %s\n",
  107.            err, ifferrormsgs[-err - 1]);
  108.     return err;
  109. }
  110.  
  111.  
  112. static void cut(char *str, int size)
  113. {
  114.     int count;
  115.  
  116.     if (!(iff->iff_Stream = (ULONG) OpenClipboard (0)))
  117.     error ("Clipboard open failed.");
  118.  
  119.     count = clip_protect();
  120.  
  121.     /* Open clipbaord */
  122.     InitIFFasClip (iff);
  123.     clip_check(OpenIFF (iff, IFFF_WRITE));
  124.  
  125.     /* Write data */
  126.     clip_check(PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN));
  127.     clip_check(PushChunk(iff, 0, ID_CHRS, IFFSIZE_UNKNOWN));
  128.     if (WriteChunkBytes(iff, str, size) != size) clip_check(IFFERR_WRITE);
  129.     clip_check(PopChunk(iff));
  130.     clip_check(PopChunk(iff));
  131.  
  132.     /* & close */
  133.     unbind_to (count, Qnil);
  134. }
  135.  
  136. DEFUN ("amiga-cut", Famiga_cut, Samiga_cut,
  137.   1, 1, 0,
  138.   "Copy string into Amiga clipboard.")
  139.   (arg)
  140.      Lisp_Object arg;
  141. {
  142.     struct Lisp_String *p;
  143.  
  144.     CHECK_STRING (arg, 0);
  145.  
  146.     p = XSTRING (arg);
  147.     cut(p->data, p->size);
  148.  
  149.     return Qnil;
  150. }
  151.  
  152. DEFUN ("amiga-paste", Famiga_paste, Samiga_paste,
  153.   0, 0, 0,
  154.   "Returns text currently in the Amiga clipboard, or NIL if there is none.")
  155.   ()
  156. {
  157.     long err = 0;
  158.     Lisp_Object result = Qnil;
  159.     struct ContextNode  *cn;
  160.     int count;
  161.  
  162.     if (!(iff->iff_Stream = (ULONG) OpenClipboard (0)))
  163.     error ("Clipboard open failed.");
  164.  
  165.     count = clip_protect();
  166.  
  167.     /* Open clipbaord */
  168.     InitIFFasClip (iff);
  169.     clip_check(OpenIFF (iff, IFFF_READ));
  170.     clip_check(StopChunk(iff, ID_FTXT, ID_CHRS));
  171.  
  172.     /* Find the first FTXT CHRS chunks */
  173.     while (result == Qnil)
  174.     {
  175.     long err = ParseIFF(iff, IFFPARSE_SCAN);
  176.  
  177.     if (err == IFFERR_EOC) continue; /* enter next context */
  178.     else if (err == IFFERR_EOF) break;
  179.     else clip_check(err);
  180.  
  181.     /* We only asked to stop at FTXT CHRS chunks
  182.      * If no error we've hit a stop chunk
  183.      * Read the CHRS chunk data
  184.      */
  185.     cn = CurrentChunk(iff);
  186.  
  187.     if ((cn) && (cn->cn_Type == ID_FTXT) && (cn->cn_ID == ID_CHRS))
  188.     {
  189.         int size = cn->cn_Size, rlen;
  190.  
  191.         result = make_string("", size);
  192.  
  193.         if ((rlen = ReadChunkBytes(iff, XSTRING (result)->data, size)) != size)
  194.         if (rlen < 0) clip_check(rlen);
  195.         else clip_check(IFFERR_EOC);
  196.     }
  197.     }
  198.     unbind_to (count, Qnil);
  199.  
  200.     return result;
  201. }
  202.  
  203. void syms_of_amiga_clipboard(void)
  204. {
  205.     DEFVAR_BOOL ("amiga-new-clip", &amiga_new_clip,
  206.          "Set to t every time a new clip is put in the Amiga clipboard");
  207.     amiga_new_clip = 0;
  208.  
  209.     defsubr (&Samiga_cut);
  210.     defsubr (&Samiga_paste);
  211. }
  212.  
  213. void early_clipboard(void)
  214. {
  215.     IFFParseBase = 0;
  216. }
  217.  
  218. void init_clipboard(void)
  219. {
  220.     /* Initialise IFF for clipboard */
  221.     if (!(IFFParseBase = OpenLibrary("iffparse.library", 0)))
  222.       _fail("iffparse.library is required");
  223.     if (!(iff = AllocIFF())) no_memory();
  224.  
  225.     ClipRequest = (struct IOClipReq *)
  226.     _device_open("clipboard.device", 0L, 0L, 0L, 0, sizeof(struct IOClipReq));
  227.     if (!ClipRequest) _fail("clipboard.device missing !?");
  228.  
  229.     cliphook.h_Entry = (ULONG (*)())clip_change;
  230.     ClipRequest->io_Command = CBD_CHANGEHOOK;
  231.     ClipRequest->io_Length = 1; /* install */
  232.     ClipRequest->io_Data = (APTR)&cliphook;
  233.     DoIO((struct IORequest *)ClipRequest);
  234. }
  235.  
  236. void cleanup_clipboard(void)
  237. {
  238.     if (ClipRequest)
  239.     {
  240.     cliphook.h_Entry = (ULONG (*)())clip_change;
  241.     ClipRequest->io_Command = CBD_CHANGEHOOK;
  242.     ClipRequest->io_Length = 0; /* remove */
  243.     ClipRequest->io_Data = (APTR)&cliphook;
  244.     DoIO((struct IORequest *)ClipRequest);
  245.     }
  246.     if (iff) FreeIFF(iff);
  247.     if (IFFParseBase) CloseLibrary(IFFParseBase);
  248.     _device_close((struct IORequest *)ClipRequest);
  249. }
  250.