/***********************************************\ * * * Snap * * © Mikael Karlsson 1988 * * * \***********************************************/ #include "snap.h" /* signals */ LONGBITS startsignal, insertsignal, cancelsignal, donesignal; LONGBITS movesignal, clicksignal, timersignal, initsignal; ULONG startsignum = -1L; ULONG insertsignum = -1L; ULONG cancelsignum = -1L; ULONG donesignum = -1L; ULONG movesignum = -1L; ULONG clicksignum = -1L; ULONG timersignum = -1L; ULONG initsignum = -1L; ULONG WaitSignal; extern short Enable_Abort; /* program */ struct MsgPort *port = NULL; struct Task *MyTask; /* Snap state machine */ WORD action; WORD state; WORD StartUnit = UNIT_FRAME; /* clipboard */ struct IOClipReq *ClipReq = NULL; struct MsgPort *ClipPort = NULL; /* input device */ struct MsgPort *inputDevPort = NULL; struct Interrupt handlerStuff; struct IOStdReq *inputRequestBlock = NULL; struct InputEvent SimEvent; WORD Priority = 51; /* Default priority for input handler */ WORD textqual = IEQUALIFIER_LCOMMAND; WORD gfxqual = IEQUALIFIER_RCOMMAND; WORD insertkey = 23; WORD xerox = 0; UBYTE *CharData = NULL; /* console */ struct MsgPort *ConPort = NULL; struct IOStdReq *ConIOR = NULL; struct KeyMap keymap; LONG linedelay = 0; LONG chardelay = 0; /* windows */ struct MsgPort *Sharedport = NULL; SHORT Sharedrefs; /* libraries */ struct IntuitionBase *IntuitionBase = NULL; struct GfxBase *GfxBase = NULL; struct LayersBase *LayersBase = NULL; /* struct DosLibrary *DosBase = NULL; */ /* graphics */ struct Screen *theScreen; struct Layer *theLayer; struct Layer_Info *LockedLayerInfo = NULL; struct RastPort rp, TempRp, MyRP; struct BitMap TempBM, MyBM; UBYTE *TempRaster = NULL; UWORD CrawlPtrn = 0x7777; WORD FrameMask = 1; /* detaching */ ULONG _BackGroundIO = 0; ULONG _stack = 4096L; ULONG _priority = 4L; char *_procname = "Snap"; int isdigit(c) REGISTER char c; { return (c>='0' && c<='9'); } long dectoint(str) REGISTER char *str; { REGISTER long val = 0; REGISTER char c; while (isdigit(c = *str)) { val = (((val<<2)+val)<<1) + c-'0'; str++; } return(val); } long hextoint(str) REGISTER char *str; { REGISTER long val = 0; REGISTER char c; while (c = *str) { val <<= 4; val |= (c & 15) + (isdigit(c) ? 0 : 9); str++; } return(val); } void main(argc, argv) WORD argc; char *argv[]; { int i; Enable_Abort = 0; i = 1; /* Don't parse program name */ while (i50 && pri<128) { Priority = pri; } break; } case 't': { textqual = hextoint(&arg[2]); break; } case 'g': { gfxqual = hextoint(&arg[2]); break; } case 'i': { insertkey = hextoint(&arg[2]); break; } case 'c': { chardelay = dectoint(&arg[2]); break; } case 'l': { linedelay = dectoint(&arg[2]); break; } case 'a': { CrawlPtrn = hextoint(&arg[2]); break; } case 'x': { xerox = 1; } case 'u': { switch(dectoint(&arg[2])) { case 1: { StartUnit = UNIT_CHAR; break; } case 0: default: { StartUnit = UNIT_FRAME; break; } } break; } case 'b': { FrameMask = hextoint(&arg[2]); break; } default: { break; } } } i++; /* Next argument, please */ } OpenStuff(); /* This is what we're waiting for */ WaitSignal = startsignal | insertsignal | initsignal | cancelsignal | SIGBREAKF_CTRL_C | 1L << port->mp_SigBit; FOREVER { REGISTER LONGBITS sig = Wait(WaitSignal | (Sharedport ? (1L << Sharedport->mp_SigBit) : 0L)); if (Sharedport) { REGISTER SHORT CloseTime = 0; REGISTER struct IntuiMessage *Msg; REGISTER struct Window *MyWin; while (Msg = (struct IntuiMessage *)GetMsg(Sharedport)) { if (Msg->Class == CLOSEWINDOW) { /* Want to close? */ CloseTime = 1; /* Set a flag */ MyWin = Msg->IDCMPWindow; /* Window to close*/ } ReplyMsg(Msg); } if (CloseTime) { closesharedwindow(MyWin); } } if (sig & SIGBREAKF_CTRL_C) { /* This is my cue. Exit if there are no open windows depending on us */ if (Sharedrefs) { DisplayBeep(NULL); } else { CloseStuff(); } } if (sig & initsignal) { SafePatch(); /* Patch dangerous functions */ } if (sig & cancelsignal) { SafeRestore(); } if (sig & startsignal) { /* The handler wants a word in. */ if (action == snapgfx) { /* Check user action */ HandleGfx(); /* Get the picture :-) */ } else if (action == snaptext) { if (HandleChars()) { /* Snap some chars */ if (xerox) { sig |= insertsignal; } } } else { /* Previous snap wasn't finished when this one started. */ SetSignal(0L, movesignal|cancelsignal|donesignal|clicksignal|timersignal); DisplayBeep(NULL); action = noaction; } if (!(sig & insertsignal)) { SafeRestore(); /* Layers unlocked - all safe */ } } if (sig & insertsignal) { LONG i; UBYTE *SnapSpace; ULONG ascii; action = insert; if (SnapSpace = FetchClip()) { /* Get clipboard data */ /* Not necessary to patch here but it guarantees that all inserted chars end up in the same window. */ SafePatch(); /* get the current keymap */ ConIOR->io_Command = CD_ASKDEFAULTKEYMAP; ConIOR->io_Length = sizeof (struct KeyMap); ConIOR->io_Data = (APTR) &keymap; ConIOR->io_Flags = 1; /* no IOQuick */ DoIO(ConIOR); /* Set up an input request */ inputRequestBlock->io_Command = IND_WRITEEVENT; inputRequestBlock->io_Flags = 0L; inputRequestBlock->io_Length = (long)sizeof(struct InputEvent); inputRequestBlock->io_Data = (APTR)&SimEvent; /* Translate chars in SnapSpace and insert them into the input stream. */ for (i=4; SnapSpace[i] && (action == insert); i++) { ascii = SnapSpace[i]; if (ascii == 10) { ascii = 13; /* WYSIWYG? Hah! */ if (linedelay) { /* Almost missed this one */ Delay(linedelay); /* Give the man some air */ } } InvertKeyMap(ascii, &SimEvent, &keymap); DoIO(inputRequestBlock); if (chardelay) { Delay(chardelay); } } SafeRestore(); /* "Depatch" */ /* Free memory given to us by FetchClip() */ FreeMem(SnapSpace, *(ULONG *)SnapSpace); } action = noaction; } } CloseStuff(); /* Guess what */ }