
/*
 *  This function will store the characters read from the screen, whether
 *  this is by printing them to the CLI, saving them to a file, or pasting
 *  them to the clipboard.
 *
 *  I have just added some "saver" code to the interpretation routine. Now
 *  the stash function can determine how to handle the section that has been
 *  cut. At the moment I am tending towards including two possible stash
 *  methods -- saving to the clipboard, or writing to a PIPE: file so that
 *  programs without clipboard support can still receive the text.
 *
 *  (This is like late '87)
 *
 *  OK, I finally got some clipboard code (from AmigaMail, free plug). It
 *  ought to be very simple to integrate. I don't know if I have anything
 *  to test it out on though... doesn't speak very well for the widespread
 *  acceptance of the clipboard as a standard!
 *
 *  John    03-07-88
 *
 *  Found a very old example of controlling mouse movements via software.
 *  Adapted to send phoney keyboard events very easily.
 *
 *  John    04-25-88
 */

#include "snip:defs.h"
#include "intuition/intuitionbase.h"

extern struct IntuitionBase *IntuitionBase;

extern short save_format, scratchheight, scratchwidth;
extern struct FileHandle *fp, *outfilehandle;
extern char *scratch;
extern struct Window *w;
extern BOOL reactivate;

stash()
{
    register short counter = 0;
    register short y;
    register struct FileHandle *out = Output();
    register struct IntuiMessage *msg;
    register BOOL done = FALSE, printcr = TRUE;

    switch (save_format)
    {
        case PRINT_STDOUT:

            if (outfilehandle)
                out = outfilehandle;

            for (y = 0; y < scratchheight; y++)
            {
                Wrlen(out,&scratch[counter]);
                Wr(out,"\n");
                counter += (scratchwidth + 1);  /* jump to next line */
            }
            break;

        case WRITE_PIPE:
            if ((fp = Open("PIPE:snip",MODE_NEWFILE)) == NULL)
            {
                Wr(out,"Error: PIPE device not available\n");
                break;
            }

            for (y = 0; y < scratchheight; y++)
            {
                Wrlen(fp,&scratch[counter]);
                Wr(fp,"\n");
                counter += (scratchwidth + 1);
            }
            Close(fp);     /* so we can do multiple cuts */
            fp = NULL;
            break;

        case PASTE_CLIPBOARD:
            if (CBOpen(0))
            {
                Wr(out,"Error: ClipBoard not available\n");
                goto CBERROR;
            }

            for (y = 0; y < scratchheight; y++)
            {
                register char *ptr = &scratch[counter];

                CBCut(ptr,strlen(ptr));
                counter += (scratchwidth + 1);
            }
CBERROR:
            CBClose();
            break;

        case KEYBOARD_NOCR:
            printcr = FALSE;
        case TYPE_KEYBOARD:
/*
 *  This is an interesting one: I can't actually put the text down until
 *  some other window gets selected; if the window is closed I'll just close
 *  everything and exit without doing the paste.
 *
 */

            while (!done)
            {
                WaitPort(w->UserPort);
                while (msg = (struct IntuiMessage *)GetMsg(w->UserPort))
                {
                    if (msg->Class == INACTIVEWINDOW)
                    {
                        ReplyMsg(msg);
                        done = TRUE;
                    }
                    else if (msg->Class == CLOSEWINDOW)
                    {
                        ReplyMsg(msg);
                        _abort();
                    }
                }
            }

            for (y = 0; y < scratchheight; y++)
            {
                sendline(&scratch[counter],printcr);
                counter += (scratchwidth + 1);  /* jump to next line */
            }

            if (reactivate)     ActivateWindow(w);

            break;

        default:
            break;
    }
}

