summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Fourdan <ofourdan@redhat.com>2016-09-22 09:38:50 +0200
committerOlivier Fourdan <ofourdan@redhat.com>2016-09-23 09:19:05 +0200
commit6a929fafbdaa83d1d496011b0cd0d7477cc8153e (patch)
tree2060067e4e426b885dcce6cfa2b04c1f76aa6ad6
parent2b54aedfd15a0e1c6fafabbc27446b6cf2ff12ef (diff)
xwayland: Clear up x_cursor on UnrealizeCursor()server-1.18-backports
In Xwayland's xwl_unrealize_cursor(), the x_cursor is cleared up only when a device value is provided to the UnrealizeCursor() routine, but if the device is NULL as called from FreeCursor(), the corresponding x_cursor for the xwl_seat is left untouched. This might cause a segfault when trying to access the unrealized cursor's devPrivates in xwl_seat_set_cursor(). A possible occurrence of this is the client changing the cursor, the Xserver calling FreeCursor() which does UnrealizeCursor() and then the Wayland server sending a pointer enter event, which invokes xwl_seat_set_cursor() while the seat's x_cursor has just been unrealized. To avoid this, walk through all the xwl_seats and clear up all x_cursor matching the cursor being unrealized. Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Jonas Ã…dahl <jadahl@gmail.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> (cherry picked from commit 0a20d5f8cb3f3f9a81b2795ae1865e72541022d4)
-rw-r--r--hw/xwayland/xwayland-cursor.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
index 7d14a3d52..b2ae93ff9 100644
--- a/hw/xwayland/xwayland-cursor.c
+++ b/hw/xwayland/xwayland-cursor.c
@@ -76,6 +76,7 @@ static Bool
xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
{
PixmapPtr pixmap;
+ struct xwl_screen *xwl_screen;
struct xwl_seat *xwl_seat;
pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
@@ -85,9 +86,9 @@ xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, NULL);
/* When called from FreeCursor(), device is always NULL */
- if (device) {
- xwl_seat = device->public.devicePrivate;
- if (xwl_seat && cursor == xwl_seat->x_cursor)
+ xwl_screen = xwl_screen_get(screen);
+ xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
+ if (cursor == xwl_seat->x_cursor)
xwl_seat->x_cursor = NULL;
}