21#include <freerdp/config.h>
24#include <winpr/assert.h>
26#include <freerdp/input.h>
27#include <freerdp/log.h>
33#define TAG FREERDP_TAG("core")
36#define INPUT_EVENT_SYNC 0x0000
37#define INPUT_EVENT_SCANCODE 0x0004
38#define INPUT_EVENT_UNICODE 0x0005
39#define INPUT_EVENT_MOUSE 0x8001
40#define INPUT_EVENT_MOUSEX 0x8002
41#define INPUT_EVENT_MOUSEREL 0x8004
43static void rdp_write_client_input_pdu_header(
wStream* s, UINT16 number)
46 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 4);
47 Stream_Write_UINT16(s, number);
48 Stream_Write_UINT16(s, 0);
51static void rdp_write_input_event_header(
wStream* s, UINT32 time, UINT16 type)
54 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 6);
55 Stream_Write_UINT32(s, time);
56 Stream_Write_UINT16(s, type);
59static wStream* rdp_client_input_pdu_init(rdpRdp* rdp, UINT16 type, UINT16* sec_flags)
61 wStream* s = rdp_data_pdu_init(rdp, sec_flags);
66 rdp_write_client_input_pdu_header(s, 1);
67 rdp_write_input_event_header(s, 0, type);
71static BOOL rdp_send_client_input_pdu(rdpRdp* rdp,
wStream* s, UINT16 sec_flags)
74 WINPR_ASSERT(rdp->mcs);
75 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_INPUT, rdp->mcs->userId, sec_flags);
78static void input_write_synchronize_event(
wStream* s, UINT32 flags)
81 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 6);
82 Stream_Write_UINT16(s, 0);
83 Stream_Write_UINT32(s, flags);
86static BOOL input_ensure_client_running(rdpInput* input)
89 if (freerdp_shall_disconnect_context(input->context))
91 WLog_WARN(TAG,
"[APPLICATION BUG] input functions called after the session terminated");
97static BOOL input_send_synchronize_event(rdpInput* input, UINT32 flags)
101 if (!input || !input->context)
104 rdpRdp* rdp = input->context->rdp;
106 if (!input_ensure_client_running(input))
109 wStream* s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_SYNC, &sec_flags);
114 input_write_synchronize_event(s, flags);
115 return rdp_send_client_input_pdu(rdp, s, sec_flags);
118static void input_write_keyboard_event(
wStream* s, UINT16 flags, UINT16 code)
121 WINPR_ASSERT(code <= UINT8_MAX);
123 Stream_Write_UINT16(s, flags);
124 Stream_Write_UINT16(s, code);
125 Stream_Write_UINT16(s, 0);
128static BOOL input_send_keyboard_event(rdpInput* input, UINT16 flags, UINT8 code)
130 UINT16 sec_flags = 0;
134 if (!input || !input->context)
137 rdp = input->context->rdp;
139 if (!input_ensure_client_running(input))
142 s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_SCANCODE, &sec_flags);
147 input_write_keyboard_event(s, flags, code);
148 return rdp_send_client_input_pdu(rdp, s, sec_flags);
151static void input_write_unicode_keyboard_event(
wStream* s, UINT16 flags, UINT16 code)
153 Stream_Write_UINT16(s, flags);
154 Stream_Write_UINT16(s, code);
155 Stream_Write_UINT16(s, 0);
158static BOOL input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
160 UINT16 sec_flags = 0;
164 if (!input || !input->context)
167 if (!input_ensure_client_running(input))
172 WLog_WARN(TAG,
"Unicode input not supported by server.");
176 rdp = input->context->rdp;
177 s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_UNICODE, &sec_flags);
182 input_write_unicode_keyboard_event(s, flags, code);
183 return rdp_send_client_input_pdu(rdp, s, sec_flags);
186static void input_write_mouse_event(
wStream* s, UINT16 flags, UINT16 x, UINT16 y)
188 Stream_Write_UINT16(s, flags);
189 Stream_Write_UINT16(s, x);
190 Stream_Write_UINT16(s, y);
193static BOOL input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
195 UINT16 sec_flags = 0;
197 if (!input || !input->context || !input->context->settings)
200 rdpRdp* rdp = input->context->rdp;
202 if (!input_ensure_client_running(input))
207 if (flags & PTR_FLAGS_HWHEEL)
210 "skip mouse event %" PRIu16
"x%" PRIu16
" flags=0x%04" PRIX16
211 ", no horizontal mouse wheel supported",
217 wStream* s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_MOUSE, &sec_flags);
222 input_write_mouse_event(s, flags, x, y);
223 return rdp_send_client_input_pdu(rdp, s, sec_flags);
226static BOOL input_send_relmouse_event(rdpInput* input, UINT16 flags, INT16 xDelta, INT16 yDelta)
228 UINT16 sec_flags = 0;
232 if (!input || !input->context || !input->context->settings)
235 rdp = input->context->rdp;
237 if (!input_ensure_client_running(input))
242 WLog_ERR(TAG,
"Sending relative mouse event, but no support for that");
246 s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_MOUSEREL, &sec_flags);
251 Stream_Write_UINT16(s, flags);
252 Stream_Write_INT16(s, xDelta);
253 Stream_Write_INT16(s, yDelta);
255 return rdp_send_client_input_pdu(rdp, s, sec_flags);
258static void input_write_extended_mouse_event(
wStream* s, UINT16 flags, UINT16 x, UINT16 y)
260 Stream_Write_UINT16(s, flags);
261 Stream_Write_UINT16(s, x);
262 Stream_Write_UINT16(s, y);
265static BOOL input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
267 UINT16 sec_flags = 0;
270 WINPR_ASSERT(input->context);
271 WINPR_ASSERT(input->context->settings);
273 rdpRdp* rdp = input->context->rdp;
276 if (!input_ensure_client_running(input))
282 "skip extended mouse event %" PRIu16
"x%" PRIu16
" flags=0x%04" PRIX16
283 ", no extended mouse events supported",
288 wStream* s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_MOUSEX, &sec_flags);
293 input_write_extended_mouse_event(s, flags, x, y);
294 return rdp_send_client_input_pdu(rdp, s, sec_flags);
297static BOOL input_send_focus_in_event(rdpInput* input, UINT16 toggleStates)
300 if (!input_send_keyboard_event(input, KBD_FLAGS_RELEASE, 0x0f))
304 if (!input_send_synchronize_event(input, (toggleStates & 0x1F)))
308 return input_send_keyboard_event(input, KBD_FLAGS_RELEASE, 0x0f);
311static BOOL input_send_keyboard_pause_event(rdpInput* input)
319 if (!input_send_keyboard_event(input, KBD_FLAGS_EXTENDED1,
320 RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL)))
324 if (!input_send_keyboard_event(input, 0, RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK)))
328 if (!input_send_keyboard_event(input, KBD_FLAGS_RELEASE | KBD_FLAGS_EXTENDED1,
329 RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL)))
333 return input_send_keyboard_event(input, KBD_FLAGS_RELEASE,
334 RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK));
337static BOOL input_send_fastpath_synchronize_event(rdpInput* input, UINT32 flags)
339 UINT16 sec_flags = 0;
344 WINPR_ASSERT(input->context);
346 rdp = input->context->rdp;
349 if (!input_ensure_client_running(input))
353 s = fastpath_input_pdu_init(rdp->fastpath, (BYTE)flags, FASTPATH_INPUT_EVENT_SYNC, &sec_flags);
358 return fastpath_send_input_pdu(rdp->fastpath, s, sec_flags);
361static BOOL input_send_fastpath_keyboard_event(rdpInput* input, UINT16 flags, UINT8 code)
363 UINT16 sec_flags = 0;
369 WINPR_ASSERT(input->context);
371 rdp = input->context->rdp;
374 if (!input_ensure_client_running(input))
377 eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0;
378 eventFlags |= (flags & KBD_FLAGS_EXTENDED) ? FASTPATH_INPUT_KBDFLAGS_EXTENDED : 0;
379 eventFlags |= (flags & KBD_FLAGS_EXTENDED1) ? FASTPATH_INPUT_KBDFLAGS_PREFIX_E1 : 0;
380 s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_SCANCODE,
386 WINPR_ASSERT(code <= UINT8_MAX);
387 Stream_Write_UINT8(s, code);
388 return fastpath_send_input_pdu(rdp->fastpath, s, sec_flags);
391static BOOL input_send_fastpath_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
393 UINT16 sec_flags = 0;
399 WINPR_ASSERT(input->context);
400 WINPR_ASSERT(input->context->settings);
402 rdp = input->context->rdp;
405 if (!input_ensure_client_running(input))
410 WLog_WARN(TAG,
"Unicode input not supported by server.");
414 eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0;
415 s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_UNICODE,
421 Stream_Write_UINT16(s, code);
422 return fastpath_send_input_pdu(rdp->fastpath, s, sec_flags);
425static BOOL input_send_fastpath_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
427 UINT16 sec_flags = 0;
432 WINPR_ASSERT(input->context);
433 WINPR_ASSERT(input->context->settings);
435 rdp = input->context->rdp;
438 if (!input_ensure_client_running(input))
443 if (flags & PTR_FLAGS_HWHEEL)
446 "skip mouse event %" PRIu16
"x%" PRIu16
" flags=0x%04" PRIX16
447 ", no horizontal mouse wheel supported",
453 s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_MOUSE, &sec_flags);
458 input_write_mouse_event(s, flags, x, y);
459 return fastpath_send_input_pdu(rdp->fastpath, s, sec_flags);
462static BOOL input_send_fastpath_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x,
465 UINT16 sec_flags = 0;
470 WINPR_ASSERT(input->context);
472 rdp = input->context->rdp;
475 if (!input_ensure_client_running(input))
481 "skip extended mouse event %" PRIu16
"x%" PRIu16
" flags=0x%04" PRIX16
482 ", no extended mouse events supported",
487 s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_MOUSEX, &sec_flags);
492 input_write_extended_mouse_event(s, flags, x, y);
493 return fastpath_send_input_pdu(rdp->fastpath, s, sec_flags);
496static BOOL input_send_fastpath_relmouse_event(rdpInput* input, UINT16 flags, INT16 xDelta,
499 UINT16 sec_flags = 0;
504 WINPR_ASSERT(input->context);
505 WINPR_ASSERT(input->context->settings);
507 rdp = input->context->rdp;
510 if (!input_ensure_client_running(input))
515 WLog_ERR(TAG,
"Sending relative fastpath mouse event, but no support for that announced");
519 s = fastpath_input_pdu_init(rdp->fastpath, 0, TS_FP_RELPOINTER_EVENT, &sec_flags);
524 Stream_Write_UINT16(s, flags);
525 Stream_Write_INT16(s, xDelta);
526 Stream_Write_INT16(s, yDelta);
527 return fastpath_send_input_pdu(rdp->fastpath, s, sec_flags);
530static BOOL input_send_fastpath_qoe_event(rdpInput* input, UINT32 timestampMS)
533 WINPR_ASSERT(input->context);
534 WINPR_ASSERT(input->context->settings);
536 rdpRdp* rdp = input->context->rdp;
539 if (!input_ensure_client_running(input))
544 WLog_ERR(TAG,
"Sending qoe event, but no support for that announced");
548 UINT16 sec_flags = 0;
549 wStream* s = fastpath_input_pdu_init(rdp->fastpath, 0, TS_FP_QOETIMESTAMP_EVENT, &sec_flags);
554 if (!Stream_EnsureRemainingCapacity(s, 4))
556 Stream_Free(s, TRUE);
560 Stream_Write_UINT32(s, timestampMS);
561 return fastpath_send_input_pdu(rdp->fastpath, s, sec_flags);
564static BOOL input_send_fastpath_focus_in_event(rdpInput* input, UINT16 toggleStates)
566 UINT16 sec_flags = 0;
572 WINPR_ASSERT(input->context);
574 rdp = input->context->rdp;
577 if (!input_ensure_client_running(input))
580 s = fastpath_input_pdu_init_header(rdp->fastpath, &sec_flags);
586 eventFlags = FASTPATH_INPUT_KBDFLAGS_RELEASE | FASTPATH_INPUT_EVENT_SCANCODE << 5;
587 Stream_Write_UINT8(s, eventFlags);
588 Stream_Write_UINT8(s, 0x0f);
590 eventFlags = (toggleStates & 0x1F) | FASTPATH_INPUT_EVENT_SYNC << 5;
591 Stream_Write_UINT8(s, eventFlags);
593 eventFlags = FASTPATH_INPUT_KBDFLAGS_RELEASE | FASTPATH_INPUT_EVENT_SCANCODE << 5;
594 Stream_Write_UINT8(s, eventFlags);
595 Stream_Write_UINT8(s, 0x0f);
596 return fastpath_send_multiple_input_pdu(rdp->fastpath, s, 3, sec_flags);
599static BOOL input_send_fastpath_keyboard_pause_event(rdpInput* input)
605 UINT16 sec_flags = 0;
607 const BYTE keyDownEvent = FASTPATH_INPUT_EVENT_SCANCODE << 5;
608 const BYTE keyUpEvent = (FASTPATH_INPUT_EVENT_SCANCODE << 5) | FASTPATH_INPUT_KBDFLAGS_RELEASE;
612 WINPR_ASSERT(input->context);
614 rdp = input->context->rdp;
617 if (!input_ensure_client_running(input))
620 s = fastpath_input_pdu_init_header(rdp->fastpath, &sec_flags);
626 Stream_Write_UINT8(s, keyDownEvent | FASTPATH_INPUT_KBDFLAGS_PREFIX_E1);
627 Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL));
629 Stream_Write_UINT8(s, keyDownEvent);
630 Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK));
632 Stream_Write_UINT8(s, keyUpEvent | FASTPATH_INPUT_KBDFLAGS_PREFIX_E1);
633 Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL));
635 Stream_Write_UINT8(s, keyUpEvent);
636 Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK));
637 return fastpath_send_multiple_input_pdu(rdp->fastpath, s, 4, sec_flags);
640static BOOL input_recv_sync_event(rdpInput* input,
wStream* s)
642 UINT32 toggleFlags = 0;
647 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
651 Stream_Read_UINT32(s, toggleFlags);
652 return IFCALLRESULT(TRUE, input->SynchronizeEvent, input, toggleFlags);
655static BOOL input_recv_keyboard_event(rdpInput* input,
wStream* s)
657 UINT16 keyboardFlags = 0;
663 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
666 Stream_Read_UINT16(s, keyboardFlags);
667 Stream_Read_UINT16(s, keyCode);
670 if (keyboardFlags & KBD_FLAGS_RELEASE)
671 keyboardFlags &= ~KBD_FLAGS_DOWN;
673 if (keyCode & 0xFF00)
675 "Problematic [MS-RDPBCGR] 2.2.8.1.1.3.1.1.1 Keyboard Event (TS_KEYBOARD_EVENT) "
676 "keyCode=0x%04" PRIx16
677 ", high byte values should be sent in keyboardFlags field, ignoring.",
679 return IFCALLRESULT(TRUE, input->KeyboardEvent, input, keyboardFlags, keyCode & 0xFF);
682static BOOL input_recv_unicode_keyboard_event(rdpInput* input,
wStream* s)
684 UINT16 keyboardFlags = 0;
685 UINT16 unicodeCode = 0;
690 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
693 Stream_Read_UINT16(s, keyboardFlags);
694 Stream_Read_UINT16(s, unicodeCode);
699 if (keyboardFlags & KBD_FLAGS_RELEASE)
700 keyboardFlags &= ~KBD_FLAGS_DOWN;
702 return IFCALLRESULT(TRUE, input->UnicodeKeyboardEvent, input, keyboardFlags, unicodeCode);
705static BOOL input_recv_mouse_event(rdpInput* input,
wStream* s)
707 UINT16 pointerFlags = 0;
714 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
717 Stream_Read_UINT16(s, pointerFlags);
718 Stream_Read_UINT16(s, xPos);
719 Stream_Read_UINT16(s, yPos);
720 return IFCALLRESULT(TRUE, input->MouseEvent, input, pointerFlags, xPos, yPos);
723static BOOL input_recv_relmouse_event(rdpInput* input,
wStream* s)
725 UINT16 pointerFlags = 0;
732 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
735 Stream_Read_UINT16(s, pointerFlags);
736 Stream_Read_INT16(s, xDelta);
737 Stream_Read_INT16(s, yDelta);
742 "Received relative mouse event(flags=0x%04" PRIx16
", xPos=%" PRId16
743 ", yPos=%" PRId16
"), but we did not announce support for that",
744 pointerFlags, xDelta, yDelta);
748 return IFCALLRESULT(TRUE, input->RelMouseEvent, input, pointerFlags, xDelta, yDelta);
751static BOOL input_recv_extended_mouse_event(rdpInput* input,
wStream* s)
753 UINT16 pointerFlags = 0;
760 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
763 Stream_Read_UINT16(s, pointerFlags);
764 Stream_Read_UINT16(s, xPos);
765 Stream_Read_UINT16(s, yPos);
770 "Received extended mouse event(flags=0x%04" PRIx16
", xPos=%" PRIu16
771 ", yPos=%" PRIu16
"), but we did not announce support for that",
772 pointerFlags, xPos, yPos);
776 return IFCALLRESULT(TRUE, input->ExtendedMouseEvent, input, pointerFlags, xPos, yPos);
779static BOOL input_recv_event(rdpInput* input,
wStream* s)
781 UINT16 messageType = 0;
786 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
790 Stream_Read_UINT16(s, messageType);
794 case INPUT_EVENT_SYNC:
795 if (!input_recv_sync_event(input, s))
800 case INPUT_EVENT_SCANCODE:
801 if (!input_recv_keyboard_event(input, s))
806 case INPUT_EVENT_UNICODE:
807 if (!input_recv_unicode_keyboard_event(input, s))
812 case INPUT_EVENT_MOUSE:
813 if (!input_recv_mouse_event(input, s))
818 case INPUT_EVENT_MOUSEX:
819 if (!input_recv_extended_mouse_event(input, s))
824 case INPUT_EVENT_MOUSEREL:
825 if (!input_recv_relmouse_event(input, s))
831 WLog_ERR(TAG,
"Unknown messageType %" PRIu16
"", messageType);
840BOOL input_recv(rdpInput* input,
wStream* s)
842 UINT16 numberEvents = 0;
847 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
850 Stream_Read_UINT16(s, numberEvents);
854 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, numberEvents, 6ull))
857 for (UINT16 i = 0; i < numberEvents; i++)
859 if (!input_recv_event(input, s))
866BOOL input_register_client_callbacks(rdpInput* input)
868 rdpSettings* settings = NULL;
873 settings = input->context->settings;
880 input->SynchronizeEvent = input_send_fastpath_synchronize_event;
881 input->KeyboardEvent = input_send_fastpath_keyboard_event;
882 input->KeyboardPauseEvent = input_send_fastpath_keyboard_pause_event;
883 input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event;
884 input->MouseEvent = input_send_fastpath_mouse_event;
885 input->RelMouseEvent = input_send_fastpath_relmouse_event;
886 input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event;
887 input->FocusInEvent = input_send_fastpath_focus_in_event;
888 input->QoEEvent = input_send_fastpath_qoe_event;
892 input->SynchronizeEvent = input_send_synchronize_event;
893 input->KeyboardEvent = input_send_keyboard_event;
894 input->KeyboardPauseEvent = input_send_keyboard_pause_event;
895 input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event;
896 input->MouseEvent = input_send_mouse_event;
897 input->RelMouseEvent = input_send_relmouse_event;
898 input->ExtendedMouseEvent = input_send_extended_mouse_event;
899 input->FocusInEvent = input_send_focus_in_event;
906static BOOL input_update_last_event(rdpInput* input, BOOL mouse, UINT16 x, UINT16 y)
911 WINPR_ASSERT(input->context);
915 const time_t now = time(NULL);
916 in->lastInputTimestamp = WINPR_ASSERTING_INT_CAST(UINT64, now);
927BOOL freerdp_input_send_synchronize_event(rdpInput* input, UINT32 flags)
929 if (!input || !input->context)
935 return IFCALLRESULT(TRUE, input->SynchronizeEvent, input, flags);
938BOOL freerdp_input_send_keyboard_event(rdpInput* input, UINT16 flags, UINT8 code)
940 if (!input || !input->context)
946 input_update_last_event(input, FALSE, 0, 0);
948 return IFCALLRESULT(TRUE, input->KeyboardEvent, input, flags, code);
951BOOL freerdp_input_send_keyboard_event_ex(rdpInput* input, BOOL down, BOOL repeat,
954 UINT16 flags = (RDP_SCANCODE_EXTENDED(rdp_scancode) ? KBD_FLAGS_EXTENDED : 0);
956 flags |= KBD_FLAGS_DOWN;
958 flags |= KBD_FLAGS_RELEASE;
960 return freerdp_input_send_keyboard_event(input, flags, RDP_SCANCODE_CODE(rdp_scancode));
963BOOL freerdp_input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
965 if (!input || !input->context)
971 input_update_last_event(input, FALSE, 0, 0);
973 return IFCALLRESULT(TRUE, input->UnicodeKeyboardEvent, input, flags, code);
976BOOL freerdp_input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
978 if (!input || !input->context)
984 input_update_last_event(
985 input, flags & (PTR_FLAGS_MOVE | PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 | PTR_FLAGS_BUTTON3),
988 return IFCALLRESULT(TRUE, input->MouseEvent, input, flags, x, y);
991BOOL freerdp_input_send_rel_mouse_event(rdpInput* input, UINT16 flags, INT16 xDelta, INT16 yDelta)
993 if (!input || !input->context)
999 return IFCALLRESULT(TRUE, input->RelMouseEvent, input, flags, xDelta, yDelta);
1002BOOL freerdp_input_send_qoe_timestamp(rdpInput* input, UINT32 timestampMS)
1004 if (!input || !input->context)
1007 return IFCALLRESULT(TRUE, input->QoEEvent, input, timestampMS);
1010BOOL freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
1012 if (!input || !input->context)
1018 input_update_last_event(input, TRUE, x, y);
1020 return IFCALLRESULT(TRUE, input->ExtendedMouseEvent, input, flags, x, y);
1023BOOL freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates)
1025 if (!input || !input->context)
1031 return IFCALLRESULT(TRUE, input->FocusInEvent, input, toggleStates);
1034BOOL freerdp_input_send_keyboard_pause_event(rdpInput* input)
1036 if (!input || !input->context)
1042 return IFCALLRESULT(TRUE, input->KeyboardPauseEvent, input);
1045int input_process_events(rdpInput* input)
1050 return input_message_queue_process_pending_messages(input);
1053static void input_free_queued_message(
void* obj)
1055 wMessage* msg = (wMessage*)obj;
1056 input_message_queue_free_message(msg);
1059rdpInput* input_new(rdpRdp* rdp)
1061 const wObject cb = { NULL, NULL, NULL, input_free_queued_message, NULL };
1069 input->common.context = rdp->context;
1070 input->queue = MessageQueue_New(&cb);
1078 return &input->common;
1081void input_free(rdpInput* input)
1087 MessageQueue_Free(in->queue);
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
This struct contains function pointer to initialize/free objects.