clients: use rdp scancode definitions when sending key events

This also introduces a slightly more high-level convenience function for
sending key events. The existing function where an RDP protocol flag field has
to be encoded by the caller is very lowlevel ... and a bad fit for fastpath
input. That could use a refactoring.
This commit is contained in:
Mads Kiilerich 2012-03-29 01:12:48 +02:00
parent 7f399c6020
commit 3e4b434925
5 changed files with 47 additions and 62 deletions

View File

@ -190,10 +190,7 @@ void df_send_mouse_wheel_event(rdpInput* input, sint16 axisrel, uint16 x, uint16
void df_send_keyboard_event(rdpInput* input, boolean down, uint8 keycode, uint8 function) void df_send_keyboard_event(rdpInput* input, boolean down, uint8 keycode, uint8 function)
{ {
uint16 flags;
uint8 vkcode; uint8 vkcode;
uint8 scancode;
boolean extended;
RDP_SCANCODE rdp_scancode; RDP_SCANCODE rdp_scancode;
if (keycode) if (keycode)
@ -204,13 +201,8 @@ void df_send_keyboard_event(rdpInput* input, boolean down, uint8 keycode, uint8
return; return;
rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(vkcode); rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(vkcode);
scancode = rdp_scancode_code(rdp_scancode);
extended = rdp_scancode_extended(rdp_scancode);
flags = (extended) ? KBD_FLAGS_EXTENDED : 0; freerdp_input_send_keyboard_event_2(input, down, rdp_scancode);
flags |= (down) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE;
input->KeyboardEvent(input, flags, scancode);
} }
boolean df_event_process(freerdp* instance, DFBEvent* event) boolean df_event_process(freerdp* instance, DFBEvent* event)

View File

@ -33,11 +33,9 @@ extern HCURSOR g_default_cursor;
LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
{ {
DWORD flags;
wfInfo* wfi; wfInfo* wfi;
uint8 scanCode; RDP_SCANCODE rdp_scancode;
rdpInput* input; rdpInput* input;
uint16 kbdFlags;
PKBDLLHOOKSTRUCT p; PKBDLLHOOKSTRUCT p;
DEBUG_KBD("Low-level keyboard hook, hWnd %X nCode %X wParam %X", g_focus_hWnd, nCode, wParam); DEBUG_KBD("Low-level keyboard hook, hWnd %X nCode %X wParam %X", g_focus_hWnd, nCode, wParam);
@ -52,13 +50,11 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
case WM_SYSKEYUP: case WM_SYSKEYUP:
wfi = (wfInfo*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA); wfi = (wfInfo*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA);
p = (PKBDLLHOOKSTRUCT) lParam; p = (PKBDLLHOOKSTRUCT) lParam;
scanCode = (uint8) p->scanCode;
input = wfi->instance->input; input = wfi->instance->input;
flags = p->flags; rdp_scancode = mk_rdp_scancode((uint8) p->scanCode, p->flags & LLKHF_EXTENDED);
kbdFlags = 0;
DEBUG_KBD("keydown %d scanCode %04X flags %02X vkCode %02X", DEBUG_KBD("keydown %d scanCode %04X flags %02X vkCode %02X",
(wParam == WM_KEYDOWN), scanCode, flags, p->vkCode); (wParam == WM_KEYDOWN), (uint8) p->scanCode, p->flags, p->vkCode);
if (wfi->fs_toggle && if (wfi->fs_toggle &&
((p->vkCode == VK_RETURN) || (p->vkCode == VK_CANCEL)) && ((p->vkCode == VK_RETURN) || (p->vkCode == VK_CANCEL)) &&
@ -70,25 +66,23 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
return 1; return 1;
} }
if (scanCode == 0x45) /* NumLock-ish */ if (rdp_scancode == RDP_SCANCODE_NUMLOCK_EXTENDED)
{
if (flags & LLKHF_EXTENDED)
{ {
/* Windows sends NumLock as extended - rdp doesn't */ /* Windows sends NumLock as extended - rdp doesn't */
DEBUG_KBD("hack: NumLock (x45) should not be extended"); DEBUG_KBD("hack: NumLock (x45) should not be extended");
flags &= ~LLKHF_EXTENDED; rdp_scancode = RDP_SCANCODE_NUMLOCK;
} }
else else if (rdp_scancode == RDP_SCANCODE_NUMLOCK)
{ {
/* Windows sends Pause as if it was a RDP NumLock (handled above). /* Windows sends Pause as if it was a RDP NumLock (handled above).
* It must however be sent as a one-shot Ctrl+NumLock */ * It must however be sent as a one-shot Ctrl+NumLock */
if (wParam == WM_KEYDOWN) if (wParam == WM_KEYDOWN)
{ {
DEBUG_KBD("Pause, sent as Ctrl+NumLock"); DEBUG_KBD("Pause, sent as Ctrl+NumLock");
input->KeyboardEvent(input, KBD_FLAGS_DOWN, 0x1D); /* Ctrl down */ freerdp_input_send_keyboard_event_2(input, true, RDP_SCANCODE_LCONTROL);
input->KeyboardEvent(input, KBD_FLAGS_DOWN, 0x45); /* NumLock down */ freerdp_input_send_keyboard_event_2(input, true, RDP_SCANCODE_NUMLOCK);
input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x1D); /* Ctrl up */ freerdp_input_send_keyboard_event_2(input, false, RDP_SCANCODE_LCONTROL);
input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x45); /* NumLock up */ freerdp_input_send_keyboard_event_2(input, false, RDP_SCANCODE_NUMLOCK);
} }
else else
{ {
@ -97,17 +91,13 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
return 1; return 1;
} }
} else if (rdp_scancode == RDP_SCANCODE_RSHIFT_EXTENDED)
if ((scanCode == 0x36) && (flags & LLKHF_EXTENDED))
{ {
DEBUG_KBD("hack: right shift (x36) should not be extended"); DEBUG_KBD("right shift (x36) should not be extended");
flags &= ~LLKHF_EXTENDED; rdp_scancode = RDP_SCANCODE_RSHIFT;
} }
kbdFlags |= (flags & LLKHF_UP) ? KBD_FLAGS_RELEASE : KBD_FLAGS_DOWN; freerdp_input_send_keyboard_event_2(input, !(flags & LLKHF_UP), rdp_scancode);
kbdFlags |= (flags & LLKHF_EXTENDED) ? KBD_FLAGS_EXTENDED : 0;
input->KeyboardEvent(input, kbdFlags, scanCode);
if (p->vkCode == VK_CAPITAL) if (p->vkCode == VK_CAPITAL)
DEBUG_KBD("caps lock is processed on client side too to toggle caps lock indicator"); DEBUG_KBD("caps lock is processed on client side too to toggle caps lock indicator");

View File

@ -58,41 +58,33 @@ boolean xf_kbd_key_pressed(xfInfo* xfi, KeySym keysym)
void xf_kbd_send_key(xfInfo* xfi, boolean down, uint8 keycode) void xf_kbd_send_key(xfInfo* xfi, boolean down, uint8 keycode)
{ {
uint16 flags;
RDP_SCANCODE rdp_scancode; RDP_SCANCODE rdp_scancode;
uint8 scancode;
boolean extended;
rdpInput* input; rdpInput* input;
input = xfi->instance->input; input = xfi->instance->input;
rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode); rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode);
scancode = rdp_scancode_code(rdp_scancode);
extended = rdp_scancode_extended(rdp_scancode);
if (scancode == 0) if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
{ {
/* unknown key */ printf("Unknown key with X keycode 0x%02x\n", keycode);
} }
else if ((scancode == 0x46) && extended && else if (rdp_scancode == RDP_SCANCODE_PAUSE &&
!xf_kbd_key_pressed(xfi, XK_Control_L) && !xf_kbd_key_pressed(xfi, XK_Control_R)) !xf_kbd_key_pressed(xfi, XK_Control_L) && !xf_kbd_key_pressed(xfi, XK_Control_R))
{ {
/* Pause without Ctrl has to be sent as Ctrl + NumLock. */ /* Pause without Ctrl has to be sent as Ctrl + NumLock. */
if (down) if (down)
{ {
input->KeyboardEvent(input, KBD_FLAGS_DOWN, 0x1D); /* Ctrl down */ freerdp_input_send_keyboard_event_2(input, true, RDP_SCANCODE_LCONTROL);
input->KeyboardEvent(input, KBD_FLAGS_DOWN, 0x45); /* NumLock down */ freerdp_input_send_keyboard_event_2(input, true, RDP_SCANCODE_NUMLOCK);
input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x1D); /* Ctrl up */ freerdp_input_send_keyboard_event_2(input, false, RDP_SCANCODE_LCONTROL);
input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x45); /* NumLock up */ freerdp_input_send_keyboard_event_2(input, false, RDP_SCANCODE_NUMLOCK);
} }
} }
else else
{ {
flags = (extended) ? KBD_FLAGS_EXTENDED : 0; freerdp_input_send_keyboard_event_2(input, down, rdp_scancode);
flags |= (down) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE;
input->KeyboardEvent(input, flags, scancode); if ((rdp_scancode == RDP_SCANCODE_CAPITAL) && (down == false))
if ((scancode == 0x3A) && (down == false)) /* caps lock was released */
{ {
uint32 syncFlags; uint32 syncFlags;
syncFlags = xf_kbd_get_toggle_keys_state(xfi); syncFlags = xf_kbd_get_toggle_keys_state(xfi);

View File

@ -24,6 +24,7 @@ typedef struct rdp_input rdpInput;
#include <freerdp/api.h> #include <freerdp/api.h>
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#include <freerdp/keyboard_scancode.h>
/* keyboard Flags */ /* keyboard Flags */
#define KBD_FLAGS_EXTENDED 0x0100 #define KBD_FLAGS_EXTENDED 0x0100
@ -79,4 +80,10 @@ FREERDP_API void freerdp_input_send_unicode_keyboard_event(rdpInput* input, uint
FREERDP_API void freerdp_input_send_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); FREERDP_API void freerdp_input_send_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y);
FREERDP_API void freerdp_input_send_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); FREERDP_API void freerdp_input_send_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y);
#define freerdp_input_send_keyboard_event_2(input, down, rdp_scancode) \
freerdp_input_send_keyboard_event(input, \
(rdp_scancode_extended(rdp_scancode) ? KBD_FLAGS_EXTENDED : 0) | \
((down) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE), \
rdp_scancode_code(rdp_scancode))
#endif /* __INPUT_API_H */ #endif /* __INPUT_API_H */

View File

@ -157,7 +157,7 @@ typedef uint32 RDP_SCANCODE; /* Our own representation of a RDP protocol scancod
#define RDP_SCANCODE_F22 mk_rdp_scancode(0x6D, false) /* VK_F22 */ #define RDP_SCANCODE_F22 mk_rdp_scancode(0x6D, false) /* VK_F22 */
#define RDP_SCANCODE_F23 mk_rdp_scancode(0x6E, false) /* VK_F23 */ #define RDP_SCANCODE_F23 mk_rdp_scancode(0x6E, false) /* VK_F23 */
#define RDP_SCANCODE_F24 mk_rdp_scancode(0x6F, false) /* VK_F24 */ #define RDP_SCANCODE_F24 mk_rdp_scancode(0x6F, false) /* VK_F24 */
#define RDP_SCANCODE_NUMLOCK mk_rdp_scancode(0x45, false) /* VK_NUMLOCK */ #define RDP_SCANCODE_NUMLOCK mk_rdp_scancode(0x45, false) /* VK_NUMLOCK */ /* Note: when this seems to appear in PKBDLLHOOKSTRUCT it means Pause which must be sent as Ctrl + NumLock */
#define RDP_SCANCODE_SCROLL mk_rdp_scancode(0x46, false) /* VK_SCROLL */ #define RDP_SCANCODE_SCROLL mk_rdp_scancode(0x46, false) /* VK_SCROLL */
#define RDP_SCANCODE_LSHIFT mk_rdp_scancode(0x2A, false) /* VK_LSHIFT */ #define RDP_SCANCODE_LSHIFT mk_rdp_scancode(0x2A, false) /* VK_LSHIFT */
#define RDP_SCANCODE_RSHIFT mk_rdp_scancode(0x36, false) /* VK_RSHIFT */ #define RDP_SCANCODE_RSHIFT mk_rdp_scancode(0x36, false) /* VK_RSHIFT */
@ -210,4 +210,8 @@ typedef uint32 RDP_SCANCODE; /* Our own representation of a RDP protocol scancod
/* #define RDP_SCANCODE_PA1 VK_PA1 */ /* #define RDP_SCANCODE_PA1 VK_PA1 */
/* #define RDP_SCANCODE_OEM_CLEAR VK_OEM_CLEAR */ /* #define RDP_SCANCODE_OEM_CLEAR VK_OEM_CLEAR */
/* _not_ valid scancode, but this is what a windows PKBDLLHOOKSTRUCT for NumLock contains */
#define RDP_SCANCODE_NUMLOCK_EXTENDED mk_rdp_scancode(0x45, true) /* should be RDP_SCANCODE_NUMLOCK */
#define RDP_SCANCODE_RSHIFT_EXTENDED mk_rdp_scancode(0x36, true) /* should be RDP_SCANCODE_RSHIFT */
#endif /* __FREERDP_LOCALE_KEYBOARD_RDP_SCANCODE_H */ #endif /* __FREERDP_LOCALE_KEYBOARD_RDP_SCANCODE_H */