mirror of https://github.com/FreeRDP/FreeRDP
Implement server-side support for slow-path Input Event PDU.
This commit is contained in:
parent
4117e71a79
commit
eb8c5c5f81
|
@ -182,6 +182,168 @@ void input_send_fastpath_extended_mouse_event(rdpInput* input, uint16 flags, uin
|
|||
fastpath_send_input_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
static boolean input_recv_sync_event(rdpInput* input, STREAM* s)
|
||||
{
|
||||
uint32 toggleFlags;
|
||||
|
||||
if (stream_get_left(s) < 6)
|
||||
return false;
|
||||
|
||||
stream_seek(s, 2); /* pad2Octets (2 bytes) */
|
||||
stream_read_uint32(s, toggleFlags); /* toggleFlags (4 bytes) */
|
||||
|
||||
IFCALL(input->SynchronizeEvent, input, toggleFlags);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean input_recv_keyboard_event(rdpInput* input, STREAM* s)
|
||||
{
|
||||
uint16 keyboardFlags, keyCode;
|
||||
|
||||
if (stream_get_left(s) < 6)
|
||||
return false;
|
||||
|
||||
stream_read_uint16(s, keyboardFlags); /* keyboardFlags (2 bytes) */
|
||||
stream_read_uint16(s, keyCode); /* keyCode (2 bytes) */
|
||||
stream_seek(s, 2); /* pad2Octets (2 bytes) */
|
||||
|
||||
IFCALL(input->KeyboardEvent, input, keyboardFlags, keyCode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean input_recv_unicode_keyboard_event(rdpInput* input, STREAM* s)
|
||||
{
|
||||
uint16 keyboardFlags, unicodeCode;
|
||||
|
||||
if (stream_get_left(s) < 6)
|
||||
return false;
|
||||
|
||||
stream_read_uint16(s, keyboardFlags); /* keyboardFlags (2 bytes) */
|
||||
stream_read_uint16(s, unicodeCode); /* unicodeCode (2 bytes) */
|
||||
stream_seek(s, 2); /* pad2Octets (2 bytes) */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* Set the KBD_FLAGS_DOWN flag if the KBD_FLAGS_RELEASE flag is missing.
|
||||
*/
|
||||
|
||||
if ((keyboardFlags & KBD_FLAGS_RELEASE) == 0)
|
||||
keyboardFlags |= KBD_FLAGS_DOWN;
|
||||
|
||||
IFCALL(input->UnicodeKeyboardEvent, input, keyboardFlags, unicodeCode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean input_recv_mouse_event(rdpInput* input, STREAM* s)
|
||||
{
|
||||
uint16 pointerFlags, xPos, yPos;
|
||||
|
||||
if (stream_get_left(s) < 6)
|
||||
return false;
|
||||
|
||||
stream_read_uint16(s, pointerFlags); /* pointerFlags (2 bytes) */
|
||||
stream_read_uint16(s, xPos); /* xPos (2 bytes) */
|
||||
stream_read_uint16(s, yPos); /* yPos (2 bytes) */
|
||||
|
||||
IFCALL(input->MouseEvent, input, pointerFlags, xPos, yPos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean input_recv_extended_mouse_event(rdpInput* input, STREAM* s)
|
||||
{
|
||||
uint16 pointerFlags, xPos, yPos;
|
||||
|
||||
if (stream_get_left(s) < 6)
|
||||
return false;
|
||||
|
||||
stream_read_uint16(s, pointerFlags); /* pointerFlags (2 bytes) */
|
||||
stream_read_uint16(s, xPos); /* xPos (2 bytes) */
|
||||
stream_read_uint16(s, yPos); /* yPos (2 bytes) */
|
||||
|
||||
IFCALL(input->ExtendedMouseEvent, input, pointerFlags, xPos, yPos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean input_recv_event(rdpInput* input, STREAM* s)
|
||||
{
|
||||
uint16 messageType;
|
||||
|
||||
if (stream_get_left(s) < 4)
|
||||
return false;
|
||||
|
||||
stream_seek(s, 4); /* eventTime (4 bytes), ignored by the server */
|
||||
stream_read_uint16(s, messageType); /* messageType (2 bytes) */
|
||||
|
||||
switch (messageType)
|
||||
{
|
||||
case INPUT_EVENT_SYNC:
|
||||
if (!input_recv_sync_event(input, s))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case INPUT_EVENT_SCANCODE:
|
||||
if (!input_recv_keyboard_event(input, s))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case INPUT_EVENT_UNICODE:
|
||||
if (!input_recv_unicode_keyboard_event(input, s))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case INPUT_EVENT_MOUSE:
|
||||
if (!input_recv_mouse_event(input, s))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case INPUT_EVENT_MOUSEX:
|
||||
if (!input_recv_extended_mouse_event(input, s))
|
||||
return false;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown messageType %u\n", messageType);
|
||||
/* Each input event uses 6 bytes. */
|
||||
stream_seek(s, 6);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean input_recv(rdpInput* input, STREAM* s)
|
||||
{
|
||||
uint16 i, numberEvents;
|
||||
|
||||
if (stream_get_left(s) < 4)
|
||||
return false;
|
||||
|
||||
stream_read_uint16(s, numberEvents); /* numberEvents (2 bytes) */
|
||||
stream_seek(s, 2); /* pad2Octets (2 bytes) */
|
||||
|
||||
/* Each input event uses 6 exactly bytes. */
|
||||
if (stream_get_left(s) < 6 * numberEvents)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < numberEvents; i++)
|
||||
{
|
||||
if (!input_recv_event(input, s))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void input_register_client_callbacks(rdpInput* input)
|
||||
{
|
||||
rdpRdp* rdp = input->context->rdp;
|
||||
|
@ -225,4 +387,3 @@ void input_free(rdpInput* input)
|
|||
xfree(input);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,8 @@ void input_send_fastpath_unicode_keyboard_event(rdpInput* input, 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);
|
||||
|
||||
boolean input_recv(rdpInput* input, STREAM* s);
|
||||
|
||||
void input_register_client_callbacks(rdpInput* input);
|
||||
|
||||
rdpInput* input_new(rdpRdp* rdp);
|
||||
|
|
|
@ -77,6 +77,11 @@ static boolean peer_recv_data_pdu(freerdp_peer* client, STREAM* s)
|
|||
return false;
|
||||
break;
|
||||
|
||||
case DATA_PDU_TYPE_INPUT:
|
||||
if (!input_recv(client->context->rdp->input, s))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST:
|
||||
/* TODO: notify server bitmap cache data */
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue