From 80204e2536327f46610d5925c552aff235e9f447 Mon Sep 17 00:00:00 2001 From: speidy Date: Tue, 11 Feb 2014 00:28:43 +0200 Subject: [PATCH] libxrdp: work on fastpath input, added fastpath option to xrdp.ini --- common/xrdp_constants.h | 1 + libxrdp/xrdp_fastpath.c | 8 ++-- libxrdp/xrdp_iso.c | 3 +- libxrdp/xrdp_mcs.c | 2 +- libxrdp/xrdp_rdp.c | 88 +++++++++++++++++++++++++++++++++++++---- libxrdp/xrdp_sec.c | 2 +- xrdp/xrdp.ini | 3 ++ 7 files changed, 92 insertions(+), 15 deletions(-) diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h index 0dc327df..d3f20a46 100644 --- a/common/xrdp_constants.h +++ b/common/xrdp_constants.h @@ -161,6 +161,7 @@ #define RDP_INPUT_VIRTKEY 2 #define RDP_INPUT_SCANCODE 4 #define RDP_INPUT_MOUSE 0x8001 +#define RDP_INPUT_MOUSEX 0x8002 /* Device flags */ #define KBD_FLAG_RIGHT 0x0001 diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index 71e7f7c6..fcd7ac72 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -58,7 +58,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) int fp_hdr; int len = 0; int byte; - int hdr_len = 2; + int hdr_len = 2; /* fastpath header lenght - can be 2 or 3 bytes long, depends on length */ DEBUG((" in xrdp_fastpath_recv")); /* read the first fastpath byte @@ -68,7 +68,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) self->numEvents = (fp_hdr & 0x3C) >> 2; self->secFlags = (fp_hdr & 0xC0) >> 6; - // receive fastpath first packet length + // receive fastpath first length packet if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) { return 1; @@ -80,7 +80,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) { byte &= ~(0x80); len = (byte << 8); - // receive fastpath second packet length + // receive fastpath second length packet if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) { return 1; @@ -94,7 +94,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) len = byte; } - g_writeln("len= %d , numEvents= %d, secFlags= %d, bytesleft: %d", len, self->numEvents, self->secFlags, (s->p - s->data)); + //g_writeln("len= %d , numEvents= %d, secFlags= %d, bytesleft: %d", len, self->numEvents, self->secFlags, (s->p - s->data)); // receive the left bytes if (xrdp_tcp_recv(self->tcp_layer, s, len - hdr_len) != 0) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index f29cbf23..1f546b0b 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -98,7 +98,7 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len) if (plen == 2) { - DEBUG((" xrdp_iso_recv_msg: non-TPKT header detected, we try fastpath")); + DEBUG(("xrdp_iso_recv_msg: non-TPKT header detected, we try fastpath")); return plen; } @@ -164,7 +164,6 @@ xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s) } in_uint8_peek(s, ver); // Peek only so we can use it later in fastpath layer, if needed - g_writeln(" tpkt version: %x", ver); // TODO: delete it if (ver != 3) { diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 81e8b758..2c643373 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -132,7 +132,7 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan) if (iso_msg == 2) // non-TPKT header { - DEBUG((" out xrdp_mcs_recv, non-TPKT header detected, we try fastpath")); + DEBUG((" out xrdp_mcs_recv, non-TPKT header detected, we try fastpath")); return iso_msg; } diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 226b1b52..a98d507e 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -118,6 +118,31 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info) { client_info->require_credentials = g_text2bool(value); } + else if (g_strcasecmp(item, "use_fastpath") == 0) + { + if (g_strcasecmp(value, "output") == 0) + { + client_info->use_fast_path = 1; + } + else if (g_strcasecmp(value, "input") == 0) + { + client_info->use_fast_path = 2; + } + else if (g_strcasecmp(value, "both") == 0) + { + client_info->use_fast_path = 3; + } + else if (g_strcasecmp(value, "none") == 0) + { + client_info->use_fast_path = 0; + } + else + { + log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured fastpath level is" + "undefined, fastpath will not be used"); + client_info->use_fast_path = 0; + } + } } list_delete(items); @@ -778,7 +803,7 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp *self) INPUT_FLAG_FASTPATH_INPUT 0x0008 INPUT_FLAG_FASTPATH_INPUT2 0x0020 */ flags = 0x0001 | 0x0004; -// if (self->client_info.use_fast_path & 2) + if (self->client_info.use_fast_path & 2) flags |= 0x0008 | 0x0020; out_uint16_le(s, flags); out_uint8s(s, 82); @@ -1711,6 +1736,9 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) int flags; int param2; int time; + int pointerFlags; + int xPos; + int yPos; // process fastpath input events for (i = 0 ; i < self->sec_layer->fastpath_layer->numEvents ; i++) { @@ -1718,12 +1746,15 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) eventFlags = (eventHeader & 0x1F); eventCode = (eventHeader >> 5); - g_writeln("eventCode= %d, eventFlags= %d, numEvents= %d", eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents); + + //g_writeln("eventCode= %d, eventFlags= %d, numEvents= %d", + // eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents); + switch (eventCode) { case FASTPATH_INPUT_EVENT_SCANCODE: in_uint8(s, code); /* keyCode (1 byte) */ - g_writeln("scan code detected: %d", code); + //g_writeln("scan code detected: %d", code); flags = 0; if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) flags |= KBD_FLAG_UP; @@ -1747,15 +1778,58 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) break; case FASTPATH_INPUT_EVENT_MOUSE: - in_uint8s(s, 6); + in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ + in_uint16_le(s, xPos); /* xPos (2 bytes) */ + in_uint16_le(s, yPos); /* yPos (2 bytes) */ + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_MOUSE, xPos, yPos, + pointerFlags, 0); + } break; case FASTPATH_INPUT_EVENT_MOUSEX: - in_uint8s(s, 6); + in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ + in_uint16_le(s, xPos); /* xPos (2 bytes) */ + in_uint16_le(s, yPos); /* yPos (2 bytes) */ + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_MOUSEX, xPos, yPos, + pointerFlags, 0); + } break; case FASTPATH_INPUT_EVENT_SYNC: - + /* + * The eventCode bitfield (3 bits in size) MUST be set to FASTPATH_INPUT_EVENT_SYNC (3). + * The eventFlags bitfield (5 bits in size) contains flags indicating the "on" + * status of the keyboard toggle keys. + */ + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_SYNCHRONIZE, eventCode, 0, + eventFlags, 0); + } break; case FASTPATH_INPUT_EVENT_UNICODE: @@ -1763,7 +1837,7 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) break; default: - printf("Unknown eventCode %d\n", eventCode); + g_writeln("xrdp_rdp_process_fastpath_data_input: unknown eventCode %d", eventCode); break; } diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 4846c356..37209772 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -774,8 +774,8 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan) if (mcs_msg == 2) { - DEBUG((" out xrdp_sec_recv : non-TPKT msg detected, we try fastpath")); xrdp_sec_recv_fastpath(self, s); + DEBUG((" out xrdp_sec_recv : non-TPKT msg detected, we try fastpath")); return mcs_msg; } diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index 0e8d302b..f89e78d9 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -37,6 +37,9 @@ tcp_keepalive=yes #nego_sec_layer=0 allow_multimon=true +# fastpath - can be set to input / output / both / none +use_fastpath=input + [Logging] LogFile=xrdp.log LogLevel=DEBUG