21 #include <freerdp/config.h>
23 #include <winpr/crt.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
43 static 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);
51 static 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);
59 static wStream* rdp_client_input_pdu_init(rdpRdp* rdp, UINT16 type)
62 s = rdp_data_pdu_init(rdp);
67 rdp_write_client_input_pdu_header(s, 1);
68 rdp_write_input_event_header(s, 0, type);
72 static BOOL rdp_send_client_input_pdu(rdpRdp* rdp,
wStream* s)
74 return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_INPUT, rdp->mcs->userId);
77 static void input_write_synchronize_event(
wStream* s, UINT32 flags)
80 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 6);
81 Stream_Write_UINT16(s, 0);
82 Stream_Write_UINT32(s, flags);
85 static BOOL input_ensure_client_running(rdpInput* input)
88 if (freerdp_shall_disconnect_context(input->context))
90 WLog_WARN(TAG,
"[APPLICATION BUG] input functions called after the session terminated");
96 static BOOL input_send_synchronize_event(rdpInput* input, UINT32 flags)
101 if (!input || !input->context)
104 rdp = input->context->rdp;
106 if (!input_ensure_client_running(input))
109 s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_SYNC);
114 input_write_synchronize_event(s, flags);
115 return rdp_send_client_input_pdu(rdp, s);
118 static 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);
128 static BOOL input_send_keyboard_event(rdpInput* input, UINT16 flags, UINT8 code)
133 if (!input || !input->context)
136 rdp = input->context->rdp;
138 if (!input_ensure_client_running(input))
141 s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_SCANCODE);
146 input_write_keyboard_event(s, flags, code);
147 return rdp_send_client_input_pdu(rdp, s);
150 static void input_write_unicode_keyboard_event(
wStream* s, UINT16 flags, UINT16 code)
152 Stream_Write_UINT16(s, flags);
153 Stream_Write_UINT16(s, code);
154 Stream_Write_UINT16(s, 0);
157 static BOOL input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
162 if (!input || !input->context)
165 if (!input_ensure_client_running(input))
170 WLog_WARN(TAG,
"Unicode input not supported by server.");
174 rdp = input->context->rdp;
175 s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_UNICODE);
180 input_write_unicode_keyboard_event(s, flags, code);
181 return rdp_send_client_input_pdu(rdp, s);
184 static void input_write_mouse_event(
wStream* s, UINT16 flags, UINT16 x, UINT16 y)
186 Stream_Write_UINT16(s, flags);
187 Stream_Write_UINT16(s, x);
188 Stream_Write_UINT16(s, y);
191 static BOOL input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
196 if (!input || !input->context || !input->context->settings)
199 rdp = input->context->rdp;
201 if (!input_ensure_client_running(input))
206 if (flags & PTR_FLAGS_HWHEEL)
209 "skip mouse event %" PRIu16
"x%" PRIu16
" flags=0x%04" PRIX16
210 ", no horizontal mouse wheel supported",
216 s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_MOUSE);
221 input_write_mouse_event(s, flags, x, y);
222 return rdp_send_client_input_pdu(rdp, s);
225 static BOOL input_send_relmouse_event(rdpInput* input, UINT16 flags, INT16 xDelta, INT16 yDelta)
230 if (!input || !input->context || !input->context->settings)
233 rdp = input->context->rdp;
235 if (!input_ensure_client_running(input))
240 WLog_ERR(TAG,
"Sending relative mouse event, but no support for that");
244 s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_MOUSEREL);
249 Stream_Write_UINT16(s, flags);
250 Stream_Write_INT16(s, xDelta);
251 Stream_Write_INT16(s, yDelta);
253 return rdp_send_client_input_pdu(rdp, s);
256 static void input_write_extended_mouse_event(
wStream* s, UINT16 flags, UINT16 x, UINT16 y)
258 Stream_Write_UINT16(s, flags);
259 Stream_Write_UINT16(s, x);
260 Stream_Write_UINT16(s, y);
263 static BOOL input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
269 WINPR_ASSERT(input->context);
270 WINPR_ASSERT(input->context->settings);
272 rdp = input->context->rdp;
275 if (!input_ensure_client_running(input))
281 "skip extended mouse event %" PRIu16
"x%" PRIu16
" flags=0x%04" PRIX16
282 ", no extended mouse events supported",
287 s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_MOUSEX);
292 input_write_extended_mouse_event(s, flags, x, y);
293 return rdp_send_client_input_pdu(rdp, s);
296 static BOOL input_send_focus_in_event(rdpInput* input, UINT16 toggleStates)
299 if (!input_send_keyboard_event(input, KBD_FLAGS_RELEASE, 0x0f))
303 if (!input_send_synchronize_event(input, (toggleStates & 0x1F)))
307 return input_send_keyboard_event(input, KBD_FLAGS_RELEASE, 0x0f);
310 static BOOL input_send_keyboard_pause_event(rdpInput* input)
318 if (!input_send_keyboard_event(input, KBD_FLAGS_EXTENDED1,
319 RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL)))
323 if (!input_send_keyboard_event(input, 0, RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK)))
327 if (!input_send_keyboard_event(input, KBD_FLAGS_RELEASE | KBD_FLAGS_EXTENDED1,
328 RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL)))
332 return input_send_keyboard_event(input, KBD_FLAGS_RELEASE,
333 RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK));
336 static BOOL input_send_fastpath_synchronize_event(rdpInput* input, UINT32 flags)
342 WINPR_ASSERT(input->context);
344 rdp = input->context->rdp;
347 if (!input_ensure_client_running(input))
351 s = fastpath_input_pdu_init(rdp->fastpath, (BYTE)flags, FASTPATH_INPUT_EVENT_SYNC);
356 return fastpath_send_input_pdu(rdp->fastpath, s);
359 static BOOL input_send_fastpath_keyboard_event(rdpInput* input, UINT16 flags, UINT8 code)
366 WINPR_ASSERT(input->context);
368 rdp = input->context->rdp;
371 if (!input_ensure_client_running(input))
374 eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0;
375 eventFlags |= (flags & KBD_FLAGS_EXTENDED) ? FASTPATH_INPUT_KBDFLAGS_EXTENDED : 0;
376 eventFlags |= (flags & KBD_FLAGS_EXTENDED1) ? FASTPATH_INPUT_KBDFLAGS_PREFIX_E1 : 0;
377 s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_SCANCODE);
382 WINPR_ASSERT(code <= UINT8_MAX);
383 Stream_Write_UINT8(s, code);
384 return fastpath_send_input_pdu(rdp->fastpath, s);
387 static BOOL input_send_fastpath_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
394 WINPR_ASSERT(input->context);
395 WINPR_ASSERT(input->context->settings);
397 rdp = input->context->rdp;
400 if (!input_ensure_client_running(input))
405 WLog_WARN(TAG,
"Unicode input not supported by server.");
409 eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0;
410 s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_UNICODE);
415 Stream_Write_UINT16(s, code);
416 return fastpath_send_input_pdu(rdp->fastpath, s);
419 static BOOL input_send_fastpath_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
425 WINPR_ASSERT(input->context);
426 WINPR_ASSERT(input->context->settings);
428 rdp = input->context->rdp;
431 if (!input_ensure_client_running(input))
436 if (flags & PTR_FLAGS_HWHEEL)
439 "skip mouse event %" PRIu16
"x%" PRIu16
" flags=0x%04" PRIX16
440 ", no horizontal mouse wheel supported",
446 s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_MOUSE);
451 input_write_mouse_event(s, flags, x, y);
452 return fastpath_send_input_pdu(rdp->fastpath, s);
455 static BOOL input_send_fastpath_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x,
462 WINPR_ASSERT(input->context);
464 rdp = input->context->rdp;
467 if (!input_ensure_client_running(input))
473 "skip extended mouse event %" PRIu16
"x%" PRIu16
" flags=0x%04" PRIX16
474 ", no extended mouse events supported",
479 s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_MOUSEX);
484 input_write_extended_mouse_event(s, flags, x, y);
485 return fastpath_send_input_pdu(rdp->fastpath, s);
488 static BOOL input_send_fastpath_relmouse_event(rdpInput* input, UINT16 flags, INT16 xDelta,
495 WINPR_ASSERT(input->context);
496 WINPR_ASSERT(input->context->settings);
498 rdp = input->context->rdp;
501 if (!input_ensure_client_running(input))
506 WLog_ERR(TAG,
"Sending relative fastpath mouse event, but no support for that announced");
510 s = fastpath_input_pdu_init(rdp->fastpath, 0, TS_FP_RELPOINTER_EVENT);
515 Stream_Write_UINT16(s, flags);
516 Stream_Write_INT16(s, xDelta);
517 Stream_Write_INT16(s, yDelta);
518 return fastpath_send_input_pdu(rdp->fastpath, s);
521 static BOOL input_send_fastpath_qoe_event(rdpInput* input, UINT32 timestampMS)
524 WINPR_ASSERT(input->context);
525 WINPR_ASSERT(input->context->settings);
527 rdpRdp* rdp = input->context->rdp;
530 if (!input_ensure_client_running(input))
535 WLog_ERR(TAG,
"Sending qoe event, but no support for that announced");
539 wStream* s = fastpath_input_pdu_init(rdp->fastpath, 0, TS_FP_QOETIMESTAMP_EVENT);
544 if (!Stream_EnsureRemainingCapacity(s, 4))
546 Stream_Free(s, TRUE);
550 Stream_Write_UINT32(s, timestampMS);
551 return fastpath_send_input_pdu(rdp->fastpath, s);
554 static BOOL input_send_fastpath_focus_in_event(rdpInput* input, UINT16 toggleStates)
561 WINPR_ASSERT(input->context);
563 rdp = input->context->rdp;
566 if (!input_ensure_client_running(input))
569 s = fastpath_input_pdu_init_header(rdp->fastpath);
575 eventFlags = FASTPATH_INPUT_KBDFLAGS_RELEASE | FASTPATH_INPUT_EVENT_SCANCODE << 5;
576 Stream_Write_UINT8(s, eventFlags);
577 Stream_Write_UINT8(s, 0x0f);
579 eventFlags = (toggleStates & 0x1F) | FASTPATH_INPUT_EVENT_SYNC << 5;
580 Stream_Write_UINT8(s, eventFlags);
582 eventFlags = FASTPATH_INPUT_KBDFLAGS_RELEASE | FASTPATH_INPUT_EVENT_SCANCODE << 5;
583 Stream_Write_UINT8(s, eventFlags);
584 Stream_Write_UINT8(s, 0x0f);
585 return fastpath_send_multiple_input_pdu(rdp->fastpath, s, 3);
588 static BOOL input_send_fastpath_keyboard_pause_event(rdpInput* input)
595 const BYTE keyDownEvent = FASTPATH_INPUT_EVENT_SCANCODE << 5;
596 const BYTE keyUpEvent = (FASTPATH_INPUT_EVENT_SCANCODE << 5) | FASTPATH_INPUT_KBDFLAGS_RELEASE;
600 WINPR_ASSERT(input->context);
602 rdp = input->context->rdp;
605 if (!input_ensure_client_running(input))
608 s = fastpath_input_pdu_init_header(rdp->fastpath);
614 Stream_Write_UINT8(s, keyDownEvent | FASTPATH_INPUT_KBDFLAGS_PREFIX_E1);
615 Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL));
617 Stream_Write_UINT8(s, keyDownEvent);
618 Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK));
620 Stream_Write_UINT8(s, keyUpEvent | FASTPATH_INPUT_KBDFLAGS_PREFIX_E1);
621 Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL));
623 Stream_Write_UINT8(s, keyUpEvent);
624 Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK));
625 return fastpath_send_multiple_input_pdu(rdp->fastpath, s, 4);
628 static BOOL input_recv_sync_event(rdpInput* input,
wStream* s)
630 UINT32 toggleFlags = 0;
635 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
639 Stream_Read_UINT32(s, toggleFlags);
640 return IFCALLRESULT(TRUE, input->SynchronizeEvent, input, toggleFlags);
643 static BOOL input_recv_keyboard_event(rdpInput* input,
wStream* s)
645 UINT16 keyboardFlags = 0;
651 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
654 Stream_Read_UINT16(s, keyboardFlags);
655 Stream_Read_UINT16(s, keyCode);
658 if (keyboardFlags & KBD_FLAGS_RELEASE)
659 keyboardFlags &= ~KBD_FLAGS_DOWN;
661 if (keyCode & 0xFF00)
663 "Problematic [MS-RDPBCGR] 2.2.8.1.1.3.1.1.1 Keyboard Event (TS_KEYBOARD_EVENT) "
664 "keyCode=0x%04" PRIx16
665 ", high byte values should be sent in keyboardFlags field, ignoring.",
667 return IFCALLRESULT(TRUE, input->KeyboardEvent, input, keyboardFlags, keyCode & 0xFF);
670 static BOOL input_recv_unicode_keyboard_event(rdpInput* input,
wStream* s)
672 UINT16 keyboardFlags = 0;
673 UINT16 unicodeCode = 0;
678 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
681 Stream_Read_UINT16(s, keyboardFlags);
682 Stream_Read_UINT16(s, unicodeCode);
687 if (keyboardFlags & KBD_FLAGS_RELEASE)
688 keyboardFlags &= ~KBD_FLAGS_DOWN;
690 return IFCALLRESULT(TRUE, input->UnicodeKeyboardEvent, input, keyboardFlags, unicodeCode);
693 static BOOL input_recv_mouse_event(rdpInput* input,
wStream* s)
695 UINT16 pointerFlags = 0;
702 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
705 Stream_Read_UINT16(s, pointerFlags);
706 Stream_Read_UINT16(s, xPos);
707 Stream_Read_UINT16(s, yPos);
708 return IFCALLRESULT(TRUE, input->MouseEvent, input, pointerFlags, xPos, yPos);
711 static BOOL input_recv_relmouse_event(rdpInput* input,
wStream* s)
713 UINT16 pointerFlags = 0;
720 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
723 Stream_Read_UINT16(s, pointerFlags);
724 Stream_Read_INT16(s, xDelta);
725 Stream_Read_INT16(s, yDelta);
730 "Received relative mouse event(flags=0x%04" PRIx16
", xPos=%" PRId16
731 ", yPos=%" PRId16
"), but we did not announce support for that",
732 pointerFlags, xDelta, yDelta);
736 return IFCALLRESULT(TRUE, input->RelMouseEvent, input, pointerFlags, xDelta, yDelta);
739 static BOOL input_recv_extended_mouse_event(rdpInput* input,
wStream* s)
741 UINT16 pointerFlags = 0;
748 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
751 Stream_Read_UINT16(s, pointerFlags);
752 Stream_Read_UINT16(s, xPos);
753 Stream_Read_UINT16(s, yPos);
758 "Received extended mouse event(flags=0x%04" PRIx16
", xPos=%" PRIu16
759 ", yPos=%" PRIu16
"), but we did not announce support for that",
760 pointerFlags, xPos, yPos);
764 return IFCALLRESULT(TRUE, input->ExtendedMouseEvent, input, pointerFlags, xPos, yPos);
767 static BOOL input_recv_event(rdpInput* input,
wStream* s)
769 UINT16 messageType = 0;
774 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
778 Stream_Read_UINT16(s, messageType);
782 case INPUT_EVENT_SYNC:
783 if (!input_recv_sync_event(input, s))
788 case INPUT_EVENT_SCANCODE:
789 if (!input_recv_keyboard_event(input, s))
794 case INPUT_EVENT_UNICODE:
795 if (!input_recv_unicode_keyboard_event(input, s))
800 case INPUT_EVENT_MOUSE:
801 if (!input_recv_mouse_event(input, s))
806 case INPUT_EVENT_MOUSEX:
807 if (!input_recv_extended_mouse_event(input, s))
812 case INPUT_EVENT_MOUSEREL:
813 if (!input_recv_relmouse_event(input, s))
819 WLog_ERR(TAG,
"Unknown messageType %" PRIu16
"", messageType);
828 BOOL input_recv(rdpInput* input,
wStream* s)
830 UINT16 numberEvents = 0;
835 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
838 Stream_Read_UINT16(s, numberEvents);
842 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, numberEvents, 6ull))
845 for (UINT16 i = 0; i < numberEvents; i++)
847 if (!input_recv_event(input, s))
854 BOOL input_register_client_callbacks(rdpInput* input)
856 rdpSettings* settings = NULL;
861 settings = input->context->settings;
868 input->SynchronizeEvent = input_send_fastpath_synchronize_event;
869 input->KeyboardEvent = input_send_fastpath_keyboard_event;
870 input->KeyboardPauseEvent = input_send_fastpath_keyboard_pause_event;
871 input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event;
872 input->MouseEvent = input_send_fastpath_mouse_event;
873 input->RelMouseEvent = input_send_fastpath_relmouse_event;
874 input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event;
875 input->FocusInEvent = input_send_fastpath_focus_in_event;
876 input->QoEEvent = input_send_fastpath_qoe_event;
880 input->SynchronizeEvent = input_send_synchronize_event;
881 input->KeyboardEvent = input_send_keyboard_event;
882 input->KeyboardPauseEvent = input_send_keyboard_pause_event;
883 input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event;
884 input->MouseEvent = input_send_mouse_event;
885 input->RelMouseEvent = input_send_relmouse_event;
886 input->ExtendedMouseEvent = input_send_extended_mouse_event;
887 input->FocusInEvent = input_send_focus_in_event;
894 static BOOL input_update_last_event(rdpInput* input, BOOL mouse, UINT16 x, UINT16 y)
899 WINPR_ASSERT(input->context);
903 const time_t now = time(NULL);
904 in->lastInputTimestamp = now;
915 BOOL freerdp_input_send_synchronize_event(rdpInput* input, UINT32 flags)
917 if (!input || !input->context)
923 return IFCALLRESULT(TRUE, input->SynchronizeEvent, input, flags);
926 BOOL freerdp_input_send_keyboard_event(rdpInput* input, UINT16 flags, UINT8 code)
928 if (!input || !input->context)
934 input_update_last_event(input, FALSE, 0, 0);
936 return IFCALLRESULT(TRUE, input->KeyboardEvent, input, flags, code);
939 BOOL freerdp_input_send_keyboard_event_ex(rdpInput* input, BOOL down, BOOL repeat,
942 UINT16 flags = (RDP_SCANCODE_EXTENDED(rdp_scancode) ? KBD_FLAGS_EXTENDED : 0);
944 flags |= KBD_FLAGS_DOWN;
946 flags |= KBD_FLAGS_RELEASE;
948 return freerdp_input_send_keyboard_event(input, flags, RDP_SCANCODE_CODE(rdp_scancode));
951 BOOL freerdp_input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
953 if (!input || !input->context)
959 input_update_last_event(input, FALSE, 0, 0);
961 return IFCALLRESULT(TRUE, input->UnicodeKeyboardEvent, input, flags, code);
964 BOOL freerdp_input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
966 if (!input || !input->context)
972 input_update_last_event(
973 input, flags & (PTR_FLAGS_MOVE | PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 | PTR_FLAGS_BUTTON3),
976 return IFCALLRESULT(TRUE, input->MouseEvent, input, flags, x, y);
979 BOOL freerdp_input_send_rel_mouse_event(rdpInput* input, UINT16 flags, INT16 xDelta, INT16 yDelta)
981 if (!input || !input->context)
987 return IFCALLRESULT(TRUE, input->RelMouseEvent, input, flags, xDelta, yDelta);
990 BOOL freerdp_input_send_qoe_timestamp(rdpInput* input, UINT32 timestampMS)
992 if (!input || !input->context)
995 return IFCALLRESULT(TRUE, input->QoEEvent, input, timestampMS);
998 BOOL freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
1000 if (!input || !input->context)
1006 input_update_last_event(input, TRUE, x, y);
1008 return IFCALLRESULT(TRUE, input->ExtendedMouseEvent, input, flags, x, y);
1011 BOOL freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates)
1013 if (!input || !input->context)
1019 return IFCALLRESULT(TRUE, input->FocusInEvent, input, toggleStates);
1022 BOOL freerdp_input_send_keyboard_pause_event(rdpInput* input)
1024 if (!input || !input->context)
1030 return IFCALLRESULT(TRUE, input->KeyboardPauseEvent, input);
1033 int input_process_events(rdpInput* input)
1038 return input_message_queue_process_pending_messages(input);
1041 static void input_free_queued_message(
void* obj)
1043 wMessage* msg = (wMessage*)obj;
1044 input_message_queue_free_message(msg);
1047 rdpInput* input_new(rdpRdp* rdp)
1049 const wObject cb = { NULL, NULL, NULL, input_free_queued_message, NULL };
1057 input->common.context = rdp->context;
1058 input->queue = MessageQueue_New(&cb);
1066 return &input->common;
1069 void input_free(rdpInput* input)
1075 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.