]> granicus.if.org Git - nethack/commitdiff
Add <Someone>'s key handling as loadable handler
authornethack.allison <nethack.allison>
Sun, 11 May 2003 23:25:08 +0000 (23:25 +0000)
committernethack.allison <nethack.allison>
Sun, 11 May 2003 23:25:08 +0000 (23:25 +0000)
Files
doc/fixes34.2
sys/winnt/Makefile.msc
sys/winnt/nh340key.c
sys/winnt/nhdefkey.c
sys/winnt/nhraykey.c [new file with mode: 0644]
sys/winnt/nttty.c

diff --git a/Files b/Files
index f0d9ef07d4971f0cf51871f8f1eb513fffd53dc9..66683f292a43f72f63b1d49752e0c436bdd00a54 100644 (file)
--- 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)
index b64a11192dc46fc13557c0f50f5c1fe298ee792f..78a4ad1dd8b3f41a79f71aa2e338800add895773 100644 (file)
@@ -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
 
index 95933af4c746adab53b0d1db0418c9d6f7f11cbd..0dda2879cec46cd09094f1ee9f3e22a2d0032b2e 100644 (file)
@@ -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.
 #
index fc8c1f26b6f501ded65b3a8ea032b27e12bced4e..31bf1f61549ac43e93873fad527f080a2a89b03f 100644 (file)
@@ -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)
index eeeeb0f30ee68adf3a8e43c94c8b0a12577986ec..74a2bdd2c8bbef20d64fd5329704b69a48acd3cd 100644 (file)
@@ -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 (file)
index 0000000..0e73459
--- /dev/null
@@ -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;
+}
+
index 8d878e3a71bb108b79b131430d6c22855d4e7a76..2afdd6ee44f4f9d171b0a16aca9dbd664066bba8 100644 (file)
@@ -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 =