diff --git a/client/Wayland/wlf_input.c b/client/Wayland/wlf_input.c index 20f3c21f3..a3f5a6a25 100644 --- a/client/Wayland/wlf_input.c +++ b/client/Wayland/wlf_input.c @@ -340,7 +340,7 @@ BOOL wlf_handle_key(freerdp* instance, const UwacKeyEvent* ev) if (rdp_scancode == RDP_SCANCODE_UNKNOWN) return TRUE; - return freerdp_input_send_keyboard_event_ex(input, ev->pressed, rdp_scancode); + return freerdp_input_send_keyboard_event_ex(input, ev->pressed, ev->repeated, rdp_scancode); } BOOL wlf_handle_ungrab_key(freerdp* instance, const UwacKeyEvent* ev) diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c index 1debb4704..2433a5bd6 100644 --- a/client/Windows/wf_event.c +++ b/client/Windows/wf_event.c @@ -64,8 +64,11 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) wfContext* wfc = NULL; DWORD rdp_scancode; + BOOL keystate; rdpInput* input; PKBDLLHOOKSTRUCT p; + + static BOOL keystates[256] = { 0 }; DEBUG_KBD("Low-level keyboard hook, hWnd %X nCode %X wParam %X", g_focus_hWnd, nCode, wParam); if (g_flipping_in) @@ -110,6 +113,20 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) input = wfc->common.context.input; rdp_scancode = MAKE_RDP_SCANCODE((BYTE)p->scanCode, p->flags & LLKHF_EXTENDED); + keystate = keystates[p->scanCode & 0xFF]; + + switch (wParam) + { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + keystates[p->scanCode & 0xFF] = TRUE; + break; + case WM_KEYUP: + case WM_SYSKEYUP: + default: + keystates[p->scanCode & 0xFF] = FALSE; + break; + } DEBUG_KBD("keydown %d scanCode 0x%08lX flags 0x%08lX vkCode 0x%08lX", (wParam == WM_KEYDOWN), p->scanCode, p->flags, p->vkCode); @@ -138,10 +155,14 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) if (wParam == WM_KEYDOWN) { DEBUG_KBD("Pause, sent as Ctrl+NumLock"); - freerdp_input_send_keyboard_event_ex(input, TRUE, RDP_SCANCODE_LCONTROL); - freerdp_input_send_keyboard_event_ex(input, TRUE, RDP_SCANCODE_NUMLOCK); - freerdp_input_send_keyboard_event_ex(input, FALSE, RDP_SCANCODE_LCONTROL); - freerdp_input_send_keyboard_event_ex(input, FALSE, RDP_SCANCODE_NUMLOCK); + freerdp_input_send_keyboard_event_ex(input, TRUE, FALSE, + RDP_SCANCODE_LCONTROL); + freerdp_input_send_keyboard_event_ex(input, TRUE, FALSE, + RDP_SCANCODE_NUMLOCK); + freerdp_input_send_keyboard_event_ex(input, FALSE, FALSE, + RDP_SCANCODE_LCONTROL); + freerdp_input_send_keyboard_event_ex(input, FALSE, FALSE, + RDP_SCANCODE_NUMLOCK); } else { @@ -156,7 +177,8 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) rdp_scancode = RDP_SCANCODE_RSHIFT; } - freerdp_input_send_keyboard_event_ex(input, !(p->flags & LLKHF_UP), rdp_scancode); + freerdp_input_send_keyboard_event_ex(input, !(p->flags & LLKHF_UP), keystate, + rdp_scancode); if (p->vkCode == VK_NUMLOCK || p->vkCode == VK_CAPITAL || p->vkCode == VK_SCROLL || p->vkCode == VK_KANA) @@ -165,6 +187,8 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) else return 1; + break; + default: break; } } diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 924473b5c..e1c520771 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -62,7 +62,7 @@ BOOL xf_keyboard_update_modifier_map(xfContext* xfc) return xfc->modifierMap != NULL; } -static void xf_keyboard_send_key(xfContext* xfc, BOOL down, const XKeyEvent* ev); +static void xf_keyboard_send_key(xfContext* xfc, BOOL down, BOOL repeat, const XKeyEvent* ev); static BOOL xf_sync_kbd_state(xfContext* xfc) { @@ -175,18 +175,21 @@ void xf_keyboard_free(xfContext* xfc) void xf_keyboard_key_press(xfContext* xfc, const XKeyEvent* event, KeySym keysym) { + BOOL last; + WINPR_ASSERT(xfc); WINPR_ASSERT(event); if (event->keycode < 8) return; + last = xfc->KeyboardState[event->keycode]; xfc->KeyboardState[event->keycode] = TRUE; if (xf_keyboard_handle_special_keys(xfc, keysym)) return; - xf_keyboard_send_key(xfc, TRUE, event); + xf_keyboard_send_key(xfc, TRUE, last, event); } void xf_keyboard_key_release(xfContext* xfc, const XKeyEvent* event, KeySym keysym) @@ -197,9 +200,10 @@ void xf_keyboard_key_release(xfContext* xfc, const XKeyEvent* event, KeySym keys if (event->keycode < 8) return; + BOOL last = xfc->KeyboardState[event->keycode]; xfc->KeyboardState[event->keycode] = FALSE; xf_keyboard_handle_special_keys_release(xfc, keysym); - xf_keyboard_send_key(xfc, FALSE, event); + xf_keyboard_send_key(xfc, FALSE, last, event); } void xf_keyboard_release_all_keypress(xfContext* xfc) @@ -218,10 +222,11 @@ void xf_keyboard_release_all_keypress(xfContext* xfc) // release tab before releasing the windows key. // this stops the start menu from opening on unfocus event. if (rdp_scancode == RDP_SCANCODE_LWIN) - freerdp_input_send_keyboard_event_ex(xfc->common.context.input, FALSE, + freerdp_input_send_keyboard_event_ex(xfc->common.context.input, FALSE, FALSE, RDP_SCANCODE_TAB); - freerdp_input_send_keyboard_event_ex(xfc->common.context.input, FALSE, rdp_scancode); + freerdp_input_send_keyboard_event_ex(xfc->common.context.input, FALSE, FALSE, + rdp_scancode); xfc->KeyboardState[keycode] = FALSE; } } @@ -234,7 +239,7 @@ BOOL xf_keyboard_key_pressed(xfContext* xfc, KeySym keysym) return xfc->KeyboardState[keycode]; } -void xf_keyboard_send_key(xfContext* xfc, BOOL down, const XKeyEvent* event) +void xf_keyboard_send_key(xfContext* xfc, BOOL down, BOOL repeat, const XKeyEvent* event) { DWORD rdp_scancode; rdpInput* input; @@ -290,7 +295,7 @@ void xf_keyboard_send_key(xfContext* xfc, BOOL down, const XKeyEvent* event) if (rdp_scancode == RDP_SCANCODE_UNKNOWN) WLog_ERR(TAG, "Unknown key with X keycode 0x%02" PRIx8 "", event->keycode); else - freerdp_input_send_keyboard_event_ex(input, down, rdp_scancode); + freerdp_input_send_keyboard_event_ex(input, down, repeat, rdp_scancode); } else freerdp_input_send_unicode_keyboard_event(input, down ? KBD_FLAGS_RELEASE : 0, @@ -299,7 +304,7 @@ void xf_keyboard_send_key(xfContext* xfc, BOOL down, const XKeyEvent* event) else if (rdp_scancode == RDP_SCANCODE_UNKNOWN) WLog_ERR(TAG, "Unknown key with X keycode 0x%02" PRIx8 "", event->keycode); else - freerdp_input_send_keyboard_event_ex(input, down, rdp_scancode); + freerdp_input_send_keyboard_event_ex(input, down, repeat, rdp_scancode); if ((rdp_scancode == RDP_SCANCODE_CAPSLOCK) && (down == FALSE)) {