aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xwayland
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xwayland')
-rw-r--r--xorg-server/hw/xwayland/Makefile.am4
-rw-r--r--xorg-server/hw/xwayland/xwayland-input.c9
-rw-r--r--xorg-server/hw/xwayland/xwayland.c48
-rw-r--r--xorg-server/hw/xwayland/xwayland.h1
4 files changed, 46 insertions, 16 deletions
diff --git a/xorg-server/hw/xwayland/Makefile.am b/xorg-server/hw/xwayland/Makefile.am
index dc16b8bbe..4e0e1bb00 100644
--- a/xorg-server/hw/xwayland/Makefile.am
+++ b/xorg-server/hw/xwayland/Makefile.am
@@ -39,8 +39,6 @@ nodist_Xwayland_SOURCES = \
CLEANFILES = $(nodist_Xwayland_SOURCES)
-EXTRA_DIST = drm.xml
-
xwayland-glamor.c : $(nodist_Xwayland_SOURCES)
glamor_lib = $(top_builddir)/glamor/libglamor.la
@@ -48,6 +46,8 @@ glamor_lib = $(top_builddir)/glamor/libglamor.la
Xwayland_LDADD += $(GLAMOR_LIBS) $(GBM_LIBS) -lEGL -lGL
endif
+EXTRA_DIST = drm.xml
+
relink:
$(AM_V_at)rm -f Xwayland$(EXEEXT) && $(MAKE) Xwayland$(EXEEXT)
diff --git a/xorg-server/hw/xwayland/xwayland-input.c b/xorg-server/hw/xwayland/xwayland-input.c
index cc5f7df05..b8c543ce4 100644
--- a/xorg-server/hw/xwayland/xwayland-input.c
+++ b/xorg-server/hw/xwayland/xwayland-input.c
@@ -152,6 +152,15 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
ValuatorMask mask;
+ /* There's a race here where if we create and then immediately
+ * destroy a surface, we might end up in a state where the Wayland
+ * compositor sends us an event for a surface that doesn't exist.
+ *
+ * Don't process enter events in this case.
+ */
+ if (surface == NULL)
+ return;
+
xwl_seat->xwl_screen->serial = serial;
xwl_seat->pointer_enter_serial = serial;
diff --git a/xorg-server/hw/xwayland/xwayland.c b/xorg-server/hw/xwayland/xwayland.c
index 17b7bf7fd..913296947 100644
--- a/xorg-server/hw/xwayland/xwayland.c
+++ b/xorg-server/hw/xwayland/xwayland.c
@@ -308,6 +308,9 @@ xwl_unrealize_window(WindowPtr window)
xorg_list_del(&xwl_window->link_damage);
DamageUnregister(xwl_window->damage);
DamageDestroy(xwl_window->damage);
+ if (xwl_window->frame_callback)
+ wl_callback_destroy(xwl_window->frame_callback);
+
free(xwl_window);
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
@@ -321,20 +324,35 @@ xwl_save_screen(ScreenPtr pScreen, int on)
}
static void
+frame_callback(void *data,
+ struct wl_callback *callback,
+ uint32_t time)
+{
+ struct xwl_window *xwl_window = data;
+ xwl_window->frame_callback = NULL;
+}
+
+static const struct wl_callback_listener frame_listener = {
+ frame_callback
+};
+
+static void
xwl_screen_post_damage(struct xwl_screen *xwl_screen)
{
- struct xwl_window *xwl_window;
+ struct xwl_window *xwl_window, *next_xwl_window;
RegionPtr region;
BoxPtr box;
- int count, i;
struct wl_buffer *buffer;
PixmapPtr pixmap;
- xorg_list_for_each_entry(xwl_window, &xwl_screen->damage_window_list,
- link_damage) {
- region = DamageRegion(xwl_window->damage);
- count = RegionNumRects(region);
+ xorg_list_for_each_entry_safe(xwl_window, next_xwl_window,
+ &xwl_screen->damage_window_list, link_damage) {
+ /* If we're waiting on a frame callback from the server,
+ * don't attach a new buffer. */
+ if (xwl_window->frame_callback)
+ continue;
+ region = DamageRegion(xwl_window->damage);
pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window);
#if GLAMOR_HAS_GBM
@@ -345,17 +363,19 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
- for (i = 0; i < count; i++) {
- box = &RegionRects(region)[i];
- wl_surface_damage(xwl_window->surface,
- box->x1, box->y1,
- box->x2 - box->x1, box->y2 - box->y1);
- }
+
+ box = RegionExtents(region);
+ wl_surface_damage(xwl_window->surface, box->x1, box->y1,
+ box->x2 - box->x1, box->y2 - box->y1);
+
+ xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
+ wl_callback_add_listener(xwl_window->frame_callback, &frame_listener, xwl_window);
+
wl_surface_commit(xwl_window->surface);
DamageEmpty(xwl_window->damage);
- }
- xorg_list_init(&xwl_screen->damage_window_list);
+ xorg_list_del(&xwl_window->link_damage);
+ }
}
static void
diff --git a/xorg-server/hw/xwayland/xwayland.h b/xorg-server/hw/xwayland/xwayland.h
index 60b0c2964..bfffa712f 100644
--- a/xorg-server/hw/xwayland/xwayland.h
+++ b/xorg-server/hw/xwayland/xwayland.h
@@ -102,6 +102,7 @@ struct xwl_window {
WindowPtr window;
DamagePtr damage;
struct xorg_list link_damage;
+ struct wl_callback *frame_callback;
};
#define MODIFIER_META 0x01