[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#926540: unblock: xorg-server/2:1.20.4-1



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package xorg-server:

This stable release fixes a bunch of important issues including
xserver crashes. There are multiple fixes related to xwayland, present
and modesetting.

Debian changelog entry:
xorg-server (2:1.20.4-1) unstable; urgency=medium

  [ Timo Aaltonen ]
  * New upstream release.
    - present/wnmd: Fix use after free on CRTC removal
      (Closes: #920665).
    - xwayland: Replace xwl_window::present_window with
      ::present_flipped (Closes: #921734).

  [ Andreas Boll ]
  * Refresh 07_use-modesetting-driver-by-default-on-GeForce.diff.

 -- Andreas Boll <aboll@debian.org>  Tue, 05 Mar 2019 21:11:12 +0100


Further I've attached a git-diff with the following command to exclude
uninteresting CI stuff and tests to make the diff more readable:

git diff xorg-server-2_1.20.3-1..xorg-server-2_1.20.4-1 -- . ':(exclude)test' ':(exclude).gitlab-ci*' ':(exclude).travis.yml' > ../xorg-server_1.20.4-1.diff

I've also attached the output of git-shortlog to list all commit
titles.

unblock xorg-server/2:1.20.4-1

Thanks,
Andreas
diff --git a/Makefile.am b/Makefile.am
index 32d4d21e76..19511f765d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -72,7 +72,7 @@ pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = xorg-server.pc
 endif
 
-EXTRA_DIST = xorg-server.pc.in xorg-server.m4 autogen.sh
+EXTRA_DIST = xorg-server.pc.in xorg-server.m4 autogen.sh README.md
 
 DISTCHECK_CONFIGURE_FLAGS=\
 	--with-xkb-path=$(XKB_BASE_DIRECTORY) \
diff --git a/README b/README.md
similarity index 65%
rename from README
rename to README.md
index 529526d189..bc39f41cd4 100644
--- a/README
+++ b/README.md
@@ -1,4 +1,5 @@
-					X Server
+X Server
+--------
 
 The X server accepts requests from client applications to create windows,
 which are (normally rectangular) "virtual screens" that the client program
@@ -16,29 +17,19 @@ https://en.wikipedia.org/wiki/X_server
 All questions regarding this software should be directed at the
 Xorg mailing list:
 
-        https://lists.freedesktop.org/mailman/listinfo/xorg
-
-Please submit bug reports to the Xorg bugzilla:
-
-        https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
+  https://lists.freedesktop.org/mailman/listinfo/xorg
 
 The master development code repository can be found at:
 
-        git://anongit.freedesktop.org/git/xorg/xserver
-
-        https://cgit.freedesktop.org/xorg/xserver
+  https://gitlab.freedesktop.org/xorg/xserver
 
 For patch submission instructions, see:
 
-	https://www.x.org/wiki/Development/Documentation/SubmittingPatches
-
-For more information on the git code manager, see:
-
-        https://wiki.x.org/wiki/GitPage
+  https://www.x.org/wiki/Development/Documentation/SubmittingPatches
 
 As with other projects hosted on freedesktop.org, X.Org follows its
 Code of Conduct, based on the Contributor Covenant. Please conduct
 yourself in a respectful and civilized manner when using the above
 mailing lists, bug trackers, etc:
 
-	https://www.freedesktop.org/wiki/CodeOfConduct
+  https://www.freedesktop.org/wiki/CodeOfConduct
diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index d0be701352..1926762add 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -611,7 +611,9 @@ CreatePointerBarrierClient(ClientPtr client,
         }
         pbd->deviceid = dev->id;
 
+        input_lock();
         xorg_list_add(&pbd->entry, &ret->per_device);
+        input_unlock();
     }
 
     ret->id = stuff->barrier;
@@ -626,7 +628,9 @@ CreatePointerBarrierClient(ClientPtr client,
         ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
     if (barrier_is_vertical(&ret->barrier))
         ret->barrier.directions &= ~(BarrierPositiveY | BarrierNegativeY);
+    input_lock();
     xorg_list_add(&ret->entry, &cs->barriers);
+    input_unlock();
 
     *client_out = ret;
     return Success;
@@ -689,7 +693,9 @@ BarrierFreeBarrier(void *data, XID id)
         mieqEnqueue(dev, (InternalEvent *) &ev);
     }
 
+    input_lock();
     xorg_list_del(&c->entry);
+    input_unlock();
 
     FreePointerBarrierClient(c);
     return Success;
@@ -709,7 +715,9 @@ static void add_master_func(void *res, XID id, void *devid)
     pbd = AllocBarrierDevice();
     pbd->deviceid = *deviceid;
 
+    input_lock();
     xorg_list_add(&pbd->entry, &barrier->per_device);
+    input_unlock();
 }
 
 static void remove_master_func(void *res, XID id, void *devid)
@@ -752,7 +760,9 @@ static void remove_master_func(void *res, XID id, void *devid)
         mieqEnqueue(dev, (InternalEvent *) &ev);
     }
 
+    input_lock();
     xorg_list_del(&pbd->entry);
+    input_unlock();
     free(pbd);
 }
 
diff --git a/configure.ac b/configure.ac
index 80f0ce7853..30544218a6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,9 +26,9 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.60)
-AC_INIT([xorg-server], 1.20.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2018-10-25"
-RELEASE_NAME="Harissa Roasted Carrots"
+AC_INIT([xorg-server], 1.20.4, [https://gitlab.freedesktop.org/xorg/xserver/issues], xorg-server)
+RELEASE_DATE="2019-02-25"
+RELEASE_NAME="Chestnut Tortelloni"
 AC_CONFIG_SRCDIR([Makefile.am])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
diff --git a/debian/changelog b/debian/changelog
index df7fb11337..ab4743def3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,17 @@
+xorg-server (2:1.20.4-1) unstable; urgency=medium
+
+  [ Timo Aaltonen ]
+  * New upstream release.
+    - present/wnmd: Fix use after free on CRTC removal
+      (Closes: #920665).
+    - xwayland: Replace xwl_window::present_window with
+      ::present_flipped (Closes: #921734).
+
+  [ Andreas Boll ]
+  * Refresh 07_use-modesetting-driver-by-default-on-GeForce.diff.
+
+ -- Andreas Boll <aboll@debian.org>  Tue, 05 Mar 2019 21:11:12 +0100
+
 xorg-server (2:1.20.3-1) unstable; urgency=medium
 
   * New upstream release.
diff --git a/debian/patches/07_use-modesetting-driver-by-default-on-GeForce.diff b/debian/patches/07_use-modesetting-driver-by-default-on-GeForce.diff
index 1b1306e284..be8342911d 100644
--- a/debian/patches/07_use-modesetting-driver-by-default-on-GeForce.diff
+++ b/debian/patches/07_use-modesetting-driver-by-default-on-GeForce.diff
@@ -24,7 +24,7 @@ index 8158c2b62..78d1c947d 100644
 @@ -1190,6 +1191,25 @@ xf86VideoPtrToDriverList(struct pci_device *dev,
          int idx = 0;
  
- #ifdef __linux__
+ #if defined(__linux__) || defined(__NetBSD__)
 +        char busid[32];
 +        int fd;
 +
diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c
index e34bebedb4..958877efad 100644
--- a/dri3/dri3_request.c
+++ b/dri3/dri3_request.c
@@ -135,7 +135,7 @@ proc_dri3_open(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xDRI3OpenReq);
 
-    status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixReadAccess);
+    status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess);
     if (status != Success)
         return status;
 
@@ -365,7 +365,7 @@ proc_dri3_get_supported_modifiers(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq);
 
-    status = dixLookupWindow(&window, stuff->window, client, DixReadAccess);
+    status = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
     if (status != Success)
         return status;
     pScreen = window->drawable.pScreen;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 0417df4e63..d5737018f8 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -766,18 +766,27 @@ glamor_set_normalize_tcoords_generic(PixmapPtr pixmap,
  *
  * We could support many more formats by using GL_ARB_texture_view to
  * parse the same bits as different formats.  For now, we only support
- * tweaking whether we sample the alpha bits of an a8r8g8b8, or just
- * force them to 1.
+ * tweaking whether we sample the alpha bits, or just force them to 1.
  */
 static Bool
-glamor_render_format_is_supported(PictFormatShort format)
+glamor_render_format_is_supported(PicturePtr picture)
 {
-    switch (format) {
+    PictFormatShort storage_format;
+
+    /* Source-only pictures should always work */
+    if (!picture->pDrawable)
+        return TRUE;
+
+    storage_format = format_for_depth(picture->pDrawable->depth);
+
+    switch (picture->format) {
     case PICT_x2r10g10b10:
+        return storage_format == PICT_x2r10g10b10;
     case PICT_a8r8g8b8:
     case PICT_x8r8g8b8:
+        return storage_format == PICT_a8r8g8b8 || storage_format == PICT_x8r8g8b8;
     case PICT_a8:
-        return TRUE;
+        return storage_format == PICT_a8;
     default:
         return FALSE;
     }
@@ -815,7 +824,7 @@ glamor_composite_choose_shader(CARD8 op,
         goto fail;
     }
 
-    if (!glamor_render_format_is_supported(dest->format)) {
+    if (!glamor_render_format_is_supported(dest)) {
         glamor_fallback("Unsupported dest picture format.\n");
         goto fail;
     }
@@ -978,7 +987,7 @@ glamor_composite_choose_shader(CARD8 op,
                 goto fail;
             }
         } else {
-            if (source && !glamor_render_format_is_supported(source->format)) {
+            if (source && !glamor_render_format_is_supported(source)) {
                 glamor_fallback("Unsupported source picture format.\n");
                 goto fail;
             }
@@ -990,7 +999,7 @@ glamor_composite_choose_shader(CARD8 op,
                 goto fail;
             }
         } else if (mask) {
-            if (!glamor_render_format_is_supported(mask->format)) {
+            if (!glamor_render_format_is_supported(mask)) {
                 glamor_fallback("Unsupported mask picture format.\n");
                 goto fail;
             }
diff --git a/glx/vndcmds.c b/glx/vndcmds.c
index 45b1eafaac..f0779d14a2 100644
--- a/glx/vndcmds.c
+++ b/glx/vndcmds.c
@@ -386,10 +386,6 @@ static int dispatch_GLXVendorPriv(ClientPtr client)
         // Note that even if none of the vendors provides a dispatch stub,
         // we'll still add an entry to the dispatch table, so that we don't
         // have to look it up again later.
-        disp = (GlxVendorPrivDispatch *) malloc(sizeof(GlxVendorPrivDispatch));
-        if (disp == NULL) {
-            return BadAlloc;
-        }
 
         disp->proc = GetVendorDispatchFunc(stuff->glxCode,
                                            GlxCheckSwap(client,
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 0718cdcb03..6575c4ec8b 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -1190,7 +1190,7 @@ xf86VideoPtrToDriverList(struct pci_device *dev, XF86MatchedDrivers *md)
     {
         int idx = 0;
 
-#ifdef __linux__
+#if defined(__linux__) || defined(__NetBSD__)
         driverList[idx++] = "nouveau";
 #endif
         driverList[idx++] = "nv";
diff --git a/hw/xfree86/dri2/pci_ids/i965_pci_ids.h b/hw/xfree86/dri2/pci_ids/i965_pci_ids.h
index 82e4a549e0..1ef1a0edff 100644
--- a/hw/xfree86/dri2/pci_ids/i965_pci_ids.h
+++ b/hw/xfree86/dri2/pci_ids/i965_pci_ids.h
@@ -174,6 +174,7 @@ CHIPSET(0x3EA4, cfl_gt1, "Intel(R) HD Graphics (Coffeelake 2x6 GT1)")
 CHIPSET(0x3E91, cfl_gt2, "Intel(R) UHD Graphics 630 (Coffeelake 3x8 GT2)")
 CHIPSET(0x3E92, cfl_gt2, "Intel(R) UHD Graphics 630 (Coffeelake 3x8 GT2)")
 CHIPSET(0x3E96, cfl_gt2, "Intel(R) HD Graphics (Coffeelake 3x8 GT2)")
+CHIPSET(0x3E98, cfl_gt2, "Intel(R) UHD Graphics 630 (Coffeelake 3x8 GT2)")
 CHIPSET(0x3E9A, cfl_gt2, "Intel(R) HD Graphics (Coffeelake 3x8 GT2)")
 CHIPSET(0x3E9B, cfl_gt2, "Intel(R) UHD Graphics 630 (Coffeelake 3x8 GT2)")
 CHIPSET(0x3E94, cfl_gt2, "Intel(R) HD Graphics (Coffeelake 3x8 GT2)")
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 9717d9d399..336f7686ed 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1354,13 +1354,19 @@ drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
 {
     modesettingPtr ms = modesettingPTR(crtc->scrn);
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+    drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
     /* XXX Check if DPMS mode is already the right one */
 
     drmmode_crtc->dpms_mode = mode;
 
-    if (ms->atomic_modeset && mode != DPMSModeOn && !ms->pending_modeset)
-        drmmode_crtc_disable(crtc);
+    if (ms->atomic_modeset) {
+        if (mode != DPMSModeOn && !ms->pending_modeset)
+            drmmode_crtc_disable(crtc);
+    } else if (crtc->enabled == FALSE) {
+        drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+                       0, 0, 0, NULL, 0, NULL);
+    }
 }
 
 #ifdef GLAMOR_HAS_GBM
@@ -2834,7 +2840,7 @@ static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id,
     if (len + 1> 5)
         return -1;
     memcpy(conn_id, blob_data + 4, len);
-    conn_id[len + 1] = '\0';
+    conn_id[len] = '\0';
     id = strtoul(conn_id, NULL, 10);
 
     *conn_base_id = id;
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index b49d4c789c..34f2652bf4 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -2019,7 +2019,7 @@ xf86RandR12ChangeGamma(ScrnInfoPtr pScrn, Gamma gamma)
     RRCrtcPtr randr_crtc = xf86CompatRRCrtc(pScrn);
     int size;
 
-    if (!randr_crtc)
+    if (!randr_crtc || pScrn->LoadPalette == xf86RandR12LoadPalette)
         return Success;
 
     size = max(0, randr_crtc->gammaSize);
diff --git a/hw/xquartz/mach-startup/Makefile.am b/hw/xquartz/mach-startup/Makefile.am
index a0f9e9fe43..b2c446af8c 100644
--- a/hw/xquartz/mach-startup/Makefile.am
+++ b/hw/xquartz/mach-startup/Makefile.am
@@ -76,6 +76,8 @@ nodist_Xquartz_SOURCES = \
 Xquartz_LDFLAGS =  \
 	-Wl,-framework,CoreServices
 
+if XQUARTZ
+
 BUILT_SOURCES = \
 	mach_startupServer.c \
 	mach_startupUser.c \
@@ -88,6 +90,8 @@ CLEANFILES = \
 $(BUILT_SOURCES): $(srcdir)/mach_startup.defs
 	mig -sheader mach_startupServer.h $(srcdir)/mach_startup.defs
 
+endif
+
 EXTRA_DIST = \
 	launchd_fd.h \
 	mach_startup.defs \
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 6aa1e4641d..5f8a68fd8c 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -244,6 +244,9 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap,
     uint64_t modifier;
     int i;
 
+    if (xwl_pixmap == NULL)
+       return NULL;
+
     if (xwl_pixmap->buffer) {
         /* Buffer already exists. Return it and inform caller if interested. */
         if (created)
@@ -494,6 +497,9 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
 
     xwl_pixmap = xwl_pixmap_get(pixmap);
 
+    if (xwl_pixmap == NULL)
+       return 0;
+
     if (!xwl_pixmap->bo)
        return 0;
 
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 316e044434..74fe846720 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -85,28 +85,23 @@ xwl_present_timer_callback(OsTimerPtr timer,
 static inline Bool
 xwl_present_has_events(struct xwl_present_window *xwl_present_window)
 {
-    return !xorg_list_is_empty(&xwl_present_window->event_list) ||
-           !xorg_list_is_empty(&xwl_present_window->release_queue);
-}
-
-static inline Bool
-xwl_present_is_flipping(WindowPtr window, struct xwl_window *xwl_window)
-{
-    return xwl_window && xwl_window->present_window == window;
+    return !!xwl_present_window->sync_flip ||
+           !xorg_list_is_empty(&xwl_present_window->event_list);
 }
 
 static void
 xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
 {
     if (xwl_present_has_events(xwl_present_window)) {
-        WindowPtr present_window = xwl_present_window->window;
-        Bool is_flipping = xwl_present_is_flipping(present_window,
-                                                   xwl_window_from_window(present_window));
+        CARD32 timeout;
+
+        if (xwl_present_window->frame_callback)
+            timeout = TIMER_LEN_FLIP;
+        else
+            timeout = TIMER_LEN_COPY;
 
         xwl_present_window->frame_timer = TimerSet(xwl_present_window->frame_timer,
-                                                   0,
-                                                   is_flipping ? TIMER_LEN_FLIP :
-                                                                 TIMER_LEN_COPY,
+                                                   0, timeout,
                                                    &xwl_present_timer_callback,
                                                    xwl_present_window);
     } else {
@@ -117,16 +112,12 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
 void
 xwl_present_cleanup(WindowPtr window)
 {
-    struct xwl_window *xwl_window = xwl_window_from_window(window);
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
     struct xwl_present_event *event, *tmp;
 
     if (!xwl_present_window)
         return;
 
-    if (xwl_window && xwl_window->present_window == window)
-        xwl_window->present_window = NULL;
-
     if (xwl_present_window->frame_callback) {
         wl_callback_destroy(xwl_present_window->frame_callback);
         xwl_present_window->frame_callback = NULL;
@@ -139,6 +130,16 @@ xwl_present_cleanup(WindowPtr window)
     }
 
     /* Clear remaining buffer releases and inform Present about free ressources */
+    event = xwl_present_window->sync_flip;
+    xwl_present_window->sync_flip = NULL;
+    if (event) {
+        if (event->buffer_released) {
+            free(event);
+        } else {
+            event->pending = FALSE;
+            event->abort = TRUE;
+        }
+    }
     xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->release_queue, list) {
         xorg_list_del(&event->list);
         event->abort = TRUE;
@@ -192,11 +193,31 @@ static const struct wl_buffer_listener xwl_present_release_listener = {
 };
 
 static void
-xwl_present_events_notify(struct xwl_present_window *xwl_present_window)
+xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
 {
-    uint64_t                    msc = xwl_present_window->msc;
+    uint64_t msc = ++xwl_present_window->msc;
     struct xwl_present_event    *event, *tmp;
 
+    xwl_present_window->ust = GetTimeInMicros();
+
+    event = xwl_present_window->sync_flip;
+    xwl_present_window->sync_flip = NULL;
+    if (event) {
+        event->pending = FALSE;
+
+        present_wnmd_event_notify(xwl_present_window->window, event->event_id,
+                                  xwl_present_window->ust, msc);
+
+        if (event->buffer_released) {
+            /* If the buffer was already released, clean up now */
+            present_wnmd_event_notify(xwl_present_window->window, event->event_id,
+                                      xwl_present_window->ust, msc);
+            free(event);
+        } else {
+            xorg_list_add(&event->list, &xwl_present_window->release_queue);
+        }
+    }
+
     xorg_list_for_each_entry_safe(event, tmp,
                                   &xwl_present_window->event_list,
                                   list) {
@@ -216,24 +237,13 @@ xwl_present_timer_callback(OsTimerPtr timer,
                            void *arg)
 {
     struct xwl_present_window *xwl_present_window = arg;
-    WindowPtr present_window = xwl_present_window->window;
-    struct xwl_window *xwl_window = xwl_window_from_window(present_window);
 
     xwl_present_window->frame_timer_firing = TRUE;
-    xwl_present_window->msc++;
-    xwl_present_window->ust = GetTimeInMicros();
 
-    xwl_present_events_notify(xwl_present_window);
+    xwl_present_msc_bump(xwl_present_window);
+    xwl_present_reset_timer(xwl_present_window);
 
-    if (xwl_present_has_events(xwl_present_window)) {
-        /* Still events, restart timer */
-        return xwl_present_is_flipping(present_window, xwl_window) ? TIMER_LEN_FLIP :
-                                                                     TIMER_LEN_COPY;
-    } else {
-        /* No more events, do not restart timer and delete it instead */
-        xwl_present_free_timer(xwl_present_window);
-        return 0;
-    }
+    return 0;
 }
 
 static void
@@ -251,10 +261,7 @@ xwl_present_frame_callback(void *data,
         return;
     }
 
-    xwl_present_window->msc++;
-    xwl_present_window->ust = GetTimeInMicros();
-
-    xwl_present_events_notify(xwl_present_window);
+    xwl_present_msc_bump(xwl_present_window);
 
     /* we do not need the timer anymore for this frame,
      * reset it for potentially the next one
@@ -274,6 +281,9 @@ xwl_present_sync_callback(void *data,
     struct xwl_present_event *event = data;
     struct xwl_present_window *xwl_present_window = event->xwl_present_window;
 
+    wl_callback_destroy(xwl_present_window->sync_callback);
+    xwl_present_window->sync_callback = NULL;
+
     event->pending = FALSE;
 
     if (event->abort) {
@@ -289,12 +299,14 @@ xwl_present_sync_callback(void *data,
                               xwl_present_window->ust,
                               xwl_present_window->msc);
 
-    if (event->buffer_released)
+    if (event->buffer_released) {
         /* If the buffer was already released, send the event now again */
         present_wnmd_event_notify(xwl_present_window->window,
                                   event->event_id,
                                   xwl_present_window->ust,
                                   xwl_present_window->msc);
+        xwl_present_free_event(event);
+    }
 }
 
 static const struct wl_callback_listener xwl_present_sync_listener = {
@@ -311,6 +323,10 @@ xwl_present_get_crtc(WindowPtr present_window)
         return NULL;
 
     rr_private = rrGetScrPriv(present_window->drawable.pScreen);
+
+    if (rr_private->numCrtcs == 0)
+        return NULL;
+
     return rr_private->crtcs[0];
 }
 
@@ -337,17 +353,9 @@ xwl_present_queue_vblank(WindowPtr present_window,
                          uint64_t event_id,
                          uint64_t msc)
 {
-    struct xwl_window *xwl_window = xwl_window_from_window(present_window);
     struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
     struct xwl_present_event *event;
 
-    if (!xwl_window)
-        return BadMatch;
-
-    if (xwl_window->present_window &&
-            xwl_window->present_window != present_window)
-        return BadMatch;
-
     event = malloc(sizeof *event);
     if (!event)
         return BadAlloc;
@@ -417,13 +425,6 @@ xwl_present_check_flip2(RRCrtcPtr crtc,
         return FALSE;
 
     /*
-     * Do not flip if there is already another child window doing flips.
-     */
-    if (xwl_window->present_window &&
-            xwl_window->present_window != present_window)
-        return FALSE;
-
-    /*
      * We currently only allow flips of windows, that have the same
      * dimensions as their xwl_window parent window. For the case of
      * different sizes subsurfaces are presumably the way forward.
@@ -459,19 +460,22 @@ xwl_present_flip(WindowPtr present_window,
     if (!event)
         return FALSE;
 
-    xwl_window->present_window = present_window;
-
     buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, &buffer_created);
 
     event->event_id = event_id;
     event->xwl_present_window = xwl_present_window;
     event->buffer = buffer;
-    event->target_msc = xwl_present_window->msc;
+    event->target_msc = target_msc;
     event->pending = TRUE;
     event->abort = FALSE;
     event->buffer_released = FALSE;
 
-    xorg_list_add(&event->list, &xwl_present_window->release_queue);
+    if (sync_flip) {
+        xorg_list_init(&event->list);
+        xwl_present_window->sync_flip = event;
+    } else {
+        xorg_list_add(&event->list, &xwl_present_window->release_queue);
+    }
 
     if (buffer_created)
         wl_buffer_add_listener(buffer, &xwl_present_release_listener, NULL);
@@ -480,13 +484,6 @@ xwl_present_flip(WindowPtr present_window,
     /* We can flip directly to the main surface (full screen window without clips) */
     wl_surface_attach(xwl_window->surface, buffer, 0, 0);
 
-    if (!xwl_present_window->frame_timer ||
-            xwl_present_window->frame_timer_firing) {
-        /* Realign timer */
-        xwl_present_window->frame_timer_firing = FALSE;
-        xwl_present_reset_timer(xwl_present_window);
-    }
-
     if (!xwl_present_window->frame_callback) {
         xwl_present_window->frame_callback = wl_surface_frame(xwl_window->surface);
         wl_callback_add_listener(xwl_present_window->frame_callback,
@@ -494,35 +491,51 @@ xwl_present_flip(WindowPtr present_window,
                                  xwl_present_window);
     }
 
+    /* Realign timer */
+    xwl_present_window->frame_timer_firing = FALSE;
+    xwl_present_reset_timer(xwl_present_window);
+
     wl_surface_damage(xwl_window->surface, 0, 0,
                       damage_box->x2 - damage_box->x1,
                       damage_box->y2 - damage_box->y1);
 
     wl_surface_commit(xwl_window->surface);
 
-    xwl_present_window->sync_callback = wl_display_sync(xwl_window->xwl_screen->display);
-    wl_callback_add_listener(xwl_present_window->sync_callback,
-                             &xwl_present_sync_listener,
-                             event);
+    if (!sync_flip) {
+        xwl_present_window->sync_callback =
+            wl_display_sync(xwl_window->xwl_screen->display);
+        wl_callback_add_listener(xwl_present_window->sync_callback,
+                                 &xwl_present_sync_listener,
+                                 event);
+    }
 
     wl_display_flush(xwl_window->xwl_screen->display);
+    xwl_window->present_flipped = TRUE;
     return TRUE;
 }
 
 static void
 xwl_present_flips_stop(WindowPtr window)
 {
-    struct xwl_window *xwl_window = xwl_window_from_window(window);
     struct xwl_present_window   *xwl_present_window = xwl_present_window_priv(window);
 
-    if (!xwl_window)
-        return;
+    /* Change back to the fast refresh rate */
+    xwl_present_reset_timer(xwl_present_window);
+}
 
-    assert(xwl_window->present_window == window);
+void
+xwl_present_unrealize_window(WindowPtr window)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
 
-    xwl_window->present_window = NULL;
+    if (!xwl_present_window || !xwl_present_window->frame_callback)
+        return;
 
-    /* Change back to the fast refresh rate */
+    /* The pending frame callback may never be called, so drop it and shorten
+     * the frame timer interval.
+     */
+    wl_callback_destroy(xwl_present_window->frame_callback);
+    xwl_present_window->frame_callback = NULL;
     xwl_present_reset_timer(xwl_present_window);
 }
 
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 96b4db18c5..7e6e0ab254 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -370,6 +370,18 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
     struct xwl_window *xwl_window = data;
     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
 
+#ifdef GLAMOR_HAS_GBM
+    if (xwl_window->present_flipped) {
+        /* This damage is from a Present flip, which already committed a new
+         * buffer for the surface, so we don't need to do anything in response
+         */
+        RegionEmpty(DamageRegion(pDamage));
+        xorg_list_del(&xwl_window->link_damage);
+        xwl_window->present_flipped = FALSE;
+        return;
+    }
+#endif
+
     xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list);
 }
 
@@ -597,6 +609,11 @@ xwl_unrealize_window(WindowPtr window)
     xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
     screen->UnrealizeWindow = xwl_unrealize_window;
 
+#ifdef GLAMOR_HAS_GBM
+    if (xwl_screen->present)
+        xwl_present_unrealize_window(window);
+#endif
+
     xwl_window = xwl_window_get(window);
     if (!xwl_window)
         return ret;
@@ -721,11 +738,6 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
 
     xorg_list_for_each_entry_safe(xwl_window, next_xwl_window,
                                   &xwl_screen->damage_window_list, link_damage) {
-#ifdef GLAMOR_HAS_GBM
-        /* Present on the main surface. So don't commit here as well. */
-        if (xwl_window->present_window)
-            continue;
-#endif
         /* If we're waiting on a frame callback from the server,
          * don't attach a new buffer. */
         if (xwl_window->frame_callback)
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 67819e1780..463622669d 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -182,12 +182,15 @@ struct xwl_window {
     struct xorg_list link_damage;
     struct wl_callback *frame_callback;
     Bool allow_commits;
-    WindowPtr present_window;
+#ifdef GLAMOR_HAS_GBM
+    Bool present_flipped;
+#endif
 };
 
 #ifdef GLAMOR_HAS_GBM
 struct xwl_present_window {
     struct xwl_screen *xwl_screen;
+    struct xwl_present_event *sync_flip;
     WindowPtr window;
     struct xorg_list link;
 
@@ -451,6 +454,7 @@ void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
 #ifdef GLAMOR_HAS_GBM
 Bool xwl_present_init(ScreenPtr screen);
 void xwl_present_cleanup(WindowPtr window);
+void xwl_present_unrealize_window(WindowPtr window);
 #endif /* GLAMOR_HAS_GBM */
 
 #ifdef XV
diff --git a/hw/xwin/glx/Makefile.am b/hw/xwin/glx/Makefile.am
index 1fc57f2399..119fee4042 100644
--- a/hw/xwin/glx/Makefile.am
+++ b/hw/xwin/glx/Makefile.am
@@ -62,9 +62,10 @@ generated_gl_thunks.ic: $(srcdir)/gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/gl.xml
 
 generated_gl_thunks.def: $(srcdir)/gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/gl.xml $(KHRONOS_SPEC_DIR)/reg.py
 	$(AM_V_GEN)PYTHONPATH=$(KHRONOS_SPEC_DIR) $(PYTHON3) $(srcdir)/gen_gl_wrappers.py -registry $(KHRONOS_SPEC_DIR)/gl.xml -thunkdefs $(GENGLWRAPPERSOPTS) -outfile $@
-endif
 
 BUILT_SOURCES = generated_gl_shim.ic generated_gl_thunks.ic generated_gl_thunks.def generated_wgl_wrappers.ic
 CLEANFILES = $(BUILT_SOURCES)
 
+endif
+
 EXTRA_DIST = gen_gl_wrappers.py
diff --git a/include/Makefile.am b/include/Makefile.am
index 0ce7faa6ea..9c22ce1130 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -79,5 +79,8 @@ EXTRA_DIST = 	\
 	swapreq.h \
 	systemd-logind.h \
         vidmodestr.h \
+	xorg-config.h.meson.in \
 	xorg-server.h.meson.in \
+	xwayland-config.h.meson.in \
+	xwin-config.h.meson.in \
 	xsha1.h
diff --git a/include/xserver_poll.h b/include/xserver_poll.h
index 5a42307df4..0f3a37c736 100644
--- a/include/xserver_poll.h
+++ b/include/xserver_poll.h
@@ -24,7 +24,7 @@
 #define _XSERVER_POLL_H_
 
 #ifndef _DIX_CONFIG_H_
-#error must inclue dix-config.h to use xserver_poll.h
+#error must include dix-config.h to use xserver_poll.h
 #endif
 
 #ifdef HAVE_POLL
diff --git a/meson.build b/meson.build
index ec9a24be69..999c408912 100644
--- a/meson.build
+++ b/meson.build
@@ -3,7 +3,7 @@ project('xserver', 'c',
             'buildtype=debugoptimized',
             'c_std=gnu99',
         ],
-        version: '1.20.3',
+        version: '1.20.4',
         meson_version: '>= 0.42.0',
 )
 add_project_arguments('-DHAVE_DIX_CONFIG_H', language: 'c')
diff --git a/mi/miinitext.c b/mi/miinitext.c
index 5596e212f9..b7c702127a 100644
--- a/mi/miinitext.c
+++ b/mi/miinitext.c
@@ -190,7 +190,7 @@ EnableDisableExtension(const char *name, Bool enable)
 
     for (i = 0; i < ARRAY_SIZE(staticExtensions); i++) {
         ext = &staticExtensions[i];
-        if (strcmp(name, ext->name) == 0) {
+        if (strcasecmp(name, ext->name) == 0) {
             if (ext->disablePtr != NULL) {
                 *ext->disablePtr = !enable;
                 return TRUE;
diff --git a/os/auth.c b/os/auth.c
index da8b70985a..d3254349d3 100644
--- a/os/auth.c
+++ b/os/auth.c
@@ -42,6 +42,7 @@ from The Open Group.
 #include   "dixstruct.h"
 #include   <sys/types.h>
 #include   <sys/stat.h>
+#include   <errno.h>
 #ifdef WIN32
 #include    <X11/Xw32defs.h>
 #endif
@@ -119,9 +120,15 @@ LoadAuthorization(void)
     if (!authorization_file)
         return 0;
 
+    errno = 0;
     f = Fopen(authorization_file, "r");
-    if (!f)
+    if (!f) {
+        LogMessageVerb(X_ERROR, 0,
+                       "Failed to open authorization file \"%s\": %s\n",
+                       authorization_file,
+                       errno != 0 ? strerror(errno) : "Unknown error");
         return -1;
+    }
 
     while ((auth = XauReadAuth(f)) != 0) {
         for (i = 0; i < NUM_AUTHORIZATION; i++) {
diff --git a/os/utils.c b/os/utils.c
index 6e3c168696..2ba1c80132 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -485,14 +485,15 @@ GetTimeInMicros(void)
     struct timeval tv;
 #ifdef MONOTONIC_CLOCK
     struct timespec tp;
+    static clockid_t uclockid;
 
-    if (!clockid) {
+    if (!uclockid) {
         if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
-            clockid = CLOCK_MONOTONIC;
+            uclockid = CLOCK_MONOTONIC;
         else
-            clockid = ~0L;
+            uclockid = ~0L;
     }
-    if (clockid != ~0L && clock_gettime(clockid, &tp) == 0)
+    if (uclockid != ~0L && clock_gettime(uclockid, &tp) == 0)
         return (CARD64) tp.tv_sec * (CARD64)1000000 + tp.tv_nsec / 1000;
 #endif
 
diff --git a/present/present.c b/present/present.c
index 37cbf07204..3eddb74344 100644
--- a/present/present.c
+++ b/present/present.c
@@ -108,7 +108,7 @@ present_pixmap_idle(PixmapPtr pixmap, WindowPtr window, CARD32 serial, struct pr
     if (present_fence)
         present_fence_set_triggered(present_fence);
     if (window) {
-        DebugPresent(("\ti %08lx\n", pixmap ? pixmap->drawable.id : 0));
+        DebugPresent(("\ti %08" PRIx32 "\n", pixmap ? pixmap->drawable.id : 0));
         present_send_idle_notify(window, serial, pixmap, present_fence);
     }
 }
diff --git a/present/present_priv.h b/present/present_priv.h
index f62456755d..5849b9e0bd 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -34,6 +34,7 @@
 #include <syncsrv.h>
 #include <xfixes.h>
 #include <randrstr.h>
+#include <inttypes.h>
 
 #if 0
 #define DebugPresent(x) ErrorF x
diff --git a/present/present_scmd.c b/present/present_scmd.c
index 0803a0c0bb..6a580cb7aa 100644
--- a/present/present_scmd.c
+++ b/present/present_scmd.c
@@ -133,12 +133,12 @@ present_check_flip(RRCrtcPtr            crtc,
     /* Ask the driver for permission */
     if (screen_priv->info->version >= 1 && screen_priv->info->check_flip2) {
         if (!(*screen_priv->info->check_flip2) (crtc, window, pixmap, sync_flip, reason)) {
-            DebugPresent(("\td %08lx -> %08lx\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0));
+            DebugPresent(("\td %08" PRIx32 " -> %08" PRIx32 "\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0));
             return FALSE;
         }
     } else if (screen_priv->info->check_flip) {
         if (!(*screen_priv->info->check_flip) (crtc, window, pixmap, sync_flip)) {
-            DebugPresent(("\td %08lx -> %08lx\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0));
+            DebugPresent(("\td %08" PRIx32 " -> %08" PRIx32 "\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0));
             return FALSE;
         }
     }
@@ -351,7 +351,7 @@ present_unflip(ScreenPtr screen)
     present_restore_screen_pixmap(screen);
 
     screen_priv->unflip_event_id = ++present_event_id;
-    DebugPresent(("u %lld\n", screen_priv->unflip_event_id));
+    DebugPresent(("u %" PRIu64 "\n", screen_priv->unflip_event_id));
     (*screen_priv->info->unflip) (screen, screen_priv->unflip_event_id);
 }
 
@@ -361,7 +361,7 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     ScreenPtr                   screen = vblank->screen;
     present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
 
-    DebugPresent(("\tn %lld %p %8lld: %08lx -> %08lx\n",
+    DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
                   vblank->event_id, vblank, vblank->target_msc,
                   vblank->pixmap ? vblank->pixmap->drawable.id : 0,
                   vblank->window ? vblank->window->drawable.id : 0));
@@ -402,7 +402,7 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc)
 
     if (!event_id)
         return;
-    DebugPresent(("\te %lld ust %lld msc %lld\n", event_id, ust, msc));
+    DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n", event_id, ust, msc));
     xorg_list_for_each_entry(vblank, &present_exec_queue, event_queue) {
         int64_t match = event_id - vblank->event_id;
         if (match == 0) {
@@ -425,7 +425,7 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc)
         present_screen_priv_ptr screen_priv = present_screen_priv(screen);
 
         if (event_id == screen_priv->unflip_event_id) {
-            DebugPresent(("\tun %lld\n", event_id));
+            DebugPresent(("\tun %" PRIu64 "\n", event_id));
             screen_priv->unflip_event_id = 0;
             present_flip_idle(screen);
             present_flip_try_ready(screen);
@@ -547,7 +547,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 
     if (vblank->flip && vblank->pixmap && vblank->window) {
         if (screen_priv->flip_pending || screen_priv->unflip_event_id) {
-            DebugPresent(("\tr %lld %p (pending %p unflip %lld)\n",
+            DebugPresent(("\tr %" PRIu64 " %p (pending %p unflip %" PRIu64 ")\n",
                           vblank->event_id, vblank,
                           screen_priv->flip_pending, screen_priv->unflip_event_id));
             xorg_list_del(&vblank->event_queue);
@@ -565,7 +565,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 
         if (vblank->flip) {
 
-            DebugPresent(("\tf %lld %p %8lld: %08lx -> %08lx\n",
+            DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
                           vblank->event_id, vblank, crtc_msc,
                           vblank->pixmap->drawable.id, vblank->window->drawable.id));
 
@@ -609,7 +609,8 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             screen_priv->flip_pending = NULL;
             vblank->flip = FALSE;
         }
-        DebugPresent(("\tc %p %8lld: %08lx -> %08lx\n", vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
+        DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
+                      vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
         if (screen_priv->flip_pending) {
 
             /* Check pending flip
@@ -713,7 +714,7 @@ present_scmd_pixmap(WindowPtr window,
             if (vblank->crtc != target_crtc || vblank->target_msc != target_msc)
                 continue;
 
-            DebugPresent(("\tx %lld %p %8lld: %08lx -> %08lx (crtc %p)\n",
+            DebugPresent(("\tx %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p)\n",
                           vblank->event_id, vblank, vblank->target_msc,
                           vblank->pixmap->drawable.id, vblank->window->drawable.id,
                           vblank->crtc));
diff --git a/present/present_vblank.c b/present/present_vblank.c
index f93a1afa99..2c124f4bb6 100644
--- a/present/present_vblank.c
+++ b/present/present_vblank.c
@@ -138,7 +138,7 @@ present_vblank_create(WindowPtr window,
     }
 
     if (pixmap)
-        DebugPresent(("q %lld %p %8lld: %08lx -> %08lx (crtc %p) flip %d vsync %d serial %d\n",
+        DebugPresent(("q %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p) flip %d vsync %d serial %d\n",
                       vblank->event_id, vblank, *target_msc,
                       vblank->pixmap->drawable.id, vblank->window->drawable.id,
                       target_crtc, vblank->flip, vblank->sync_flip, vblank->serial));
@@ -153,7 +153,7 @@ no_mem:
 void
 present_vblank_scrap(present_vblank_ptr vblank)
 {
-    DebugPresent(("\tx %lld %p %8lld: %08lx -> %08lx (crtc %p)\n",
+    DebugPresent(("\tx %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p)\n",
                   vblank->event_id, vblank, vblank->target_msc,
                   vblank->pixmap->drawable.id, vblank->window->drawable.id,
                   vblank->crtc));
@@ -175,7 +175,7 @@ present_vblank_destroy(present_vblank_ptr vblank)
     /* Also make sure vblank is removed from event queue (wnmd) */
     xorg_list_del(&vblank->event_queue);
 
-    DebugPresent(("\td %lld %p %8lld: %08lx -> %08lx\n",
+    DebugPresent(("\td %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
                   vblank->event_id, vblank, vblank->target_msc,
                   vblank->pixmap ? vblank->pixmap->drawable.id : 0,
                   vblank->window ? vblank->window->drawable.id : 0));
diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index 8f38364406..9d0b147cc3 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -168,7 +168,7 @@ present_wnmd_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_
     WindowPtr                   window = vblank->window;
     present_window_priv_ptr     window_priv = present_window_priv(window);
 
-    DebugPresent(("\tn %lld %p %8lld: %08lx -> %08lx\n",
+    DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
                   vblank->event_id, vblank, vblank->target_msc,
                   vblank->pixmap ? vblank->pixmap->drawable.id : 0,
                   vblank->window ? vblank->window->drawable.id : 0));
@@ -213,7 +213,7 @@ present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uin
         return;
     }
 
-    DebugPresent(("\te %lld ust %lld msc %lld\n", event_id, ust, msc));
+    DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n", event_id, ust, msc));
     xorg_list_for_each_entry(vblank, &window_priv->exec_queue, event_queue) {
         if (event_id == vblank->event_id) {
             present_wnmd_execute(vblank, ust, msc);
@@ -270,8 +270,8 @@ present_wnmd_check_flip(RRCrtcPtr           crtc,
     if (!screen_priv->wnmd_info->flip)
         return FALSE;
 
-    /* Don't flip redirected windows */
-    if (window->redirectDraw != RedirectDrawNone)
+    /* Can't flip redirected child windows */
+    if (screen->GetWindowPixmap(window) != screen->GetWindowPixmap(toplvl_window))
         return FALSE;
 
     /* Source pixmap must align with window exactly */
@@ -292,7 +292,8 @@ present_wnmd_check_flip(RRCrtcPtr           crtc,
     /* Ask the driver for permission */
     if (screen_priv->wnmd_info->check_flip2) {
         if (!(*screen_priv->wnmd_info->check_flip2) (crtc, window, pixmap, sync_flip, reason)) {
-            DebugPresent(("\td %08lx -> %08lx\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0));
+            DebugPresent(("\td %08" PRIx32 " -> %08" PRIx32 "\n",
+                          window->drawable.id, pixmap ? pixmap->drawable.id : 0));
             return FALSE;
         }
     }
@@ -354,7 +355,7 @@ present_wnmd_flip(WindowPtr window,
                   Bool sync_flip,
                   RegionPtr damage)
 {
-    ScreenPtr                   screen = crtc->pScreen;
+    ScreenPtr                   screen = window->drawable.pScreen;
     present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
 
     return (*screen_priv->wnmd_info->flip) (window,
@@ -425,7 +426,7 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 
     if (vblank->flip && vblank->pixmap && vblank->window) {
         if (window_priv->flip_pending) {
-            DebugPresent(("\tr %lld %p (pending %p)\n",
+            DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
                           vblank->event_id, vblank,
                           window_priv->flip_pending));
             xorg_list_del(&vblank->event_queue);
@@ -444,7 +445,7 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
         if (vblank->flip) {
             RegionPtr damage;
 
-            DebugPresent(("\tf %lld %p %8lld: %08lx -> %08lx\n",
+            DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
                           vblank->event_id, vblank, crtc_msc,
                           vblank->pixmap->drawable.id, vblank->window->drawable.id));
 
@@ -489,7 +490,8 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             window_priv->flip_pending = NULL;
             vblank->flip = FALSE;
         }
-        DebugPresent(("\tc %p %8lld: %08lx -> %08lx\n", vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
+        DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
+                      vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
 
         present_wnmd_cancel_flip(window);
 
A. Wilcox (1):
      DRI2: Add another Coffeelake PCI ID

Adam Jackson (6):
      automake: Distribute meson's configure header templates
      dri3: Fix XACE access mode for open and get_supported_modifiers
      mi: When {en,dis}abling extensions, match names case-insensitively
      vnd: Fix a silly memory leak
      gitlab: Skip the docker-in-docker step
      xserver 1.20.4

Alan Coopersmith (3):
      Update README for gitlab migration
      Update configure.ac bug URL for gitlab migration
      os: Report errors opening authorization file (#469)

Andreas Boll (3):
      Refresh 07_use-modesetting-driver-by-default-on-GeForce.diff.
      Close bugs #920665 and #921734
      Upload to unstable

Ilia Mirkin (1):
      modesetting: fix conn_id termination and potential overrun by 1 byte

Lionel Landwerlin (1):
      present: fix compile warning with debug traces

Lyude Paul (1):
      modesetting: Actually disable CRTCs in legacy mode

Maya Rashish (2):
      Fix typo in error message
      xfree86: Try nouveau on NetBSD as well.

Michel Daenzer (2):
      travis: Use a single meson invocation
      Make artifacts of piglit results if job fails

Michel Dänzer (22):
      xwayland: Plug leaks in xwl_present_sync_callback
      xwayland: Use xwl_present_reset_timer in xwl_present_timer_callback
      xwayland: Rename xwl_present_events_notify to xwl_present_msc_bump
      xwayland: Complete "synchronous" Present flips from xwl_present_msc_bump
      xwayland: Replace xwl_window::present_window with ::present_flipped
      xwayland: Add xwl_present_unrealize_window
      xwayland: Don't need xwl_window anymore in xwl_present_queue_vblank
      xwayland: Don't take buffer release queue into account for frame timer
      glamor: Check that storage format is compatible with RENDER format
      xfree86/modes: Don't clobber gamma LUT of compatibility output's CRTC
      Drop Travis Linux build in favour of GitLab CI
      gitlab-ci: Docker image can be generated as part of pipeline
      test: Use .../piglit instead of .../piglit-*.py
      gitlab-ci: Set LC_ALL=C.UTF-8
      gitlab-ci: Only run docker-image stage if relevant source files change
      gitlab-ci: Don't rely on $CI_PROJECT_NAME
      gitlab-ci: Add ccache to docker image, and leave in autotools
      gitlab-ci: Use ccache
      gitlab-ci: Add autotools build & test job (Cherry picked from commit 2f12c8017508f23195db92503435fc3ef183da4b)
      present/wnmd: Allow flipping if the window pixmap matches the toplevel's
      glx,xquartz: Fix make distcheck
      gitlab-ci: Run make distcheck in autotools build & test job

Olivier Fourdan (3):
      present/wnmd: Fix use after free on CRTC removal
      xwayland: do not crash if `gbm_bo_create()` fails
      xwayland: handle case without any crtc

Peter Harris (1):
      os: Fix GetTimeInMicros resolution

Peter Hutterer (2):
      test: fix failing tests
      Xi: lock the input thread for any pointer barrier list manipulation

Timo Aaltonen (2):
      Merge branch 'upstream-unstable' into debian-unstable
      bump the version


Reply to: