diff --git a/include/freerdp/input.h b/include/freerdp/input.h index 04ed6dc94..e59bed2de 100644 --- a/include/freerdp/input.h +++ b/include/freerdp/input.h @@ -54,7 +54,7 @@ typedef struct rdp_input rdpInput; typedef void (*pSynchronizeEvent)(rdpInput* input, uint32 flags); typedef void (*pKeyboardEvent)(rdpInput* input, uint16 flags, uint16 code); -typedef void (*pUnicodeKeyboardEvent)(rdpInput* input, uint16 code); +typedef void (*pUnicodeKeyboardEvent)(rdpInput* input, uint16 flags, uint16 code); typedef void (*pMouseEvent)(rdpInput* input, uint16 flags, uint16 x, uint16 y); typedef void (*pExtendedMouseEvent)(rdpInput* input, uint16 flags, uint16 x, uint16 y); diff --git a/libfreerdp-core/fastpath.c b/libfreerdp-core/fastpath.c index b7ac3c685..035ed9474 100644 --- a/libfreerdp-core/fastpath.c +++ b/libfreerdp-core/fastpath.c @@ -385,13 +385,20 @@ static boolean fastpath_recv_input_event_sync(rdpFastPath* fastpath, STREAM* s, static boolean fastpath_recv_input_event_unicode(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags) { uint16 unicodeCode; + uint16 flags; if (stream_get_left(s) < 2) return false; stream_read_uint16(s, unicodeCode); /* unicodeCode (2 bytes) */ - IFCALL(fastpath->rdp->input->UnicodeKeyboardEvent, fastpath->rdp->input, unicodeCode); + flags = 0; + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) + flags |= KBD_FLAGS_RELEASE; + else + flags |= KBD_FLAGS_DOWN; + + IFCALL(fastpath->rdp->input->UnicodeKeyboardEvent, fastpath->rdp->input, flags, unicodeCode); return true; } diff --git a/libfreerdp-core/input.c b/libfreerdp-core/input.c index ae54a1f3e..ea31a733c 100644 --- a/libfreerdp-core/input.c +++ b/libfreerdp-core/input.c @@ -78,20 +78,32 @@ void input_send_keyboard_event(rdpInput* input, uint16 flags, uint16 code) rdp_send_client_input_pdu(rdp, s); } -void input_write_unicode_keyboard_event(STREAM* s, uint16 code) +void input_write_unicode_keyboard_event(STREAM* s, uint16 flags, uint16 code) { - stream_write_uint16(s, 0); /* pad2OctetsA (2 bytes) */ + stream_write_uint16(s, flags); /* keyboardFlags (2 bytes) */ stream_write_uint16(s, code); /* unicodeCode (2 bytes) */ - stream_write_uint16(s, 0); /* pad2OctetsB (2 bytes) */ + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ } -void input_send_unicode_keyboard_event(rdpInput* input, uint16 code) +void input_send_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code) { STREAM* s; + uint16 keyboardFlags = 0; rdpRdp* rdp = input->context->rdp; + /* + * According to the specification, the slow path Unicode Keyboard Event + * (TS_UNICODE_KEYBOARD_EVENT) contains KBD_FLAGS_RELEASE flag when key + * is released, but contains no flags when it is pressed. + * This is different from the slow path Keyboard Event + * (TS_KEYBOARD_EVENT) which does contain KBD_FLAGS_DOWN flag when the + * key is pressed. + * There is no KBD_FLAGS_EXTENDED flag in TS_UNICODE_KEYBOARD_EVENT. + */ + keyboardFlags |= (flags & KBD_FLAGS_RELEASE) ? KBD_FLAGS_RELEASE : 0; + s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_UNICODE); - input_write_unicode_keyboard_event(s, code); + input_write_unicode_keyboard_event(s, flags, code); rdp_send_client_input_pdu(rdp, s); } @@ -152,12 +164,14 @@ void input_send_fastpath_keyboard_event(rdpInput* input, uint16 flags, uint16 co fastpath_send_input_pdu(rdp->fastpath, s); } -void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 code) +void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code) { STREAM* s; + uint8 eventFlags = 0; rdpRdp* rdp = input->context->rdp; - s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_UNICODE); + eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0; + s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_UNICODE); stream_write_uint16(s, code); /* unicodeCode (2 bytes) */ fastpath_send_input_pdu(rdp->fastpath, s); } diff --git a/libfreerdp-core/input.h b/libfreerdp-core/input.h index a9ad2baf6..433d83e2d 100644 --- a/libfreerdp-core/input.h +++ b/libfreerdp-core/input.h @@ -39,13 +39,13 @@ void input_send_synchronize_event(rdpInput* input, uint32 flags); void input_send_keyboard_event(rdpInput* input, uint16 flags, uint16 code); -void input_send_unicode_keyboard_event(rdpInput* input, uint16 code); +void input_send_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code); void input_send_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); void input_send_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); void input_send_fastpath_synchronize_event(rdpInput* input, uint32 flags); void input_send_fastpath_keyboard_event(rdpInput* input, uint16 flags, uint16 code); -void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 code); +void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code); void input_send_fastpath_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); void input_send_fastpath_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); diff --git a/server/X11/xf_input.c b/server/X11/xf_input.c index 1784c01c1..ad3938f20 100644 --- a/server/X11/xf_input.c +++ b/server/X11/xf_input.c @@ -54,9 +54,9 @@ void xf_input_keyboard_event(rdpInput* input, uint16 flags, uint16 code) } } -void xf_input_unicode_keyboard_event(rdpInput* input, uint16 code) +void xf_input_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code) { - printf("Client sent a unicode keyboard event (code:0x%X)\n", code); + printf("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code); } void xf_input_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) diff --git a/server/test/tfreerdp.c b/server/test/tfreerdp.c index bf67f13c5..354836043 100644 --- a/server/test/tfreerdp.c +++ b/server/test/tfreerdp.c @@ -493,9 +493,9 @@ void tf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code) } } -void tf_peer_unicode_keyboard_event(rdpInput* input, uint16 code) +void tf_peer_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code) { - printf("Client sent a unicode keyboard event (code:0x%X)\n", code); + printf("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code); } void tf_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)