xserver: Branch 'server-21.1-branch' - 2 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 1 12:40:40 UTC 2022


 dix/events.c                                        |   15 +++------
 hw/xfree86/drivers/inputtest/xf86-input-inputtest.c |   33 ++++++++++++--------
 2 files changed, 27 insertions(+), 21 deletions(-)

New commits:
commit 855b96a85bc0711460a2542573a9a3959d1bfefa
Author: Povilas Kanapickas <povilas at radix.lt>
Date:   Sun Dec 19 16:51:39 2021 +0200

    xfree86: Fix event data alignment in inputtest driver
    
    This fixes address sanitizer errors when running unit tests. The
    additional copying may reduce performance by a small amount, but we
    don't care about that because this driver is used for testing only.
    
    Signed-off-by: Povilas Kanapickas <povilas at radix.lt>
    (cherry picked from commit 7d2014e7d523e10623203582b9f573303750f087)

diff --git a/hw/xfree86/drivers/inputtest/xf86-input-inputtest.c b/hw/xfree86/drivers/inputtest/xf86-input-inputtest.c
index 63a48522a..dd19f47a9 100644
--- a/hw/xfree86/drivers/inputtest/xf86-input-inputtest.c
+++ b/hw/xfree86/drivers/inputtest/xf86-input-inputtest.c
@@ -856,39 +856,48 @@ read_input_from_connection(InputInfoPtr pInfo)
         driver_data->buffer.valid_length += read_size;
 
         while (1) {
-            xf86ITEventHeader *event_header;
+            xf86ITEventHeader event_header;
             char *event_begin = driver_data->buffer.data + processed_size;
 
             if (driver_data->buffer.valid_length - processed_size < sizeof(xf86ITEventHeader))
                 break;
 
-            event_header = (xf86ITEventHeader*) event_begin;
+            /* Note that event_begin pointer is not aligned, accessing it directly is
+               undefined behavior. We must use memcpy to copy the data to aligned data
+               area. Most compilers will optimize out this call out and use whatever
+               is most efficient to access unaligned data on a particular platform */
+            memcpy(&event_header, event_begin, sizeof(xf86ITEventHeader));
 
-            if (event_header->length >= EVENT_BUFFER_SIZE) {
+            if (event_header.length >= EVENT_BUFFER_SIZE) {
                 xf86IDrvMsg(pInfo, X_ERROR, "Received event with too long length: %d\n",
-                            event_header->length);
+                            event_header.length);
                 teardown_client_connection(pInfo);
                 return;
             }
 
-            if (driver_data->buffer.valid_length - processed_size < event_header->length)
+            if (driver_data->buffer.valid_length - processed_size < event_header.length)
                 break;
 
-            if (is_supported_event(event_header->type)) {
-                int expected_event_size = get_event_size(event_header->type);
+            if (is_supported_event(event_header.type)) {
+                int expected_event_size = get_event_size(event_header.type);
 
-                if (event_header->length != expected_event_size) {
+                if (event_header.length != expected_event_size) {
                     xf86IDrvMsg(pInfo, X_ERROR, "Unexpected event length: was %d bytes, "
                                 "expected %d (event type: %d)\n",
-                                event_header->length, expected_event_size,
-                                (int) event_header->type);
+                                event_header.length, expected_event_size,
+                                (int) event_header.type);
                     teardown_client_connection(pInfo);
                     return;
                 }
 
-                handle_event(pInfo, (xf86ITEventAny*) event_begin);
+                /* We could use event_begin pointer directly, but we want to ensure correct
+                   data alignment (if only so that address sanitizer does not complain) */
+                xf86ITEventAny event_data;
+                memset(&event_data, 0, sizeof(event_data));
+                memcpy(&event_data, event_begin, event_header.length);
+                handle_event(pInfo, &event_data);
             }
-            processed_size += event_header->length;
+            processed_size += event_header.length;
         }
 
         if (processed_size > 0) {
commit 9d05ee10c231edacc69b342677ae8c3cc32f97e5
Author: Povilas Kanapickas <povilas at radix.lt>
Date:   Sun Jan 16 10:42:15 2022 +0200

    dix: Don't send touch end to clients that do async grab without touches
    
    GTK3 menu widget creates a selection for touch and other events and
    after receiving touch events creates an async grab that excludes touch
    events. Unfortunately it relies on X server not sending the touch end
    event in order to function properly. Sending touch end event will cause
    it to think that the initiating touch ended and when it actually ends,
    the ButtonRelease event will make it think that the menu should be
    closed. As a result, the menu will be open only for the duration of the
    touch making it useless.
    
    This commit reverts f682e0563f736ed2c2c612ed575e05b6e3db945e.
    
    Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1255
    
    Signed-off-by: Povilas Kanapickas <povilas at radix.lt>
    (cherry picked from commit 43e934a19f644cddedae73602e86429c9dc5074a)

diff --git a/dix/events.c b/dix/events.c
index 28d7d177c..782ed35dc 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1505,16 +1505,13 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
             CLIENT_BITS(listener->listener) == grab->resource) {
             if (grab->grabtype == CORE || grab->grabtype == XI ||
                 !xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin)) {
+                /*  Note that the grab will override any current listeners and if these listeners
+                    already received touch events then this is the place to send touch end event
+                    to complete the touch sequence.
 
-                if (listener->type == TOUCH_LISTENER_REGULAR &&
-                    listener->state != TOUCH_LISTENER_AWAITING_BEGIN &&
-                    listener->state != TOUCH_LISTENER_HAS_END) {
-                    /* if the listener already got any events relating to the touch, we must send
-                       a touch end because the grab overrides the previous listener and won't
-                       itself send any touch events.
-                    */
-                    TouchEmitTouchEnd(mouse, ti, 0, listener->listener);
-                }
+                    Unfortunately GTK3 menu widget implementation relies on not getting touch end
+                    event, so we can't fix the current behavior.
+                */
                 listener->type = TOUCH_LISTENER_POINTER_GRAB;
             } else {
                 listener->type = TOUCH_LISTENER_GRAB;


More information about the xorg-commit mailing list