server: process client input events.

This commit is contained in:
Vic Lee 2011-08-23 15:51:51 +08:00
parent 719f521a39
commit 2d4f10038e
6 changed files with 243 additions and 42 deletions

View File

@ -52,7 +52,10 @@ uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s)
stream_read_uint8(s, header); stream_read_uint8(s, header);
if (fastpath != NULL) if (fastpath != NULL)
{
fastpath->encryptionFlags = (header & 0xC0) >> 6; fastpath->encryptionFlags = (header & 0xC0) >> 6;
fastpath->numberEvents = (header & 0x3C) >> 2;
}
stream_read_uint8(s, length); /* length1 */ stream_read_uint8(s, length); /* length1 */
/* If most significant bit is not set, length2 is not presented. */ /* 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; 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; return True;
} }
@ -320,7 +483,7 @@ STREAM* fastpath_pdu_init(rdpFastPath* fastpath)
return s; return s;
} }
void fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents) boolean fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
{ {
int length; int length;
@ -328,7 +491,7 @@ void fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
if (length > 127) if (length > 127)
{ {
printf("Maximum FastPath PDU length is 127\n"); printf("Maximum FastPath PDU length is 127\n");
return; return False;
} }
stream_set_pos(s, 0); 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_write_uint8(s, length);
stream_set_pos(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) rdpFastPath* fastpath_new(rdpRdp* rdp)

View File

@ -72,20 +72,41 @@ enum FASTPATH_OUTPUT_COMPRESSION
FASTPATH_OUTPUT_COMPRESSION_USED = 0x2 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 struct rdp_fastpath
{ {
rdpRdp* rdp; rdpRdp* rdp;
uint8 encryptionFlags; uint8 encryptionFlags;
uint8 numberEvents;
STREAM* updateData; STREAM* updateData;
}; };
uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s); uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s);
boolean fastpath_read_security_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_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); 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); rdpFastPath* fastpath_new(rdpRdp* rdp);
void fastpath_free(rdpFastPath* fastpath); void fastpath_free(rdpFastPath* fastpath);

View File

@ -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); 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) void input_send_fastpath_synchronize_event(rdpInput* input, uint32 flags)
{ {
rdpRdp* rdp = (rdpRdp*)input->rdp;
STREAM* s; STREAM* s;
/* The FastPath Synchronization eventFlags has identical values as SlowPath */ /* The FastPath Synchronization eventFlags has identical values as SlowPath */
s = rdp_client_fastpath_input_pdu_init(input->rdp, (uint8)flags, FASTPATH_INPUT_EVENT_SYNC); s = fastpath_input_pdu_init(rdp->fastpath, (uint8)flags, FASTPATH_INPUT_EVENT_SYNC);
rdp_send_client_fastpath_input_pdu(input->rdp, s); fastpath_send_input_pdu(rdp->fastpath, s);
} }
void input_send_fastpath_keyboard_event(rdpInput* input, uint16 flags, uint16 code) void input_send_fastpath_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
{ {
rdpRdp* rdp = (rdpRdp*)input->rdp;
STREAM* s; STREAM* s;
uint8 eventFlags = 0; uint8 eventFlags = 0;
eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0; eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0;
eventFlags |= (flags & KBD_FLAGS_EXTENDED) ? FASTPATH_INPUT_KBDFLAGS_EXTENDED : 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) */ 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) void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 code)
{ {
rdpRdp* rdp = (rdpRdp*)input->rdp;
STREAM* s; 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) */ 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) void input_send_fastpath_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
{ {
rdpRdp* rdp = (rdpRdp*)input->rdp;
STREAM* s; 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); 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) void input_send_fastpath_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
{ {
rdpRdp* rdp = (rdpRdp*)input->rdp;
STREAM* s; 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); 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) void input_register_client_callbacks(rdpInput* input)

View File

@ -35,17 +35,6 @@
#define INPUT_EVENT_MOUSE 0x8001 #define INPUT_EVENT_MOUSE 0x8001
#define INPUT_EVENT_MOUSEX 0x8002 #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 #define RDP_CLIENT_INPUT_PDU_HEADER_LENGTH 4
void input_send_synchronize_event(rdpInput* input, uint32 flags); void input_send_synchronize_event(rdpInput* input, uint32 flags);

View File

@ -137,7 +137,19 @@ static boolean peer_recv_tpkt_pdu(rdpPeer* peer, STREAM* s)
static boolean peer_recv_fastpath_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) static boolean peer_recv_pdu(rdpPeer* peer, STREAM* s)

View File

@ -45,13 +45,16 @@ boolean test_peer_post_connect(freerdp_peer* client)
} }
printf("\n"); 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 False here would stop the execution of the peer mainloop. */
return True; return True;
} }
void test_peer_synchronize_event(rdpInput* input, uint32 flags) 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) void test_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)