]> granicus.if.org Git - nethack/commitdiff
Fix for bug 324 (aka H4216). We now will use nhraykey by default if the
authorBart House <bart@barthouse.com>
Sun, 13 May 2018 01:06:23 +0000 (18:06 -0700)
committerBart House <bart@barthouse.com>
Sun, 13 May 2018 01:06:23 +0000 (18:06 -0700)
players keyboard layout is non-english.  nhraykey properly handles
non-english input.  We also now support changing altkeyhandler in game.

include/ntconf.h
src/options.c
sys/winnt/nttty.c
sys/winnt/stubs.c

index 88db55b8488f2197f4715cb967269b040376bf4f..36a87e2e42a87db01d56bd09996a67f3a577c58b 100644 (file)
@@ -203,7 +203,9 @@ extern void NDECL(win32_abort);
 extern void FDECL(nttty_preference_update, (const char *));
 extern void NDECL(toggle_mouse_support);
 extern void FDECL(map_subkeyvalue, (char *));
-extern void NDECL(load_keyboard_handler);
+#if defined(WIN32CON)
+extern void FDECL(set_altkeyhandler, (const char *));
+#endif
 extern void NDECL(raw_clear_screen);
 
 #include <fcntl.h>
index b0c125051f529536cb07b37572533adc3a95642b..4eea256a7dc134f132d536821fcfb2eb804838e3 100644 (file)
@@ -263,7 +263,7 @@ static struct Comp_Opt {
       DISP_IN_GAME },
     { "align_message", "message window alignment", 20, DISP_IN_GAME }, /*WC*/
     { "align_status", "status window alignment", 20, DISP_IN_GAME },   /*WC*/
-    { "altkeyhandler", "alternate key handler", 20, DISP_IN_GAME },
+    { "altkeyhandler", "alternate key handler", 20, SET_IN_GAME },
 #ifdef BACKWARD_COMPAT
     { "boulder", "deprecated (use S_boulder in sym file instead)", 1,
       SET_IN_GAME },
@@ -2651,9 +2651,8 @@ boolean tinitial, tfrom_file;
             bad_negation(fullname, FALSE);
             return FALSE;
         } else if ((op = string_for_opt(opts, negated)) != 0) {
-#ifdef WIN32
-            (void) strncpy(iflags.altkeyhandler, op, MAX_ALTKEYHANDLER - 5);
-            load_keyboard_handler();
+#if defined(WIN32CON)
+            set_altkeyhandler(op);
 #endif
         } else
             return FALSE;
index 51bbad4449ec6bd38edb59cadc35a2c0fd5f707e..d641b29818657ddad32ec33f3bfb479c56ac0d28 100644 (file)
@@ -190,13 +190,19 @@ typedef int(__stdcall *SOURCEAUTHOR)(char **);
 
 typedef int(__stdcall *KEYHANDLERNAME)(char **, int);
 
-HANDLE hLibrary;
-PROCESS_KEYSTROKE pProcessKeystroke;
-NHKBHIT pNHkbhit;
-CHECKINPUT pCheckInput;
-SOURCEWHERE pSourceWhere;
-SOURCEAUTHOR pSourceAuthor;
-KEYHANDLERNAME pKeyHandlerName;
+typedef struct {
+    char *              name;       // name without DLL extension
+    HANDLE              hLibrary;
+    PROCESS_KEYSTROKE   pProcessKeystroke;
+    NHKBHIT             pNHkbhit;
+    CHECKINPUT          pCheckInput;
+    SOURCEWHERE         pSourceWhere;
+    SOURCEAUTHOR        pSourceAuthor;
+    KEYHANDLERNAME      pKeyHandlerName;
+} keyboard_handler_t;
+
+keyboard_handler_t keyboard_handler;
+
 
 /* Console buffer flipping support */
 
@@ -383,7 +389,6 @@ int mode; // unused
 {
     DWORD cmode;
 
-    load_keyboard_handler();
     /* Initialize the function pointer that points to
      * the kbhit() equivalent, in this TTY case nttty_kbhit()
      */
@@ -407,7 +412,8 @@ boolean *valid;
 boolean numberpad;
 int portdebug;
 {
-    int ch = pProcessKeystroke(console.hConIn, ir, valid, numberpad, portdebug);
+    int ch = keyboard_handler.pProcessKeystroke(
+                    console.hConIn, ir, valid, numberpad, portdebug);
     /* check for override */
     if (ch && ch < MAX_OVERRIDES && key_overrides[ch])
         ch = key_overrides[ch];
@@ -417,7 +423,7 @@ int portdebug;
 int
 nttty_kbhit()
 {
-    return pNHkbhit(console.hConIn, &ir);
+    return keyboard_handler.pNHkbhit(console.hConIn, &ir);
 }
 
 int
@@ -429,8 +435,8 @@ tgetch()
     really_move_cursor();
     return (program_state.done_hup)
                ? '\033'
-               : pCheckInput(console.hConIn, &ir, &count, iflags.num_pad, 0, &mod,
-                             &cc);
+               : keyboard_handler.pCheckInput(
+                   console.hConIn, &ir, &count, iflags.num_pad, 0, &mod, &cc);
 }
 
 int
@@ -443,7 +449,8 @@ int *x, *y, *mod;
     really_move_cursor();
     ch = (program_state.done_hup)
              ? '\033'
-             : pCheckInput(console.hConIn, &ir, &count, iflags.num_pad, 1, mod, &cc);
+             : keyboard_handler.pCheckInput(
+                   console.hConIn, &ir, &count, iflags.num_pad, 1, mod, &cc);
     if (!ch) {
         *x = cc.x;
         *y = cc.y;
@@ -909,20 +916,23 @@ win32con_handler_info()
 {
     char *buf;
     int ci;
-    if (!pSourceAuthor && !pSourceWhere)
+    if (!keyboard_handler.pSourceAuthor && !keyboard_handler.pSourceWhere)
         pline("Keyboard handler source info and author unavailable.");
     else {
-        if (pKeyHandlerName && pKeyHandlerName(&buf, 1)) {
+        if (keyboard_handler.pKeyHandlerName &&
+            keyboard_handler.pKeyHandlerName(&buf, 1)) {
             xputs("\n");
             xputs("Keystroke handler loaded: \n    ");
             xputs(buf);
         }
-        if (pSourceAuthor && pSourceAuthor(&buf)) {
+        if (keyboard_handler.pSourceAuthor &&
+            keyboard_handler.pSourceAuthor(&buf)) {
             xputs("\n");
             xputs("Keystroke handler Author: \n    ");
             xputs(buf);
         }
-        if (pSourceWhere && pSourceWhere(&buf)) {
+        if (keyboard_handler.pSourceWhere &&
+            keyboard_handler.pSourceWhere(&buf)) {
             xputs("\n");
             xputs("Keystroke handler source code available at:\n    ");
             xputs(buf);
@@ -974,86 +984,79 @@ register char *op;
     key_overrides[idx] = val;
 }
 
-void
-load_keyboard_handler()
-{
-    char suffx[] = ".dll";
-    char *truncspot;
-#define MAX_DLLNAME 25
-    char kh[MAX_ALTKEYHANDLER];
-    if (iflags.altkeyhandler[0]) {
-        if (hLibrary) { /* already one loaded apparently */
-            FreeLibrary(hLibrary);
-            hLibrary = (HANDLE) 0;
-            pNHkbhit = (NHKBHIT) 0;
-            pCheckInput = (CHECKINPUT) 0;
-            pSourceWhere = (SOURCEWHERE) 0;
-            pSourceAuthor = (SOURCEAUTHOR) 0;
-            pKeyHandlerName = (KEYHANDLERNAME) 0;
-            pProcessKeystroke = (PROCESS_KEYSTROKE) 0;
-        }
-        if ((truncspot = strstri(iflags.altkeyhandler, suffx)) != 0)
-            *truncspot = '\0';
-        (void) strncpy(kh, iflags.altkeyhandler,
-                       (MAX_ALTKEYHANDLER - sizeof suffx) - 1);
-        kh[(MAX_ALTKEYHANDLER - sizeof suffx) - 1] = '\0';
-        Strcat(kh, suffx);
-        Strcpy(iflags.altkeyhandler, kh);
-        hLibrary = LoadLibrary(kh);
-        if (hLibrary) {
-            pProcessKeystroke = (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 =
-                (SOURCEAUTHOR) GetProcAddress(hLibrary, TEXT("SourceAuthor"));
-            pKeyHandlerName = (KEYHANDLERNAME) GetProcAddress(
-                hLibrary, TEXT("KeyHandlerName"));
-        }
+void unload_keyboard_handler()
+{
+    ntassert(keyboard_handler.hLibrary != NULL);
+
+    FreeLibrary(keyboard_handler.hLibrary);
+    memset(&keyboard_handler, 0, sizeof(keyboard_handler_t));
+}
+
+boolean
+load_keyboard_handler(const char * inName)
+{
+    char path[MAX_ALTKEYHANDLER + 4];
+    strcpy(path, inName);
+    strcat(path, ".dll");
+
+    HANDLE hLibrary = LoadLibrary(path);
+
+    if (hLibrary == NULL)
+        return FALSE;
+
+    PROCESS_KEYSTROKE pProcessKeystroke = (PROCESS_KEYSTROKE) GetProcAddress(
+        hLibrary, TEXT("ProcessKeystroke"));
+    NHKBHIT pNHkbhit = (NHKBHIT) GetProcAddress(
+        hLibrary, TEXT("NHkbhit"));
+    CHECKINPUT pCheckInput =
+        (CHECKINPUT) GetProcAddress(hLibrary, TEXT("CheckInput"));
+
+    if (!pProcessKeystroke || !pNHkbhit || !pCheckInput)
+    {
+        return FALSE;
+    } else {
+        if (keyboard_handler.hLibrary != NULL)
+            unload_keyboard_handler();
+
+        keyboard_handler.hLibrary = hLibrary;
+
+        keyboard_handler.pProcessKeystroke = pProcessKeystroke;
+        keyboard_handler.pNHkbhit = pNHkbhit;
+        keyboard_handler.pCheckInput = pCheckInput;
+
+        keyboard_handler.pSourceWhere =
+            (SOURCEWHERE) GetProcAddress(hLibrary, TEXT("SourceWhere"));
+        keyboard_handler.pSourceAuthor =
+            (SOURCEAUTHOR) GetProcAddress(hLibrary, TEXT("SourceAuthor"));
+        keyboard_handler.pKeyHandlerName = (KEYHANDLERNAME) GetProcAddress(
+            hLibrary, TEXT("KeyHandlerName"));
     }
-    if (!pProcessKeystroke || !pNHkbhit || !pCheckInput) {
-        if (hLibrary) {
-            FreeLibrary(hLibrary);
-            hLibrary = (HANDLE) 0;
-            pNHkbhit = (NHKBHIT) 0;
-            pCheckInput = (CHECKINPUT) 0;
-            pSourceWhere = (SOURCEWHERE) 0;
-            pSourceAuthor = (SOURCEAUTHOR) 0;
-            pKeyHandlerName = (KEYHANDLERNAME) 0;
-            pProcessKeystroke = (PROCESS_KEYSTROKE) 0;
-        }
-        (void) strncpy(kh, "nhdefkey.dll",
-                       (MAX_ALTKEYHANDLER - sizeof suffx) - 1);
-        kh[(MAX_ALTKEYHANDLER - sizeof suffx) - 1] = '\0';
-        Strcpy(iflags.altkeyhandler, kh);
-        hLibrary = LoadLibrary(kh);
-        if (hLibrary) {
-            pProcessKeystroke = (PROCESS_KEYSTROKE) GetProcAddress(
-                hLibrary, TEXT("ProcessKeystroke"));
-            pCheckInput =
-                (CHECKINPUT) GetProcAddress(hLibrary, TEXT("CheckInput"));
-            pNHkbhit = (NHKBHIT) GetProcAddress(hLibrary, TEXT("NHkbhit"));
-            pSourceWhere =
-                (SOURCEWHERE) GetProcAddress(hLibrary, TEXT("SourceWhere"));
-            pSourceAuthor =
-                (SOURCEAUTHOR) GetProcAddress(hLibrary, TEXT("SourceAuthor"));
-            pKeyHandlerName = (KEYHANDLERNAME) GetProcAddress(
-                hLibrary, TEXT("KeyHandlerName"));
-        }
+
+    return TRUE;
+}
+
+void set_altkeyhandler(const char * inName)
+{
+    if (strlen(inName) >= MAX_ALTKEYHANDLER) {
+        config_error_add("altkeyhandler name '%s' is too long", inName);
+        return;
     }
-    if (!pProcessKeystroke || !pNHkbhit || !pCheckInput) {
-        if (!hLibrary)
-            raw_printf("\nNetHack was unable to load keystroke handler.\n");
-        else {
-            FreeLibrary(hLibrary);
-            hLibrary = (HANDLE) 0;
-            raw_printf("\nNetHack keystroke handler is invalid.\n");
-        }
-        exit(EXIT_FAILURE);
+
+    char name[MAX_ALTKEYHANDLER];
+    strcpy(name, inName);
+
+    /* We support caller mistakenly giving name with '.dll' extension */
+    char * ext = strchr(name, '.');
+    if (ext != NULL) *ext = '\0';
+
+    if (load_keyboard_handler(name))
+        strcpy(iflags.altkeyhandler, name);
+    else {
+        config_error_add("unable to load altkeyhandler '%s'", name);
+        return;
     }
+
+    return;
 }
 
 /* this is used as a printf() replacement when the window
@@ -1853,6 +1856,17 @@ void nethack_enter_nttty()
 #endif
     SetConsoleMode(console.hConIn, cmode);
 
+    /* load default keyboard handler */
+    HKL keyboard_layout = GetKeyboardLayout(0);
+    DWORD primary_language = (DWORD) keyboard_layout & 0x3f;
+
+    if (primary_language == LANG_ENGLISH) {
+        if (!load_keyboard_handler("nhdefkey"))
+            error("Unable to load nhdefkey.dll");
+    } else {
+        if (!load_keyboard_handler("nhraykey"))
+            error("Unable to load nhdefkey.dll");
+    }
 }
 
 #endif /* WIN32 */
index 712164dc1567ba60862e03b63463174340f9611a..61e031c7f39f5bf95c6ef7b3d8d494bef31c015f 100644 (file)
@@ -136,12 +136,6 @@ register char *op;
     return;
 }
 
-void
-load_keyboard_handler()
-{
-    return;
-}
-
 /* this is used as a printf() replacement when the window
  * system isn't initialized yet
  */