- Move the code for keystroke handling into its own source file.
- Compile and link it as a dynamic link library.
- Dynamically load the keystroke handler at runtime
- Add support for specifying a different handler in defaults.nh
so that internationalization issues can be dealt with without
rebuilding nethack, just supply alternative handlers in HACKDIR.
The following exported functions need to be present in
the keystroke handler .dll:
ProcessKeystroke - returns an ascii value to NetHack
NHkbhit - allows peeking to see if a key/mouse press is waiting
SourceWhere - returns location for souce code for a keystroke handler
SourceAuthor - returns author information for a keystroke handler
KeyHandlerName - returns the full or short name of the keystroke handling dll.
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 nhico.uu nhsetup.bat
-ntsound.c nttty.c porthelp win32api.h winnt.c
+defaults.nh mapimail.c nethack.def nhdefkey.c nhico.uu
+nhsetup.bat ntsound.c nttty.c porthelp win32api.h
+winnt.c
util:
(files for all versions)
boolean cmdassist; /* provide detailed assistance for some commands */
boolean obsolete; /* obsolete options can point at this, it isn't used */
+#ifdef WIN32CON
+#define MAX_ALTKEYHANDLER 25
+ char altkeyhandler[MAX_ALTKEYHANDLER];
+#endif
};
/*
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);
#endif
#include <fcntl.h>
#endif
extern int FDECL(set_win32_option, (const char *, const char *));
+#ifdef WIN32CON
+#define LEFTBUTTON FROM_LEFT_1ST_BUTTON_PRESSED
+#define RIGHTBUTTON RIGHTMOST_BUTTON_PRESSED
+#define MIDBUTTON FROM_LEFT_2ND_BUTTON_PRESSED
+#define MOUSEMASK (LEFTBUTTON | RIGHTBUTTON | MIDBUTTON)
+#endif /* WIN32CON */
#endif /* NTCONF_H */
#ifdef PORT_DEBUG
# ifdef WIN32CON
extern void NDECL(win32con_debug_keystrokes);
+extern void NDECL(win32con_author_info);
# endif
int
} menu_selections[] = {
#ifdef WIN32CON
{"test win32 keystrokes", win32con_debug_keystrokes},
+ {"show keystroke handler information", win32con_handler_info},
#endif
{(char *)0, (void NDECL((*)))0} /* array terminator */
};
8, 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 },
{ "boulder", "the symbol to use for displaying boulders",
1, SET_IN_GAME },
{ "catname", "the name of your (first) cat (e.g., catname:Tabby)",
return;
}
+ /* altkeyhandler:string */
+ fullname = "altkeyhandler";
+ if (match_optname(opts, fullname, 4, TRUE)) {
+ if (negated) bad_negation(fullname, FALSE);
+ else if ((op = string_for_opt(opts, negated))) {
+#ifdef WIN32CON
+ (void)strncpy(iflags.altkeyhandler, op, MAX_ALTKEYHANDLER - 5);
+ load_keyboard_handler();
+#endif
+ }
+ return;
+ }
+
/* WINCAP
* align_status:[left|top|right|bottom] */
fullname = "align_status";
#
# If you have any questions read the sys/winnt/Install.nt file included
# with the distribution.
-# --
-# Michael Allison
#==============================================================================
# Do not delete the following 3 lines.
#
# DO NOT INDENT THE << below!
#
-$(GAMEFILE) : $(ALLOBJ) $(NHRES)
+$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(GAMEDIR)\nhdefkey.dll
@if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR)
@echo Linking....
$(link) $(LFLAGS) user32.lib winmm.lib -out:$@ @<<$(GAME).lnk
@if exist $(O)install.tag del $(O)install.tag
@if exist $(GAMEDIR)\$(GAME).bak del $(GAMEDIR)\$(GAME).bak
+$(O)nhdefkey.def:
+ @echo EXPORTS >$@
+ @echo ProcessKeystroke >>$@
+ @echo NHkbhit >>$@
+ @echo SourceWhere >>$@
+ @echo SourceAuthor >>$@
+ @echo KeyHandlerName >>$@
+
+$(GAMEDIR)\nhdefkey.dll : $(O)$(@B).o $(O)$(@B).def
+ @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR)
+ @echo Linking $@
+ $(link) -debug:full -debugtype:cv /RELEASE /NOLOGO /DLL user32.lib \
+ /PDB:"$(@B).PDB" /MAP:"$(@B).map" /DEF:$(O)$(@B).def \
+ -out:$@ $(O)$(@B).o
+
#
# Secondary Targets.
#
#
$(O)nttty.o: $(HACK_H) $(TILE_H) $(INCL)\win32api.h $(NTSYS)\nttty.c
- @@$(CC) $(CFLAGS) -I$(WSHR) -Fo$@ $(NTSYS)\nttty.c
+ @$(CC) $(CFLAGS) -I$(WSHR) -Fo$@ $(NTSYS)\nttty.c
+$(O)nhkeys.o: $(HACK_H) $(TILE_H) $(INCL)\win32api.h $(NTSYS)\nhkeys.c
+ @$(CC) $(CFLAGS) -I$(WSHR) -Fo$@ $(NTSYS)\nhkeys.c
$(O)winnt.o: $(HACK_H) $(INCL)\win32api.h $(NTSYS)\winnt.c
- @@$(CC) $(CFLAGS) -Fo$@ $(NTSYS)\winnt.c
+ @$(CC) $(CFLAGS) -Fo$@ $(NTSYS)\winnt.c
$(O)ntsound.o: $(HACK_H) $(NTSYS)\ntsound.c
- @@$(CC) $(CFLAGS) -Fo$@ $(NTSYS)\ntsound.c
+ @$(CC) $(CFLAGS) -Fo$@ $(NTSYS)\ntsound.c
$(O)mapimail.o: $(HACK_H) $(INCL)\nhlan.h $(NTSYS)\mapimail.c
- @@$(CC) $(CFLAGS) -DMAPI_VERBOSE -Fo$@ $(NTSYS)\mapimail.c
+ @$(CC) $(CFLAGS) -DMAPI_VERBOSE -Fo$@ $(NTSYS)\mapimail.c
#
# util dependencies
#
$(O)panic.o: $(U)panic.c $(CONFIG_H)
- @@$(CC) $(CFLAGS) -Fo$@ $(U)panic.c
+ @$(CC) $(CFLAGS) -Fo$@ $(U)panic.c
#
# The rest are stolen from sys/unix/Makefile.src,
--- /dev/null
+/* 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;
+
+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;
+ }
+ 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)
+
+/*
+ * 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')
+
+static BYTE KeyState[256];
+
+int __declspec(dllexport) __stdcall
+ProcessKeystroke(ir, valid, numberpad, portdebug)
+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;
+
+ 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;
+ KeyState[VK_SHIFT] = (shiftstate & SHIFT_PRESSED) ? 0x81 : 0;
+ KeyState[VK_CONTROL] = (shiftstate & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) ?
+ 0x81 : 0;
+ KeyState[VK_CAPITAL] = (shiftstate & CAPSLOCK_ON) ? 0x81 : 0;
+
+ if (shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) {
+ 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)) {
+ 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 */
+ if (vk == 0xBF) ch = M('?');
+ else ch = M(tolower(keycode));
+ }
+ /* Attempt to work better with international keyboards. */
+ else {
+ WORD chr[2];
+ k = ToAscii(vk, scan, KeyState, chr, 0);
+ if (k <= 2)
+ switch(k) {
+ case 2: /* two characters */
+ ch = (unsigned char)chr[1];
+ *valid = TRUE;
+ break;
+ case 1: /* one character */
+ ch = (unsigned char)chr[0];
+ *valid = TRUE;
+ break;
+ case 0: /* no translation */
+ default: /* negative */
+ *valid = FALSE;
+ }
+ }
+ if (ch == '\r') ch = '\n';
+#ifdef PORT_DEBUG
+ if (portdebug) {
+ char buf[BUFSZ];
+ Sprintf(buf,
+ "PORTDEBUG (%s): ch=%u, sc=%u, vk=%d, pre=%d, sh=0x%X, ta=%d (ESC to end)",
+ shortdllname, ch, scan, vk, pre_ch, shiftstate, k);
+ fprintf(stdout, "\n%s", buf);
+ }
+#endif
+ 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 (shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) {
+ 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;
+}
+
#include <sys\types.h>
#include <sys\stat.h>
#include "win32api.h"
-#include <wincon.h>
void FDECL(cmov, (int, int));
void FDECL(nocmov, (int, int));
int GUILaunched;
static BOOL FDECL(CtrlHandler, (DWORD));
+/* dynamic keystroke handling .DLL support */
+typedef int (__stdcall * PROCESS_KEYSTROKE)(
+ INPUT_RECORD *,
+ boolean *,
+ BOOLEAN_P,
+ int
+);
+
+typedef int (__stdcall * NHKBHIT)(
+ HANDLE,
+ INPUT_RECORD *
+);
+
+typedef int (__stdcall * SOURCEWHERE)(
+ char **
+);
+
+typedef int (__stdcall * SOURCEAUTHOR)(
+ char **
+);
+
+typedef int (__stdcall * KEYHANDLERNAME)(
+ char **,
+ int
+);
+
+HANDLE hLibrary;
+PROCESS_KEYSTROKE pProcessKeystroke;
+NHKBHIT pNHkbhit;
+SOURCEWHERE pSourceWhere;
+SOURCEAUTHOR pSourceAuthor;
+KEYHANDLERNAME pKeyHandlerName;
+
#ifndef CLR_MAX
#define CLR_MAX 16
#endif
static char currentbackground = 0;
static boolean colorchange = TRUE;
-#define LEFTBUTTON FROM_LEFT_1ST_BUTTON_PRESSED
-#define RIGHTBUTTON RIGHTMOST_BUTTON_PRESSED
-#define MIDBUTTON FROM_LEFT_2ND_BUTTON_PRESSED
-#define MOUSEMASK (LEFTBUTTON | RIGHTBUTTON | MIDBUTTON)
-
/*
* Called after returning from ! or ^Z
*/
HANDLE hStdOut;
DWORD cmode;
long mask;
-
+
+ load_keyboard_handler();
/* Initialize the function pointer that points to
* the kbhit() equivalent, in this TTY case nttty_kbhit()
*/
-
nt_kbhit = nttty_kbhit;
/* The following 6 lines of code were suggested by
get_scr_size();
}
+int process_keystroke(ir, valid, numberpad, portdebug)
+INPUT_RECORD *ir;
+boolean *valid;
+boolean numberpad;
+int portdebug;
+{
+ int ch = pProcessKeystroke(ir, valid, numberpad, portdebug);
+ /* check for override */
+ if (ch && ch < MAX_OVERRIDES && key_overrides[ch])
+ ch = key_overrides[ch];
+ return ch;
+}
+
+int
+nttty_kbhit()
+{
+ return pNHkbhit(hConIn, &ir);
+}
+
+
void
get_scr_size()
{
}
}
-
-/*
- * 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)
-
-/*
- * 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')
-
-static BYTE KeyState[256];
-
-int FDECL(process_keystroke, (INPUT_RECORD *ir, boolean *valid, int portdebug));
-
-int process_keystroke(ir, valid, portdebug)
-INPUT_RECORD *ir;
-boolean *valid;
-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;
-
- 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;
- KeyState[VK_SHIFT] = (shiftstate & SHIFT_PRESSED) ? 0x81 : 0;
- KeyState[VK_CONTROL] = (shiftstate & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) ?
- 0x81 : 0;
- KeyState[VK_CAPITAL] = (shiftstate & CAPSLOCK_ON) ? 0x81 : 0;
-
- if (shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) {
- 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)) {
- kpad = iflags.num_pad ? 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 */
- if (vk == 0xBF) ch = M('?');
- else ch = M(tolower(keycode));
- }
- /* Attempt to work better with international keyboards. */
- else {
- WORD chr[2];
- k = ToAscii(vk, scan, KeyState, chr, 0);
- if (k <= 2)
- switch(k) {
- case 2: /* two characters */
- ch = (unsigned char)chr[1];
- *valid = TRUE;
- break;
- case 1: /* one character */
- ch = (unsigned char)chr[0];
- *valid = TRUE;
- break;
- case 0: /* no translation */
- default: /* negative */
- *valid = FALSE;
- }
- }
- /* check for override */
- if (ch && ch < MAX_OVERRIDES && key_overrides[ch]) {
- mk = ch;
- ch = key_overrides[ch];
- *valid = TRUE;
- }
-
- if (ch == '\r') ch = '\n';
-#ifdef PORT_DEBUG
- if (portdebug) {
- char buf[BUFSZ];
- Sprintf(buf,
- "PORTDEBUG: ch=%u, sc=%u, vk=%d, pre=%d, sh=0x%X, ta=%d, mk=%d (ESC to end)\n",
- ch, scan, vk, pre_ch, shiftstate, k, mk);
- xputs(buf);
- }
-#endif
- return ch;
-}
-
int
tgetch()
{
while (!valid) {
ReadConsoleInput(hConIn,&ir,1,&count);
if ((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown)
- ch = process_keystroke(&ir, &valid, 0);
+ ch = process_keystroke(&ir, &valid, iflags.num_pad, 0);
}
return ch;
}
ReadConsoleInput(hConIn,&ir,1,&count);
if (count > 0) {
if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
- keystroke = process_keystroke(&ir, &valid, 0);
+ 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) &&
return 0;
}
-int
-nttty_kbhit()
-{
- 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 (shiftstate & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) {
- 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;
-}
-
void
nocmov(x, y)
int x,y;
}
(void)doredraw();
}
+void
+win32con_handler_info()
+{
+ char *buf;
+ int ci;
+ if (!pSourceAuthor && !pSourceWhere)
+ pline("Keyboard handler source info and author unavailable.");
+ else {
+ if (pKeyHandlerName && pKeyHandlerName(&buf, 1)) {
+ xputs("\n");
+ xputs("Keystroke handler loaded: \n ");
+ xputs(buf);
+ }
+ if (pSourceAuthor && pSourceAuthor(&buf)) {
+ xputs("\n");
+ xputs("Keystroke handler Author: \n ");
+ xputs(buf);
+ }
+ if (pSourceWhere && pSourceWhere(&buf)) {
+ xputs("\n");
+ xputs("Keystroke handler source code available at:\n ");
+ xputs(buf);
+ }
+ xputs("\nPress any key to resume.");
+ ci=nhgetch();
+ (void)doredraw();
+ }
+}
#endif
void
key_overrides[idx] = val;
}
+void
+load_keyboard_handler()
+{
+ char suffx[] = ".dll";
+#define MAX_DLLNAME 25
+ char kh[MAX_ALTKEYHANDLER];
+ if (iflags.altkeyhandler[0]) {
+ if (hLibrary) { /* already one loaded apparently */
+ FreeLibrary(hLibrary);
+ hLibrary = (HANDLE)0;
+ }
+ (void) strncpy(kh, iflags.altkeyhandler,
+ (MAX_ALTKEYHANDLER - sizeof suffx) - 1);
+ kh[(MAX_ALTKEYHANDLER - sizeof suffx) - 1] = '\0';
+ Strcat(kh, suffx);
+ hLibrary = LoadLibrary(kh);
+ if (hLibrary) {
+ pProcessKeystroke =
+ (PROCESS_KEYSTROKE) GetProcAddress (hLibrary, TEXT ("ProcessKeystroke"));
+ 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) {
+ if (hLibrary) {
+ FreeLibrary(hLibrary);
+ hLibrary = (HANDLE)0;
+ }
+ hLibrary = LoadLibrary("nhdefkey.dll");
+ if (hLibrary) {
+ pProcessKeystroke =
+ (PROCESS_KEYSTROKE) GetProcAddress (hLibrary, TEXT ("ProcessKeystroke"));
+ 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) {
+ 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);
+ }
+}
+
#endif /* WIN32CON */