server: process client input events.
This commit is contained in:
parent
719f521a39
commit
2d4f10038e
@ -52,7 +52,10 @@ uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s)
|
||||
|
||||
stream_read_uint8(s, header);
|
||||
if (fastpath != NULL)
|
||||
{
|
||||
fastpath->encryptionFlags = (header & 0xC0) >> 6;
|
||||
fastpath->numberEvents = (header & 0x3C) >> 2;
|
||||
}
|
||||
|
||||
stream_read_uint8(s, length); /* length1 */
|
||||
/* If most significant bit is not set, length2 is not presented. */
|
||||
@ -306,8 +309,168 @@ boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean fastpath_recv_input(rdpFastPath* fastpath, STREAM* s)
|
||||
static boolean fastpath_read_input_event_header(STREAM* s, uint8* eventFlags, uint8* eventCode)
|
||||
{
|
||||
uint8 eventHeader;
|
||||
|
||||
if (stream_get_left(s) < 1)
|
||||
return False;
|
||||
|
||||
stream_read_uint8(s, eventHeader); /* eventHeader (1 byte) */
|
||||
|
||||
*eventFlags = (eventHeader & 0x1F);
|
||||
*eventCode = (eventHeader >> 5);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event_scancode(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags)
|
||||
{
|
||||
uint16 flags;
|
||||
uint16 code;
|
||||
|
||||
if (stream_get_left(s) < 1)
|
||||
return False;
|
||||
|
||||
stream_read_uint8(s, code); /* keyCode (1 byte) */
|
||||
|
||||
flags = 0;
|
||||
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE))
|
||||
flags |= KBD_FLAGS_RELEASE;
|
||||
else
|
||||
flags |= KBD_FLAGS_DOWN;
|
||||
|
||||
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED))
|
||||
flags |= KBD_FLAGS_EXTENDED;
|
||||
|
||||
IFCALL(fastpath->rdp->input->KeyboardEvent, fastpath->rdp->input, flags, code);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event_mouse(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags)
|
||||
{
|
||||
uint16 pointerFlags;
|
||||
uint16 xPos;
|
||||
uint16 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(fastpath->rdp->input->MouseEvent, fastpath->rdp->input, pointerFlags, xPos, yPos);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event_mousex(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags)
|
||||
{
|
||||
uint16 pointerFlags;
|
||||
uint16 xPos;
|
||||
uint16 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(fastpath->rdp->input->ExtendedMouseEvent, fastpath->rdp->input, pointerFlags, xPos, yPos);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event_sync(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags)
|
||||
{
|
||||
IFCALL(fastpath->rdp->input->SynchronizeEvent, fastpath->rdp->input, eventFlags);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event_unicode(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags)
|
||||
{
|
||||
uint16 unicodeCode;
|
||||
|
||||
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);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
uint8 eventFlags;
|
||||
uint8 eventCode;
|
||||
|
||||
if (!fastpath_read_input_event_header(s, &eventFlags, &eventCode))
|
||||
return False;
|
||||
|
||||
switch (eventCode)
|
||||
{
|
||||
case FASTPATH_INPUT_EVENT_SCANCODE:
|
||||
if (!fastpath_recv_input_event_scancode(fastpath, s, eventFlags))
|
||||
return False;
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_MOUSE:
|
||||
if (!fastpath_recv_input_event_mouse(fastpath, s, eventFlags))
|
||||
return False;
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_MOUSEX:
|
||||
if (!fastpath_recv_input_event_mousex(fastpath, s, eventFlags))
|
||||
return False;
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_SYNC:
|
||||
if (!fastpath_recv_input_event_sync(fastpath, s, eventFlags))
|
||||
return False;
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_UNICODE:
|
||||
if (!fastpath_recv_input_event_unicode(fastpath, s, eventFlags))
|
||||
return False;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown eventCode %d\n", eventCode);
|
||||
break;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
uint8 i;
|
||||
|
||||
if (fastpath->numberEvents == 0)
|
||||
{
|
||||
/**
|
||||
* If numberEvents is not provided in fpInputHeader, it will be provided
|
||||
* as onee additional byte here.
|
||||
*/
|
||||
|
||||
if (stream_get_left(s) < 1)
|
||||
return False;
|
||||
|
||||
stream_read_uint8(s, fastpath->numberEvents); /* eventHeader (1 byte) */
|
||||
}
|
||||
|
||||
for (i = 0; i < fastpath->numberEvents; i++)
|
||||
{
|
||||
if (!fastpath_recv_input_event(fastpath, s))
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -320,7 +483,7 @@ STREAM* fastpath_pdu_init(rdpFastPath* fastpath)
|
||||
return s;
|
||||
}
|
||||
|
||||
void fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
|
||||
boolean fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
|
||||
{
|
||||
int length;
|
||||
|
||||
@ -328,7 +491,7 @@ void fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
|
||||
if (length > 127)
|
||||
{
|
||||
printf("Maximum FastPath PDU length is 127\n");
|
||||
return;
|
||||
return False;
|
||||
}
|
||||
|
||||
stream_set_pos(s, 0);
|
||||
@ -336,7 +499,23 @@ void fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
|
||||
stream_write_uint8(s, length);
|
||||
|
||||
stream_set_pos(s, length);
|
||||
transport_write(fastpath->rdp->transport, s);
|
||||
if (transport_write(fastpath->rdp->transport, s) < 0)
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode)
|
||||
{
|
||||
STREAM* s;
|
||||
s = fastpath_pdu_init(fastpath);
|
||||
stream_write_uint8(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */
|
||||
return s;
|
||||
}
|
||||
|
||||
boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
return fastpath_send_pdu(fastpath, s, 1);
|
||||
}
|
||||
|
||||
rdpFastPath* fastpath_new(rdpRdp* rdp)
|
||||
|
@ -72,20 +72,41 @@ enum FASTPATH_OUTPUT_COMPRESSION
|
||||
FASTPATH_OUTPUT_COMPRESSION_USED = 0x2
|
||||
};
|
||||
|
||||
/* FastPath Input Events */
|
||||
enum FASTPATH_INPUT_EVENT_CODE
|
||||
{
|
||||
FASTPATH_INPUT_EVENT_SCANCODE = 0x0,
|
||||
FASTPATH_INPUT_EVENT_MOUSE = 0x1,
|
||||
FASTPATH_INPUT_EVENT_MOUSEX = 0x2,
|
||||
FASTPATH_INPUT_EVENT_SYNC = 0x3,
|
||||
FASTPATH_INPUT_EVENT_UNICODE = 0x4
|
||||
};
|
||||
|
||||
/* FastPath Keyboard Event Flags */
|
||||
enum FASTPATH_INPUT_KBDFLAGS
|
||||
{
|
||||
FASTPATH_INPUT_KBDFLAGS_RELEASE = 0x01,
|
||||
FASTPATH_INPUT_KBDFLAGS_EXTENDED = 0x02
|
||||
};
|
||||
|
||||
struct rdp_fastpath
|
||||
{
|
||||
rdpRdp* rdp;
|
||||
uint8 encryptionFlags;
|
||||
uint8 numberEvents;
|
||||
STREAM* updateData;
|
||||
};
|
||||
|
||||
uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_read_security_header(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_recv_input(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s);
|
||||
|
||||
STREAM* fastpath_pdu_init(rdpFastPath* fastpath);
|
||||
void fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents);
|
||||
boolean fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents);
|
||||
|
||||
STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode);
|
||||
boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s);
|
||||
|
||||
rdpFastPath* fastpath_new(rdpRdp* rdp);
|
||||
void fastpath_free(rdpFastPath* fastpath);
|
||||
|
@ -119,60 +119,57 @@ void input_send_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, ui
|
||||
rdp_send_client_input_pdu(input->rdp, s);
|
||||
}
|
||||
|
||||
STREAM* rdp_client_fastpath_input_pdu_init(rdpRdp* rdp, uint8 flags, uint8 code)
|
||||
{
|
||||
STREAM* s;
|
||||
s = fastpath_pdu_init(rdp->fastpath);
|
||||
stream_write_uint8(s, flags | (code << 5)); /* eventHeader */
|
||||
return s;
|
||||
}
|
||||
|
||||
void rdp_send_client_fastpath_input_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
fastpath_send_pdu(rdp->fastpath, s, 1);
|
||||
}
|
||||
|
||||
void input_send_fastpath_synchronize_event(rdpInput* input, uint32 flags)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)input->rdp;
|
||||
STREAM* s;
|
||||
|
||||
/* The FastPath Synchronization eventFlags has identical values as SlowPath */
|
||||
s = rdp_client_fastpath_input_pdu_init(input->rdp, (uint8)flags, FASTPATH_INPUT_EVENT_SYNC);
|
||||
rdp_send_client_fastpath_input_pdu(input->rdp, s);
|
||||
s = fastpath_input_pdu_init(rdp->fastpath, (uint8)flags, FASTPATH_INPUT_EVENT_SYNC);
|
||||
fastpath_send_input_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
void input_send_fastpath_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)input->rdp;
|
||||
STREAM* s;
|
||||
uint8 eventFlags = 0;
|
||||
|
||||
eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0;
|
||||
eventFlags |= (flags & KBD_FLAGS_EXTENDED) ? FASTPATH_INPUT_KBDFLAGS_EXTENDED : 0;
|
||||
s = rdp_client_fastpath_input_pdu_init(input->rdp, eventFlags, FASTPATH_INPUT_EVENT_SCANCODE);
|
||||
s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_SCANCODE);
|
||||
stream_write_uint8(s, code); /* keyCode (1 byte) */
|
||||
rdp_send_client_fastpath_input_pdu(input->rdp, s);
|
||||
fastpath_send_input_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 code)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)input->rdp;
|
||||
STREAM* s;
|
||||
s = rdp_client_fastpath_input_pdu_init(input->rdp, 0, FASTPATH_INPUT_EVENT_UNICODE);
|
||||
|
||||
s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_UNICODE);
|
||||
stream_write_uint16(s, code); /* unicodeCode (2 bytes) */
|
||||
rdp_send_client_fastpath_input_pdu(input->rdp, s);
|
||||
fastpath_send_input_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
void input_send_fastpath_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)input->rdp;
|
||||
STREAM* s;
|
||||
s = rdp_client_fastpath_input_pdu_init(input->rdp, 0, FASTPATH_INPUT_EVENT_MOUSE);
|
||||
|
||||
s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_MOUSE);
|
||||
input_write_mouse_event(s, flags, x, y);
|
||||
rdp_send_client_fastpath_input_pdu(input->rdp, s);
|
||||
fastpath_send_input_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
void input_send_fastpath_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)input->rdp;
|
||||
STREAM* s;
|
||||
s = rdp_client_fastpath_input_pdu_init(input->rdp, 0, FASTPATH_INPUT_EVENT_MOUSEX);
|
||||
|
||||
s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_MOUSEX);
|
||||
input_write_extended_mouse_event(s, flags, x, y);
|
||||
rdp_send_client_fastpath_input_pdu(input->rdp, s);
|
||||
fastpath_send_input_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
void input_register_client_callbacks(rdpInput* input)
|
||||
|
@ -35,17 +35,6 @@
|
||||
#define INPUT_EVENT_MOUSE 0x8001
|
||||
#define INPUT_EVENT_MOUSEX 0x8002
|
||||
|
||||
/* FastPath Input Events */
|
||||
#define FASTPATH_INPUT_EVENT_SCANCODE 0x0
|
||||
#define FASTPATH_INPUT_EVENT_MOUSE 0x1
|
||||
#define FASTPATH_INPUT_EVENT_MOUSEX 0x2
|
||||
#define FASTPATH_INPUT_EVENT_SYNC 0x3
|
||||
#define FASTPATH_INPUT_EVENT_UNICODE 0x4
|
||||
|
||||
/* FastPath Keyboard Event Flags */
|
||||
#define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01
|
||||
#define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02
|
||||
|
||||
#define RDP_CLIENT_INPUT_PDU_HEADER_LENGTH 4
|
||||
|
||||
void input_send_synchronize_event(rdpInput* input, uint32 flags);
|
||||
|
@ -137,7 +137,19 @@ static boolean peer_recv_tpkt_pdu(rdpPeer* peer, STREAM* s)
|
||||
|
||||
static boolean peer_recv_fastpath_pdu(rdpPeer* peer, STREAM* s)
|
||||
{
|
||||
return True;
|
||||
uint16 length;
|
||||
|
||||
length = fastpath_read_header(peer->rdp->fastpath, s);
|
||||
if (length == 0 || length > stream_get_size(s))
|
||||
{
|
||||
printf("incorrect FastPath PDU header length %d\n", length);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!fastpath_read_security_header(peer->rdp->fastpath, s))
|
||||
return False;
|
||||
|
||||
return fastpath_recv_inputs(peer->rdp->fastpath, s);
|
||||
}
|
||||
|
||||
static boolean peer_recv_pdu(rdpPeer* peer, STREAM* s)
|
||||
|
@ -45,13 +45,16 @@ boolean test_peer_post_connect(freerdp_peer* client)
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("Client requested desktop: %dx%dx%d\n",
|
||||
client->settings->width, client->settings->height, client->settings->color_depth);
|
||||
|
||||
/* Return False here would stop the execution of the peer mainloop. */
|
||||
return True;
|
||||
}
|
||||
|
||||
void test_peer_synchronize_event(rdpInput* input, uint32 flags)
|
||||
{
|
||||
printf("Client sent a synchronize event\n");
|
||||
printf("Client sent a synchronize event (flags:0x%X)\n", flags);
|
||||
}
|
||||
|
||||
void test_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
|
||||
|
Loading…
Reference in New Issue
Block a user