From: nethack.allison Date: Sun, 11 May 2003 23:25:08 +0000 (+0000) Subject: Add 's key handling as loadable handler X-Git-Tag: MOVE2GIT~1995 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6406ef5f93611daa63cff942d1aa4edd7effc2ef;p=nethack Add 's key handling as loadable handler --- diff --git a/Files b/Files index f0d9ef07d..66683f292 100644 --- a/Files +++ b/Files @@ -191,8 +191,8 @@ sys/winnt: (files for Windows 9x, NT and Windows2000 version) Install.nt Makefile.bcc Makefile.gcc Makefile.msc console.rc defaults.nh mapimail.c nethack.def nhdefkey.c nh340key.c -nhico.uu nhsetup.bat ntsound.c nttty.c porthelp -win32api.h winnt.c +nhraykey.c nhico.uu nhsetup.bat ntsound.c nttty.c +porthelp win32api.h winnt.c util: (files for all versions) diff --git a/doc/fixes34.2 b/doc/fixes34.2 index b64a11192..78a4ad1dd 100644 --- a/doc/fixes34.2 +++ b/doc/fixes34.2 @@ -78,5 +78,5 @@ Platform- and/or Interface-Specific New Features ------------------------------------------------ win32tty: keystroke handlers can be dynamically loaded to assist in resolving internationalization issues - +win32tty: add Ray Chason's code for international keyboard handling diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 95933af4c..0dda2879c 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -576,7 +576,7 @@ $(NHRES): $(NTSYS)\console.rc $(NTSYS)\NetHack.ico $(GAMEFILE) : $(ALLOBJ) $(NHRES) !ELSE $(GAMEFILE) : $(ALLOBJ) $(NHRES) $(O)gamedir.tag \ - $(GAMEDIR)\nhdefkey.dll $(GAMEDIR)\nh340key.dll + $(GAMEDIR)\nhdefkey.dll $(GAMEDIR)\nh340key.dll $(GAMEDIR)\nhraykey.dll !ENDIF @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR) @echo Linking.... @@ -596,6 +596,7 @@ $(O)nhdefkey.def: @echo EXPORTS >$@ @echo ProcessKeystroke >>$@ @echo NHkbhit >>$@ + @echo CheckInput >>$@ @echo SourceWhere >>$@ @echo SourceAuthor >>$@ @echo KeyHandlerName >>$@ @@ -610,6 +611,7 @@ $(O)nh340key.def: @echo EXPORTS >$@ @echo ProcessKeystroke >>$@ @echo NHkbhit >>$@ + @echo CheckInput >>$@ @echo SourceWhere >>$@ @echo SourceAuthor >>$@ @echo KeyHandlerName >>$@ @@ -620,6 +622,21 @@ $(GAMEDIR)\nh340key.dll : $(O)$(@B).o $(O)gamedir.tag $(O)$(@B).def /PDB:"$(@B).PDB" /MAP:"$(@B).map" /DEF:$(O)$(@B).def \ /IMPLIB:$(O)$(@B).lib -out:$@ $(O)$(@B).o +$(O)nhraykey.def: + @echo EXPORTS >$@ + @echo ProcessKeystroke >>$@ + @echo NHkbhit >>$@ + @echo CheckInput >>$@ + @echo SourceWhere >>$@ + @echo SourceAuthor >>$@ + @echo KeyHandlerName >>$@ + +$(GAMEDIR)\nhraykey.dll : $(O)$(@B).o $(O)gamedir.tag $(O)$(@B).def + @echo Linking $@ + @$(link) -debug:full -debugtype:cv /RELEASE /NOLOGO /DLL user32.lib \ + /PDB:"$(@B).PDB" /MAP:"$(@B).map" /DEF:$(O)$(@B).def \ + /IMPLIB:$(O)$(@B).lib -out:$@ $(O)$(@B).o + # # Secondary Targets. # diff --git a/sys/winnt/nh340key.c b/sys/winnt/nh340key.c index fc8c1f26b..31bf1f615 100644 --- a/sys/winnt/nh340key.c +++ b/sys/winnt/nh340key.c @@ -88,7 +88,8 @@ static const struct pad { #define inmap(x,vk) (((x) > 'A' && (x) < 'Z') || (vk) == 0xBF || (x) == '2') int __declspec(dllexport) __stdcall -ProcessKeystroke(ir, valid, numberpad, portdebug) +ProcessKeystroke(hConIn, ir, valid, numberpad, portdebug) +HANDLE hConIn; INPUT_RECORD *ir; boolean *valid; boolean numberpad; @@ -209,6 +210,53 @@ INPUT_RECORD *ir; return retval; } +int __declspec(dllexport) __stdcall +CheckInput(hConIn, ir, count, numpad, mode, mod, cc) +HANDLE hConIn; +INPUT_RECORD *ir; +int *count; +boolean numpad; +int mode; +int *mod; +coord *cc; +{ + int ch; + boolean valid = 0, done = 0; + while (!done) { + ReadConsoleInput(hConIn,ir,1,count); + if (mode == 0) { + if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) { + ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0); + done = valid; + } + } else { + if (count > 0) { + if (ir->EventType == KEY_EVENT && ir->Event.KeyEvent.bKeyDown) { + ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0); + if (valid) return ch; + } else if (ir->EventType == MOUSE_EVENT) { + if ((ir->Event.MouseEvent.dwEventFlags == 0) && + (ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) { + cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1; + cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1; + + if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON) + *mod = CLICK_1; + else if (ir->Event.MouseEvent.dwButtonState & RIGHTBUTTON) + *mod = CLICK_2; +#if 0 /* middle button */ + else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON) + *mod = CLICK_3; +#endif + return 0; + } + } + } else + done = 1; + } + } + return mode ? 0 : ch; +} int __declspec(dllexport) __stdcall SourceWhere(buf) diff --git a/sys/winnt/nhdefkey.c b/sys/winnt/nhdefkey.c index eeeeb0f30..74a2bdd2c 100644 --- a/sys/winnt/nhdefkey.c +++ b/sys/winnt/nhdefkey.c @@ -96,7 +96,8 @@ static const struct pad { static BYTE KeyState[256]; int __declspec(dllexport) __stdcall -ProcessKeystroke(ir, valid, numberpad, portdebug) +ProcessKeystroke(hConIn,ir, valid, numberpad, portdebug) +HANDLE hConIn; INPUT_RECORD *ir; boolean *valid; boolean numberpad; @@ -190,6 +191,7 @@ int portdebug; return ch; } + int __declspec(dllexport) __stdcall NHkbhit(hConIn, ir) HANDLE hConIn; @@ -240,6 +242,53 @@ INPUT_RECORD *ir; return retval; } +int __declspec(dllexport) __stdcall +CheckInput(hConIn, ir, count, numpad, mode, mod, cc) +HANDLE hConIn; +INPUT_RECORD *ir; +int *count; +boolean numpad; +int mode; +int *mod; +coord *cc; +{ + int ch; + boolean valid = 0, done = 0; + while (!done) { + ReadConsoleInput(hConIn,ir,1,count); + if (mode == 0) { + if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) { + ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0); + done = valid; + } + } else { + if (count > 0) { + if (ir->EventType == KEY_EVENT && ir->Event.KeyEvent.bKeyDown) { + ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0); + if (valid) return ch; + } else if (ir->EventType == MOUSE_EVENT) { + if ((ir->Event.MouseEvent.dwEventFlags == 0) && + (ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) { + cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1; + cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1; + + if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON) + *mod = CLICK_1; + else if (ir->Event.MouseEvent.dwButtonState & RIGHTBUTTON) + *mod = CLICK_2; +#if 0 /* middle button */ + else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON) + *mod = CLICK_3; +#endif + return 0; + } + } + } else + done = 1; + } + } + return mode ? 0 : ch; +} int __declspec(dllexport) __stdcall SourceWhere(buf) diff --git a/sys/winnt/nhraykey.c b/sys/winnt/nhraykey.c new file mode 100644 index 000000000..0e7345944 --- /dev/null +++ b/sys/winnt/nhraykey.c @@ -0,0 +1,449 @@ +/* SCCS Id: @(#)nhdefkey.c 3.4 $Date$ */ +/* Copyright (c) NetHack PC Development Team 2003 */ +/* NetHack may be freely redistributed. See license for details. */ + +/* + * This is the default NetHack keystroke processing. + * It can be built as a run-time loadable dll (nhdefkey.dll). + * Alternative keystroke handlers can be built using the + * entry points in this file as a template. + * + * Use the defaults.nh "altkeyhandler" option to set a + * different dll name (without the ".DLL" extension) to + * get different processing. Ensure that the dll referenced + * in defaults.nh exists in the same directory as NetHack in + * order for it to load successfully. + * + */ + +static char where_to_get_source[] = "http://www.nethack.org/"; +static char author[] = "The NetHack Development Team"; + +#include "hack.h" +#include "wintty.h" +#include "win32api.h" + +extern HANDLE hConIn; +extern INPUT_RECORD ir; +char dllname[512]; +char *shortdllname; + +static INPUT_RECORD bogus_key; + +int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) +{ + char dlltmpname[512]; + char *tmp = dlltmpname, *tmp2; + *(tmp + GetModuleFileName(hInstance, tmp, 511)) = '\0'; + (void)strcpy(dllname, tmp); + tmp2 = strrchr(dllname, '\\'); + if (tmp2) { + tmp2++; + shortdllname = tmp2; + } + /* A bogus key that will be filtered when received, to keep ReadConsole + * from blocking */ + bogus_key.EventType = KEY_EVENT; + bogus_key.Event.KeyEvent.bKeyDown = 1; + bogus_key.Event.KeyEvent.wRepeatCount = 1; + bogus_key.Event.KeyEvent.wVirtualKeyCode = 0; + bogus_key.Event.KeyEvent.wVirtualScanCode = 0; + bogus_key.Event.KeyEvent.uChar.AsciiChar = (uchar)0x80; + bogus_key.Event.KeyEvent.dwControlKeyState = 0; + return TRUE; +} + +/* + * Keyboard translation tables. + * (Adopted from the MSDOS port) + */ + +#define KEYPADLO 0x47 +#define KEYPADHI 0x53 + +#define PADKEYS (KEYPADHI - KEYPADLO + 1) +#define iskeypad(x) (KEYPADLO <= (x) && (x) <= KEYPADHI) +#define isnumkeypad(x) (KEYPADLO <= (x) && (x) <= 0x51 && (x) != 0x4A && (x) != 0x4E) + +/* + * Keypad keys are translated to the normal values below. + * Shifted keypad keys are translated to the + * shift values below. + */ + +static const struct pad { + uchar normal, shift, cntrl; +} keypad[PADKEYS] = { + {'y', 'Y', C('y')}, /* 7 */ + {'k', 'K', C('k')}, /* 8 */ + {'u', 'U', C('u')}, /* 9 */ + {'m', C('p'), C('p')}, /* - */ + {'h', 'H', C('h')}, /* 4 */ + {'g', 'G', 'g'}, /* 5 */ + {'l', 'L', C('l')}, /* 6 */ + {'+', 'P', C('p')}, /* + */ + {'b', 'B', C('b')}, /* 1 */ + {'j', 'J', C('j')}, /* 2 */ + {'n', 'N', C('n')}, /* 3 */ + {'i', 'I', C('i')}, /* Ins */ + {'.', ':', ':'} /* Del */ +}, numpad[PADKEYS] = { + {'7', M('7'), '7'}, /* 7 */ + {'8', M('8'), '8'}, /* 8 */ + {'9', M('9'), '9'}, /* 9 */ + {'m', C('p'), C('p')}, /* - */ + {'4', M('4'), '4'}, /* 4 */ + {'g', 'G', 'g'}, /* 5 */ + {'6', M('6'), '6'}, /* 6 */ + {'+', 'P', C('p')}, /* + */ + {'1', M('1'), '1'}, /* 1 */ + {'2', M('2'), '2'}, /* 2 */ + {'3', M('3'), '3'}, /* 3 */ + {'i', 'I', C('i')}, /* Ins */ + {'.', ':', ':'} /* Del */ +}; + +#define inmap(x,vk) (((x) > 'A' && (x) < 'Z') || (vk) == 0xBF || (x) == '2') + +/* Use process_keystroke for key commands, process_keystroke2 for prompts */ +/* int FDECL(process_keystroke, (INPUT_RECORD *ir, boolean *valid, int portdebug)); */ +int FDECL(process_keystroke2, (HANDLE,INPUT_RECORD *ir, boolean *valid)); +static int FDECL(is_altseq, (unsigned long shiftstate)); + +static int +is_altseq(shiftstate) +unsigned long shiftstate; +{ + /* We need to distinguish the Alt keys from the AltGr key. + * On NT-based Windows, AltGr signals as right Alt and left Ctrl together; + * on 95-based Windows, AltGr signals as right Alt only. + * So on NT, we signal Alt if either Alt is pressed and left Ctrl is not, + * and on 95, we signal Alt for left Alt only. */ + switch (shiftstate & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED)) { + case LEFT_ALT_PRESSED: + case LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED: + return 1; + + case RIGHT_ALT_PRESSED: + case RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED: + return (GetVersion() & 0x80000000) == 0; + + default: + return 0; + } +} + +int __declspec(dllexport) __stdcall +ProcessKeystroke(hConIn, ir, valid, numberpad, portdebug) +HANDLE hConIn; +INPUT_RECORD *ir; +boolean *valid; +boolean numberpad; +int portdebug; +{ + int metaflags = 0, k = 0; + int keycode, vk; + unsigned char ch, pre_ch, mk = 0; + unsigned short int scan; + unsigned long shiftstate; + int altseq = 0; + const struct pad *kpad; + DWORD count; + + shiftstate = 0L; + ch = pre_ch = ir->Event.KeyEvent.uChar.AsciiChar; + scan = ir->Event.KeyEvent.wVirtualScanCode; + vk = ir->Event.KeyEvent.wVirtualKeyCode; + keycode = MapVirtualKey(vk, 2); + shiftstate = ir->Event.KeyEvent.dwControlKeyState; + if (scan == 0 && vk == 0) { + /* It's the bogus_key */ + ReadConsoleInput(hConIn,ir,1,&count); + *valid = FALSE; + return 0; + } + + if (is_altseq(shiftstate)) { + if (ch || inmap(keycode,vk)) altseq = 1; + else altseq = -1; /* invalid altseq */ + } + if (ch || (iskeypad(scan)) || (altseq > 0)) + *valid = TRUE; + /* if (!valid) return 0; */ + /* + * shiftstate can be checked to see if various special + * keys were pressed at the same time as the key. + * Currently we are using the ALT & SHIFT & CONTROLS. + * + * RIGHT_ALT_PRESSED, LEFT_ALT_PRESSED, + * RIGHT_CTRL_PRESSED, LEFT_CTRL_PRESSED, + * SHIFT_PRESSED,NUMLOCK_ON, SCROLLLOCK_ON, + * CAPSLOCK_ON, ENHANCED_KEY + * + * are all valid bit masks to use on shiftstate. + * eg. (shiftstate & LEFT_CTRL_PRESSED) is true if the + * left control key was pressed with the keystroke. + */ + if (iskeypad(scan)) { + ReadConsoleInput(hConIn,ir,1,&count); + kpad = numberpad ? numpad : keypad; + if (shiftstate & SHIFT_PRESSED) { + ch = kpad[scan - KEYPADLO].shift; + } + else if (shiftstate & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) { + ch = kpad[scan - KEYPADLO].cntrl; + } + else { + ch = kpad[scan - KEYPADLO].normal; + } + } + else if (altseq > 0) { /* ALT sequence */ + ReadConsoleInput(hConIn,ir,1,&count); + if (vk == 0xBF) ch = M('?'); + else ch = M(tolower(keycode)); + } + else if (ch < 32 && !isnumkeypad(scan)) { + /* Control code; ReadConsole seems to filter some of these, + * including ESC */ + ReadConsoleInput(hConIn,ir,1,&count); + } + /* Attempt to work better with international keyboards. */ + else { + CHAR ch2; + DWORD written; + /* The bogus_key guarantees that ReadConsole will return, + * and does not itself do anything */ + WriteConsoleInput(hConIn, &bogus_key, 1, &written); + ReadConsole(hConIn,&ch2,1,&count,NULL); + /* Prevent high characters from being interpreted as alt + * sequences; also filter the bogus_key */ + if (ch2 & 0x80) + *valid = FALSE; + else + ch = ch2; + if (ch == 0) *valid = FALSE; + } + if (ch == '\r') ch = '\n'; +#ifdef PORT_DEBUG + if (portdebug) { + char buf[BUFSZ]; + Sprintf(buf, + "PORTDEBUG: ch=%u, scan=%u, vk=%d, pre=%d, shiftstate=0x%X (ESC to end)\n", + ch, scan, vk, pre_ch, shiftstate); + fprintf(stdout, "\n%s", buf); + } +#endif + return ch; +} + +int process_keystroke2(hConIn, ir, valid) +HANDLE hConIn; +INPUT_RECORD *ir; +boolean *valid; +{ + /* Use these values for the numeric keypad */ + static const char keypad_nums[] = "789-456+1230."; + + unsigned char ch; + int vk; + unsigned short int scan; + unsigned long shiftstate; + int altseq; + DWORD count; + + ch = ir->Event.KeyEvent.uChar.AsciiChar; + vk = ir->Event.KeyEvent.wVirtualKeyCode; + scan = ir->Event.KeyEvent.wVirtualScanCode; + shiftstate = ir->Event.KeyEvent.dwControlKeyState; + + if (scan == 0 && vk == 0) { + /* It's the bogus_key */ + ReadConsoleInput(hConIn,ir,1,&count); + *valid = FALSE; + return 0; + } + + altseq = is_altseq(shiftstate); + if (ch || (iskeypad(scan)) || altseq) + *valid = TRUE; + /* if (!valid) return 0; */ + /* + * shiftstate can be checked to see if various special + * keys were pressed at the same time as the key. + * Currently we are using the ALT & SHIFT & CONTROLS. + * + * RIGHT_ALT_PRESSED, LEFT_ALT_PRESSED, + * RIGHT_CTRL_PRESSED, LEFT_CTRL_PRESSED, + * SHIFT_PRESSED,NUMLOCK_ON, SCROLLLOCK_ON, + * CAPSLOCK_ON, ENHANCED_KEY + * + * are all valid bit masks to use on shiftstate. + * eg. (shiftstate & LEFT_CTRL_PRESSED) is true if the + * left control key was pressed with the keystroke. + */ + if (iskeypad(scan) && !altseq) { + ReadConsoleInput(hConIn,ir,1,&count); + ch = keypad_nums[scan - KEYPADLO]; + } + else if (ch < 32 && !isnumkeypad(scan)) { + /* Control code; ReadConsole seems to filter some of these, + * including ESC */ + ReadConsoleInput(hConIn,ir,1,&count); + } + /* Attempt to work better with international keyboards. */ + else { + CHAR ch2; + ReadConsole(hConIn,&ch2,1,&count,NULL); + ch = ch2 & 0xFF; + if (ch == 0) *valid = FALSE; + } + if (ch == '\r') ch = '\n'; + return ch; +} + +int __declspec(dllexport) __stdcall +CheckInput(hConIn, ir, count, numpad, mode, mod, cc) +HANDLE hConIn; +INPUT_RECORD *ir; +int *count, *mod; +boolean numpad; +coord *cc; +{ + int ch; + boolean valid = 0, done = 0; + while (!done) { + *count = 0; + WaitForSingleObject(hConIn, INFINITE); + PeekConsoleInput(hConIn,ir,1,count); + if (mode == 0) { + if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) { + ch = process_keystroke2(hConIn, ir, &valid); + done = valid; + } else + ReadConsoleInput(hConIn,ir,1,count); + } else { + ch = 0; + if (count > 0) { + if (ir->EventType == KEY_EVENT && ir->Event.KeyEvent.bKeyDown) { + ch = ProcessKeystroke(hConIn, ir, &valid, numpad, +#ifdef PORTDEBUG + 1); +#else + 0); +#endif + if (valid) return ch; + } else { + ReadConsoleInput(hConIn,ir,1,count); + if (ir->EventType == MOUSE_EVENT) { + if ((ir->Event.MouseEvent.dwEventFlags == 0) && + (ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) { + cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1; + cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1; + + if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON) + *mod = CLICK_1; + else if (ir->Event.MouseEvent.dwButtonState & RIGHTBUTTON) + *mod = CLICK_2; +#if 0 /* middle button */ + else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON) + *mod = CLICK_3; +#endif + return 0; + } + } +#if 0 + /* We ignore these types of console events */ + else if (ir->EventType == FOCUS_EVENT) { + } + else if (ir->EventType == MENU_EVENT) { + } +#endif + } + } else + done = 1; + } + } + *mod = 0; + return ch; +} + +int __declspec(dllexport) __stdcall +NHkbhit(hConIn, ir) +HANDLE hConIn; +INPUT_RECORD *ir; +{ + int done = 0; /* true = "stop searching" */ + int retval; /* true = "we had a match" */ + DWORD count; + unsigned short int scan; + unsigned char ch; + unsigned long shiftstate; + int altseq = 0, keycode, vk; + done = 0; + retval = 0; + while (!done) + { + count = 0; + PeekConsoleInput(hConIn,ir,1,&count); + if (count > 0) { + if (ir->EventType == KEY_EVENT && ir->Event.KeyEvent.bKeyDown) { + ch = ir->Event.KeyEvent.uChar.AsciiChar; + scan = ir->Event.KeyEvent.wVirtualScanCode; + shiftstate = ir->Event.KeyEvent.dwControlKeyState; + vk = ir->Event.KeyEvent.wVirtualKeyCode; + keycode = MapVirtualKey(vk, 2); + if (is_altseq(shiftstate)) { + if (ch || inmap(keycode,vk)) altseq = 1; + else altseq = -1; /* invalid altseq */ + } + if (ch || iskeypad(scan) || altseq) { + done = 1; /* Stop looking */ + retval = 1; /* Found what we sought */ + } + } + else if ((ir->EventType == MOUSE_EVENT && + (ir->Event.MouseEvent.dwButtonState & MOUSEMASK))) { + done = 1; + retval = 1; + } + + else /* Discard it, it's an insignificant event */ + ReadConsoleInput(hConIn,ir,1,&count); + } else /* There are no events in console event queue */ { + done = 1; /* Stop looking */ + retval = 0; + } + } + return retval; +} + + +int __declspec(dllexport) __stdcall +SourceWhere(buf) +char **buf; +{ + if (!buf) return 0; + *buf = where_to_get_source; + return 1; +} + +int __declspec(dllexport) __stdcall +SourceAuthor(buf) +char **buf; +{ + if (!buf) return 0; + *buf = author; + return 1; +} + +int __declspec(dllexport) __stdcall +KeyHandlerName(buf, full) +char **buf; +int full; +{ + if (!buf) return 0; + if (full) *buf = dllname; + else *buf = shortdllname; + return 1; +} + diff --git a/sys/winnt/nttty.c b/sys/winnt/nttty.c index 8d878e3a7..2afdd6ee4 100644 --- a/sys/winnt/nttty.c +++ b/sys/winnt/nttty.c @@ -54,6 +54,7 @@ static BOOL FDECL(CtrlHandler, (DWORD)); /* dynamic keystroke handling .DLL support */ typedef int (__stdcall * PROCESS_KEYSTROKE)( + HANDLE, INPUT_RECORD *, boolean *, BOOLEAN_P, @@ -65,6 +66,16 @@ typedef int (__stdcall * NHKBHIT)( INPUT_RECORD * ); +typedef int (__stdcall * CHECKINPUT)( + HANDLE, + INPUT_RECORD *, + int *, + BOOLEAN_P, + int, + int *, + coord * +); + typedef int (__stdcall * SOURCEWHERE)( char ** ); @@ -81,6 +92,7 @@ typedef int (__stdcall * KEYHANDLERNAME)( HANDLE hLibrary; PROCESS_KEYSTROKE pProcessKeystroke; NHKBHIT pNHkbhit; +CHECKINPUT pCheckInput; SOURCEWHERE pSourceWhere; SOURCEAUTHOR pSourceAuthor; KEYHANDLERNAME pKeyHandlerName; @@ -192,6 +204,7 @@ tty_end_screen() csbi.dwSize.X * csbi.dwSize.Y, newcoord, &ccnt); } + FlushConsoleInputBuffer(hConIn); } extern boolean getreturn_disable; /* from sys/share/pcsys.c */ @@ -285,7 +298,7 @@ boolean *valid; boolean numberpad; int portdebug; { - int ch = pProcessKeystroke(ir, valid, numberpad, portdebug); + int ch = pProcessKeystroke(hConIn, ir, valid, numberpad, portdebug); /* check for override */ if (ch && ch < MAX_OVERRIDES && key_overrides[ch]) ch = key_overrides[ch]; @@ -323,64 +336,25 @@ get_scr_size() int tgetch() { + int mod; + coord cc; DWORD count; - boolean valid = 0; - int ch; - valid = 0; - while (!valid) { - ReadConsoleInput(hConIn,&ir,1,&count); - if ((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown) - ch = process_keystroke(&ir, &valid, iflags.num_pad, 0); - } - return ch; + return pCheckInput(hConIn, &ir, &count, iflags.num_pad, 0, &mod, &cc); } int ntposkey(x, y, mod) int *x, *y, *mod; { + int ch; + coord cc; DWORD count; - int keystroke = 0; - int done = 0; - boolean valid = 0; - while (!done) - { - count = 0; - ReadConsoleInput(hConIn,&ir,1,&count); - if (count > 0) { - if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) { - keystroke = process_keystroke(&ir, &valid, iflags.num_pad, 0); - if (valid) return keystroke; - } else if (ir.EventType == MOUSE_EVENT) { - if ((ir.Event.MouseEvent.dwEventFlags == 0) && - (ir.Event.MouseEvent.dwButtonState & MOUSEMASK)) { - *x = ir.Event.MouseEvent.dwMousePosition.X + 1; - *y = ir.Event.MouseEvent.dwMousePosition.Y - 1; - - if (ir.Event.MouseEvent.dwButtonState & LEFTBUTTON) - *mod = CLICK_1; - else if (ir.Event.MouseEvent.dwButtonState & RIGHTBUTTON) - *mod = CLICK_2; -#if 0 /* middle button */ - else if (ir.Event.MouseEvent.dwButtonState & MIDBUTTON) - *mod = CLICK_3; -#endif - return 0; - } - } -#if 0 - /* We ignore these types of console events */ - else if (ir.EventType == FOCUS_EVENT) { - } - else if (ir.EventType == MENU_EVENT) { - } -#endif - } else - done = 1; + ch = pCheckInput(hConIn, &ir, &count, iflags.num_pad, 1, mod, &cc); + if (!ch) { + *x = cc.x; + *y = cc.y; } - /* NOTREACHED */ - *mod = 0; - return 0; + return ch; } void @@ -869,6 +843,8 @@ load_keyboard_handler() (PROCESS_KEYSTROKE) GetProcAddress (hLibrary, TEXT ("ProcessKeystroke")); pNHkbhit = (NHKBHIT) GetProcAddress (hLibrary, TEXT ("NHkbhit")); + pCheckInput = + (CHECKINPUT) GetProcAddress (hLibrary, TEXT ("CheckInput")); pSourceWhere = (SOURCEWHERE) GetProcAddress (hLibrary, TEXT ("SourceWhere")); pSourceAuthor = @@ -886,6 +862,8 @@ load_keyboard_handler() if (hLibrary) { pProcessKeystroke = (PROCESS_KEYSTROKE) GetProcAddress (hLibrary, TEXT ("ProcessKeystroke")); + pCheckInput = + (CHECKINPUT) GetProcAddress (hLibrary, TEXT ("CheckInput")); pNHkbhit = (NHKBHIT) GetProcAddress (hLibrary, TEXT ("NHkbhit")); pSourceWhere =