#include #include #include #include #include "keyboard.h" #define XLATBUFSIZE 2048 #define MAXXLATKEYS 100 typedef struct { unsigned long key; char* value; } XLATKEY; XLATKEY CommonKeynames[] = { { NUMLOCK, "numlock" }, { CAPLOCK, "caplock" }, { ENTER, "enter" }, { ENTER, "return" }, { KP(ENTER), "kp-enter" }, { KP(ENTER), "kp-return" }, { DELETE, "kp-." }, { DELETE, "kp-delete" }, { INSERT, "kp-0" }, { INSERT, "kp-insert" }, { END, "kp-1" }, { END, "kp-end" }, { DOWN, "kp-2" }, { DOWN, "kp-down" }, { PAGEDOWN, "kp-3" }, { PAGEDOWN, "kp-pagedown" }, { LEFT, "kp-4" }, { LEFT, "kp-left" }, { KPFIVE, "kp-5" }, { RIGHT, "kp-6" }, { RIGHT, "kp-right" }, { HOME, "kp-7" }, { HOME, "kp-home" }, { UP, "kp-8" }, { UP, "kp-up" }, { PAGEUP, "kp-9" }, { PAGEUP, "kp-pageup" }, { KP(PLUS), "kp-+" }, { KP(PLUS), "kp-plus" }, { KP(MINUS), "kp--" }, { KP(MINUS), "kp-minus" }, { KP(ASTERIX), "kp-*" }, { KP(ASTERIX), "kp-asterix" }, { KP(0x2f), "kp-/" }, { KP(0x2f), "kp-slash" }, { KP(UP), "up" }, { KP(DOWN), "down" }, { KP(LEFT), "left" }, { KP(RIGHT), "right" }, { KP(INSERT), "insert" }, { KP(DELETE), "delete" }, { KP(HOME), "home" }, { KP(END), "end" }, { KP(PAGEUP), "pageup" }, { KP(PAGEDOWN), "pagedown" }, { BACKSPACE, "backspace" }, { TAB, "tab" }, { BACKTAB, "back-tab" }, { BACKTAB, "shift-tab" }, { F1, "f1" }, { F2, "f2" }, { F3, "f3" }, { F4, "f4" }, { F5, "f5" }, { F6, "f6" }, { F7, "f7" }, { F8, "f8" }, { F9, "f9" }, { F10, "f10" }, { F11, "f11" }, { F12, "f12" }, { 0, 0 } }; int XLatFlag[8]; static XLATKEY XLatKey[MAXXLATKEYS]; static char XLatBuf[XLATBUFSIZE]; static char* XLatPtr; static int XLatCount = 0; static void interrupt (*oldint9)(); static void interrupt (*oldint1b)(); static void interrupt (*oldint23)(); static unsigned int far* sPtrHead = (unsigned int far*) MK_FP(0x40,0x1A); static unsigned int far* sPtrTail = (unsigned int far*) MK_FP(0x40,0x1C); static unsigned int far* sPtrLo = (unsigned int far*) MK_FP(0x40,0x80); static unsigned int far* sPtrHi = (unsigned int far*) MK_FP(0x40,0x82); static unsigned int far* sNewKey; static unsigned int sNewTail; static unsigned char far* kbdata = (unsigned char far*) MK_FP( 0x40, 0x17 ); static int FLAG = -1; static unsigned CODE = 0; static int FILTERCL = 0; static int FILTERNL = 0; static int FILTERSL = 0; static char KbdPath[81] = "."; #define FILLKEY 1 unsigned KEYVAL; struct REKEY { int flag; int scan; int lead; int val; } ReKeyTab[] = { { 4, 30, 2, 128 + 1 }, /* Ctrl-A */ { 4, 48, 2, 128 + 2 }, /* Ctrl-B */ { 4, 46, 2, 128 + 3 }, /* Ctrl-C */ { 4, 32, 2, 128 + 4 }, /* Ctrl-D */ { 4, 25, 2, 128 +16 }, /* Ctrl-P */ { 4, 16, 2, 128 +17 }, /* Ctrl-Q */ { 4, 31, 2, 128 +19 }, /* Ctrl-S */ { 4, 3, 2, 128 }, /* Ctrl-@ */ { 0, 14, 4, 8 }, /* BackSpace */ { 0, 55, 4, '*' }, /* Grey * */ { 0, 74, 4, '-' }, /* Grey - */ { 0, 78, 4, '+' }, /* Grey + */ { 12, 83, 2, 255 } }; #define NUMREKEYS 13 #define ACKKEY al = ah = inportb( 0x61 ); \ al |= 0x80; \ outportb( 0x61, al ); \ outportb( 0x61, ah ); \ outportb( 0x20, 0x20 ) static int EXTFLAG = 0; void interrupt int9( void ) { register i; unsigned char al, ah; disable(); FLAG = *kbdata; CODE = inportb( 0x60 ); if( (CODE == 0x3a && FILTERCL) || (CODE == 0x45 && FILTERNL) || (CODE == 0x46 && FILTERSL) ) { ACKKEY; KEY_StuffKey( 1 ); KEY_StuffKey( CODE ); EXTFLAG = 0; } else if( CODE == 0xe0 ) { ACKKEY; EXTFLAG = 1; } else { for( i = 0; i < NUMREKEYS; i++ ) { if( (ReKeyTab[i].flag == 0 || ReKeyTab[i].flag & FLAG) && (ReKeyTab[i].scan == CODE) ) { ACKKEY; KEY_StuffKey( ReKeyTab[i].lead ); KEY_StuffKey( ReKeyTab[i].val ); EXTFLAG = 0; break; } } if( i == NUMREKEYS ) { if( EXTFLAG && CODE < 128 ) KEY_StuffKey( 4 ); EXTFLAG = 0; enable(); _chain_intr( oldint9 ); /* oldint9(); */ } } enable(); } void interrupt int1b( void ) { disable(); KEYVAL = 3; KEY_StuffKey( FILLKEY ); enable(); } void interrupt int23( void ) { } KEY_SetPath( char* path, char* var ) { char* p; p = getenv( var ); if( p ) strcpy( KbdPath, p ); else strcpy( KbdPath, path ); p = strrchr( KbdPath, '\\' ); if( *p ) *p = 0; } void KEY_Init() { oldint9 = getvect( 0x09 ); oldint1b = getvect( 0x1b ); oldint23 = getvect( 0x23 ); setvect( 0x09, int9 ); setvect( 0x1b, int1b ); setvect( 0x23, int23 ); } void KEY_Term() { setvect( 0x09, oldint9 ); setvect( 0x1b, oldint1b ); setvect( 0x23, oldint23 ); } void KEY_GetFilterCL() { return FILTERCL; } void KEY_GetFilterNL() { return FILTERNL; } void KEY_GetFilterSL() { return FILTERSL; } void KEY_SetFilterCL( int i ) { FILTERCL = (i != 0); } void KEY_SetFilterNL( int i ) { FILTERNL = (i != 0); if( FILTERNL ) KEY_SetNL( 0 ); } void KEY_SetFilterSL( int i ) { FILTERSL = (i != 0); if( FILTERSL ) KEY_SetSL( 0 ); } void KEY_SetNL( int i ) { if( i ) *kbdata |= 32; else *kbdata &= (255-32); } void KEY_SetSL( int i ) { if( i ) *kbdata |= 16; else *kbdata &= (255-16); } int KEY_GetCL() { return (*kbdata & 64) == 64; } int KEY_GetNL() { return (*kbdata & 32) == 32; } int KEY_GetSL() { return (*kbdata & 16) == 16; } int KEY_StuffKey( unsigned pKey ) { int r = 0; disable(); sNewKey = (unsigned int far*) MK_FP( 0x40,*sPtrTail ); sNewTail = *sPtrTail; sNewTail += 2; if( sNewTail >= *sPtrHi ) sNewTail = *sPtrLo; if( sNewTail != *sPtrHead ) { *sNewKey = pKey; *sPtrTail = sNewTail; r = 1; } enable(); return r; } int KEY_GetKey( unsigned int* x ) { int k; if( x ) *x = 0; k = getch(); if( k == 4 ) { if( x ) *x = 1; k = getch(); } if( k == 2 ) { k = getch(); if( k == 255 ) k = CTRLALTDEL; else k -= 128; } else if( k == 1 || k == 0 ) k = getch() * 256; if( k == 4 && *x ) return -1; return k; } int KEY_GetKeyT( int t, int* x ) { while( t-- ) { if( kbhit() ) return KEY_GetKey( x ); delay( 1 ); } return -1; } compare( const void* x1, const void* x2 ) { if( ((XLATKEY*)x1)->key < ((XLATKEY*)x2)->key ) return -1; else if( ((XLATKEY*)x1)->key > ((XLATKEY*)x2)->key ) return 1; return 0; } unsigned long lookupkeyname( char* s ) { register i; for( i = 0; CommonKeynames[i].value; i++ ) if( !stricmp( s, CommonKeynames[i].value ) ) return CommonKeynames[i].key; return 0; } void KEY_InitDriver() { int i; XLatCount = 0; XLatPtr = XLatBuf; for( i = 0; i < 8; i++ ) XLatFlag[i] = 0; } int KEY_DefineKey( unsigned long key, char* value ) { register i; char* v; v = value + strlen( value ) - 1; while( v >= value && (*v == ' ' || *v == '\t') ) *v-- = 0; if( !*value ) return 0; if( XLatCount > MAXXLATKEYS ) return 0; if( XLatPtr >= (XLatBuf + XLATBUFSIZE) - strlen( value ) ) return 0; for( i = 0; i < XLatCount; i++ ) if( XLatKey[i].key == key ) break; XLatKey[i].key = key; XLatKey[i].value = XLatPtr; v = XLatPtr + 2; *(XLatKey[i].value + 1) = 0; *XLatKey[i].value = '*'; if( *value >= '0' && *value <= '7' ) *XLatKey[i].value = *value - '0'; while( *value && *value != ' ' && *value != '\t' ) value++; while( *value == ' ' || *value == '\t' ) value++; while( *value ) { while( *value && *value != ' ' && *value != '\t' ) { if( *value == '^' ) { value++; *v++ = *value++ - 64; } else if( *value == '\\' ) { value++; if( *value >= '0' && *value <= '9' && *(value + 1) >= '0' && *(value + 1) <= '9' && *(value + 2) >= '0' && *(value + 2) <= '9' ) { *v++ = (value[0] - '0') * 100 + (value[1] - '0') * 10 + (value[2] - '0'); value += 3; } else *v++ = *value++; } else *v++ = *value++; } *v++ = 0; while( *value == ' ' || *value == '\t' ) value++; if( *value ) *(XLatKey[i].value + 1) += 1; } XLatPtr = v; XLatCount++; qsort( XLatKey, XLatCount, sizeof(XLATKEY), compare ); } int KEY_LoadDriver( char* file ) { FILE* fp; char line[81]; char* k; char* v; unsigned long key; KEY_InitDriver(); strcpy( line, KbdPath ); strcat( line, "\\" ); strcat( line, file ); strcat( line, ".KBD" ); fp = fopen( line, "r" ); if( !fp ) return 0; for( fgets( line, 80, fp ); !feof( fp ); fgets( line, 80, fp ) ) { line[strlen( line ) - 1] = 0; for( k = line; *k == ' ' || *k == '\t'; k++ ); if( !*k || *k == ';' || *k == '#' ) continue; for( v = k; *v && *v != ' ' && *v != '\t' && *v != '='; v++ ); if( !*v ) continue; *v++ = 0; while( *v == ' ' || *v == '\t' || *v == '=' ) v++; if( !*v ) continue; if( *k >= '0' && *k <= '9' ) key = atol( k ); else if( !stricmp( k, "filter-nl" ) ) KEY_SetFilterNL( !stricmp( v, "on" ) ); else if( !stricmp( k, "filter-cl" ) ) KEY_SetFilterCL( !stricmp( v, "on" ) ); else key = lookupkeyname( k ); if( key ) { /* ADD SUPPORT FOR COMMON KEY VALUES HERE! */ KEY_DefineKey( key, v ); } } fclose( fp ); return 1; } char* KEY_Translate( unsigned long key ) { XLATKEY* x; int n; char* p; if( key == 0 ) return (char*) 0; x = (XLATKEY*) bsearch( &key, XLatKey, XLatCount, sizeof(XLATKEY), compare ); if( x == NULL ) return (char*) 0; n = 0; if( *x->value != '*' ) n = XLatFlag[*x->value]; if( *(x->value + 1) < n ) n = *(x->value + 1); p = x->value + 2; while( n-- ) while( *p++ ); return p; } KEY_GetFlag( int f ) { if( f >= 0 && f <= 7 ) return( XLatFlag[f] ); return 0; } KEY_SetFlag( int f, int v ) { if( f >= 0 && f <= 7 ) XLatFlag[f] = v; }