/* SD2_KEYIN.C - ScreenDoor II Keystroke Capture & Mapping Routines This Code Captures A Keystroke And Maps It According To The Global Key Value Maps. Last Modified: 08-02-88 Copyright (C) 1988, T.A. Daneliuk Input keystrokes are translated two ways. First, a keystroke is checked to see if it might be the beginning of a system specific control key sequence. If so, additional keystrokes are read and if a sequence of keystrokes matches one of the entries in the control key mapping table (ctrl_xlate), an internal ScreenDoor control code is returned. (This value is found in sd2_ctrl_codes.) If after examining CTRL_SIZE number of keystrokes no entry has been found in ctrl_xlate, those keystrokes are thrown away. If an input is seen as data, it is translated via the key_xlate array. This allows one-for-one character mapping. The idea behind this is that all of the internal code representations and key bindings can be modified at init time via sd2_init(). */ #include <stdio.h> #include <sd2_defs.h> #if ANSI static BOOL match(unsigned x, unsigned y); #else static BOOL match(); #endif /*============ Global Control And Keystroke Translation Tables ===============*/ KEYSTR sd2_ctrl_codes[C_XLATE]; /* Intialized By sd2_init() !!! */ #if PCDOS & PC_BIOS /* Ctrl. Table Must Be Redefined For Each Environment */ struct CXLATE ctrl_xlate[CTRL_ENTRY] = {2, 0, 80, NXT_FLD, /* Dn. Arrow */ 1, 9, 0, NXT_FLD, /* Tab */ 2, 0, 15, PRV_FLD, /* Back Tab */ 2, 0, 72, PRV_FLD, /* Up Arrow */ 2, 0, 73, FST_FLD, /* PgUp */ 2, 0, 81, LST_FLD, /* PgDn */ 2, 0, 75, CUR_LFT, /* Lft. Arrow */ 2, 0, 77, CUR_RGT, /* Rt. Arrow */ 2, 0, 71, BEG_FLD, /* Home */ 2, 0, 79, END_FLD, /* End */ 1, 10, 0, CLR_FLD, /* Ctrl-Enter */ 2, 0, 117, CLR_END, /* Ctrl-End */ 1, 13, 0, EXT_FLD, /* Enter */ 2, 0, 82, INS, /* Ins */ 2, 0, 83, DEL, /* Del */ 1, 8, 00, BS, /* Backspace */ 2, 0, 59, HELP, /* Fn. 1 */ 1, 27, 0, EXT_SCR /* Esc */ }; #endif KEYSTR key_xlate[K_XLATE]; /* Initialized By sd2_init() !!! */ /*====================== Get And Map Keyboard Input ==========================*/ static KEYSTR work[CTRL_SIZE]; /* Working Buffer For Ctrl. Sequences */ static BOOL match(); KEYSTR sd2_keyin() { BOOL in_ctrl; /* TRUE = Now Parsing Ctrl. String */ unsigned first_ctrl; /* Index Of 1st Possible Ctrl. Match */ unsigned index; /* Index Into Control String Itself */ KEYSTR key; unsigned x; /* Working Variable */ in_ctrl = FALSE; first_ctrl = 0; index = 1; key = sd2_getc(); /* Get A Character */ first_ctrl = 0; /* See If It Might Be A Ctrl. String */ while ((first_ctrl < CTRL_ENTRY) && (in_ctrl == FALSE)) { if ((ctrl_xlate[first_ctrl].length > 0) && (ctrl_xlate[first_ctrl].ctrlin[0] == key)) { in_ctrl = TRUE; /* 1st Char Matches */ work[0] = key; /* So Save It */ } first_ctrl++; } if (in_ctrl == FALSE) /* Not A Control String */ key = key_xlate[(unsigned) key]; /* So Translate The Character */ else /* Match/Xlate Control String */ { first_ctrl--; /* Adjust To Point To Real Field */ while (in_ctrl == TRUE) /* Go 'Till Match Or Miss */ { x = first_ctrl; while ((x < CTRL_ENTRY) && (in_ctrl == TRUE)) { if (match(x, index) == TRUE) { in_ctrl = FALSE; key = sd2_ctrl_codes[ctrl_xlate[x].sd_ctrl]; } x++; /* Check From first_ctrl On For Match */ } if (in_ctrl == TRUE) /* Still No Match */ { if (index == CTRL_SIZE) /* Max. Length Input String */ { key = sd2_ctrl_codes[IEBAD_CTRL]; /* Bad Control String */ in_ctrl = FALSE; /* We're Done */ } else { key = sd2_getc(); /* Get Another Keystroke */ work[index] = key; index++; } } } } return(key); } /*=========See If Control String So Far Matches A Translation Entry ==========*/ static BOOL match(x, y) unsigned x, y; { BOOL flag; unsigned z, len; z = 0; len = ctrl_xlate[x].length; if (y != len) /* String Lengths Don't Match */ flag = FALSE; else /* Lengths The Same */ { while ((work[z] == ctrl_xlate[x].ctrlin[z]) && (z < len)) z++; if (z == len) /* All Chars Matched */ flag = TRUE; else flag = FALSE; } return (flag); }