diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index 758d4e9a7..77eb8a959 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -241,7 +241,8 @@ static UINT rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 UINT32 pduLength) { UINT status; - if (!callback || !s || !callback->channel || !callback->channel->Write) + + if (!callback || !s || !callback->channel || !callback->channel->Write || !callback->plugin) return ERROR_INTERNAL_ERROR; Stream_SetPosition(s, 0); @@ -366,6 +367,10 @@ static UINT rdpei_send_pen_frame(RdpeiClientContext* context, RDPINPUT_PEN_FRAME rdpei = (RDPEI_PLUGIN*)context->handle; if (!rdpei || !rdpei->listener_callback) return ERROR_INTERNAL_ERROR; + if (!rdpei || !rdpei->rdpcontext) + return ERROR_INTERNAL_ERROR; + if (freerdp_settings_get_bool(rdpei->rdpcontext->settings, FreeRDP_SuspendInput)) + return CHANNEL_RC_OK; callback = rdpei->listener_callback->channel_callback; /* Just ignore the event if the channel is not connected */ @@ -663,8 +668,15 @@ static UINT rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, UINT status; wStream* s; UINT32 pduLength; + RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*)callback->plugin->pInterface; + if (!rdpei || !rdpei->rdpcontext) + return ERROR_INTERNAL_ERROR; + if (freerdp_settings_get_bool(rdpei->rdpcontext->settings, FreeRDP_SuspendInput)) + return CHANNEL_RC_OK; + if (!frame) return ERROR_INTERNAL_ERROR; + pduLength = 64 + (frame->contactCount * 64); s = Stream_New(NULL, pduLength); diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 544c99747..04e72dc2b 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -821,6 +821,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_KeyboardHook (2633) #define FreeRDP_HasHorizontalWheel (2634) #define FreeRDP_HasExtendedMouseEvent (2635) +#define FreeRDP_SuspendInput (2636) #define FreeRDP_BrushSupportLevel (2688) #define FreeRDP_GlyphSupportLevel (2752) #define FreeRDP_GlyphCache (2753) @@ -1368,7 +1369,13 @@ struct rdp_settings ALIGN64 UINT32 KeyboardHook; /* 2633 */ ALIGN64 BOOL HasHorizontalWheel; /* 2634 */ ALIGN64 BOOL HasExtendedMouseEvent; /* 2635 */ - UINT64 padding2688[2688 - 2636]; /* 2636 */ + + /** SuspendInput disables processing of keyboard/mouse/multitouch input. + * If used by an implementation ensure proper state resync after reenabling + * input + */ + ALIGN64 BOOL SuspendInput; /* 2636 */ + UINT64 padding2688[2688 - 2637]; /* 2637 */ /* Brush Capabilities */ ALIGN64 UINT32 BrushSupportLevel; /* 2688 */ diff --git a/libfreerdp/common/settings_getters.c b/libfreerdp/common/settings_getters.c index 4afb1afc5..d5bbd16df 100644 --- a/libfreerdp/common/settings_getters.c +++ b/libfreerdp/common/settings_getters.c @@ -492,6 +492,9 @@ BOOL freerdp_settings_get_bool(const rdpSettings* settings, size_t id) case FreeRDP_SurfaceFrameMarkerEnabled: return settings->SurfaceFrameMarkerEnabled; + case FreeRDP_SuspendInput: + return settings->SuspendInput; + case FreeRDP_TcpKeepAlive: return settings->TcpKeepAlive; @@ -1161,6 +1164,10 @@ BOOL freerdp_settings_set_bool(rdpSettings* settings, size_t id, BOOL val) settings->SurfaceFrameMarkerEnabled = val; break; + case FreeRDP_SuspendInput: + settings->SuspendInput = val; + break; + case FreeRDP_TcpKeepAlive: settings->TcpKeepAlive = val; break; diff --git a/libfreerdp/common/settings_str.c b/libfreerdp/common/settings_str.c index e2fa6105c..41c2eb066 100644 --- a/libfreerdp/common/settings_str.c +++ b/libfreerdp/common/settings_str.c @@ -169,6 +169,7 @@ static const struct settings_str_entry settings_map[] = { { FreeRDP_SuppressOutput, 0, "FreeRDP_SuppressOutput" }, { FreeRDP_SurfaceCommandsEnabled, 0, "FreeRDP_SurfaceCommandsEnabled" }, { FreeRDP_SurfaceFrameMarkerEnabled, 0, "FreeRDP_SurfaceFrameMarkerEnabled" }, + { FreeRDP_SuspendInput, 0, "FreeRDP_SuspendInput" }, { FreeRDP_TcpKeepAlive, 0, "FreeRDP_TcpKeepAlive" }, { FreeRDP_TlsSecurity, 0, "FreeRDP_TlsSecurity" }, { FreeRDP_ToggleFullscreen, 0, "FreeRDP_ToggleFullscreen" }, diff --git a/libfreerdp/core/input.c b/libfreerdp/core/input.c index 4518d6564..3c0eb39e5 100644 --- a/libfreerdp/core/input.c +++ b/libfreerdp/core/input.c @@ -672,17 +672,23 @@ BOOL input_register_client_callbacks(rdpInput* input) BOOL freerdp_input_send_synchronize_event(rdpInput* input, UINT32 flags) { - if (!input) + if (!input || !input->context) return FALSE; + if (freerdp_settings_get_bool(input->context->settings, FreeRDP_SuspendInput)) + return TRUE; + return IFCALLRESULT(TRUE, input->SynchronizeEvent, input, flags); } BOOL freerdp_input_send_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { - if (!input) + if (!input || !input->context) return FALSE; + if (freerdp_settings_get_bool(input->context->settings, FreeRDP_SuspendInput)) + return TRUE; + return IFCALLRESULT(TRUE, input->KeyboardEvent, input, flags, code); } @@ -697,41 +703,56 @@ BOOL freerdp_input_send_keyboard_event_ex(rdpInput* input, BOOL down, UINT32 rdp BOOL freerdp_input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { - if (!input) + if (!input || !input->context) return FALSE; + if (freerdp_settings_get_bool(input->context->settings, FreeRDP_SuspendInput)) + return TRUE; + return IFCALLRESULT(TRUE, input->UnicodeKeyboardEvent, input, flags, code); } BOOL freerdp_input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { - if (!input) + if (!input || !input->context) return FALSE; + if (freerdp_settings_get_bool(input->context->settings, FreeRDP_SuspendInput)) + return TRUE; + return IFCALLRESULT(TRUE, input->MouseEvent, input, flags, x, y); } BOOL freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { - if (!input) + if (!input || !input->context) return FALSE; + if (freerdp_settings_get_bool(input->context->settings, FreeRDP_SuspendInput)) + return TRUE; + return IFCALLRESULT(TRUE, input->ExtendedMouseEvent, input, flags, x, y); } BOOL freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates) { - if (!input) + if (!input || !input->context) return FALSE; + if (freerdp_settings_get_bool(input->context->settings, FreeRDP_SuspendInput)) + return TRUE; + return IFCALLRESULT(TRUE, input->FocusInEvent, input, toggleStates); } BOOL freerdp_input_send_keyboard_pause_event(rdpInput* input) { - if (!input) + if (!input || !input->context) return FALSE; + if (freerdp_settings_get_bool(input->context->settings, FreeRDP_SuspendInput)) + return TRUE; + return IFCALLRESULT(TRUE, input->KeyboardPauseEvent, input); } diff --git a/libfreerdp/core/test/settings_property_lists.h b/libfreerdp/core/test/settings_property_lists.h index c6f494646..e8f2c4a88 100644 --- a/libfreerdp/core/test/settings_property_lists.h +++ b/libfreerdp/core/test/settings_property_lists.h @@ -158,6 +158,7 @@ static const size_t bool_list_indices[] = { FreeRDP_SuppressOutput, FreeRDP_SurfaceCommandsEnabled, FreeRDP_SurfaceFrameMarkerEnabled, + FreeRDP_SuspendInput, FreeRDP_TcpKeepAlive, FreeRDP_TlsSecurity, FreeRDP_ToggleFullscreen,