diff --git a/common/ms-rdpbcgr.h b/common/ms-rdpbcgr.h index 4538483231..6c1b998761 100644 --- a/common/ms-rdpbcgr.h +++ b/common/ms-rdpbcgr.h @@ -471,6 +471,7 @@ #define RDP_INPUT_UNICODE 5 #define RDP_INPUT_MOUSE 0x8001 #define RDP_INPUT_MOUSEX 0x8002 +#define RDP_INPUT_MOUSEREL 0x8004 /* Keyboard Event: keyboardFlags (2.2.8.1.1.3.1.1.1) */ /* TODO: to be renamed */ @@ -512,6 +513,7 @@ #define FASTPATH_INPUT_EVENT_MOUSEX 0x2 #define FASTPATH_INPUT_EVENT_SYNC 0x3 #define FASTPATH_INPUT_EVENT_UNICODE 0x4 +#define FASTPATH_INPUT_EVENT_MOUSEREL 0x5 #define FASTPATH_INPUT_EVENT_QOE_TIMESTAMP 0x6 /* Fast-Path Keyboard Event: eventHeader (2.2.8.1.2.2.1) */ diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h index 9cefbcbcbc..282baf0a6e 100644 --- a/common/xrdp_constants.h +++ b/common/xrdp_constants.h @@ -254,29 +254,30 @@ #define TOUCH_TWO_FINGERS_RIGHT 3 /* messages */ -#define WM_PAINT 3 -#define WM_KEYDOWN 15 -#define WM_KEYUP 16 -#define WM_KEYBRD_SYNC 17 -#define WM_MOUSEMOVE 100 -#define WM_LBUTTONUP 101 -#define WM_LBUTTONDOWN 102 -#define WM_RBUTTONUP 103 -#define WM_RBUTTONDOWN 104 -#define WM_BUTTON3UP 105 -#define WM_BUTTON3DOWN 106 -#define WM_BUTTON4UP 107 -#define WM_BUTTON4DOWN 108 -#define WM_BUTTON5UP 109 -#define WM_BUTTON5DOWN 110 -#define WM_BUTTON6UP 111 -#define WM_BUTTON6DOWN 112 -#define WM_BUTTON7UP 113 -#define WM_BUTTON7DOWN 114 -#define WM_BUTTON8UP 115 -#define WM_BUTTON8DOWN 116 -#define WM_BUTTON9UP 117 -#define WM_BUTTON9DOWN 118 +#define WM_PAINT 3 +#define WM_KEYDOWN 15 +#define WM_KEYUP 16 +#define WM_KEYBRD_SYNC 17 +#define WM_MOUSEMOVE 100 +#define WM_LBUTTONUP 101 +#define WM_LBUTTONDOWN 102 +#define WM_RBUTTONUP 103 +#define WM_RBUTTONDOWN 104 +#define WM_BUTTON3UP 105 +#define WM_BUTTON3DOWN 106 +#define WM_BUTTON4UP 107 +#define WM_BUTTON4DOWN 108 +#define WM_BUTTON5UP 109 +#define WM_BUTTON5DOWN 110 +#define WM_BUTTON6UP 111 +#define WM_BUTTON6DOWN 112 +#define WM_BUTTON7UP 113 +#define WM_BUTTON7DOWN 114 +#define WM_BUTTON8UP 115 +#define WM_BUTTON8DOWN 116 +#define WM_BUTTON9UP 117 +#define WM_BUTTON9DOWN 118 +#define WM_MOUSERELMOVE 119 #define WM_TOUCH_VSCROLL 140 #define WM_TOUCH_HSCROLL 141 diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index 325bee618c..5f3e3c1404 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -123,7 +123,8 @@ xrdp_fastpath_session_callback(struct xrdp_fastpath *self, int msg, RDP_INPUT_SYNCHRONIZE - 0 RDP_INPUT_SCANCODE - 4 RDP_INPUT_MOUSE - 0x8001 - RDP_INPUT_MOUSEX - 0x8002 */ + RDP_INPUT_MOUSEX - 0x8002 + RDP_INPUT_MOUSEREL - 0x8004 */ /* call to xrdp_wm.c : callback */ self->session->callback(self->session->id, msg, param1, param2, param3, param4); @@ -319,6 +320,39 @@ xrdp_fastpath_process_EVENT_UNICODE(struct xrdp_fastpath *self, return 0; } +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT_MOUSEREL */ +static int +xrdp_fastpath_process_EVENT_MOUSEREL(struct xrdp_fastpath *self, + int eventFlags, struct stream *s) +{ + int pointerFlags; + int xDelta; + int yDelta; + + /* eventFlags MUST be zeroed out */ + if (eventFlags != 0) + { + return 1; + } + + if (!s_check_rem_and_log(s, 2 + 2 + 2, "Parsing [MS-RDPBCGR] TS_FP_RELPOINTER_EVENT")) + { + return 1; + } + in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ + in_sint16_le(s, xDelta); /* xDelta (2 bytes) */ + in_sint16_le(s, yDelta); /* yDelta (2 bytes) */ + LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_RELPOINTER_EVENT " + "eventHeader.eventFlags 0x00, eventHeader.eventCode (ignored), " + "pointerFlags 0x%4.4x, xDelta %d, yDelta %d", pointerFlags, xDelta, yDelta); + + xrdp_fastpath_session_callback(self, RDP_INPUT_MOUSEREL, + xDelta, yDelta, pointerFlags, 0); + + return 0; +} + /*****************************************************************************/ /* FASTPATH_INPUT_EVENT */ int @@ -387,6 +421,14 @@ xrdp_fastpath_process_input_event(struct xrdp_fastpath *self, return 1; } break; + case FASTPATH_INPUT_EVENT_MOUSEREL: + if (xrdp_fastpath_process_EVENT_MOUSEREL(self, + eventFlags, + s) != 0) + { + return 1; + } + break; default: LOG(LOG_LEVEL_ERROR, "xrdp_fastpath_process_input_event: " "unknown eventCode %d", eventCode); diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index deefd7a1f1..70f8403047 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -1046,6 +1046,11 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s) "pointerFlags 0x%4.4x, xPos %d, yPos %d", device_flags, param1, param2); break; + case RDP_INPUT_MOUSEREL: + LOG_DEVEL(LOG_LEVEL_TRACE, "With field [MS-RDPBCGR] TS_INPUT_EVENT - TS_RELPOINTER_EVENT " + "pointerFlags 0x%4.4x, xDelta %d, yDelta %d", + device_flags, param1, param2); + break; default: LOG_DEVEL(LOG_LEVEL_WARNING, "Received unknown [MS-RDPBCGR] TS_INPUT_EVENT " "messageType 0x%4.4x", msg_type); @@ -1058,7 +1063,8 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s) RDP_INPUT_SYNCHRONIZE - 0 RDP_INPUT_SCANCODE - 4 RDP_INPUT_MOUSE - 0x8001 - RDP_INPUT_MOUSEX - 0x8002 */ + RDP_INPUT_MOUSEX - 0x8002 + RDP_INPUT_MOUSEREL - 0x8004 */ /* call to xrdp_wm.c : callback */ self->session->callback(self->session->id, msg_type, param1, param2, device_flags, time); diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 91a262179c..3f4cdfe2b2 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -144,6 +144,8 @@ xrdp_wm_get_vis_region(struct xrdp_wm *self, struct xrdp_bitmap *bitmap, int xrdp_wm_mouse_move(struct xrdp_wm *self, int x, int y); int +xrdp_wm_mouse_relative_move(struct xrdp_wm *self, int xDelta, int yDelta); +int xrdp_wm_mouse_touch(struct xrdp_wm *self, int gesture, int param); int xrdp_wm_mouse_click(struct xrdp_wm *self, int x, int y, int but, int down); diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 3038da3fe4..7904d16cb1 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -1244,6 +1244,26 @@ xrdp_wm_mouse_move(struct xrdp_wm *self, int x, int y) return 0; } +/*****************************************************************************/ +int +xrdp_wm_mouse_relative_move(struct xrdp_wm *self, int xDelta, int yDelta) +{ + if (self == 0) + { + return 0; + } + + if (self->mm->mod != 0) /* if screen is mod controlled */ + { + if (self->mm->mod->mod_event != 0) + { + self->mm->mod->mod_event(self->mm->mod, WM_MOUSERELMOVE, xDelta, yDelta, 0, 0); + } + } + + return 0; +} + /*****************************************************************************/ static int xrdp_wm_clear_popup(struct xrdp_wm *self) @@ -1851,14 +1871,21 @@ xrdp_wm_pu(struct xrdp_wm *self, struct xrdp_bitmap *control) /*****************************************************************************/ static int -xrdp_wm_process_input_mouse(struct xrdp_wm *self, int device_flags, - int x, int y) +xrdp_wm_process_input_mouse_common(struct xrdp_wm *self, int device_flags, + int absolute, int x, int y) { LOG_DEVEL(LOG_LEVEL_TRACE, "mouse event flags %4.4x x %d y %d", device_flags, x, y); if (device_flags & PTRFLAGS_MOVE) { - xrdp_wm_mouse_move(self, x, y); + if (absolute) + { + xrdp_wm_mouse_move(self, x, y); + } + else + { + xrdp_wm_mouse_relative_move(self, x, y); + } } if (device_flags & PTRFLAGS_BUTTON1) @@ -1987,6 +2014,14 @@ xrdp_wm_process_input_mouse(struct xrdp_wm *self, int device_flags, return 0; } +/*****************************************************************************/ +static int +xrdp_wm_process_input_mouse(struct xrdp_wm *self, int device_flags, + int x, int y) +{ + return xrdp_wm_process_input_mouse_common(self, device_flags, 1, x, y); +} + /*****************************************************************************/ static int xrdp_wm_process_input_mousex(struct xrdp_wm *self, int device_flags, @@ -2017,6 +2052,14 @@ xrdp_wm_process_input_mousex(struct xrdp_wm *self, int device_flags, return 0; } +/*****************************************************************************/ +static int +xrdp_wm_process_input_mouserel(struct xrdp_wm *self, int device_flags, + int xDelta, int yDelta) +{ + return xrdp_wm_process_input_mouse_common(self, device_flags, 0, xDelta, yDelta); +} + /******************************************************************************/ /* param1 = MAKELONG(channel_id, flags) param2 = size @@ -2091,6 +2134,9 @@ callback(intptr_t id, int msg, intptr_t param1, intptr_t param2, case RDP_INPUT_MOUSEX: rv = xrdp_wm_process_input_mousex(wm, param3, param1, param2); break; + case RDP_INPUT_MOUSEREL: + rv = xrdp_wm_process_input_mouserel(wm, param3, param1, param2); + break; case 0x4444: /* invalidate, this is not from RDP_DATA_PDU_INPUT */ /* like the rest, it's from RDP_PDU_DATA with code 33 */ /* it's the rdp client asking for a screen update */