/* :ts=4 * * Amiga SnipIt 1.2 * (c) (opyright 1987,1988 - Scott Evernden - All Rights Reserved * * reco.c - recognize & construct char code input * */ #include "hs.h" char *_AllocMem(); /* ascii to keycode (this is a hack; is there a correct way to do this?) */ char table[] = { /* ! " # $ % & ' */ /* ( ) * + , - . / */ /* 0 1 2 3 4 5 6 7 */ /* 8 9 : ; < = > ? */ /* @ A B C D E F G */ /* H I J K L M N O */ /* P Q R S T U V W */ /* X Y Z [ \ ] ^ _ */ /* ` a b c d e f g */ /* h i j k l m n o */ /* p q r s t u v w */ /* x y z { | } ~ */ 0x40, 0x81, 0xAA, 0x83, 0x84, 0x85, 0x87, 0x2A, 0x89, 0x8A, 0x88, 0x8C, 0x38, 0x0B, 0x39, 0x3A, 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xA9, 0x29, 0xB8, 0x0C, 0xB9, 0xBA, 0x82, 0xA0, 0xB5, 0xB3, 0xA2, 0x92, 0xA3, 0xA4, 0xA5, 0x97, 0xA6, 0xA7, 0xA8, 0xB7, 0xB6, 0x98, 0x99, 0x90, 0x93, 0xA1, 0x94, 0x96, 0xB4, 0x91, 0xB2, 0x95, 0xB1, 0x1A, 0x0D, 0x1B, 0x86, 0x8B, 0x00, 0x20, 0x35, 0x33, 0x22, 0x12, 0x23, 0x24, 0x25, 0x17, 0x26, 0x27, 0x28, 0x37, 0x36, 0x18, 0x19, 0x10, 0x13, 0x21, 0x14, 0x16, 0x34, 0x11, 0x32, 0x15, 0x31, 0x9A, 0x8D, 0x9B, 0x80 }; static struct InputEvent event; char *evs, *evp; char preString[PRE_SIZE + 1] = "> "; /* a prestring */ int evslen; extern struct IOStdReq *inpReq; extern struct TextFont *capttf; extern struct BitMap captbm; extern int captx, capty; extern int charx, chary; extern int left, right; extern int cmd1, cmd2, jobFlag; /*********************************************/ /* cleanup, local to this module */ finiReco() { /* event string is allocated */ if (evs) _FreeMem(evs, (long) evslen); } /*********************************************/ /* entry to recognizer; generates keycode events from the capture bitmap */ buildEvents() { register char *cp; PLANEPTR p; int code; /* prepare request to input device */ inpReq->io_Command = IND_WRITEEVENT; inpReq->io_Flags = 0; inpReq->io_Length = sizeof (struct InputEvent); inpReq->io_Data = (APTR) &event; /* new snip-map? */ if (capttf) { /* new buffer for keycodes */ if (evs) _FreeMem(evs, (long) evslen); evslen = (captx / charx) * (capty / chary); evs = (char *) _AllocMem((long) evslen, 0L); if (evp = evs) buildCodes(); capttf = NULL; /* reset "newly-captured" indicator */ /* reco'ed, so drop the bitmap */ if (p = captbm.Planes[0]) { FreeRaster(p, (long) captx, (long) capty); captbm.Planes[0] = NULL; } } else if (evp = evs) { while (*evp != -1) { if (jobFlag & cmd2) { cp = preString; while (*cp) sendKey(*cp++); } do sendKey(code = *evp++); while (code != '\n' && *evp != -1); } } } /*********************************************/ /* inject a (fake) keyboard press/release into the input stream */ sendKey(code) int code; { /* convert to raw key */ code = code == '\n' ? 0x44 : table[code - 32]; /* build key down event */ event.ie_Class = IECLASS_RAWKEY; event.ie_Code = code & 0x7F; event.ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE; if (code & 0x80) event.ie_Qualifier |= IEQUALIFIER_LSHIFT; event.ie_NextEvent = NULL; /* make it happen */ DoIO(inpReq); /* build key up event (req'd?) */ event.ie_Class = IECLASS_RAWKEY; event.ie_Code = (code & 0x7F) | IECODE_UP_PREFIX; event.ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE; if (code & 0x80) event.ie_Qualifier |= IEQUALIFIER_LSHIFT; event.ie_NextEvent = NULL; /* make it happen */ DoIO(inpReq); } /*********************************************/ /* actually makes the keycodes */ buildCodes() { register int code, px, py, wid, lastx, lasty, spaces; char *cp; /* heuristics for text structure (i.e., newlines) */ px = left; py = 0; lastx = captx / charx - 1; lasty = capty / chary - 1; wid = lastx; while (py <= lasty) { /* prestring on cmd2 key */ if (jobFlag & cmd2) { cp = preString; while (*cp) sendKey(*cp++); /* don't record */ } /* on the last line? */ if (py == lasty) lastx = right; /* for each cell... */ while (px <= lastx) { /* recognize single character */ code = reco(px++, py); /* we're gonna count runs of spaces */ spaces = 0; while (code == ' ' && px <= wid) { spaces++; code = reco(px++, py); } /* send / record, if no spaces */ if (!spaces) sendKey(*evp++ = code); /* if end of line is all spaces, then regard as newline */ else if (code == ' ' && wid < px) sendKey(*evp++ = '\n'); /* if more text on line after snip area, then not a newline */ else if (py < lasty || px <= lastx + 1) { while (spaces--) sendKey(*evp++ = ' '); sendKey(*evp++ = code); } /* emit spaces */ else { spaces -= px - lastx - 2; while (spaces--) sendKey(*evp++ = ' '); } } /* next is leftside of next row down */ px = 0; py++; } *evp = -1; /* record terminator */ } /*********************************************/ /* return ascii code of character in capture bitmap at (x,y) */ int reco(x, y) int x, y; { register char *s, *d, *sp, *dp; register int hyt, i; /* recognize cell at (x,y) */ sp = (char *) capttf->tf_CharData; dp = (char *) captbm.Planes[0] + y * chary * captbm.BytesPerRow + x; for (i = 32; i < 128; sp++, i++) { s = sp; d = dp; hyt = capttf->tf_YSize; if (*s == *d) { do { if (--hyt == 0) return i; s += capttf->tf_Modulo; d += captbm.BytesPerRow; } while (*s == *d); } else if (*s == ~*d) { do { if (--hyt == 0) return i; s += capttf->tf_Modulo; d += captbm.BytesPerRow; } while (*s == ~*d); } } return '?'; /* unknown */ }