Merge pull request #11384 from akallabeth/rel-mouse-change

Rel mouse change
This commit is contained in:
akallabeth 2025-04-11 08:21:14 +02:00 committed by GitHub
commit 3805575c58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 288 additions and 73 deletions

View File

@ -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

View File

@ -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;

View File

@ -173,6 +173,7 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl)
SDL_SetCursor(ptr->cursor);
SDL_ShowCursor();
sdl->setHasCursor(true);
return TRUE;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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 =

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;