aboutsummaryrefslogtreecommitdiffstats
path: root/vncviewer/win32.c
diff options
context:
space:
mode:
Diffstat (limited to 'vncviewer/win32.c')
-rw-r--r--vncviewer/win32.c66
1 files changed, 40 insertions, 26 deletions
diff --git a/vncviewer/win32.c b/vncviewer/win32.c
index b0a3813c..c649f783 100644
--- a/vncviewer/win32.c
+++ b/vncviewer/win32.c
@@ -27,39 +27,50 @@ static HANDLE thread;
static DWORD thread_id;
static HHOOK hook = 0;
+static BYTE kbd_state[256];
static HWND target_wnd = 0;
-static int is_system_hotkey(int vkCode) {
- switch (vkCode) {
- case VK_LWIN:
- case VK_RWIN:
- case VK_SNAPSHOT:
- return 1;
- case VK_TAB:
- if (GetAsyncKeyState(VK_MENU) & 0x8000)
- return 1;
- break;
- case VK_ESCAPE:
- if (GetAsyncKeyState(VK_MENU) & 0x8000)
- return 1;
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
- return 1;
- break;
- }
- return 0;
-}
-
static LRESULT CALLBACK keyboard_hook(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= 0) {
KBDLLHOOKSTRUCT* msgInfo = (KBDLLHOOKSTRUCT*)lParam;
- // Grabbing everything seems to mess up some keyboard state that
- // FLTK relies on, so just grab the keys that we normally cannot.
- if (is_system_hotkey(msgInfo->vkCode)) {
- PostMessage(target_wnd, wParam, msgInfo->vkCode,
- (msgInfo->scanCode & 0xff) << 16 |
- (msgInfo->flags & 0xff) << 24);
+ BYTE vkey;
+ BYTE scanCode;
+ BYTE flags;
+
+ vkey = msgInfo->vkCode;
+ scanCode = msgInfo->scanCode;
+ flags = msgInfo->flags;
+
+ // We get the low level vkeys here, but the application code
+ // expects this to have been translated to the generic ones
+ switch (vkey) {
+ case VK_LSHIFT:
+ case VK_RSHIFT:
+ vkey = VK_SHIFT;
+ // The extended bit is also always missing for right shift
+ flags &= ~0x01;
+ break;
+ case VK_LCONTROL:
+ case VK_RCONTROL:
+ vkey = VK_CONTROL;
+ break;
+ case VK_LMENU:
+ case VK_RMENU:
+ vkey = VK_MENU;
+ break;
+ }
+
+ // If the key was pressed before the grab was activated, then we
+ // need to avoid intercepting the release event or Windows will get
+ // confused about the state of the key
+ if (((wParam == WM_KEYUP) || (wParam == WM_SYSKEYUP)) &&
+ (kbd_state[msgInfo->vkCode] & 0x80)) {
+ kbd_state[msgInfo->vkCode] &= ~0x80;
+ } else {
+ PostMessage(target_wnd, wParam, vkey,
+ scanCode << 16 | flags << 24);
return 1;
}
}
@@ -76,6 +87,9 @@ static DWORD WINAPI keyboard_thread(LPVOID data)
// Make sure a message queue is created
PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD);
+ // We need to know which keys are currently pressed
+ GetKeyboardState(kbd_state);
+
hook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_hook, GetModuleHandle(0), 0);
// If something goes wrong then there is not much we can do.
// Just sit around and wait for WM_QUIT...