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:
+3
-1
@@ -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
@@ -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
@@ -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 */
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user