Implement server-side support for slow-path Input Event PDU.

This commit is contained in:
Pawel Jakub Dawidek 2012-02-07 13:38:27 +01:00
parent 4117e71a79
commit eb8c5c5f81
3 changed files with 169 additions and 1 deletions

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;