Fix for bug 324 (aka H4216). We now will use nhraykey by default if the

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