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

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