[core] added relative mouse event support

This commit is contained in:
akallabeth 2023-10-12 13:43:00 +02:00 committed by akallabeth
parent 1f7bc15bb1
commit 20e15ac326
5 changed files with 181 additions and 2 deletions

View File

@ -75,6 +75,8 @@ extern "C"
typedef BOOL (*pKeyboardEvent)(rdpInput* input, UINT16 flags, UINT8 code);
typedef BOOL (*pUnicodeKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code);
typedef BOOL (*pMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
typedef BOOL (*pRelMouseEvent)(rdpInput* input, UINT16 flags, INT16 xDelta, INT16 yDelta);
typedef BOOL (*pQoEEvent)(rdpInput* input, UINT32 timestampMS);
typedef BOOL (*pExtendedMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
typedef BOOL (*pFocusInEvent)(rdpInput* input, UINT16 toggleStates);
typedef BOOL (*pKeyboardPauseEvent)(rdpInput* input);
@ -92,8 +94,10 @@ extern "C"
pExtendedMouseEvent ExtendedMouseEvent; /* 20 */
pFocusInEvent FocusInEvent; /*21 */
pKeyboardPauseEvent KeyboardPauseEvent; /* 22 */
pRelMouseEvent RelMouseEvent; /* 23 */
pQoEEvent QoEEvent; /* 24 */
UINT32 paddingB[32 - 23]; /* 23 */
UINT32 paddingB[32 - 25]; /* 25 */
};
FREERDP_API BOOL freerdp_input_send_synchronize_event(rdpInput* input, UINT32 flags);
@ -105,6 +109,8 @@ extern "C"
UINT16 code);
FREERDP_API BOOL freerdp_input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x,
UINT16 y);
FREERDP_API BOOL freerdp_input_send_rel_mouse_event(rdpInput* input, UINT16 flags, INT16 xDelta,
INT16 yDelta);
FREERDP_API BOOL freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags,
UINT16 x, UINT16 y);
FREERDP_API BOOL freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates);

View File

@ -99,6 +99,7 @@
#define INPUT_FLAG_FASTPATH_INPUT 0x0008
#define INPUT_FLAG_UNICODE 0x0010
#define INPUT_FLAG_FASTPATH_INPUT2 0x0020
#define INPUT_FLAG_MOUSE_RELATIVE 0x0080
#define TS_INPUT_FLAG_MOUSE_HWHEEL 0x0100
#define TS_INPUT_FLAG_QOE_TIMESTAMPS 0x0200

View File

@ -727,6 +727,39 @@ static BOOL fastpath_recv_input_event_mouse(rdpFastPath* fastpath, wStream* s, B
return IFCALLRESULT(TRUE, input->MouseEvent, input, pointerFlags, xPos, yPos);
}
static BOOL fastpath_recv_input_event_relmouse(rdpFastPath* fastpath, wStream* s, BYTE eventFlags)
{
rdpInput* input;
UINT16 pointerFlags;
INT16 xDelta;
INT16 yDelta;
WINPR_ASSERT(fastpath);
WINPR_ASSERT(fastpath->rdp);
WINPR_ASSERT(fastpath->rdp->context);
WINPR_ASSERT(fastpath->rdp->input);
WINPR_ASSERT(s);
if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
return FALSE;
input = fastpath->rdp->input;
Stream_Read_UINT16(s, pointerFlags); /* pointerFlags (2 bytes) */
Stream_Read_INT16(s, xDelta); /* xDelta (2 bytes) */
Stream_Read_INT16(s, yDelta); /* yDelta (2 bytes) */
if (!freerdp_settings_get_bool(input->context->settings, FreeRDP_HasRelativeMouseEvent))
{
WLog_ERR(TAG,
"Received relative mouse event(flags=0x%04" PRIx16 ", xPos=%" PRId16
", yPos=%" PRId16 "), but we did not announce support for that",
pointerFlags, xDelta, yDelta);
return FALSE;
}
return IFCALLRESULT(TRUE, input->RelMouseEvent, input, pointerFlags, xDelta, yDelta);
}
static BOOL fastpath_recv_input_event_mousex(rdpFastPath* fastpath, wStream* s, BYTE eventFlags)
{
rdpInput* input;
@ -736,6 +769,7 @@ static BOOL fastpath_recv_input_event_mousex(rdpFastPath* fastpath, wStream* s,
WINPR_ASSERT(fastpath);
WINPR_ASSERT(fastpath->rdp);
WINPR_ASSERT(fastpath->rdp->context);
WINPR_ASSERT(fastpath->rdp->input);
WINPR_ASSERT(s);
@ -747,6 +781,16 @@ static BOOL fastpath_recv_input_event_mousex(rdpFastPath* fastpath, wStream* s,
Stream_Read_UINT16(s, pointerFlags); /* pointerFlags (2 bytes) */
Stream_Read_UINT16(s, xPos); /* xPos (2 bytes) */
Stream_Read_UINT16(s, yPos); /* yPos (2 bytes) */
if (!freerdp_settings_get_bool(input->context->settings, FreeRDP_HasExtendedMouseEvent))
{
WLog_ERR(TAG,
"Received extended mouse event(flags=0x%04" PRIx16 ", xPos=%" PRIu16
", yPos=%" PRIu16 "), but we did not announce support for that",
pointerFlags, xPos, yPos);
return FALSE;
}
return IFCALLRESULT(TRUE, input->ExtendedMouseEvent, input, pointerFlags, xPos, yPos);
}
@ -830,6 +874,12 @@ static BOOL fastpath_recv_input_event(rdpFastPath* fastpath, wStream* s)
break;
case TS_FP_RELPOINTER_EVENT:
if (!fastpath_recv_input_event_relmouse(fastpath, s, eventFlags))
return FALSE;
break;
default:
WLog_ERR(TAG, "Unknown eventCode %" PRIu8 "", eventCode);
break;

View File

@ -91,7 +91,8 @@ enum FASTPATH_INPUT_EVENT_CODE
FASTPATH_INPUT_EVENT_MOUSE = 0x1,
FASTPATH_INPUT_EVENT_MOUSEX = 0x2,
FASTPATH_INPUT_EVENT_SYNC = 0x3,
FASTPATH_INPUT_EVENT_UNICODE = 0x4
FASTPATH_INPUT_EVENT_UNICODE = 0x4,
TS_FP_RELPOINTER_EVENT = 0x5
};
/* FastPath Keyboard Event Flags */

View File

@ -37,6 +37,7 @@
#define INPUT_EVENT_UNICODE 0x0005
#define INPUT_EVENT_MOUSE 0x8001
#define INPUT_EVENT_MOUSEX 0x8002
#define INPUT_EVENT_MOUSEREL 0x8004
#define RDP_CLIENT_INPUT_PDU_HEADER_LENGTH 4
@ -222,6 +223,37 @@ static BOOL input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT
return rdp_send_client_input_pdu(rdp, s);
}
static BOOL input_send_relmouse_event(rdpInput* input, UINT16 flags, INT16 xDelta, INT16 yDelta)
{
wStream* s;
rdpRdp* rdp;
if (!input || !input->context || !input->context->settings)
return FALSE;
rdp = input->context->rdp;
if (!input_ensure_client_running(input))
return FALSE;
if (!freerdp_settings_get_bool(input->context->settings, FreeRDP_HasRelativeMouseEvent))
{
WLog_ERR(TAG, "Sending relative mouse event, but no support for that");
return FALSE;
}
s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_MOUSEREL);
if (!s)
return FALSE;
Stream_Write_UINT16(s, flags); /* pointerFlags (2 bytes) */
Stream_Write_INT16(s, xDelta); /* xDelta (2 bytes) */
Stream_Write_INT16(s, yDelta); /* yDelta (2 bytes) */
return rdp_send_client_input_pdu(rdp, s);
}
static void input_write_extended_mouse_event(wStream* s, UINT16 flags, UINT16 x, UINT16 y)
{
Stream_Write_UINT16(s, flags); /* pointerFlags (2 bytes) */
@ -454,6 +486,39 @@ static BOOL input_send_fastpath_extended_mouse_event(rdpInput* input, UINT16 fla
return fastpath_send_input_pdu(rdp->fastpath, s);
}
static BOOL input_send_fastpath_relmouse_event(rdpInput* input, UINT16 flags, UINT16 xDelta,
UINT16 yDelta)
{
wStream* s;
rdpRdp* rdp;
WINPR_ASSERT(input);
WINPR_ASSERT(input->context);
WINPR_ASSERT(input->context->settings);
rdp = input->context->rdp;
WINPR_ASSERT(rdp);
if (!input_ensure_client_running(input))
return FALSE;
if (!freerdp_settings_get_bool(input->context->settings, FreeRDP_HasRelativeMouseEvent))
{
WLog_ERR(TAG, "Sending relative fastpath mouse event, but no support for that announced");
return FALSE;
}
s = fastpath_input_pdu_init(rdp->fastpath, 0, TS_FP_RELPOINTER_EVENT);
if (!s)
return FALSE;
Stream_Write_UINT16(s, flags); /* pointerFlags (2 bytes) */
Stream_Write_INT16(s, xDelta); /* xDelta (2 bytes) */
Stream_Write_INT16(s, yDelta); /* yDelta (2 bytes) */
return fastpath_send_input_pdu(rdp->fastpath, s);
}
static BOOL input_send_fastpath_focus_in_event(rdpInput* input, UINT16 toggleStates)
{
wStream* s;
@ -607,6 +672,33 @@ static BOOL input_recv_mouse_event(rdpInput* input, wStream* s)
return IFCALLRESULT(TRUE, input->MouseEvent, input, pointerFlags, xPos, yPos);
}
static BOOL input_recv_relmouse_event(rdpInput* input, wStream* s)
{
UINT16 pointerFlags;
INT16 xDelta, yDelta;
WINPR_ASSERT(input);
WINPR_ASSERT(s);
if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
return FALSE;
Stream_Read_UINT16(s, pointerFlags); /* pointerFlags (2 bytes) */
Stream_Read_INT16(s, xDelta); /* xPos (2 bytes) */
Stream_Read_INT16(s, yDelta); /* yPos (2 bytes) */
if (!freerdp_settings_get_bool(input->context->settings, FreeRDP_HasRelativeMouseEvent))
{
WLog_ERR(TAG,
"Received relative mouse event(flags=0x%04" PRIx16 ", xPos=%" PRId16
", yPos=%" PRId16 "), but we did not announce support for that",
pointerFlags, xDelta, yDelta);
return FALSE;
}
return IFCALLRESULT(TRUE, input->RelMouseEvent, input, pointerFlags, xDelta, yDelta);
}
static BOOL input_recv_extended_mouse_event(rdpInput* input, wStream* s)
{
UINT16 pointerFlags, xPos, yPos;
@ -620,6 +712,16 @@ static BOOL input_recv_extended_mouse_event(rdpInput* input, wStream* s)
Stream_Read_UINT16(s, pointerFlags); /* pointerFlags (2 bytes) */
Stream_Read_UINT16(s, xPos); /* xPos (2 bytes) */
Stream_Read_UINT16(s, yPos); /* yPos (2 bytes) */
if (!freerdp_settings_get_bool(input->context->settings, FreeRDP_HasExtendedMouseEvent))
{
WLog_ERR(TAG,
"Received extended mouse event(flags=0x%04" PRIx16 ", xPos=%" PRIu16
", yPos=%" PRIu16 "), but we did not announce support for that",
pointerFlags, xPos, yPos);
return FALSE;
}
return IFCALLRESULT(TRUE, input->ExtendedMouseEvent, input, pointerFlags, xPos, yPos);
}
@ -668,6 +770,12 @@ static BOOL input_recv_event(rdpInput* input, wStream* s)
break;
case INPUT_EVENT_MOUSEREL:
if (!input_recv_relmouse_event(input, s))
return FALSE;
break;
default:
WLog_ERR(TAG, "Unknown messageType %" PRIu16 "", messageType);
/* Each input event uses 6 bytes. */
@ -723,6 +831,7 @@ BOOL input_register_client_callbacks(rdpInput* input)
input->KeyboardPauseEvent = input_send_fastpath_keyboard_pause_event;
input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event;
input->MouseEvent = input_send_fastpath_mouse_event;
input->RelMouseEvent = input_send_fastpath_relmouse_event;
input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event;
input->FocusInEvent = input_send_fastpath_focus_in_event;
}
@ -733,6 +842,7 @@ BOOL input_register_client_callbacks(rdpInput* input)
input->KeyboardPauseEvent = input_send_keyboard_pause_event;
input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event;
input->MouseEvent = input_send_mouse_event;
input->RelMouseEvent = input_send_relmouse_event;
input->ExtendedMouseEvent = input_send_extended_mouse_event;
input->FocusInEvent = input_send_focus_in_event;
}
@ -796,6 +906,17 @@ BOOL freerdp_input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UIN
return IFCALLRESULT(TRUE, input->MouseEvent, input, flags, x, y);
}
BOOL freerdp_input_send_rel_mouse_event(rdpInput* input, UINT16 flags, INT16 xDelta, INT16 yDelta)
{
if (!input || !input->context)
return FALSE;
if (freerdp_settings_get_bool(input->context->settings, FreeRDP_SuspendInput))
return TRUE;
return IFCALLRESULT(TRUE, input->RelMouseEvent, input, flags, xDelta, yDelta);
}
BOOL freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
if (!input || !input->context)