mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-08 02:08:22 -10:00
win32: read keyboard modifiers via GetKeyboardState
Five copies of the same block queried GetKeyState once per modifier and tested the result with 0x80 (down) and 0x81 (down or toggled). Neither mask is documented. GetKeyState returns a SHORT in which only bit 15 is contractual; 0x80 happens to work because user32 builds the down value as 0xFF80, and on the slow path the encoding comes straight out of win32k and is not guaranteed at all. GetKeyboardState fills the documented 256-byte form of the same per-thread table, 0x80 down and 0x01 toggled, which is stable across every Windows and under Wine. 0x81 also conflated the two states: holding CapsLock while the lock was off reported RETROKMOD_CAPSLOCK. The toggle keys now test 0x01 only. The single call is cheaper as well. user32's GetKeyState cache covers virtual-key codes below 0x20 and nothing else, so VK_NUMLOCK, VK_SCROLL, VK_LWIN and VK_RWIN each took an unconditional kernel transition on every query - four syscalls per keyboard event, in every copy. GetKeyboardState is a bare thunk that returns all 256 keys at once. Consolidated into win32_get_keyboard_mods() in win32_common.c and used from wnd_proc_common, wnd_proc_common_internal, wnd_proc_common_dinput_internal, winraw_callback and dinput_poll. dinput_get_active_keyboard_mods() is removed as a duplicate. The GetAsyncKeyState calls in dinput_poll are left alone: they read the global physical state, which GetKeyboardState does not expose.
This commit is contained in:
1 parent
7877be2951
commit
8d6bfc4b29
4 files changed
+49
-80
No files matched your search
+40
-42
@@ -504,6 +504,43 @@ static void win32_get_av_info_geometry(unsigned *width, unsigned *height)
|
||||
*height = video_st->av_info.geometry.base_height;
|
||||
}
|
||||
|
||||
/* GetKeyState and GetKeyboardState read the same per-thread
|
||||
* synchronous key table, but only GetKeyboardState exposes it in its
|
||||
* documented form: a 256-byte array with 0x80 for down and 0x01 for
|
||||
* toggled. GetKeyState returns those bits repacked into a SHORT in
|
||||
* which only bit 15 is contractual, so the 0x80 and 0x81 masks the
|
||||
* callers below used to apply were reading undocumented territory.
|
||||
*
|
||||
* One call is also cheaper. user32's GetKeyState cache only covers
|
||||
* virtual-key codes below 0x20, so VK_NUMLOCK, VK_SCROLL, VK_LWIN and
|
||||
* VK_RWIN each took an unconditional kernel transition on every query;
|
||||
* GetKeyboardState is a single thunk for all 256 keys. */
|
||||
uint16_t win32_get_keyboard_mods(void)
|
||||
{
|
||||
BYTE ks[256];
|
||||
uint16_t mod = 0;
|
||||
|
||||
if (!GetKeyboardState(ks))
|
||||
return 0;
|
||||
|
||||
if (ks[VK_SHIFT] & 0x80)
|
||||
mod |= RETROKMOD_SHIFT;
|
||||
if (ks[VK_CONTROL] & 0x80)
|
||||
mod |= RETROKMOD_CTRL;
|
||||
if (ks[VK_MENU] & 0x80)
|
||||
mod |= RETROKMOD_ALT;
|
||||
if (ks[VK_CAPITAL] & 0x01)
|
||||
mod |= RETROKMOD_CAPSLOCK;
|
||||
if (ks[VK_SCROLL] & 0x01)
|
||||
mod |= RETROKMOD_SCROLLOCK;
|
||||
if (ks[VK_NUMLOCK] & 0x01)
|
||||
mod |= RETROKMOD_NUMLOCK;
|
||||
if ((ks[VK_LWIN] | ks[VK_RWIN]) & 0x80)
|
||||
mod |= RETROKMOD_META;
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK wnd_proc_common(
|
||||
bool *quit, HWND hwnd, UINT message,
|
||||
WPARAM wparam, LPARAM lparam)
|
||||
@@ -537,20 +574,7 @@ static LRESULT CALLBACK wnd_proc_common(
|
||||
{
|
||||
uint16_t mod = 0;
|
||||
|
||||
if (GetKeyState(VK_SHIFT) & 0x80)
|
||||
mod |= RETROKMOD_SHIFT;
|
||||
if (GetKeyState(VK_CONTROL) & 0x80)
|
||||
mod |= RETROKMOD_CTRL;
|
||||
if (GetKeyState(VK_MENU) & 0x80)
|
||||
mod |= RETROKMOD_ALT;
|
||||
if (GetKeyState(VK_CAPITAL) & 0x81)
|
||||
mod |= RETROKMOD_CAPSLOCK;
|
||||
if (GetKeyState(VK_SCROLL) & 0x81)
|
||||
mod |= RETROKMOD_SCROLLOCK;
|
||||
if (GetKeyState(VK_NUMLOCK) & 0x81)
|
||||
mod |= RETROKMOD_NUMLOCK;
|
||||
if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x80)
|
||||
mod |= RETROKMOD_META;
|
||||
mod = win32_get_keyboard_mods();
|
||||
|
||||
/* Seems to be hard to synchronize
|
||||
* WM_CHAR and WM_KEYDOWN properly.
|
||||
@@ -749,20 +773,7 @@ static LRESULT CALLBACK wnd_proc_common_internal(HWND hwnd,
|
||||
|
||||
keycode = input_keymaps_translate_keysym_to_rk(keysym);
|
||||
|
||||
if (GetKeyState(VK_SHIFT) & 0x80)
|
||||
mod |= RETROKMOD_SHIFT;
|
||||
if (GetKeyState(VK_CONTROL) & 0x80)
|
||||
mod |= RETROKMOD_CTRL;
|
||||
if (GetKeyState(VK_MENU) & 0x80)
|
||||
mod |= RETROKMOD_ALT;
|
||||
if (GetKeyState(VK_CAPITAL) & 0x81)
|
||||
mod |= RETROKMOD_CAPSLOCK;
|
||||
if (GetKeyState(VK_SCROLL) & 0x81)
|
||||
mod |= RETROKMOD_SCROLLOCK;
|
||||
if (GetKeyState(VK_NUMLOCK) & 0x81)
|
||||
mod |= RETROKMOD_NUMLOCK;
|
||||
if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x80)
|
||||
mod |= RETROKMOD_META;
|
||||
mod = win32_get_keyboard_mods();
|
||||
|
||||
input_keyboard_event(keydown, keycode,
|
||||
0, mod, RETRO_DEVICE_KEYBOARD);
|
||||
@@ -1050,20 +1061,7 @@ static LRESULT CALLBACK wnd_proc_common_dinput_internal(HWND hwnd,
|
||||
|
||||
keycode = input_keymaps_translate_keysym_to_rk(keysym);
|
||||
|
||||
if (GetKeyState(VK_SHIFT) & 0x80)
|
||||
mod |= RETROKMOD_SHIFT;
|
||||
if (GetKeyState(VK_CONTROL) & 0x80)
|
||||
mod |= RETROKMOD_CTRL;
|
||||
if (GetKeyState(VK_MENU) & 0x80)
|
||||
mod |= RETROKMOD_ALT;
|
||||
if (GetKeyState(VK_CAPITAL) & 0x81)
|
||||
mod |= RETROKMOD_CAPSLOCK;
|
||||
if (GetKeyState(VK_SCROLL) & 0x81)
|
||||
mod |= RETROKMOD_SCROLLOCK;
|
||||
if (GetKeyState(VK_NUMLOCK) & 0x81)
|
||||
mod |= RETROKMOD_NUMLOCK;
|
||||
if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x80)
|
||||
mod |= RETROKMOD_META;
|
||||
mod = win32_get_keyboard_mods();
|
||||
|
||||
input_keyboard_event(keydown, keycode,
|
||||
0, mod, RETRO_DEVICE_KEYBOARD);
|
||||
|
||||
@@ -134,6 +134,10 @@ void win32_destroy_window(void);
|
||||
|
||||
uint8_t win32_get_flags(void);
|
||||
|
||||
/* Returns the RETROKMOD_* mask for the calling thread's
|
||||
* synchronous keyboard state. */
|
||||
uint16_t win32_get_keyboard_mods(void);
|
||||
|
||||
#if defined(HAVE_D3D8) || defined(HAVE_D3D9) || defined (HAVE_D3D10) || defined (HAVE_D3D11) || defined (HAVE_D3D12)
|
||||
LRESULT CALLBACK wnd_proc_d3d_dinput(HWND hwnd, UINT message,
|
||||
WPARAM wparam, LPARAM lparam);
|
||||
|
||||
+4
-24
@@ -201,26 +201,6 @@ static void *dinput_init(const char *joypad_driver)
|
||||
return di;
|
||||
}
|
||||
|
||||
static uint16_t dinput_get_active_keyboard_mods()
|
||||
{
|
||||
uint16_t mod = 0;
|
||||
if (GetKeyState(VK_SHIFT) & 0x80)
|
||||
mod |= RETROKMOD_SHIFT;
|
||||
if (GetKeyState(VK_CONTROL) & 0x80)
|
||||
mod |= RETROKMOD_CTRL;
|
||||
if (GetKeyState(VK_MENU) & 0x80)
|
||||
mod |= RETROKMOD_ALT;
|
||||
if (GetKeyState(VK_CAPITAL) & 0x81)
|
||||
mod |= RETROKMOD_CAPSLOCK;
|
||||
if (GetKeyState(VK_SCROLL) & 0x81)
|
||||
mod |= RETROKMOD_SCROLLOCK;
|
||||
if (GetKeyState(VK_NUMLOCK) & 0x81)
|
||||
mod |= RETROKMOD_NUMLOCK;
|
||||
if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x80)
|
||||
mod |= RETROKMOD_META;
|
||||
return mod;
|
||||
}
|
||||
|
||||
static void dinput_poll(void *data)
|
||||
{
|
||||
struct dinput_input *di = (struct dinput_input*)data;
|
||||
@@ -262,13 +242,13 @@ static void dinput_poll(void *data)
|
||||
if ((di->flags & DINP_FLAG_SHIFT_L) && !(GetAsyncKeyState(VK_LSHIFT) >> 1))
|
||||
{
|
||||
input_keyboard_event(false, RETROK_LSHIFT, 0,
|
||||
dinput_get_active_keyboard_mods(), RETRO_DEVICE_KEYBOARD);
|
||||
win32_get_keyboard_mods(), RETRO_DEVICE_KEYBOARD);
|
||||
di->flags &= ~DINP_FLAG_SHIFT_L;
|
||||
}
|
||||
if ((di->flags & DINP_FLAG_SHIFT_R) && !(GetAsyncKeyState(VK_RSHIFT) >> 1))
|
||||
{
|
||||
input_keyboard_event(false, RETROK_RSHIFT, 0,
|
||||
dinput_get_active_keyboard_mods(), RETRO_DEVICE_KEYBOARD);
|
||||
win32_get_keyboard_mods(), RETRO_DEVICE_KEYBOARD);
|
||||
di->flags &= ~DINP_FLAG_SHIFT_R;
|
||||
}
|
||||
|
||||
@@ -277,13 +257,13 @@ static void dinput_poll(void *data)
|
||||
if ((di->flags & DINP_FLAG_ALT_L) && !(GetAsyncKeyState(VK_LMENU) >> 1))
|
||||
{
|
||||
input_keyboard_event(false, RETROK_LALT, 0,
|
||||
dinput_get_active_keyboard_mods(), RETRO_DEVICE_KEYBOARD);
|
||||
win32_get_keyboard_mods(), RETRO_DEVICE_KEYBOARD);
|
||||
di->flags &= ~DINP_FLAG_ALT_L;
|
||||
}
|
||||
if ((di->flags & DINP_FLAG_ALT_R) && !(GetAsyncKeyState(VK_RMENU) >> 1))
|
||||
{
|
||||
input_keyboard_event(false, RETROK_RALT, 0,
|
||||
dinput_get_active_keyboard_mods(), RETRO_DEVICE_KEYBOARD);
|
||||
win32_get_keyboard_mods(), RETRO_DEVICE_KEYBOARD);
|
||||
di->flags &= ~DINP_FLAG_ALT_R;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,20 +658,7 @@ static LRESULT CALLBACK winraw_callback(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (GetKeyState(VK_SHIFT) & 0x80)
|
||||
mod |= RETROKMOD_SHIFT;
|
||||
if (GetKeyState(VK_CONTROL) & 0x80)
|
||||
mod |= RETROKMOD_CTRL;
|
||||
if (GetKeyState(VK_MENU) & 0x80)
|
||||
mod |= RETROKMOD_ALT;
|
||||
if (GetKeyState(VK_CAPITAL) & 0x81)
|
||||
mod |= RETROKMOD_CAPSLOCK;
|
||||
if (GetKeyState(VK_SCROLL) & 0x81)
|
||||
mod |= RETROKMOD_SCROLLOCK;
|
||||
if (GetKeyState(VK_NUMLOCK) & 0x81)
|
||||
mod |= RETROKMOD_NUMLOCK;
|
||||
if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x80)
|
||||
mod |= RETROKMOD_META;
|
||||
mod = win32_get_keyboard_mods();
|
||||
|
||||
wr->kb_keys[mcode] = down;
|
||||
input_keyboard_event(down,
|
||||
|
||||
Reference in new issue
Block a user