mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
Merge pull request #11384 from akallabeth/rel-mouse-change
Rel mouse change
This commit is contained in:
commit
3805575c58
@ -938,6 +938,7 @@ static int sdl_run(SdlContext* sdl)
|
||||
case SDL_EVENT_USER_POINTER_NULL:
|
||||
SDL_HideCursor();
|
||||
sdl->setCursor(nullptr);
|
||||
sdl->setHasCursor(false);
|
||||
break;
|
||||
case SDL_EVENT_USER_POINTER_DEFAULT:
|
||||
{
|
||||
@ -945,6 +946,7 @@ static int sdl_run(SdlContext* sdl)
|
||||
SDL_SetCursor(def);
|
||||
SDL_ShowCursor();
|
||||
sdl->setCursor(nullptr);
|
||||
sdl->setHasCursor(true);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_USER_POINTER_POSITION:
|
||||
@ -1726,9 +1728,19 @@ SdlContext::SdlContext(rdpContext* context)
|
||||
WINPR_ASSERT(context);
|
||||
}
|
||||
|
||||
void SdlContext::setHasCursor(bool val)
|
||||
{
|
||||
this->_cursor_visible = val;
|
||||
}
|
||||
|
||||
bool SdlContext::hasCursor() const
|
||||
{
|
||||
return _cursor_visible;
|
||||
}
|
||||
|
||||
bool SdlContext::redraw(bool suppress) const
|
||||
{
|
||||
if (!connected)
|
||||
if (!_connected)
|
||||
return true;
|
||||
|
||||
auto gdi = context()->gdi;
|
||||
@ -1738,12 +1750,12 @@ bool SdlContext::redraw(bool suppress) const
|
||||
|
||||
void SdlContext::setConnected(bool val)
|
||||
{
|
||||
connected = val;
|
||||
_connected = val;
|
||||
}
|
||||
|
||||
bool SdlContext::isConnected() const
|
||||
{
|
||||
return connected;
|
||||
return _connected;
|
||||
}
|
||||
|
||||
rdpContext* SdlContext::context() const
|
||||
|
@ -78,9 +78,13 @@ class SdlContext
|
||||
void push(std::vector<SDL_Rect>&& rects);
|
||||
std::vector<SDL_Rect> pop();
|
||||
|
||||
void setHasCursor(bool val);
|
||||
[[nodiscard]] bool hasCursor() const;
|
||||
|
||||
private:
|
||||
rdpContext* _context;
|
||||
std::atomic<bool> connected = false;
|
||||
std::atomic<bool> _connected = false;
|
||||
bool _cursor_visible = true;
|
||||
rdpPointer* _cursor = nullptr;
|
||||
std::vector<SDL_DisplayID> _monitorIds;
|
||||
std::mutex _queue_mux;
|
||||
|
@ -173,6 +173,7 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
|
||||
|
||||
SDL_SetCursor(ptr->cursor);
|
||||
SDL_ShowCursor();
|
||||
sdl->setHasCursor(true);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,8 @@ BOOL sdl_handle_mouse_motion(SdlContext* sdl, const SDL_MouseMotionEvent* ev)
|
||||
WINPR_ASSERT(ev);
|
||||
|
||||
sdl->input.mouse_focus(ev->windowID);
|
||||
const BOOL relative = freerdp_client_use_relative_mouse_events(sdl->common());
|
||||
const BOOL relative =
|
||||
freerdp_client_use_relative_mouse_events(sdl->common()) && !sdl->hasCursor();
|
||||
auto x = static_cast<INT32>(relative ? ev->xrel : ev->x);
|
||||
auto y = static_cast<INT32>(relative ? ev->yrel : ev->y);
|
||||
sdl_scale_coordinates(sdl, ev->windowID, &x, &y, TRUE, TRUE);
|
||||
@ -266,7 +267,8 @@ BOOL sdl_handle_mouse_button(SdlContext* sdl, const SDL_MouseButtonEvent* ev)
|
||||
break;
|
||||
}
|
||||
|
||||
const BOOL relative = freerdp_client_use_relative_mouse_events(sdl->common());
|
||||
const BOOL relative =
|
||||
freerdp_client_use_relative_mouse_events(sdl->common()) && !sdl->hasCursor();
|
||||
auto x = static_cast<INT32>(relative ? 0 : ev->x);
|
||||
auto y = static_cast<INT32>(relative ? 0 : ev->y);
|
||||
sdl_scale_coordinates(sdl, ev->windowID, &x, &y, TRUE, TRUE);
|
||||
|
@ -380,6 +380,7 @@ static BOOL xf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
|
||||
WLog_WARN(TAG, "handle=%ld", handle);
|
||||
}
|
||||
#endif
|
||||
xfc->isCursorHidden = false;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -412,6 +413,7 @@ static BOOL xf_Pointer_SetNull(rdpContext* context)
|
||||
|
||||
xf_unlock_x11(xfc);
|
||||
#endif
|
||||
xfc->isCursorHidden = true;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -429,6 +431,7 @@ static BOOL xf_Pointer_SetDefault(rdpContext* context)
|
||||
|
||||
xf_unlock_x11(xfc);
|
||||
#endif
|
||||
xfc->isCursorHidden = false;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,8 @@
|
||||
|
||||
#define MIN_FINGER_DIST 5
|
||||
|
||||
static int xf_input_event(xfContext* xfc, const XEvent* xevent, XIDeviceEvent* event, int evtype);
|
||||
static int xf_input_event(xfContext* xfc, WINPR_ATTR_UNUSED const XEvent* xevent,
|
||||
XIDeviceEvent* event, int evtype);
|
||||
|
||||
#ifdef DEBUG_XINPUT
|
||||
static const char* xf_input_get_class_string(int class)
|
||||
@ -744,26 +745,25 @@ static int xf_input_pens_unhover(xfContext* xfc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xf_input_event(xfContext* xfc, const XEvent* xevent, XIDeviceEvent* event, int evtype)
|
||||
static bool xf_use_rel_mouse(xfContext* xfc)
|
||||
{
|
||||
if (!freerdp_client_use_relative_mouse_events(&xfc->common))
|
||||
return false;
|
||||
if (!xfc->isCursorHidden)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int xf_input_event(xfContext* xfc, WINPR_ATTR_UNUSED const XEvent* xevent, XIDeviceEvent* event,
|
||||
int evtype)
|
||||
{
|
||||
WINPR_ASSERT(xfc);
|
||||
WINPR_ASSERT(xevent);
|
||||
WINPR_ASSERT(event);
|
||||
|
||||
/* When not running RAILS we only care about events for this window.
|
||||
* filter out anything else, like floatbar window events
|
||||
*/
|
||||
const Window w = xevent->xany.window;
|
||||
|
||||
xfWindow* window = xfc->window;
|
||||
if (window)
|
||||
{
|
||||
if (w != window->handle)
|
||||
{
|
||||
if (!xfc->remote_app)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (xf_floatbar_is_locked(window->floatbar))
|
||||
return 0;
|
||||
}
|
||||
@ -774,8 +774,7 @@ int xf_input_event(xfContext* xfc, const XEvent* xevent, XIDeviceEvent* event, i
|
||||
{
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
xfc->xi_event = !xfc->common.mouse_grabbed ||
|
||||
!freerdp_client_use_relative_mouse_events(&xfc->common);
|
||||
xfc->xi_event = !xfc->common.mouse_grabbed || !xf_use_rel_mouse(xfc);
|
||||
|
||||
if (xfc->xi_event)
|
||||
{
|
||||
@ -785,8 +784,7 @@ int xf_input_event(xfContext* xfc, const XEvent* xevent, XIDeviceEvent* event, i
|
||||
break;
|
||||
|
||||
case XI_Motion:
|
||||
xfc->xi_event = !xfc->common.mouse_grabbed ||
|
||||
!freerdp_client_use_relative_mouse_events(&xfc->common);
|
||||
xfc->xi_event = !xfc->common.mouse_grabbed || !xf_use_rel_mouse(xfc);
|
||||
|
||||
if (xfc->xi_event)
|
||||
{
|
||||
@ -796,8 +794,7 @@ int xf_input_event(xfContext* xfc, const XEvent* xevent, XIDeviceEvent* event, i
|
||||
break;
|
||||
case XI_RawButtonPress:
|
||||
case XI_RawButtonRelease:
|
||||
xfc->xi_rawevent =
|
||||
xfc->common.mouse_grabbed && freerdp_client_use_relative_mouse_events(&xfc->common);
|
||||
xfc->xi_rawevent = xfc->common.mouse_grabbed && xf_use_rel_mouse(xfc);
|
||||
|
||||
if (xfc->xi_rawevent)
|
||||
{
|
||||
@ -807,8 +804,7 @@ int xf_input_event(xfContext* xfc, const XEvent* xevent, XIDeviceEvent* event, i
|
||||
}
|
||||
break;
|
||||
case XI_RawMotion:
|
||||
xfc->xi_rawevent =
|
||||
xfc->common.mouse_grabbed && freerdp_client_use_relative_mouse_events(&xfc->common);
|
||||
xfc->xi_rawevent = xfc->common.mouse_grabbed && xf_use_rel_mouse(xfc);
|
||||
|
||||
if (xfc->xi_rawevent)
|
||||
{
|
||||
|
@ -317,6 +317,7 @@ struct xf_context
|
||||
wLog* log;
|
||||
FREERDP_REMAP_TABLE* remap_table;
|
||||
DWORD X11_KEYCODE_TO_VIRTUAL_SCANCODE[256];
|
||||
bool isCursorHidden;
|
||||
};
|
||||
|
||||
BOOL xf_create_window(xfContext* xfc);
|
||||
|
@ -92,6 +92,10 @@ extern "C"
|
||||
UINT16 code);
|
||||
typedef BOOL (*pfnShadowMouseEvent)(rdpShadowSubsystem* subsystem, rdpShadowClient* client,
|
||||
UINT16 flags, UINT16 x, UINT16 y);
|
||||
typedef BOOL (*pfnShadowRelMouseEvent)(rdpShadowSubsystem* subsystem, rdpShadowClient* client,
|
||||
UINT16 flags, INT16 xDelta,
|
||||
INT16 yDelta); /** @since version 3.15.0 */
|
||||
|
||||
typedef BOOL (*pfnShadowExtendedMouseEvent)(rdpShadowSubsystem* subsystem,
|
||||
rdpShadowClient* client, UINT16 flags, UINT16 x,
|
||||
UINT16 y);
|
||||
@ -175,6 +179,7 @@ extern "C"
|
||||
|
||||
size_t maxClientsConnected;
|
||||
BOOL SupportMultiRectBitmapUpdates; /** @since version 3.13.0 */
|
||||
BOOL ShowMouseCursor; /** @since version 3.15.0 */
|
||||
};
|
||||
|
||||
struct rdp_shadow_surface
|
||||
@ -244,6 +249,8 @@ extern "C"
|
||||
pfnShadowClientCapabilities ClientCapabilities;
|
||||
|
||||
rdpShadowServer* server;
|
||||
|
||||
pfnShadowRelMouseEvent RelMouseEvent; /** @since version 3.15.0 */
|
||||
};
|
||||
|
||||
/* Definition of message between subsystem and clients */
|
||||
@ -332,7 +339,7 @@ extern "C"
|
||||
COMMAND_LINE_ARGUMENT_A* cargs);
|
||||
FREERDP_API int shadow_server_command_line_status_print(rdpShadowServer* server, int argc,
|
||||
char** argv, int status,
|
||||
COMMAND_LINE_ARGUMENT_A* cargs);
|
||||
const COMMAND_LINE_ARGUMENT_A* cargs);
|
||||
|
||||
FREERDP_API int shadow_server_start(rdpShadowServer* server);
|
||||
FREERDP_API int shadow_server_stop(rdpShadowServer* server);
|
||||
|
@ -342,9 +342,9 @@ extern "C"
|
||||
CLIPRDR_FLAG_REMOTE_TO_LOCAL | CLIPRDR_FLAG_REMOTE_TO_LOCAL_FILES)
|
||||
|
||||
/* Commandline helper defines */
|
||||
#define FREERDP_MONITOR_OVERRIDE_ORIENTATION (1 << 0) /** @since version 3.14.2 */
|
||||
#define FREERDP_MONITOR_OVERRIDE_DESKTOP_SCALE (1 << 1) /** @since version 3.14.2 */
|
||||
#define FREERDP_MONITOR_OVERRIDE_DEVICE_SCALE (1 << 2) /** @since version 3.14.2 */
|
||||
#define FREERDP_MONITOR_OVERRIDE_ORIENTATION (1 << 0) /** @since version 3.15.0 */
|
||||
#define FREERDP_MONITOR_OVERRIDE_DESKTOP_SCALE (1 << 1) /** @since version 3.15.0 */
|
||||
#define FREERDP_MONITOR_OVERRIDE_DEVICE_SCALE (1 << 2) /** @since version 3.15.0 */
|
||||
|
||||
/* ARC_CS_PRIVATE_PACKET */
|
||||
typedef struct
|
||||
|
@ -116,7 +116,7 @@ struct rdp_settings
|
||||
SETTINGS_DEPRECATED(ALIGN64 BOOL SupportSkipChannelJoin); /* 152 */
|
||||
SETTINGS_DEPRECATED(ALIGN64 UINT16 SupportedColorDepths); /* 153 */
|
||||
SETTINGS_DEPRECATED(ALIGN64 UINT64 MonitorOverrideFlags); /** 154
|
||||
* @since version 3.14.2
|
||||
* @since version 3.15.0
|
||||
*/
|
||||
UINT64 padding0192[192 - 155]; /* 155 */
|
||||
|
||||
|
@ -1081,8 +1081,17 @@ static BOOL updateEarlyClientCaps(rdpSettings* settings, UINT32 earlyCapabilityF
|
||||
(earlyCapabilityFlags & RNS_UD_CS_STRONG_ASYMMETRIC_KEYS) ? TRUE : FALSE;
|
||||
|
||||
if (settings->HasRelativeMouseEvent)
|
||||
settings->HasRelativeMouseEvent =
|
||||
(earlyCapabilityFlags & RNS_UD_CS_RELATIVE_MOUSE_INPUT) ? TRUE : FALSE;
|
||||
{
|
||||
/* [MS-RDPBCGR] 2.2.7.1.5 Pointer Capability Set (TS_POINTER_CAPABILITYSET)
|
||||
* the flag must be ignored if the RDP version is < 0x00080011 */
|
||||
if (settings->RdpVersion >= RDP_VERSION_10_12)
|
||||
{
|
||||
settings->HasRelativeMouseEvent =
|
||||
(earlyCapabilityFlags & RNS_UD_CS_RELATIVE_MOUSE_INPUT) ? TRUE : FALSE;
|
||||
}
|
||||
else
|
||||
settings->HasRelativeMouseEvent = FALSE;
|
||||
}
|
||||
|
||||
if (settings->NetworkAutoDetect)
|
||||
settings->NetworkAutoDetect =
|
||||
|
@ -248,7 +248,8 @@ static BOOL x11_shadow_input_keyboard_event(rdpShadowSubsystem* subsystem, rdpSh
|
||||
XFlush(x11->display);
|
||||
XUnlockDisplay(x11->display);
|
||||
}
|
||||
|
||||
#else
|
||||
WLog_WARN(TAG, "KeyboardEvent not supported by backend, ignoring");
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
@ -336,6 +337,65 @@ static BOOL x11_shadow_input_mouse_event(rdpShadowSubsystem* subsystem, rdpShado
|
||||
XTestGrabControl(x11->display, False);
|
||||
XFlush(x11->display);
|
||||
XUnlockDisplay(x11->display);
|
||||
#else
|
||||
WLog_WARN(TAG, "MouseEvent not supported by backend, ignoring");
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL x11_shadow_input_rel_mouse_event(rdpShadowSubsystem* subsystem, rdpShadowClient* client,
|
||||
UINT16 flags, INT16 xDelta, INT16 yDelta)
|
||||
{
|
||||
#ifdef WITH_XTEST
|
||||
x11ShadowSubsystem* x11 = (x11ShadowSubsystem*)subsystem;
|
||||
WINPR_ASSERT(x11);
|
||||
|
||||
unsigned int button = 0;
|
||||
BOOL down = FALSE;
|
||||
|
||||
if (!subsystem || !client)
|
||||
return FALSE;
|
||||
|
||||
rdpShadowServer* server = subsystem->server;
|
||||
|
||||
if (!server)
|
||||
return FALSE;
|
||||
|
||||
rdpShadowSurface* surface = server->surface;
|
||||
|
||||
if (!surface)
|
||||
return FALSE;
|
||||
|
||||
x11->lastMouseClient = client;
|
||||
|
||||
XLockDisplay(x11->display);
|
||||
XTestGrabControl(x11->display, True);
|
||||
|
||||
if (flags & PTR_FLAGS_MOVE)
|
||||
XTestFakeRelativeMotionEvent(x11->display, xDelta, yDelta, 0);
|
||||
|
||||
if (flags & PTR_FLAGS_BUTTON1)
|
||||
button = 1;
|
||||
else if (flags & PTR_FLAGS_BUTTON2)
|
||||
button = 3;
|
||||
else if (flags & PTR_FLAGS_BUTTON3)
|
||||
button = 2;
|
||||
else if (flags & PTR_XFLAGS_BUTTON1)
|
||||
button = 4;
|
||||
else if (flags & PTR_XFLAGS_BUTTON2)
|
||||
button = 5;
|
||||
|
||||
if (flags & PTR_FLAGS_DOWN)
|
||||
down = TRUE;
|
||||
|
||||
if (button)
|
||||
XTestFakeButtonEvent(x11->display, button, down, CurrentTime);
|
||||
|
||||
XTestGrabControl(x11->display, False);
|
||||
XFlush(x11->display);
|
||||
XUnlockDisplay(x11->display);
|
||||
#else
|
||||
WLog_WARN(TAG, "RelMouseEvent not supported by backend, ignoring");
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
@ -385,6 +445,8 @@ static BOOL x11_shadow_input_extended_mouse_event(rdpShadowSubsystem* subsystem,
|
||||
XTestGrabControl(x11->display, False);
|
||||
XFlush(x11->display);
|
||||
XUnlockDisplay(x11->display);
|
||||
#else
|
||||
WLog_WARN(TAG, "ExtendedMouseEvent not supported by backend, ignoring");
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
@ -563,8 +625,8 @@ static int x11_shadow_query_cursor(x11ShadowSubsystem* subsystem, BOOL getImage)
|
||||
|
||||
if ((x != (INT64)subsystem->common.pointerX) || (y != (INT64)subsystem->common.pointerY))
|
||||
{
|
||||
subsystem->common.pointerX = WINPR_ASSERTING_INT_CAST(UINT32, x);
|
||||
subsystem->common.pointerY = WINPR_ASSERTING_INT_CAST(UINT32, y);
|
||||
subsystem->common.pointerX = (UINT32)MAX(0, x);
|
||||
subsystem->common.pointerY = (UINT32)MAX(0, y);
|
||||
x11_shadow_pointer_position_update(subsystem);
|
||||
}
|
||||
|
||||
@ -1480,6 +1542,7 @@ static rdpShadowSubsystem* x11_shadow_subsystem_new(void)
|
||||
subsystem->common.KeyboardEvent = x11_shadow_input_keyboard_event;
|
||||
subsystem->common.UnicodeKeyboardEvent = x11_shadow_input_unicode_keyboard_event;
|
||||
subsystem->common.MouseEvent = x11_shadow_input_mouse_event;
|
||||
subsystem->common.RelMouseEvent = x11_shadow_input_rel_mouse_event;
|
||||
subsystem->common.ExtendedMouseEvent = x11_shadow_input_extended_mouse_event;
|
||||
subsystem->composite = FALSE;
|
||||
subsystem->use_xshm = FALSE; /* temporarily disabled */
|
||||
|
@ -48,10 +48,14 @@ int main(int argc, char** argv)
|
||||
NULL, NULL, -1, NULL,
|
||||
"An address to bind to. Use '[<ipv6>]' for IPv6 addresses, e.g. '[::1]' for "
|
||||
"localhost" },
|
||||
{ "server-side-cursor", COMMAND_LINE_VALUE_BOOL, NULL, NULL, NULL, -1, NULL,
|
||||
"hide mouse cursor in RDP client." },
|
||||
{ "monitors", COMMAND_LINE_VALUE_OPTIONAL, "<0,1,2...>", NULL, NULL, -1, NULL,
|
||||
"Select or list monitors" },
|
||||
{ "max-connections", COMMAND_LINE_VALUE_REQUIRED, "<number>", 0, NULL, -1, NULL,
|
||||
"maximum connections allowed to server, 0 to deactivate" },
|
||||
{ "mouse-relative", COMMAND_LINE_VALUE_BOOL, NULL, NULL, NULL, -1, NULL,
|
||||
"enable support for relative mouse events" },
|
||||
{ "rect", COMMAND_LINE_VALUE_REQUIRED, "<x,y,w,h>", NULL, NULL, -1, NULL,
|
||||
"Select rectangle within monitor to share" },
|
||||
{ "auth", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
|
||||
@ -140,14 +144,13 @@ int main(int argc, char** argv)
|
||||
!freerdp_settings_set_bool(settings, FreeRDP_GfxProgressiveV2, TRUE))
|
||||
goto fail;
|
||||
|
||||
/* TODO: We do not implement relative mouse callbacks, so deactivate it for now */
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_MouseUseRelativeMove, FALSE) ||
|
||||
!freerdp_settings_set_bool(settings, FreeRDP_HasRelativeMouseEvent, FALSE))
|
||||
goto fail;
|
||||
|
||||
if ((status = shadow_server_parse_command_line(server, argc, argv, shadow_args)) < 0)
|
||||
{
|
||||
shadow_server_command_line_status_print(server, argc, argv, status, shadow_args);
|
||||
status = shadow_server_command_line_status_print(server, argc, argv, status, shadow_args);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -2179,7 +2179,16 @@ static int shadow_client_subsystem_process_message(rdpShadowClient* client, wMes
|
||||
if (client->activated)
|
||||
{
|
||||
IFCALL(update->pointer->PointerNew, context, &pointerNew);
|
||||
IFCALL(update->pointer->PointerCached, context, &pointerCached);
|
||||
if (client->server->ShowMouseCursor)
|
||||
{
|
||||
IFCALL(update->pointer->PointerCached, context, &pointerCached);
|
||||
}
|
||||
else
|
||||
{
|
||||
POINTER_SYSTEM_UPDATE pointer_system = { 0 };
|
||||
pointer_system.type = SYSPTR_NULL;
|
||||
IFCALL(update->pointer->PointerSystem, context, &pointer_system);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -16,15 +16,24 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/assert.h>
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#include "shadow.h"
|
||||
|
||||
#define TAG SERVER_TAG("shadow.input")
|
||||
|
||||
static BOOL shadow_input_synchronize_event(rdpInput* input, UINT32 flags)
|
||||
{
|
||||
WINPR_ASSERT(input);
|
||||
rdpShadowClient* client = (rdpShadowClient*)input->context;
|
||||
WINPR_ASSERT(client);
|
||||
WINPR_ASSERT(client->server);
|
||||
rdpShadowSubsystem* subsystem = client->server->subsystem;
|
||||
WINPR_ASSERT(subsystem);
|
||||
|
||||
WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16, client->mayInteract ? "use" : "discard", flags);
|
||||
if (!client->mayInteract)
|
||||
return TRUE;
|
||||
|
||||
@ -33,9 +42,14 @@ static BOOL shadow_input_synchronize_event(rdpInput* input, UINT32 flags)
|
||||
|
||||
static BOOL shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT8 code)
|
||||
{
|
||||
WINPR_ASSERT(input);
|
||||
rdpShadowClient* client = (rdpShadowClient*)input->context;
|
||||
WINPR_ASSERT(client);
|
||||
WINPR_ASSERT(client->server);
|
||||
rdpShadowSubsystem* subsystem = client->server->subsystem;
|
||||
WINPR_ASSERT(subsystem);
|
||||
|
||||
WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16, client->mayInteract ? "use" : "discard", flags);
|
||||
if (!client->mayInteract)
|
||||
return TRUE;
|
||||
|
||||
@ -44,9 +58,14 @@ static BOOL shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT8 cod
|
||||
|
||||
static BOOL shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
|
||||
{
|
||||
WINPR_ASSERT(input);
|
||||
rdpShadowClient* client = (rdpShadowClient*)input->context;
|
||||
WINPR_ASSERT(client);
|
||||
WINPR_ASSERT(client->server);
|
||||
rdpShadowSubsystem* subsystem = client->server->subsystem;
|
||||
WINPR_ASSERT(subsystem);
|
||||
|
||||
WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16, client->mayInteract ? "use" : "discard", flags);
|
||||
if (!client->mayInteract)
|
||||
return TRUE;
|
||||
|
||||
@ -55,8 +74,12 @@ static BOOL shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, U
|
||||
|
||||
static BOOL shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
|
||||
{
|
||||
WINPR_ASSERT(input);
|
||||
rdpShadowClient* client = (rdpShadowClient*)input->context;
|
||||
WINPR_ASSERT(client);
|
||||
WINPR_ASSERT(client->server);
|
||||
rdpShadowSubsystem* subsystem = client->server->subsystem;
|
||||
WINPR_ASSERT(subsystem);
|
||||
|
||||
if (client->server->shareSubRect)
|
||||
{
|
||||
@ -64,7 +87,7 @@ static BOOL shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UI
|
||||
y += client->server->subRect.top;
|
||||
}
|
||||
|
||||
if (!(flags & PTR_FLAGS_WHEEL))
|
||||
if ((flags & (PTR_FLAGS_WHEEL | PTR_FLAGS_HWHEEL | PTR_FLAGS_WHEEL_NEGATIVE)) == 0)
|
||||
{
|
||||
client->pointerX = x;
|
||||
client->pointerY = y;
|
||||
@ -78,16 +101,47 @@ static BOOL shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UI
|
||||
}
|
||||
}
|
||||
|
||||
WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16 ", x=%" PRIu16 ", y=%" PRIu16,
|
||||
client->mayInteract ? "use" : "discard", flags, x, y);
|
||||
if (!client->mayInteract)
|
||||
return TRUE;
|
||||
|
||||
return IFCALLRESULT(TRUE, subsystem->MouseEvent, subsystem, client, flags, x, y);
|
||||
}
|
||||
|
||||
static BOOL shadow_input_rel_mouse_event(rdpInput* input, UINT16 flags, INT16 xDelta, INT16 yDelta)
|
||||
{
|
||||
WINPR_ASSERT(input);
|
||||
|
||||
rdpShadowClient* client = (rdpShadowClient*)input->context;
|
||||
WINPR_ASSERT(client);
|
||||
WINPR_ASSERT(client->server);
|
||||
|
||||
rdpShadowSubsystem* subsystem = client->server->subsystem;
|
||||
WINPR_ASSERT(subsystem);
|
||||
|
||||
WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16 ", x=%" PRId16 ", y=%" PRId16,
|
||||
client->mayInteract ? "use" : "discard", flags, xDelta, yDelta);
|
||||
const uint16_t mask = PTR_FLAGS_MOVE | PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 |
|
||||
PTR_FLAGS_BUTTON3 | PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_BUTTON2;
|
||||
if ((flags & mask) != 0)
|
||||
{
|
||||
WLog_WARN(TAG, "Unknown flags 0x%04" PRIx16, flags & ~mask);
|
||||
}
|
||||
if (!client->mayInteract)
|
||||
return TRUE;
|
||||
|
||||
return IFCALLRESULT(TRUE, subsystem->RelMouseEvent, subsystem, client, flags, xDelta, yDelta);
|
||||
}
|
||||
|
||||
static BOOL shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
|
||||
{
|
||||
WINPR_ASSERT(input);
|
||||
rdpShadowClient* client = (rdpShadowClient*)input->context;
|
||||
WINPR_ASSERT(client);
|
||||
WINPR_ASSERT(client->server);
|
||||
rdpShadowSubsystem* subsystem = client->server->subsystem;
|
||||
WINPR_ASSERT(subsystem);
|
||||
|
||||
if (client->server->shareSubRect)
|
||||
{
|
||||
@ -98,6 +152,8 @@ static BOOL shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UIN
|
||||
client->pointerX = x;
|
||||
client->pointerY = y;
|
||||
|
||||
WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16 ", x=%" PRIu16 ", y=%" PRIu16,
|
||||
client->mayInteract ? "use" : "discard", flags, x, y);
|
||||
if (!client->mayInteract)
|
||||
return TRUE;
|
||||
|
||||
@ -106,9 +162,11 @@ static BOOL shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UIN
|
||||
|
||||
void shadow_input_register_callbacks(rdpInput* input)
|
||||
{
|
||||
WINPR_ASSERT(input);
|
||||
input->SynchronizeEvent = shadow_input_synchronize_event;
|
||||
input->KeyboardEvent = shadow_input_keyboard_event;
|
||||
input->UnicodeKeyboardEvent = shadow_input_unicode_keyboard_event;
|
||||
input->MouseEvent = shadow_input_mouse_event;
|
||||
input->ExtendedMouseEvent = shadow_input_extended_mouse_event;
|
||||
input->RelMouseEvent = shadow_input_rel_mouse_event;
|
||||
}
|
||||
|
@ -59,35 +59,67 @@ static int fail_at_(const COMMAND_LINE_ARGUMENT_A* arg, int rc, const char* file
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int shadow_server_print_command_line_help(int argc, char** argv,
|
||||
COMMAND_LINE_ARGUMENT_A* largs)
|
||||
static int command_line_compare(const void* pa, const void* pb)
|
||||
{
|
||||
const COMMAND_LINE_ARGUMENT_A* a = pa;
|
||||
const COMMAND_LINE_ARGUMENT_A* b = pb;
|
||||
|
||||
if (!a && !b)
|
||||
return 0;
|
||||
if (!a)
|
||||
return -1;
|
||||
if (!b)
|
||||
return 1;
|
||||
|
||||
return strcmp(a->Name, b->Name);
|
||||
}
|
||||
|
||||
static int shadow_server_print_command_line_help(int argc, char** argv,
|
||||
const COMMAND_LINE_ARGUMENT_A* largs)
|
||||
{
|
||||
char* str = NULL;
|
||||
size_t length = 0;
|
||||
const COMMAND_LINE_ARGUMENT_A* arg = NULL;
|
||||
if ((argc < 1) || !largs || !argv)
|
||||
return -1;
|
||||
|
||||
char* path = winpr_GetConfigFilePath(TRUE, "SAM");
|
||||
printf("Usage: %s [options]\n", argv[0]);
|
||||
printf("\n");
|
||||
printf("Notes: By default NLA security is active.\n");
|
||||
printf("\tIn this mode a SAM database is required.\n");
|
||||
printf("\tProvide one with /sam-file:<file with path>\n");
|
||||
printf("\telse the default path %s is used.\n", path);
|
||||
printf("\tIf there is no existing SAM file authentication for all users will fail.\n");
|
||||
printf(
|
||||
"\n\tIf authentication against PAM is desired, start with -sec-nla (requires compiled in "
|
||||
"support for PAM)\n\n");
|
||||
printf("Syntax:\n");
|
||||
printf(" /flag (enables flag)\n");
|
||||
printf(" /option:<value> (specifies option with value)\n");
|
||||
printf(" +toggle -toggle (enables or disables toggle, where '/' is a synonym of '+')\n");
|
||||
printf("\n");
|
||||
free(path);
|
||||
{
|
||||
char* path = winpr_GetConfigFilePath(TRUE, "SAM");
|
||||
printf("Usage: %s [options]\n", argv[0]);
|
||||
printf("\n");
|
||||
printf("Notes: By default NLA security is active.\n");
|
||||
printf("\tIn this mode a SAM database is required.\n");
|
||||
printf("\tProvide one with /sam-file:<file with path>\n");
|
||||
printf("\telse the default path %s is used.\n", path);
|
||||
printf("\tIf there is no existing SAM file authentication for all users will fail.\n");
|
||||
printf("\n\tIf authentication against PAM is desired, start with -sec-nla (requires "
|
||||
"compiled in "
|
||||
"support for PAM)\n\n");
|
||||
printf("Syntax:\n");
|
||||
printf(" /flag (enables flag)\n");
|
||||
printf(" /option:<value> (specifies option with value)\n");
|
||||
printf(" +toggle -toggle (enables or disables toggle, where '/' is a synonym of '+')\n");
|
||||
printf("\n");
|
||||
free(path);
|
||||
}
|
||||
|
||||
arg = largs;
|
||||
// TODO: Sort arguments
|
||||
size_t nrArgs = 0;
|
||||
{
|
||||
const COMMAND_LINE_ARGUMENT_A* arg = largs;
|
||||
while (arg->Name != NULL)
|
||||
{
|
||||
nrArgs++;
|
||||
arg++;
|
||||
}
|
||||
nrArgs++;
|
||||
}
|
||||
COMMAND_LINE_ARGUMENT_A* args_copy = calloc(nrArgs, sizeof(COMMAND_LINE_ARGUMENT_A));
|
||||
if (!args_copy)
|
||||
return -1;
|
||||
memcpy(args_copy, largs, nrArgs * sizeof(COMMAND_LINE_ARGUMENT_A));
|
||||
qsort(args_copy, nrArgs - 1, sizeof(COMMAND_LINE_ARGUMENT_A), command_line_compare);
|
||||
|
||||
const COMMAND_LINE_ARGUMENT_A* arg = args_copy;
|
||||
|
||||
int rc = -1;
|
||||
do
|
||||
{
|
||||
if (arg->Flags & COMMAND_LINE_VALUE_FLAG)
|
||||
@ -103,11 +135,11 @@ static int shadow_server_print_command_line_help(int argc, char** argv,
|
||||
|
||||
if (arg->Format)
|
||||
{
|
||||
length = (strlen(arg->Name) + strlen(arg->Format) + 2);
|
||||
str = (char*)malloc(length + 1);
|
||||
const size_t length = (strlen(arg->Name) + strlen(arg->Format) + 2);
|
||||
char* str = (char*)calloc(length + 1, sizeof(char));
|
||||
|
||||
if (!str)
|
||||
return -1;
|
||||
goto fail;
|
||||
|
||||
(void)sprintf_s(str, length + 1, "%s:%s", arg->Name, arg->Format);
|
||||
(void)printf("%-20s\n", str);
|
||||
@ -122,26 +154,30 @@ static int shadow_server_print_command_line_help(int argc, char** argv,
|
||||
}
|
||||
else if (arg->Flags & COMMAND_LINE_VALUE_BOOL)
|
||||
{
|
||||
length = strlen(arg->Name) + 32;
|
||||
str = (char*)malloc(length + 1);
|
||||
const size_t length = strlen(arg->Name) + 32;
|
||||
char* str = calloc(length + 1, sizeof(char));
|
||||
|
||||
if (!str)
|
||||
return -1;
|
||||
goto fail;
|
||||
|
||||
(void)sprintf_s(str, length + 1, "%s (default:%s)", arg->Name,
|
||||
arg->Default ? "on" : "off");
|
||||
(void)printf(" %s", arg->Default ? "-" : "+");
|
||||
(void)printf("%-20s\n", str);
|
||||
free(str);
|
||||
(void)printf("\t%s\n", arg->Text);
|
||||
|
||||
free(str);
|
||||
}
|
||||
} while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
|
||||
return 1;
|
||||
rc = 1;
|
||||
fail:
|
||||
free(args_copy);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int shadow_server_command_line_status_print(rdpShadowServer* server, int argc, char** argv,
|
||||
int status, COMMAND_LINE_ARGUMENT_A* cargs)
|
||||
int status, const COMMAND_LINE_ARGUMENT_A* cargs)
|
||||
{
|
||||
WINPR_UNUSED(server);
|
||||
|
||||
@ -244,6 +280,17 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
||||
{
|
||||
server->mayInteract = arg->Value ? TRUE : FALSE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "server-side-cursor")
|
||||
{
|
||||
server->ShowMouseCursor = arg->Value ? TRUE : FALSE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "mouse-relative")
|
||||
{
|
||||
const BOOL val = arg->Value ? TRUE : FALSE;
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_MouseUseRelativeMove, val) ||
|
||||
!freerdp_settings_set_bool(settings, FreeRDP_HasRelativeMouseEvent, val))
|
||||
return fail_at(arg, COMMAND_LINE_ERROR);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "max-connections")
|
||||
{
|
||||
errno = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user