From 4fa839393a5962372811b14081c379e92b36900f Mon Sep 17 00:00:00 2001 From: Brenton DeGeer Date: Thu, 17 Jun 2021 20:15:57 -0700 Subject: [PATCH 1/3] Debugging implementation --- libweston/backend-rdp/rdp.c | 132 ++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 57 deletions(-) diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index 486694dae..8ee03d8d6 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -1323,6 +1323,8 @@ xf_peer_activate(freerdp_peer* client) settings->KeyboardLayout, &xkbRuleNames); + rdp_debug(b, "HorizontalWheel: %d\n", settings->HasHorizontalWheel); + keymap = NULL; if (xkbRuleNames.layout) { keymap = xkb_keymap_new_from_names(b->compositor->xkb_context, @@ -1428,28 +1430,30 @@ dump_mouseinput(RdpPeerContext *peerContext, UINT16 flags, UINT16 x, UINT16 y, b rdp_debug_verbose(b, "RDP mouse input%s: (%d, %d): flags:%x: ", is_ex ? "_ex" : "", x, y, flags); if (is_ex) { if (flags & PTR_XFLAGS_DOWN) - rdp_debug_verbose_continue(b, "DOWN "); + rdp_debug(b, "DOWN "); if (flags & PTR_XFLAGS_BUTTON1) - rdp_debug_verbose_continue(b, "XBUTTON1 "); + rdp_debug(b, "XBUTTON1 "); if (flags & PTR_XFLAGS_BUTTON2) - rdp_debug_verbose_continue(b, "XBUTTON2 "); + rdp_debug(b, "XBUTTON2 "); } else { if (flags & PTR_FLAGS_WHEEL) - rdp_debug_verbose_continue(b, "WHEEL "); + rdp_debug(b, "WHEEL "); if (flags & PTR_FLAGS_WHEEL_NEGATIVE) - rdp_debug_verbose_continue(b, "WHEEL_NEGATIVE "); + rdp_debug(b, "WHEEL_NEGATIVE "); + if (flags & PTR_FLAGS_HWHEEL) + rdp_debug(b, "HWHEEL "); if (flags & PTR_FLAGS_MOVE) - rdp_debug_verbose_continue(b, "MOVE "); + rdp_debug(b, "MOVE "); if (flags & PTR_FLAGS_DOWN) - rdp_debug_verbose_continue(b, "DOWN "); + rdp_debug(b, "DOWN "); if (flags & PTR_FLAGS_BUTTON1) - rdp_debug_verbose_continue(b, "BUTTON1 "); + rdp_debug(b, "BUTTON1 "); if (flags & PTR_FLAGS_BUTTON2) - rdp_debug_verbose_continue(b, "BUTTON2 "); + rdp_debug(b, "BUTTON2 "); if (flags & PTR_FLAGS_BUTTON3) - rdp_debug_verbose_continue(b, "BUTTON3 "); + rdp_debug(b, "BUTTON3 "); } - rdp_debug_verbose_continue(b, "\n"); + rdp_debug(b, "\n"); } static void @@ -1470,11 +1474,66 @@ rdp_validate_button_state(RdpPeerContext *peerContext, bool pressed, uint32_t* b return; } +static bool +rdp_notify_wheel_scroll(RdpPeerContext *peerContext, UINT16 flags, uint32_t axis) +{ + struct weston_pointer_axis_event weston_event; + int ivalue; + double value; + struct timespec time; + + /* + * The RDP specs says the lower bits of flags contains the "the number of rotation + * units the mouse wheel was rotated". + * + * https://blogs.msdn.microsoft.com/oldnewthing/20130123-00/?p=5473 explains the 120 value + */ + if (flags & PTR_FLAGS_WHEEL_NEGATIVE) + ivalue = (int)((char)(flags & 0xff)); + else + ivalue = (flags & 0xff); + + /* Flip the scroll direction as the RDP direction is inverse of X/Wayland */ + ivalue *= -1; + + /* + * Accumulate the wheel increments. + * + * Every 12 wheel increments, we will send an update to our Wayland + * clients with an updated value for the wheel for smooth scrolling. + * + * Every 120 wheel increments, we tick one discrete wheel click. + */ + peerContext->accumWheelRotationPrecise += ivalue; + peerContext->accumWheelRotationDiscrete += ivalue; + if (abs(peerContext->accumWheelRotationPrecise) >= 12) { + value = (double)(peerContext->accumWheelRotationPrecise / 12); + + weston_event.axis = axis; + weston_event.value = value; + weston_event.discrete = peerContext->accumWheelRotationDiscrete / 120; + weston_event.has_discrete = true; + + rdp_debug_verbose(peerContext->rdpBackend, "wheel: value:%f discrete:%d\n", + weston_event.value, weston_event.discrete); + + weston_compositor_get_time(&time); + + notify_axis(peerContext->item.seat, &time, &weston_event); + + peerContext->accumWheelRotationPrecise %= 12; + peerContext->accumWheelRotationDiscrete %= 120; + + return true; + } + + return false; +} + static FREERDP_CB_RET_TYPE xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) { RdpPeerContext *peerContext = (RdpPeerContext *)input->context; - struct rdp_backend *b = peerContext->rdpBackend; uint32_t button = 0; bool need_frame = false; struct timespec time; @@ -1514,52 +1573,11 @@ xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) } if (flags & PTR_FLAGS_WHEEL) { - struct weston_pointer_axis_event weston_event; - int ivalue; - double value; - - /* - * The RDP specs says the lower bits of flags contains the "the number of rotation - * units the mouse wheel was rotated". - * - * https://blogs.msdn.microsoft.com/oldnewthing/20130123-00/?p=5473 explains the 120 value - */ - if (flags & PTR_FLAGS_WHEEL_NEGATIVE) - ivalue = (int)((char)(flags & 0xff)); - else - ivalue = (flags & 0xff); - - /* Flip the scroll direction as the RDP direction is inverse of X/Wayland */ - ivalue *= -1; - - /* - * Accumulate the wheel increments. - * - * Every 12 wheel increments, we will send an update to our Wayland - * clients with an updated value for the wheel for smooth scrolling. - * - * Every 120 wheel increments, we tick one discrete wheel click. - */ - peerContext->accumWheelRotationPrecise += ivalue; - peerContext->accumWheelRotationDiscrete += ivalue; - if (abs(peerContext->accumWheelRotationPrecise) >= 12) { - value = (double)(peerContext->accumWheelRotationPrecise / 12); - - weston_event.axis = WL_POINTER_AXIS_VERTICAL_SCROLL; - weston_event.value = value; - weston_event.discrete = peerContext->accumWheelRotationDiscrete / 120; - weston_event.has_discrete = true; - - rdp_debug_verbose(b, "wheel: value:%f discrete:%d\n", weston_event.value, weston_event.discrete); - - weston_compositor_get_time(&time); - - notify_axis(peerContext->item.seat, &time, &weston_event); + if (rdp_notify_wheel_scroll(peerContext, flags, WL_POINTER_AXIS_VERTICAL_SCROLL)) + need_frame = true; + } else if ((flags & PTR_FLAGS_HWHEEL) && peerContext->_p.settings->HasHorizontalWheel) { + if (rdp_notify_wheel_scroll(peerContext, flags, WL_POINTER_AXIS_HORIZONTAL_SCROLL)) need_frame = true; - - peerContext->accumWheelRotationPrecise %= 12; - peerContext->accumWheelRotationDiscrete %= 120; - } } if (need_frame) From 296eb40f04e1f9e42af6f7b711d88d40ce55edc4 Mon Sep 17 00:00:00 2001 From: Brenton DeGeer Date: Fri, 18 Jun 2021 09:57:55 -0700 Subject: [PATCH 2/3] Notify FreeRDP about horizontal scroll support --- libweston/backend-rdp/rdp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index 8ee03d8d6..8e21df9d3 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -1826,6 +1826,7 @@ rdp_peer_init(freerdp_peer *client, struct rdp_backend *b) settings->SupportMonitorLayoutPdu = TRUE; settings->RedirectClipboard = TRUE; settings->HasExtendedMouseEvent = TRUE; + settings->HasHorizontalWheel = TRUE; client->Capabilities = xf_peer_capabilities; client->PostConnect = xf_peer_post_connect; From 57518ca0fa01dd88fd743d58c60b59dc7dea8adb Mon Sep 17 00:00:00 2001 From: Brenton DeGeer Date: Mon, 21 Jun 2021 11:21:28 -0700 Subject: [PATCH 3/3] Fix scroll direction --- libweston/backend-rdp/rdp.c | 42 +++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index 8e21df9d3..7e2c72ac6 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -1323,8 +1323,6 @@ xf_peer_activate(freerdp_peer* client) settings->KeyboardLayout, &xkbRuleNames); - rdp_debug(b, "HorizontalWheel: %d\n", settings->HasHorizontalWheel); - keymap = NULL; if (xkbRuleNames.layout) { keymap = xkb_keymap_new_from_names(b->compositor->xkb_context, @@ -1430,30 +1428,30 @@ dump_mouseinput(RdpPeerContext *peerContext, UINT16 flags, UINT16 x, UINT16 y, b rdp_debug_verbose(b, "RDP mouse input%s: (%d, %d): flags:%x: ", is_ex ? "_ex" : "", x, y, flags); if (is_ex) { if (flags & PTR_XFLAGS_DOWN) - rdp_debug(b, "DOWN "); + rdp_debug_verbose_continue(b, "DOWN "); if (flags & PTR_XFLAGS_BUTTON1) - rdp_debug(b, "XBUTTON1 "); + rdp_debug_verbose_continue(b, "XBUTTON1 "); if (flags & PTR_XFLAGS_BUTTON2) - rdp_debug(b, "XBUTTON2 "); + rdp_debug_verbose_continue(b, "XBUTTON2 "); } else { if (flags & PTR_FLAGS_WHEEL) - rdp_debug(b, "WHEEL "); + rdp_debug_verbose_continue(b, "WHEEL "); if (flags & PTR_FLAGS_WHEEL_NEGATIVE) - rdp_debug(b, "WHEEL_NEGATIVE "); + rdp_debug_verbose_continue(b, "WHEEL_NEGATIVE "); if (flags & PTR_FLAGS_HWHEEL) - rdp_debug(b, "HWHEEL "); + rdp_debug_verbose_continue(b, "HWHEEL "); if (flags & PTR_FLAGS_MOVE) - rdp_debug(b, "MOVE "); + rdp_debug_verbose_continue(b, "MOVE "); if (flags & PTR_FLAGS_DOWN) - rdp_debug(b, "DOWN "); + rdp_debug_verbose_continue(b, "DOWN "); if (flags & PTR_FLAGS_BUTTON1) - rdp_debug(b, "BUTTON1 "); + rdp_debug_verbose_continue(b, "BUTTON1 "); if (flags & PTR_FLAGS_BUTTON2) - rdp_debug(b, "BUTTON2 "); + rdp_debug_verbose_continue(b, "BUTTON2 "); if (flags & PTR_FLAGS_BUTTON3) - rdp_debug(b, "BUTTON3 "); + rdp_debug_verbose_continue(b, "BUTTON3 "); } - rdp_debug(b, "\n"); + rdp_debug_verbose_continue(b, "\n"); } static void @@ -1478,6 +1476,7 @@ static bool rdp_notify_wheel_scroll(RdpPeerContext *peerContext, UINT16 flags, uint32_t axis) { struct weston_pointer_axis_event weston_event; + struct rdp_backend *b = peerContext->rdpBackend; int ivalue; double value; struct timespec time; @@ -1493,8 +1492,12 @@ rdp_notify_wheel_scroll(RdpPeerContext *peerContext, UINT16 flags, uint32_t axis else ivalue = (flags & 0xff); - /* Flip the scroll direction as the RDP direction is inverse of X/Wayland */ - ivalue *= -1; + /* + * Flip the scroll direction as the RDP direction is inverse of X/Wayland + * for vertical scroll + */ + if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) + ivalue *= -1; /* * Accumulate the wheel increments. @@ -1514,7 +1517,7 @@ rdp_notify_wheel_scroll(RdpPeerContext *peerContext, UINT16 flags, uint32_t axis weston_event.discrete = peerContext->accumWheelRotationDiscrete / 120; weston_event.has_discrete = true; - rdp_debug_verbose(peerContext->rdpBackend, "wheel: value:%f discrete:%d\n", + rdp_debug_verbose(b, "wheel: value:%f discrete:%d\n", weston_event.value, weston_event.discrete); weston_compositor_get_time(&time); @@ -1572,10 +1575,13 @@ xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) need_frame = true; } + /* Per RDP spec, if both PTRFLAGS_WHEEL and PTRFLAGS_HWHEEL are specified + * then PTRFLAGS_WHEEL takes precedent + */ if (flags & PTR_FLAGS_WHEEL) { if (rdp_notify_wheel_scroll(peerContext, flags, WL_POINTER_AXIS_VERTICAL_SCROLL)) need_frame = true; - } else if ((flags & PTR_FLAGS_HWHEEL) && peerContext->_p.settings->HasHorizontalWheel) { + } else if (flags & PTR_FLAGS_HWHEEL) { if (rdp_notify_wheel_scroll(peerContext, flags, WL_POINTER_AXIS_HORIZONTAL_SCROLL)) need_frame = true; }