Added the ability for keyboard to require capture, in order for 86Box keyboard input to operate like VMWare, closes #829.

This commit is contained in:
OBattler
2021-07-19 02:27:22 +02:00
parent faee9c85ed
commit 9adf0fdcc4
6 changed files with 114 additions and 92 deletions

View File

@@ -45,6 +45,7 @@ MainMenu MENU DISCARDABLE
BEGIN
POPUP "&Action"
BEGIN
MENUITEM "&Keyboard requires capture", IDM_ACTION_KBD_REQ_CAPTURE
MENUITEM "&Right CTRL is left ALT", IDM_ACTION_RCTRL_IS_LALT
MENUITEM SEPARATOR
MENUITEM "&Hard Reset", IDM_ACTION_HRESET

View File

@@ -114,89 +114,92 @@ keyboard_handle(PRAWINPUT raw)
static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0;
RAWKEYBOARD rawKB = raw->data.keyboard;
scancode = rawKB.MakeCode;
scancode = rawKB.MakeCode;
/* If it's not a scan code that starts with 0xE1 */
if (!(rawKB.Flags & RI_KEY_E1)) {
if (rawKB.Flags & RI_KEY_E0)
scancode |= 0x100;
if (kbd_req_capture && !mouse_capture && !video_fullscreen)
return;
/* Translate the scan code to 9-bit */
scancode = convert_scan_code(scancode);
/* If it's not a scan code that starts with 0xE1 */
if (!(rawKB.Flags & RI_KEY_E1)) {
if (rawKB.Flags & RI_KEY_E0)
scancode |= 0x100;
/* Remap it according to the list from the Registry */
if (scancode != scancode_map[scancode])
pclog("Scan code remap: %03X -> %03X\n", scancode, scancode);
scancode = scancode_map[scancode];
/* Translate the scan code to 9-bit */
scancode = convert_scan_code(scancode);
/* If it's not 0xFFFF, send it to the emulated
keyboard.
We use scan code 0xFFFF to mean a mapping that
has a prefix other than E0 and that is not E1 1D,
which is, for our purposes, invalid. */
if ((scancode == 0x00F) &&
!(rawKB.Flags & RI_KEY_BREAK) &&
(recv_lalt || recv_ralt) &&
!mouse_capture) {
/* We received a TAB while ALT was pressed, while the mouse
is not captured, suppress the TAB and send an ALT key up. */
if (recv_lalt) {
keyboard_input(0, 0x038);
/* Extra key press and release so the guest is not stuck in the
menu bar. */
keyboard_input(1, 0x038);
keyboard_input(0, 0x038);
recv_lalt = 0;
}
if (recv_ralt) {
keyboard_input(0, 0x138);
/* Extra key press and release so the guest is not stuck in the
menu bar. */
keyboard_input(1, 0x138);
keyboard_input(0, 0x138);
recv_ralt = 0;
}
} else if (((scancode == 0x038) || (scancode == 0x138)) &&
!(rawKB.Flags & RI_KEY_BREAK) &&
recv_tab &&
!mouse_capture) {
/* We received an ALT while TAB was pressed, while the mouse
is not captured, suppress the ALT and send a TAB key up. */
keyboard_input(0, 0x00F);
recv_tab = 0;
} else {
switch(scancode) {
case 0x00F:
recv_tab = !(rawKB.Flags & RI_KEY_BREAK);
break;
case 0x038:
recv_lalt = !(rawKB.Flags & RI_KEY_BREAK);
break;
case 0x138:
recv_ralt = !(rawKB.Flags & RI_KEY_BREAK);
break;
}
/* Remap it according to the list from the Registry */
if (scancode != scancode_map[scancode])
pclog("Scan code remap: %03X -> %03X\n", scancode, scancode);
scancode = scancode_map[scancode];
/* Translate right CTRL to left ALT if the user has so
chosen. */
if ((scancode == 0x11D) && rctrl_is_lalt)
scancode = 0x038;
/* Normal scan code pass through, pass it through as is if
it's not an invalid scan code. */
if (scancode != 0xFFFF)
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
/* If it's not 0xFFFF, send it to the emulated
keyboard.
We use scan code 0xFFFF to mean a mapping that
has a prefix other than E0 and that is not E1 1D,
which is, for our purposes, invalid. */
if ((scancode == 0x00F) &&
!(rawKB.Flags & RI_KEY_BREAK) &&
(recv_lalt || recv_ralt) &&
!mouse_capture) {
/* We received a TAB while ALT was pressed, while the mouse
is not captured, suppress the TAB and send an ALT key up. */
if (recv_lalt) {
keyboard_input(0, 0x038);
/* Extra key press and release so the guest is not stuck in the
menu bar. */
keyboard_input(1, 0x038);
keyboard_input(0, 0x038);
recv_lalt = 0;
}
if (recv_ralt) {
keyboard_input(0, 0x138);
/* Extra key press and release so the guest is not stuck in the
menu bar. */
keyboard_input(1, 0x138);
keyboard_input(0, 0x138);
recv_ralt = 0;
}
} else if (((scancode == 0x038) || (scancode == 0x138)) &&
!(rawKB.Flags & RI_KEY_BREAK) &&
recv_tab &&
!mouse_capture) {
/* We received an ALT while TAB was pressed, while the mouse
is not captured, suppress the ALT and send a TAB key up. */
keyboard_input(0, 0x00F);
recv_tab = 0;
} else {
if (rawKB.MakeCode == 0x1D) {
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
otherwise be E0 00 but that is invalid
anyway).
Also, take a potential mapping into
account. */
} else
scancode = 0xFFFF;
switch(scancode) {
case 0x00F:
recv_tab = !(rawKB.Flags & RI_KEY_BREAK);
break;
case 0x038:
recv_lalt = !(rawKB.Flags & RI_KEY_BREAK);
break;
case 0x138:
recv_ralt = !(rawKB.Flags & RI_KEY_BREAK);
break;
}
/* Translate right CTRL to left ALT if the user has so
chosen. */
if ((scancode == 0x11D) && rctrl_is_lalt)
scancode = 0x038;
/* Normal scan code pass through, pass it through as is if
it's not an invalid scan code. */
if (scancode != 0xFFFF)
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
}
} else {
if (rawKB.MakeCode == 0x1D) {
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
otherwise be E0 00 but that is invalid
anyway).
Also, take a potential mapping into
account. */
} else
scancode = 0xFFFF;
if (scancode != 0xFFFF)
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
}
}

View File

@@ -67,6 +67,7 @@ int infocus = 1, button_down = 0;
int rctrl_is_lalt = 0;
int user_resize = 0;
int fixed_size_x = 0, fixed_size_y = 0;
int kbd_req_capture = 0;
extern char openfilestring[512];
extern WCHAR wopenfilestring[512];
@@ -80,11 +81,9 @@ static int hook_enabled = 0;
#endif
static int manager_wm = 0;
static int save_window_pos = 0, pause_state = 0;
static int dpi = 96;
static int padded_frame = 0;
static int vis = -1;
static int dpi = 96;
static int padded_frame = 0;
static int vis = -1;
/* Per Monitor DPI Aware v2 APIs, Windows 10 v1703+ */
void* user32_handle = NULL;
@@ -263,6 +262,7 @@ ResetAllMenus(void)
#endif
CheckMenuItem(menuMain, IDM_ACTION_RCTRL_IS_LALT, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_ACTION_KBD_REQ_CAPTURE, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_UPDATE_ICONS, MF_UNCHECKED);
@@ -328,6 +328,7 @@ ResetAllMenus(void)
CheckMenuItem(menuMain, IDM_VID_GRAY_RGB+4, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_ACTION_RCTRL_IS_LALT, rctrl_is_lalt ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_ACTION_KBD_REQ_CAPTURE, kbd_req_capture ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_UPDATE_ICONS, update_icons ? MF_CHECKED : MF_UNCHECKED);
@@ -406,7 +407,8 @@ LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
BOOL bControlKeyDown;
KBDLLHOOKSTRUCT *p;
if (nCode < 0 || nCode != HC_ACTION || (!mouse_capture && !video_fullscreen))
if (nCode < 0 || nCode != HC_ACTION ||
(!mouse_capture && !video_fullscreen) || (kbd_req_capture && !mouse_capture && !video_fullscreen))
return(CallNextHookEx(hKeyboardHook, nCode, wParam, lParam));
p = (KBDLLHOOKSTRUCT*)lParam;
@@ -671,6 +673,12 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
config_save();
break;
case IDM_ACTION_KBD_REQ_CAPTURE:
kbd_req_capture ^= 1;
CheckMenuItem(hmenu, IDM_ACTION_KBD_REQ_CAPTURE, kbd_req_capture ? MF_CHECKED : MF_UNCHECKED);
config_save();
break;
case IDM_ACTION_PAUSE:
plat_pause(dopause ^ 1);
CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED);
@@ -1688,7 +1696,7 @@ plat_mouse_capture(int on)
{
RECT rect;
if (mouse_type == MOUSE_TYPE_NONE)
if (!kbd_req_capture && (mouse_type == MOUSE_TYPE_NONE))
return;
if (on && !mouse_capture) {