Add <Someone>'s key handling as loadable handler
This commit is contained in:
4
Files
4
Files
@@ -191,8 +191,8 @@ sys/winnt:
|
|||||||
(files for Windows 9x, NT and Windows2000 version)
|
(files for Windows 9x, NT and Windows2000 version)
|
||||||
Install.nt Makefile.bcc Makefile.gcc Makefile.msc console.rc
|
Install.nt Makefile.bcc Makefile.gcc Makefile.msc console.rc
|
||||||
defaults.nh mapimail.c nethack.def nhdefkey.c nh340key.c
|
defaults.nh mapimail.c nethack.def nhdefkey.c nh340key.c
|
||||||
nhico.uu nhsetup.bat ntsound.c nttty.c porthelp
|
nhraykey.c nhico.uu nhsetup.bat ntsound.c nttty.c
|
||||||
win32api.h winnt.c
|
porthelp win32api.h winnt.c
|
||||||
|
|
||||||
util:
|
util:
|
||||||
(files for all versions)
|
(files for all versions)
|
||||||
|
|||||||
@@ -78,5 +78,5 @@ Platform- and/or Interface-Specific New Features
|
|||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
win32tty: keystroke handlers can be dynamically loaded to assist in resolving
|
win32tty: keystroke handlers can be dynamically loaded to assist in resolving
|
||||||
internationalization issues
|
internationalization issues
|
||||||
|
win32tty: add Ray Chason's code for international keyboard handling
|
||||||
|
|
||||||
|
|||||||
@@ -576,7 +576,7 @@ $(NHRES): $(NTSYS)\console.rc $(NTSYS)\NetHack.ico
|
|||||||
$(GAMEFILE) : $(ALLOBJ) $(NHRES)
|
$(GAMEFILE) : $(ALLOBJ) $(NHRES)
|
||||||
!ELSE
|
!ELSE
|
||||||
$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(O)gamedir.tag \
|
$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(O)gamedir.tag \
|
||||||
$(GAMEDIR)\nhdefkey.dll $(GAMEDIR)\nh340key.dll
|
$(GAMEDIR)\nhdefkey.dll $(GAMEDIR)\nh340key.dll $(GAMEDIR)\nhraykey.dll
|
||||||
!ENDIF
|
!ENDIF
|
||||||
@if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR)
|
@if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR)
|
||||||
@echo Linking....
|
@echo Linking....
|
||||||
@@ -596,6 +596,7 @@ $(O)nhdefkey.def:
|
|||||||
@echo EXPORTS >$@
|
@echo EXPORTS >$@
|
||||||
@echo ProcessKeystroke >>$@
|
@echo ProcessKeystroke >>$@
|
||||||
@echo NHkbhit >>$@
|
@echo NHkbhit >>$@
|
||||||
|
@echo CheckInput >>$@
|
||||||
@echo SourceWhere >>$@
|
@echo SourceWhere >>$@
|
||||||
@echo SourceAuthor >>$@
|
@echo SourceAuthor >>$@
|
||||||
@echo KeyHandlerName >>$@
|
@echo KeyHandlerName >>$@
|
||||||
@@ -610,6 +611,7 @@ $(O)nh340key.def:
|
|||||||
@echo EXPORTS >$@
|
@echo EXPORTS >$@
|
||||||
@echo ProcessKeystroke >>$@
|
@echo ProcessKeystroke >>$@
|
||||||
@echo NHkbhit >>$@
|
@echo NHkbhit >>$@
|
||||||
|
@echo CheckInput >>$@
|
||||||
@echo SourceWhere >>$@
|
@echo SourceWhere >>$@
|
||||||
@echo SourceAuthor >>$@
|
@echo SourceAuthor >>$@
|
||||||
@echo KeyHandlerName >>$@
|
@echo KeyHandlerName >>$@
|
||||||
@@ -620,6 +622,21 @@ $(GAMEDIR)\nh340key.dll : $(O)$(@B).o $(O)gamedir.tag $(O)$(@B).def
|
|||||||
/PDB:"$(@B).PDB" /MAP:"$(@B).map" /DEF:$(O)$(@B).def \
|
/PDB:"$(@B).PDB" /MAP:"$(@B).map" /DEF:$(O)$(@B).def \
|
||||||
/IMPLIB:$(O)$(@B).lib -out:$@ $(O)$(@B).o
|
/IMPLIB:$(O)$(@B).lib -out:$@ $(O)$(@B).o
|
||||||
|
|
||||||
|
$(O)nhraykey.def:
|
||||||
|
@echo EXPORTS >$@
|
||||||
|
@echo ProcessKeystroke >>$@
|
||||||
|
@echo NHkbhit >>$@
|
||||||
|
@echo CheckInput >>$@
|
||||||
|
@echo SourceWhere >>$@
|
||||||
|
@echo SourceAuthor >>$@
|
||||||
|
@echo KeyHandlerName >>$@
|
||||||
|
|
||||||
|
$(GAMEDIR)\nhraykey.dll : $(O)$(@B).o $(O)gamedir.tag $(O)$(@B).def
|
||||||
|
@echo Linking $@
|
||||||
|
@$(link) -debug:full -debugtype:cv /RELEASE /NOLOGO /DLL user32.lib \
|
||||||
|
/PDB:"$(@B).PDB" /MAP:"$(@B).map" /DEF:$(O)$(@B).def \
|
||||||
|
/IMPLIB:$(O)$(@B).lib -out:$@ $(O)$(@B).o
|
||||||
|
|
||||||
#
|
#
|
||||||
# Secondary Targets.
|
# Secondary Targets.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ static const struct pad {
|
|||||||
#define inmap(x,vk) (((x) > 'A' && (x) < 'Z') || (vk) == 0xBF || (x) == '2')
|
#define inmap(x,vk) (((x) > 'A' && (x) < 'Z') || (vk) == 0xBF || (x) == '2')
|
||||||
|
|
||||||
int __declspec(dllexport) __stdcall
|
int __declspec(dllexport) __stdcall
|
||||||
ProcessKeystroke(ir, valid, numberpad, portdebug)
|
ProcessKeystroke(hConIn, ir, valid, numberpad, portdebug)
|
||||||
|
HANDLE hConIn;
|
||||||
INPUT_RECORD *ir;
|
INPUT_RECORD *ir;
|
||||||
boolean *valid;
|
boolean *valid;
|
||||||
boolean numberpad;
|
boolean numberpad;
|
||||||
@@ -209,6 +210,53 @@ INPUT_RECORD *ir;
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __declspec(dllexport) __stdcall
|
||||||
|
CheckInput(hConIn, ir, count, numpad, mode, mod, cc)
|
||||||
|
HANDLE hConIn;
|
||||||
|
INPUT_RECORD *ir;
|
||||||
|
int *count;
|
||||||
|
boolean numpad;
|
||||||
|
int mode;
|
||||||
|
int *mod;
|
||||||
|
coord *cc;
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
boolean valid = 0, done = 0;
|
||||||
|
while (!done) {
|
||||||
|
ReadConsoleInput(hConIn,ir,1,count);
|
||||||
|
if (mode == 0) {
|
||||||
|
if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) {
|
||||||
|
ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0);
|
||||||
|
done = valid;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (count > 0) {
|
||||||
|
if (ir->EventType == KEY_EVENT && ir->Event.KeyEvent.bKeyDown) {
|
||||||
|
ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0);
|
||||||
|
if (valid) return ch;
|
||||||
|
} else if (ir->EventType == MOUSE_EVENT) {
|
||||||
|
if ((ir->Event.MouseEvent.dwEventFlags == 0) &&
|
||||||
|
(ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) {
|
||||||
|
cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1;
|
||||||
|
cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1;
|
||||||
|
|
||||||
|
if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON)
|
||||||
|
*mod = CLICK_1;
|
||||||
|
else if (ir->Event.MouseEvent.dwButtonState & RIGHTBUTTON)
|
||||||
|
*mod = CLICK_2;
|
||||||
|
#if 0 /* middle button */
|
||||||
|
else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON)
|
||||||
|
*mod = CLICK_3;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mode ? 0 : ch;
|
||||||
|
}
|
||||||
|
|
||||||
int __declspec(dllexport) __stdcall
|
int __declspec(dllexport) __stdcall
|
||||||
SourceWhere(buf)
|
SourceWhere(buf)
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ static const struct pad {
|
|||||||
static BYTE KeyState[256];
|
static BYTE KeyState[256];
|
||||||
|
|
||||||
int __declspec(dllexport) __stdcall
|
int __declspec(dllexport) __stdcall
|
||||||
ProcessKeystroke(ir, valid, numberpad, portdebug)
|
ProcessKeystroke(hConIn,ir, valid, numberpad, portdebug)
|
||||||
|
HANDLE hConIn;
|
||||||
INPUT_RECORD *ir;
|
INPUT_RECORD *ir;
|
||||||
boolean *valid;
|
boolean *valid;
|
||||||
boolean numberpad;
|
boolean numberpad;
|
||||||
@@ -190,6 +191,7 @@ int portdebug;
|
|||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int __declspec(dllexport) __stdcall
|
int __declspec(dllexport) __stdcall
|
||||||
NHkbhit(hConIn, ir)
|
NHkbhit(hConIn, ir)
|
||||||
HANDLE hConIn;
|
HANDLE hConIn;
|
||||||
@@ -240,6 +242,53 @@ INPUT_RECORD *ir;
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __declspec(dllexport) __stdcall
|
||||||
|
CheckInput(hConIn, ir, count, numpad, mode, mod, cc)
|
||||||
|
HANDLE hConIn;
|
||||||
|
INPUT_RECORD *ir;
|
||||||
|
int *count;
|
||||||
|
boolean numpad;
|
||||||
|
int mode;
|
||||||
|
int *mod;
|
||||||
|
coord *cc;
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
boolean valid = 0, done = 0;
|
||||||
|
while (!done) {
|
||||||
|
ReadConsoleInput(hConIn,ir,1,count);
|
||||||
|
if (mode == 0) {
|
||||||
|
if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) {
|
||||||
|
ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0);
|
||||||
|
done = valid;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (count > 0) {
|
||||||
|
if (ir->EventType == KEY_EVENT && ir->Event.KeyEvent.bKeyDown) {
|
||||||
|
ch = ProcessKeystroke(hConIn, ir, &valid, numpad, 0);
|
||||||
|
if (valid) return ch;
|
||||||
|
} else if (ir->EventType == MOUSE_EVENT) {
|
||||||
|
if ((ir->Event.MouseEvent.dwEventFlags == 0) &&
|
||||||
|
(ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) {
|
||||||
|
cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1;
|
||||||
|
cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1;
|
||||||
|
|
||||||
|
if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON)
|
||||||
|
*mod = CLICK_1;
|
||||||
|
else if (ir->Event.MouseEvent.dwButtonState & RIGHTBUTTON)
|
||||||
|
*mod = CLICK_2;
|
||||||
|
#if 0 /* middle button */
|
||||||
|
else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON)
|
||||||
|
*mod = CLICK_3;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mode ? 0 : ch;
|
||||||
|
}
|
||||||
|
|
||||||
int __declspec(dllexport) __stdcall
|
int __declspec(dllexport) __stdcall
|
||||||
SourceWhere(buf)
|
SourceWhere(buf)
|
||||||
|
|||||||
449
sys/winnt/nhraykey.c
Normal file
449
sys/winnt/nhraykey.c
Normal file
@@ -0,0 +1,449 @@
|
|||||||
|
/* 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;
|
||||||
|
|
||||||
|
static INPUT_RECORD bogus_key;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
/* A bogus key that will be filtered when received, to keep ReadConsole
|
||||||
|
* from blocking */
|
||||||
|
bogus_key.EventType = KEY_EVENT;
|
||||||
|
bogus_key.Event.KeyEvent.bKeyDown = 1;
|
||||||
|
bogus_key.Event.KeyEvent.wRepeatCount = 1;
|
||||||
|
bogus_key.Event.KeyEvent.wVirtualKeyCode = 0;
|
||||||
|
bogus_key.Event.KeyEvent.wVirtualScanCode = 0;
|
||||||
|
bogus_key.Event.KeyEvent.uChar.AsciiChar = (uchar)0x80;
|
||||||
|
bogus_key.Event.KeyEvent.dwControlKeyState = 0;
|
||||||
|
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)
|
||||||
|
#define isnumkeypad(x) (KEYPADLO <= (x) && (x) <= 0x51 && (x) != 0x4A && (x) != 0x4E)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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')
|
||||||
|
|
||||||
|
/* Use process_keystroke for key commands, process_keystroke2 for prompts */
|
||||||
|
/* int FDECL(process_keystroke, (INPUT_RECORD *ir, boolean *valid, int portdebug)); */
|
||||||
|
int FDECL(process_keystroke2, (HANDLE,INPUT_RECORD *ir, boolean *valid));
|
||||||
|
static int FDECL(is_altseq, (unsigned long shiftstate));
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_altseq(shiftstate)
|
||||||
|
unsigned long shiftstate;
|
||||||
|
{
|
||||||
|
/* We need to distinguish the Alt keys from the AltGr key.
|
||||||
|
* On NT-based Windows, AltGr signals as right Alt and left Ctrl together;
|
||||||
|
* on 95-based Windows, AltGr signals as right Alt only.
|
||||||
|
* So on NT, we signal Alt if either Alt is pressed and left Ctrl is not,
|
||||||
|
* and on 95, we signal Alt for left Alt only. */
|
||||||
|
switch (shiftstate & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED)) {
|
||||||
|
case LEFT_ALT_PRESSED:
|
||||||
|
case LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case RIGHT_ALT_PRESSED:
|
||||||
|
case RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED:
|
||||||
|
return (GetVersion() & 0x80000000) == 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int __declspec(dllexport) __stdcall
|
||||||
|
ProcessKeystroke(hConIn, ir, valid, numberpad, portdebug)
|
||||||
|
HANDLE hConIn;
|
||||||
|
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;
|
||||||
|
DWORD count;
|
||||||
|
|
||||||
|
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;
|
||||||
|
if (scan == 0 && vk == 0) {
|
||||||
|
/* It's the bogus_key */
|
||||||
|
ReadConsoleInput(hConIn,ir,1,&count);
|
||||||
|
*valid = FALSE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_altseq(shiftstate)) {
|
||||||
|
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)) {
|
||||||
|
ReadConsoleInput(hConIn,ir,1,&count);
|
||||||
|
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 */
|
||||||
|
ReadConsoleInput(hConIn,ir,1,&count);
|
||||||
|
if (vk == 0xBF) ch = M('?');
|
||||||
|
else ch = M(tolower(keycode));
|
||||||
|
}
|
||||||
|
else if (ch < 32 && !isnumkeypad(scan)) {
|
||||||
|
/* Control code; ReadConsole seems to filter some of these,
|
||||||
|
* including ESC */
|
||||||
|
ReadConsoleInput(hConIn,ir,1,&count);
|
||||||
|
}
|
||||||
|
/* Attempt to work better with international keyboards. */
|
||||||
|
else {
|
||||||
|
CHAR ch2;
|
||||||
|
DWORD written;
|
||||||
|
/* The bogus_key guarantees that ReadConsole will return,
|
||||||
|
* and does not itself do anything */
|
||||||
|
WriteConsoleInput(hConIn, &bogus_key, 1, &written);
|
||||||
|
ReadConsole(hConIn,&ch2,1,&count,NULL);
|
||||||
|
/* Prevent high characters from being interpreted as alt
|
||||||
|
* sequences; also filter the bogus_key */
|
||||||
|
if (ch2 & 0x80)
|
||||||
|
*valid = FALSE;
|
||||||
|
else
|
||||||
|
ch = ch2;
|
||||||
|
if (ch == 0) *valid = FALSE;
|
||||||
|
}
|
||||||
|
if (ch == '\r') ch = '\n';
|
||||||
|
#ifdef PORT_DEBUG
|
||||||
|
if (portdebug) {
|
||||||
|
char buf[BUFSZ];
|
||||||
|
Sprintf(buf,
|
||||||
|
"PORTDEBUG: ch=%u, scan=%u, vk=%d, pre=%d, shiftstate=0x%X (ESC to end)\n",
|
||||||
|
ch, scan, vk, pre_ch, shiftstate);
|
||||||
|
fprintf(stdout, "\n%s", buf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
int process_keystroke2(hConIn, ir, valid)
|
||||||
|
HANDLE hConIn;
|
||||||
|
INPUT_RECORD *ir;
|
||||||
|
boolean *valid;
|
||||||
|
{
|
||||||
|
/* Use these values for the numeric keypad */
|
||||||
|
static const char keypad_nums[] = "789-456+1230.";
|
||||||
|
|
||||||
|
unsigned char ch;
|
||||||
|
int vk;
|
||||||
|
unsigned short int scan;
|
||||||
|
unsigned long shiftstate;
|
||||||
|
int altseq;
|
||||||
|
DWORD count;
|
||||||
|
|
||||||
|
ch = ir->Event.KeyEvent.uChar.AsciiChar;
|
||||||
|
vk = ir->Event.KeyEvent.wVirtualKeyCode;
|
||||||
|
scan = ir->Event.KeyEvent.wVirtualScanCode;
|
||||||
|
shiftstate = ir->Event.KeyEvent.dwControlKeyState;
|
||||||
|
|
||||||
|
if (scan == 0 && vk == 0) {
|
||||||
|
/* It's the bogus_key */
|
||||||
|
ReadConsoleInput(hConIn,ir,1,&count);
|
||||||
|
*valid = FALSE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
altseq = is_altseq(shiftstate);
|
||||||
|
if (ch || (iskeypad(scan)) || altseq)
|
||||||
|
*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) && !altseq) {
|
||||||
|
ReadConsoleInput(hConIn,ir,1,&count);
|
||||||
|
ch = keypad_nums[scan - KEYPADLO];
|
||||||
|
}
|
||||||
|
else if (ch < 32 && !isnumkeypad(scan)) {
|
||||||
|
/* Control code; ReadConsole seems to filter some of these,
|
||||||
|
* including ESC */
|
||||||
|
ReadConsoleInput(hConIn,ir,1,&count);
|
||||||
|
}
|
||||||
|
/* Attempt to work better with international keyboards. */
|
||||||
|
else {
|
||||||
|
CHAR ch2;
|
||||||
|
ReadConsole(hConIn,&ch2,1,&count,NULL);
|
||||||
|
ch = ch2 & 0xFF;
|
||||||
|
if (ch == 0) *valid = FALSE;
|
||||||
|
}
|
||||||
|
if (ch == '\r') ch = '\n';
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __declspec(dllexport) __stdcall
|
||||||
|
CheckInput(hConIn, ir, count, numpad, mode, mod, cc)
|
||||||
|
HANDLE hConIn;
|
||||||
|
INPUT_RECORD *ir;
|
||||||
|
int *count, *mod;
|
||||||
|
boolean numpad;
|
||||||
|
coord *cc;
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
boolean valid = 0, done = 0;
|
||||||
|
while (!done) {
|
||||||
|
*count = 0;
|
||||||
|
WaitForSingleObject(hConIn, INFINITE);
|
||||||
|
PeekConsoleInput(hConIn,ir,1,count);
|
||||||
|
if (mode == 0) {
|
||||||
|
if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) {
|
||||||
|
ch = process_keystroke2(hConIn, ir, &valid);
|
||||||
|
done = valid;
|
||||||
|
} else
|
||||||
|
ReadConsoleInput(hConIn,ir,1,count);
|
||||||
|
} else {
|
||||||
|
ch = 0;
|
||||||
|
if (count > 0) {
|
||||||
|
if (ir->EventType == KEY_EVENT && ir->Event.KeyEvent.bKeyDown) {
|
||||||
|
ch = ProcessKeystroke(hConIn, ir, &valid, numpad,
|
||||||
|
#ifdef PORTDEBUG
|
||||||
|
1);
|
||||||
|
#else
|
||||||
|
0);
|
||||||
|
#endif
|
||||||
|
if (valid) return ch;
|
||||||
|
} else {
|
||||||
|
ReadConsoleInput(hConIn,ir,1,count);
|
||||||
|
if (ir->EventType == MOUSE_EVENT) {
|
||||||
|
if ((ir->Event.MouseEvent.dwEventFlags == 0) &&
|
||||||
|
(ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) {
|
||||||
|
cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1;
|
||||||
|
cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1;
|
||||||
|
|
||||||
|
if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON)
|
||||||
|
*mod = CLICK_1;
|
||||||
|
else if (ir->Event.MouseEvent.dwButtonState & RIGHTBUTTON)
|
||||||
|
*mod = CLICK_2;
|
||||||
|
#if 0 /* middle button */
|
||||||
|
else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON)
|
||||||
|
*mod = CLICK_3;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
/* We ignore these types of console events */
|
||||||
|
else if (ir->EventType == FOCUS_EVENT) {
|
||||||
|
}
|
||||||
|
else if (ir->EventType == MENU_EVENT) {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*mod = 0;
|
||||||
|
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 (is_altseq(shiftstate)) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -54,6 +54,7 @@ static BOOL FDECL(CtrlHandler, (DWORD));
|
|||||||
|
|
||||||
/* dynamic keystroke handling .DLL support */
|
/* dynamic keystroke handling .DLL support */
|
||||||
typedef int (__stdcall * PROCESS_KEYSTROKE)(
|
typedef int (__stdcall * PROCESS_KEYSTROKE)(
|
||||||
|
HANDLE,
|
||||||
INPUT_RECORD *,
|
INPUT_RECORD *,
|
||||||
boolean *,
|
boolean *,
|
||||||
BOOLEAN_P,
|
BOOLEAN_P,
|
||||||
@@ -65,6 +66,16 @@ typedef int (__stdcall * NHKBHIT)(
|
|||||||
INPUT_RECORD *
|
INPUT_RECORD *
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef int (__stdcall * CHECKINPUT)(
|
||||||
|
HANDLE,
|
||||||
|
INPUT_RECORD *,
|
||||||
|
int *,
|
||||||
|
BOOLEAN_P,
|
||||||
|
int,
|
||||||
|
int *,
|
||||||
|
coord *
|
||||||
|
);
|
||||||
|
|
||||||
typedef int (__stdcall * SOURCEWHERE)(
|
typedef int (__stdcall * SOURCEWHERE)(
|
||||||
char **
|
char **
|
||||||
);
|
);
|
||||||
@@ -81,6 +92,7 @@ typedef int (__stdcall * KEYHANDLERNAME)(
|
|||||||
HANDLE hLibrary;
|
HANDLE hLibrary;
|
||||||
PROCESS_KEYSTROKE pProcessKeystroke;
|
PROCESS_KEYSTROKE pProcessKeystroke;
|
||||||
NHKBHIT pNHkbhit;
|
NHKBHIT pNHkbhit;
|
||||||
|
CHECKINPUT pCheckInput;
|
||||||
SOURCEWHERE pSourceWhere;
|
SOURCEWHERE pSourceWhere;
|
||||||
SOURCEAUTHOR pSourceAuthor;
|
SOURCEAUTHOR pSourceAuthor;
|
||||||
KEYHANDLERNAME pKeyHandlerName;
|
KEYHANDLERNAME pKeyHandlerName;
|
||||||
@@ -192,6 +204,7 @@ tty_end_screen()
|
|||||||
csbi.dwSize.X * csbi.dwSize.Y,
|
csbi.dwSize.X * csbi.dwSize.Y,
|
||||||
newcoord, &ccnt);
|
newcoord, &ccnt);
|
||||||
}
|
}
|
||||||
|
FlushConsoleInputBuffer(hConIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern boolean getreturn_disable; /* from sys/share/pcsys.c */
|
extern boolean getreturn_disable; /* from sys/share/pcsys.c */
|
||||||
@@ -285,7 +298,7 @@ boolean *valid;
|
|||||||
boolean numberpad;
|
boolean numberpad;
|
||||||
int portdebug;
|
int portdebug;
|
||||||
{
|
{
|
||||||
int ch = pProcessKeystroke(ir, valid, numberpad, portdebug);
|
int ch = pProcessKeystroke(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];
|
||||||
@@ -323,64 +336,25 @@ get_scr_size()
|
|||||||
int
|
int
|
||||||
tgetch()
|
tgetch()
|
||||||
{
|
{
|
||||||
|
int mod;
|
||||||
|
coord cc;
|
||||||
DWORD count;
|
DWORD count;
|
||||||
boolean valid = 0;
|
return pCheckInput(hConIn, &ir, &count, iflags.num_pad, 0, &mod, &cc);
|
||||||
int ch;
|
|
||||||
valid = 0;
|
|
||||||
while (!valid) {
|
|
||||||
ReadConsoleInput(hConIn,&ir,1,&count);
|
|
||||||
if ((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown)
|
|
||||||
ch = process_keystroke(&ir, &valid, iflags.num_pad, 0);
|
|
||||||
}
|
|
||||||
return ch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ntposkey(x, y, mod)
|
ntposkey(x, y, mod)
|
||||||
int *x, *y, *mod;
|
int *x, *y, *mod;
|
||||||
{
|
{
|
||||||
|
int ch;
|
||||||
|
coord cc;
|
||||||
DWORD count;
|
DWORD count;
|
||||||
int keystroke = 0;
|
ch = pCheckInput(hConIn, &ir, &count, iflags.num_pad, 1, mod, &cc);
|
||||||
int done = 0;
|
if (!ch) {
|
||||||
boolean valid = 0;
|
*x = cc.x;
|
||||||
while (!done)
|
*y = cc.y;
|
||||||
{
|
|
||||||
count = 0;
|
|
||||||
ReadConsoleInput(hConIn,&ir,1,&count);
|
|
||||||
if (count > 0) {
|
|
||||||
if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
|
|
||||||
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) &&
|
|
||||||
(ir.Event.MouseEvent.dwButtonState & MOUSEMASK)) {
|
|
||||||
*x = ir.Event.MouseEvent.dwMousePosition.X + 1;
|
|
||||||
*y = ir.Event.MouseEvent.dwMousePosition.Y - 1;
|
|
||||||
|
|
||||||
if (ir.Event.MouseEvent.dwButtonState & LEFTBUTTON)
|
|
||||||
*mod = CLICK_1;
|
|
||||||
else if (ir.Event.MouseEvent.dwButtonState & RIGHTBUTTON)
|
|
||||||
*mod = CLICK_2;
|
|
||||||
#if 0 /* middle button */
|
|
||||||
else if (ir.Event.MouseEvent.dwButtonState & MIDBUTTON)
|
|
||||||
*mod = CLICK_3;
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
/* We ignore these types of console events */
|
|
||||||
else if (ir.EventType == FOCUS_EVENT) {
|
|
||||||
}
|
|
||||||
else if (ir.EventType == MENU_EVENT) {
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else
|
|
||||||
done = 1;
|
|
||||||
}
|
}
|
||||||
/* NOTREACHED */
|
return ch;
|
||||||
*mod = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -869,6 +843,8 @@ load_keyboard_handler()
|
|||||||
(PROCESS_KEYSTROKE) GetProcAddress (hLibrary, TEXT ("ProcessKeystroke"));
|
(PROCESS_KEYSTROKE) GetProcAddress (hLibrary, TEXT ("ProcessKeystroke"));
|
||||||
pNHkbhit =
|
pNHkbhit =
|
||||||
(NHKBHIT) GetProcAddress (hLibrary, TEXT ("NHkbhit"));
|
(NHKBHIT) GetProcAddress (hLibrary, TEXT ("NHkbhit"));
|
||||||
|
pCheckInput =
|
||||||
|
(CHECKINPUT) GetProcAddress (hLibrary, TEXT ("CheckInput"));
|
||||||
pSourceWhere =
|
pSourceWhere =
|
||||||
(SOURCEWHERE) GetProcAddress (hLibrary, TEXT ("SourceWhere"));
|
(SOURCEWHERE) GetProcAddress (hLibrary, TEXT ("SourceWhere"));
|
||||||
pSourceAuthor =
|
pSourceAuthor =
|
||||||
@@ -886,6 +862,8 @@ load_keyboard_handler()
|
|||||||
if (hLibrary) {
|
if (hLibrary) {
|
||||||
pProcessKeystroke =
|
pProcessKeystroke =
|
||||||
(PROCESS_KEYSTROKE) GetProcAddress (hLibrary, TEXT ("ProcessKeystroke"));
|
(PROCESS_KEYSTROKE) GetProcAddress (hLibrary, TEXT ("ProcessKeystroke"));
|
||||||
|
pCheckInput =
|
||||||
|
(CHECKINPUT) GetProcAddress (hLibrary, TEXT ("CheckInput"));
|
||||||
pNHkbhit =
|
pNHkbhit =
|
||||||
(NHKBHIT) GetProcAddress (hLibrary, TEXT ("NHkbhit"));
|
(NHKBHIT) GetProcAddress (hLibrary, TEXT ("NHkbhit"));
|
||||||
pSourceWhere =
|
pSourceWhere =
|
||||||
|
|||||||
Reference in New Issue
Block a user