From f03059e7182f5103f3cbd44d4f55079a8da35ea4 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 26 Jan 2022 14:21:53 +0100 Subject: [PATCH] Extended AINPUT API: * Each event now has a timestamp * Relative and absolute events are sent simultaneously * Added a flag indicating relative events are available --- channels/ainput/client/ainput_main.c | 8 ++++++-- channels/ainput/common/ainput_common.h | 2 ++ channels/ainput/server/ainput_main.c | 11 ++++++----- client/X11/xf_event.c | 8 ++++---- client/X11/xf_input.c | 7 ++----- client/X11/xf_keyboard.c | 4 ++-- client/X11/xfreerdp.h | 2 -- client/common/client.c | 6 ++++++ include/freerdp/channels/ainput.h | 1 + include/freerdp/client.h | 20 ++++++++++++-------- include/freerdp/server/ainput.h | 4 ++-- scripts/android-build.conf | 5 +++-- server/Sample/sf_ainput.c | 8 ++++---- 13 files changed, 50 insertions(+), 36 deletions(-) diff --git a/channels/ainput/client/ainput_main.c b/channels/ainput/client/ainput_main.c index 4d51ae3f5..e9faaf2b4 100644 --- a/channels/ainput/client/ainput_main.c +++ b/channels/ainput/client/ainput_main.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "ainput_main.h" #include @@ -111,12 +112,14 @@ static UINT ainput_send_input_event(AInputClientContext* context, UINT64 flags, AINPUT_PLUGIN* ainput; AINPUT_CHANNEL_CALLBACK* callback; BYTE buffer[32] = { 0 }; + UINT64 time; wStream sbuffer = { 0 }; wStream* s = Stream_StaticInit(&sbuffer, buffer, sizeof(buffer)); WINPR_ASSERT(s); WINPR_ASSERT(context); + time = GetTickCount64(); ainput = (AINPUT_PLUGIN*)context->handle; WINPR_ASSERT(ainput); WINPR_ASSERT(ainput->listener_callback); @@ -132,14 +135,15 @@ static UINT ainput_send_input_event(AInputClientContext* context, UINT64 flags, { char buffer[128] = { 0 }; - WLog_VRB(TAG, "[%s] sending flags=%s, %" PRId32 "x%" PRId32, __FUNCTION__, - ainput_flags_to_string(flags, buffer, sizeof(buffer)), x, y); + WLog_VRB(TAG, "[%s] sending timestamp=0x%08" PRIx64 ", flags=%s, %" PRId32 "x%" PRId32, + __FUNCTION__, time, ainput_flags_to_string(flags, buffer, sizeof(buffer)), x, y); } /* Message type */ Stream_Write_UINT16(s, MSG_AINPUT_MOUSE); /* Event data */ + Stream_Write_UINT64(s, time); Stream_Write_UINT64(s, flags); Stream_Write_INT32(s, x); Stream_Write_INT32(s, y); diff --git a/channels/ainput/common/ainput_common.h b/channels/ainput/common/ainput_common.h index 021178006..759ce155e 100644 --- a/channels/ainput/common/ainput_common.h +++ b/channels/ainput/common/ainput_common.h @@ -50,6 +50,8 @@ static INLINE const char* ainput_flags_to_string(UINT64 flags, char* buffer, siz { char number[32] = { 0 }; + if (flags & AINPUT_FLAGS_HAVE_REL) + ainput_append(buffer, size, "AINPUT_FLAGS_HAVE_REL", TRUE); if (flags & AINPUT_FLAGS_WHEEL) ainput_append(buffer, size, "AINPUT_FLAGS_WHEEL", TRUE); if (flags & AINPUT_FLAGS_MOVE) diff --git a/channels/ainput/server/ainput_main.c b/channels/ainput/server/ainput_main.c index a74bfc137..cf63d9e87 100644 --- a/channels/ainput/server/ainput_main.c +++ b/channels/ainput/server/ainput_main.c @@ -146,23 +146,24 @@ static UINT ainput_server_send_version(ainput_server* ainput, wStream* s) static UINT ainput_server_recv_mouse_event(ainput_server* ainput, wStream* s) { UINT error = CHANNEL_RC_OK; - UINT64 flags; + UINT64 flags, time; INT32 x, y; char buffer[128] = { 0 }; WINPR_ASSERT(ainput); WINPR_ASSERT(s); - if (Stream_GetRemainingLength(s) < 16) + if (Stream_GetRemainingLength(s) < 24) return ERROR_NO_DATA; + Stream_Read_UINT64(s, time); Stream_Read_UINT64(s, flags); Stream_Read_INT32(s, x); Stream_Read_INT32(s, y); - WLog_VRB(TAG, "[%s] received: flags=%s, %" PRId32 "x%" PRId32, __FUNCTION__, - ainput_flags_to_string(flags, buffer, sizeof(buffer)), x, y); - IFCALLRET(ainput->context.MouseEvent, error, &ainput->context, flags, x, y); + WLog_VRB(TAG, "[%s] received: time=0x%08" PRIx64 ", flags=%s, %" PRId32 "x%" PRId32, + __FUNCTION__, time, ainput_flags_to_string(flags, buffer, sizeof(buffer)), x, y); + IFCALLRET(ainput->context.MouseEvent, error, &ainput->context, time, flags, x, y); return error; } diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index be358efa5..66e2eb82c 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -445,7 +445,7 @@ static BOOL xf_event_MotionNotify(xfContext* xfc, const XMotionEvent* event, BOO { WINPR_ASSERT(xfc); - if (xfc->xi_event || xfc->xi_rawevent) + if (xfc->xi_event) return TRUE; if (xfc->window) @@ -534,7 +534,7 @@ static BOOL xf_grab_mouse(xfContext* xfc) ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask | EnterWindowMask | LeaveWindowMask, GrabModeAsync, GrabModeAsync, xfc->window->handle, None, CurrentTime); - xfc->mouse_grabbed = TRUE; + xfc->common.mouse_grabbed = TRUE; } return TRUE; } @@ -554,7 +554,7 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, const XButtonEvent* event, BOOL { xf_grab_mouse(xfc); - if (xfc->xi_event || xfc->xi_rawevent) + if (xfc->xi_event) return TRUE; return xf_generic_ButtonEvent(xfc, event->x, event->y, event->button, event->window, app, TRUE); } @@ -563,7 +563,7 @@ static BOOL xf_event_ButtonRelease(xfContext* xfc, const XButtonEvent* event, BO { xf_grab_mouse(xfc); - if (xfc->xi_event || xfc->xi_rawevent) + if (xfc->xi_event) return TRUE; return xf_generic_ButtonEvent(xfc, event->x, event->y, event->button, event->window, app, FALSE); diff --git a/client/X11/xf_input.c b/client/X11/xf_input.c index 77f28b0e7..7466fb43b 100644 --- a/client/X11/xf_input.c +++ b/client/X11/xf_input.c @@ -648,27 +648,24 @@ int xf_input_event(xfContext* xfc, const XEvent* xevent, XIDeviceEvent* event, i { case XI_ButtonPress: xfc->xi_event = TRUE; - if (!xfc->xi_rawevent) xf_generic_ButtonEvent(xfc, (int)event->event_x, (int)event->event_y, event->detail, event->event, xfc->remote_app, TRUE); break; case XI_ButtonRelease: xfc->xi_event = TRUE; - if (!xfc->xi_rawevent) xf_generic_ButtonEvent(xfc, (int)event->event_x, (int)event->event_y, event->detail, event->event, xfc->remote_app, FALSE); break; case XI_Motion: xfc->xi_event = TRUE; - if (!xfc->xi_rawevent) xf_generic_MotionNotify(xfc, (int)event->event_x, (int)event->event_y, event->detail, event->event, xfc->remote_app); break; case XI_RawButtonPress: case XI_RawButtonRelease: - xfc->xi_rawevent = xfc->mouse_grabbed && + xfc->xi_rawevent = xfc->common.mouse_grabbed && freerdp_settings_get_bool(settings, FreeRDP_MouseUseRelativeMove); if (xfc->xi_rawevent) @@ -679,7 +676,7 @@ int xf_input_event(xfContext* xfc, const XEvent* xevent, XIDeviceEvent* event, i } break; case XI_RawMotion: - xfc->xi_rawevent = xfc->mouse_grabbed && + xfc->xi_rawevent = xfc->common.mouse_grabbed && freerdp_settings_get_bool(settings, FreeRDP_MouseUseRelativeMove); if (xfc->xi_rawevent) diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 53a2b822d..b663b9f37 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -437,7 +437,7 @@ void xf_keyboard_focus_in(xfContext* xfc) if (XQueryPointer(xfc->display, xfc->window->handle, &w, &w, &d, &d, &x, &y, &state)) { - if (x >= 0 && x < xfc->window->width && y >= 0 && y < xfc->window->height) + if ((x >= 0) && (x < xfc->window->width) && (y >= 0) && (y < xfc->window->height)) { xf_event_adjust_coordinates(xfc, &x, &y); freerdp_client_send_button_event(&xfc->common, FALSE, PTR_FLAGS_MOVE, x, y); @@ -733,5 +733,5 @@ BOOL xf_ungrab(xfContext* xfc) WINPR_ASSERT(xfc); XUngrabKeyboard(xfc->display, CurrentTime); XUngrabPointer(xfc->display, CurrentTime); - xfc->mouse_grabbed = FALSE; + xfc->common.mouse_grabbed = FALSE; } diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index a8eb64caf..bc4b77bb6 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -300,8 +300,6 @@ struct xf_context #endif BOOL xi_rawevent; BOOL xi_event; - - BOOL mouse_grabbed; }; BOOL xf_create_window(xfContext* xfc); diff --git a/client/common/client.c b/client/common/client.c index a5fe5808a..cdbc79423 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -1088,9 +1088,15 @@ BOOL freerdp_client_send_button_event(rdpClientContext* cctx, BOOL relative, UIN if (cctx->ainput) { UINT64 flags = 0; + BOOL relativeInput = + freerdp_settings_get_bool(cctx->context.settings, FreeRDP_MouseUseRelativeMove); + + if (cctx->mouse_grabbed && relativeInput) + flags |= AINPUT_FLAGS_HAVE_REL; if (relative) flags |= AINPUT_FLAGS_REL; + if (mflags & PTR_FLAGS_DOWN) flags |= AINPUT_FLAGS_DOWN; if (mflags & PTR_FLAGS_BUTTON1) diff --git a/include/freerdp/channels/ainput.h b/include/freerdp/channels/ainput.h index 269d9ec3b..fe9faef3f 100644 --- a/include/freerdp/channels/ainput.h +++ b/include/freerdp/channels/ainput.h @@ -41,6 +41,7 @@ typedef enum AINPUT_FLAGS_DOWN = 0x0008, AINPUT_FLAGS_REL = 0x0010, + AINPUT_FLAGS_HAVE_REL = 0x0020, /* Pointer Flags */ AINPUT_FLAGS_BUTTON1 = 0x1000, /* left */ diff --git a/include/freerdp/client.h b/include/freerdp/client.h index bc1e74159..1d9e2908f 100644 --- a/include/freerdp/client.h +++ b/include/freerdp/client.h @@ -83,20 +83,21 @@ extern "C" rdpContext context; ALIGN64 HANDLE thread; /**< (offset 0) */ #if defined(CHANNEL_AINPUT_CLIENT) - ALIGN64 AInputClientContext* ainput; /**< (offset 1) */ + ALIGN64 AInputClientContext* ainput; /**< (offset 1) */ #else UINT64 reserved1; #endif #if defined(CHANNEL_RDPEI_CLIENT) - ALIGN64 RdpeiClientContext* rdpei; /**< (offset 2) */ + ALIGN64 RdpeiClientContext* rdpei; /**< (offset 2) */ #else UINT64 reserved2; #endif - ALIGN64 INT32 lastX; /**< (offset 3) */ - ALIGN64 INT32 lastY; /**< (offset 4) */ - UINT64 reserved[128 - 5]; /**< (offset 5) */ + ALIGN64 INT32 lastX; /**< (offset 3) */ + ALIGN64 INT32 lastY; /**< (offset 4) */ + ALIGN64 BOOL mouse_grabbed; /** < (offset 5) */ + UINT64 reserved[128 - 6]; /**< (offset 6) */ }; /* Common client functions */ @@ -141,9 +142,9 @@ extern "C" char** username, char** password, char** domain)); FREERDP_API - WINPR_DEPRECATED_VAR("Use client_cli_authenticate_ex", - BOOL client_cli_gw_authenticate(freerdp* instance, char** username, - char** password, char** domain)); + WINPR_DEPRECATED_VAR("Use client_cli_authenticate_ex", + BOOL client_cli_gw_authenticate(freerdp* instance, char** username, + char** password, char** domain)); FREERDP_API WINPR_DEPRECATED_VAR( "Use client_cli_verify_certificate_ex", @@ -182,6 +183,9 @@ extern "C" FREERDP_API BOOL freerdp_client_send_wheel_event(rdpClientContext* cctx, UINT16 mflags); + FREERDP_API BOOL freerdp_client_send_mouse_event(rdpClientContext* cctx, UINT64 mflags, INT32 x, + INT32 y); + FREERDP_API BOOL freerdp_client_send_button_event(rdpClientContext* cctx, BOOL relative, UINT16 mflags, INT32 x, INT32 y); diff --git a/include/freerdp/server/ainput.h b/include/freerdp/server/ainput.h index 321902d8c..412f34277 100644 --- a/include/freerdp/server/ainput.h +++ b/include/freerdp/server/ainput.h @@ -40,8 +40,8 @@ typedef BOOL (*psAInputServerIsOpen)(ainput_server_context* context); typedef UINT (*psAInputServerOpenResult)(ainput_server_context* context, AINPUT_SERVER_OPEN_RESULT result); -typedef UINT (*psAInputServerMouseEvent)(ainput_server_context* context, UINT64 flags, INT32 x, - INT32 y); +typedef UINT (*psAInputServerMouseEvent)(ainput_server_context* context, UINT64 timestamp, + UINT64 flags, INT32 x, INT32 y); struct _ainput_server_context { diff --git a/scripts/android-build.conf b/scripts/android-build.conf index 5f470a5e3..e29fb65bf 100644 --- a/scripts/android-build.conf +++ b/scripts/android-build.conf @@ -15,7 +15,7 @@ WITH_OPENSSL=1 WITH_FFMPEG=0 BUILD_DEPS=1 DEPS_ONLY=0 -NDK_TARGET=26 +NDK_TARGET=23 JPEG_TAG=master OPENH264_TAG=v1.8.0 # NOTE: NDK r15c or earlier needed in --openh624-ndk for v1.8.0 @@ -23,7 +23,8 @@ OPENSSL_TAG=OpenSSL_1_1_1m FFMPEG_TAG=n4.4.1 SRC_DIR=$SCRIPT_PATH/.. -BUILD_DST=$SCRIPT_PATH/../client/Android/Studio/freeRDPCore/src/main/jniLibs +#BUILD_DST=$SCRIPT_PATH/../client/Android/Studio/freeRDPCore/src/main/jniLibs +BUILD_DST=~/StudioProjects/tcclient-android/app/libs/ BUILD_SRC=$SRC_DIR/build CMAKE_BUILD_TYPE=Debug diff --git a/server/Sample/sf_ainput.c b/server/Sample/sf_ainput.c index 439d90e2f..7fa96c4e9 100644 --- a/server/Sample/sf_ainput.c +++ b/server/Sample/sf_ainput.c @@ -40,14 +40,14 @@ * * @return 0 on success, otherwise a Win32 error code */ -static UINT sf_peer_ainput_mouse_event(ainput_server_context* context, UINT64 flags, INT32 x, - INT32 y) +static UINT sf_peer_ainput_mouse_event(ainput_server_context* context, UINT64 timestamp, + UINT64 flags, INT32 x, INT32 y) { /* TODO: Implement */ WINPR_ASSERT(context); - WLog_WARN(TAG, "%s not implemented: 0x%08" PRIx64 ", %" PRId32 "x%" PRId32, __FUNCTION__, flags, - x, y); + WLog_WARN(TAG, "%s not implemented: 0x%08" PRIx64 ", 0x%08" PRIx64 ", %" PRId32 "x%" PRId32, + __FUNCTION__, timestamp, flags, x, y); return CHANNEL_RC_OK; }