1 /* aNetHack 0.0.1 nh340key.c $ANH-Date: 1432512793 2015/05/25 00:13:13 $ $ANH-Branch: master $:$ANH-Revision: 1.12 $ */
2 /* Copyright (c) aNetHack PC Development Team 2003 */
3 /* aNetHack may be freely redistributed. See license for details. */
6 * This is the aNetHack keystroke processing from aNetHack 3.4.0.
7 * It can be built as a run-time loadable dll (nh340key.dll),
8 * placed in the same directory as the anethack.exe executable,
9 * and loaded by specifying OPTIONS=altkeyhandler:nh340key
13 static char where_to_get_source
[] = "http://www.anethack.org/";
14 static char author
[] = "The aNetHack Development Team";
21 extern INPUT_RECORD ir
;
25 int FDECL(__declspec(dllexport
) __stdcall ProcessKeystroke
,
26 (HANDLE hConIn
, INPUT_RECORD
*ir
, boolean
*valid
,
27 BOOLEAN_P numberpad
, int portdebug
));
30 DllMain(HINSTANCE hInstance
, DWORD fdwReason
, PVOID pvReserved
)
33 char *tmp
= dlltmpname
, *tmp2
;
34 *(tmp
+ GetModuleFileName(hInstance
, tmp
, 511)) = '\0';
35 (void) strcpy(dllname
, tmp
);
36 tmp2
= strrchr(dllname
, '\\');
45 * Keyboard translation tables.
46 * (Adopted from the MSDOS port)
52 #define PADKEYS (KEYPADHI - KEYPADLO + 1)
53 #define iskeypad(x) (KEYPADLO <= (x) && (x) <= KEYPADHI)
56 * Keypad keys are translated to the normal values below.
57 * Shifted keypad keys are translated to the
61 static const struct pad
{
62 uchar normal
, shift
, cntrl
;
65 { 'y', 'Y', C('y') }, /* 7 */
66 { 'k', 'K', C('k') }, /* 8 */
67 { 'u', 'U', C('u') }, /* 9 */
68 { 'm', C('p'), C('p') }, /* - */
69 { 'h', 'H', C('h') }, /* 4 */
70 { 'g', 'G', 'g' }, /* 5 */
71 { 'l', 'L', C('l') }, /* 6 */
72 { '+', 'P', C('p') }, /* + */
73 { 'b', 'B', C('b') }, /* 1 */
74 { 'j', 'J', C('j') }, /* 2 */
75 { 'n', 'N', C('n') }, /* 3 */
76 { 'i', 'I', C('i') }, /* Ins */
77 { '.', ':', ':' } /* Del */
80 { '7', M('7'), '7' }, /* 7 */
81 { '8', M('8'), '8' }, /* 8 */
82 { '9', M('9'), '9' }, /* 9 */
83 { 'm', C('p'), C('p') }, /* - */
84 { '4', M('4'), '4' }, /* 4 */
85 { 'g', 'G', 'g' }, /* 5 */
86 { '6', M('6'), '6' }, /* 6 */
87 { '+', 'P', C('p') }, /* + */
88 { '1', M('1'), '1' }, /* 1 */
89 { '2', M('2'), '2' }, /* 2 */
90 { '3', M('3'), '3' }, /* 3 */
91 { 'i', 'I', C('i') }, /* Ins */
92 { '.', ':', ':' } /* Del */
95 #define inmap(x, vk) (((x) > 'A' && (x) < 'Z') || (vk) == 0xBF || (x) == '2')
97 int __declspec(dllexport
) __stdcall
ProcessKeystroke(hConIn
, ir
, valid
,
105 int metaflags
= 0, k
= 0;
107 unsigned char ch
, pre_ch
, mk
= 0;
108 unsigned short int scan
;
109 unsigned long shiftstate
;
111 const struct pad
*kpad
;
114 ch
= pre_ch
= ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
115 scan
= ir
->Event
.KeyEvent
.wVirtualScanCode
;
116 vk
= ir
->Event
.KeyEvent
.wVirtualKeyCode
;
117 keycode
= MapVirtualKey(vk
, 2);
118 shiftstate
= ir
->Event
.KeyEvent
.dwControlKeyState
;
120 if (shiftstate
& (LEFT_ALT_PRESSED
| RIGHT_ALT_PRESSED
)) {
121 if (ch
|| inmap(keycode
, vk
))
124 altseq
= -1; /* invalid altseq */
126 if (ch
|| (iskeypad(scan
)) || (altseq
> 0))
128 /* if (!valid) return 0; */
130 * shiftstate can be checked to see if various special
131 * keys were pressed at the same time as the key.
132 * Currently we are using the ALT & SHIFT & CONTROLS.
134 * RIGHT_ALT_PRESSED, LEFT_ALT_PRESSED,
135 * RIGHT_CTRL_PRESSED, LEFT_CTRL_PRESSED,
136 * SHIFT_PRESSED,NUMLOCK_ON, SCROLLLOCK_ON,
137 * CAPSLOCK_ON, ENHANCED_KEY
139 * are all valid bit masks to use on shiftstate.
140 * eg. (shiftstate & LEFT_CTRL_PRESSED) is true if the
141 * left control key was pressed with the keystroke.
143 if (iskeypad(scan
)) {
144 kpad
= numberpad
? numpad
: keypad
;
145 if (shiftstate
& SHIFT_PRESSED
) {
146 ch
= kpad
[scan
- KEYPADLO
].shift
;
147 } else if (shiftstate
& (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
)) {
148 ch
= kpad
[scan
- KEYPADLO
].cntrl
;
150 ch
= kpad
[scan
- KEYPADLO
].normal
;
152 } else if (altseq
> 0) { /* ALT sequence */
156 ch
= M(tolower((uchar
) keycode
));
164 "PORTDEBUG (%s): ch=%u, sc=%u, vk=%d, sh=0x%X (ESC to end)",
165 shortdllname
, ch
, scan
, vk
, shiftstate
);
166 fprintf(stdout
, "\n%s", buf
);
172 int __declspec(dllexport
) __stdcall
NHkbhit(hConIn
, ir
)
176 int done
= 0; /* true = "stop searching" */
177 int retval
; /* true = "we had a match" */
179 unsigned short int scan
;
181 unsigned long shiftstate
;
182 int altseq
= 0, keycode
, vk
;
187 PeekConsoleInput(hConIn
, ir
, 1, &count
);
189 if (ir
->EventType
== KEY_EVENT
&& ir
->Event
.KeyEvent
.bKeyDown
) {
190 ch
= ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
191 scan
= ir
->Event
.KeyEvent
.wVirtualScanCode
;
192 shiftstate
= ir
->Event
.KeyEvent
.dwControlKeyState
;
193 vk
= ir
->Event
.KeyEvent
.wVirtualKeyCode
;
194 keycode
= MapVirtualKey(vk
, 2);
195 if (shiftstate
& (LEFT_ALT_PRESSED
| RIGHT_ALT_PRESSED
)) {
196 if (ch
|| inmap(keycode
, vk
))
199 altseq
= -1; /* invalid altseq */
201 if (ch
|| iskeypad(scan
) || altseq
) {
202 done
= 1; /* Stop looking */
203 retval
= 1; /* Found what we sought */
205 /* Strange Key event; let's purge it to avoid trouble */
206 ReadConsoleInput(hConIn
, ir
, 1, &count
);
209 } else if ((ir
->EventType
== MOUSE_EVENT
210 && (ir
->Event
.MouseEvent
.dwButtonState
216 else /* Discard it, it's an insignificant event */
217 ReadConsoleInput(hConIn
, ir
, 1, &count
);
218 } else /* There are no events in console event queue */ {
219 done
= 1; /* Stop looking */
226 int __declspec(dllexport
) __stdcall
CheckInput(hConIn
, ir
, count
, numpad
,
236 #if defined(SAFERHANGUP)
240 boolean valid
= 0, done
= 0;
242 #if defined(SAFERHANGUP)
243 dwWait
= WaitForSingleObjectEx(hConIn
, // event object to wait for
244 INFINITE
, // waits indefinitely
245 TRUE
); // alertable wait enabled
246 if (dwWait
== WAIT_FAILED
)
249 ReadConsoleInput(hConIn
, ir
, 1, count
);
251 if ((ir
->EventType
== KEY_EVENT
) && ir
->Event
.KeyEvent
.bKeyDown
) {
252 ch
= ProcessKeystroke(hConIn
, ir
, &valid
, numpad
, 0);
257 if (ir
->EventType
== KEY_EVENT
258 && ir
->Event
.KeyEvent
.bKeyDown
) {
259 ch
= ProcessKeystroke(hConIn
, ir
, &valid
, numpad
, 0);
262 } else if (ir
->EventType
== MOUSE_EVENT
) {
263 if ((ir
->Event
.MouseEvent
.dwEventFlags
== 0)
264 && (ir
->Event
.MouseEvent
.dwButtonState
& MOUSEMASK
)) {
265 cc
->x
= ir
->Event
.MouseEvent
.dwMousePosition
.X
+ 1;
266 cc
->y
= ir
->Event
.MouseEvent
.dwMousePosition
.Y
- 1;
268 if (ir
->Event
.MouseEvent
.dwButtonState
& LEFTBUTTON
)
270 else if (ir
->Event
.MouseEvent
.dwButtonState
273 #if 0 /* middle button */
274 else if (ir
->Event
.MouseEvent
.dwButtonState
& MIDBUTTON
)
284 return mode
? 0 : ch
;
287 int __declspec(dllexport
) __stdcall
SourceWhere(buf
)
292 *buf
= where_to_get_source
;
296 int __declspec(dllexport
) __stdcall
SourceAuthor(buf
)
305 int __declspec(dllexport
) __stdcall
KeyHandlerName(buf
, full
)