[Xquartz-changes] xserver: Branch 'master' - 147 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Tue Jun 9 23:42:57 PDT 2015


Rebased ref, commits from common ancestor:
commit 9003a3e5c55903ce4e371b2d5cb5030b5f97ae0e
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue Jun 9 23:41:12 2015 -0700

    XQuartz: Silence -Wformat-security for NSRunAlertPanel
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 2efbd65..8a928ba 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -1069,12 +1069,12 @@ X11ApplicationCanEnterRandR(void)
     if (!XQuartzIsRootless)
         QuartzShowFullscreen(FALSE);
 
-    switch (NSRunAlertPanel(title, msg,
+    switch (NSRunAlertPanel(title, @"%@",
                             NSLocalizedString(@"Allow",
                                               @""),
                             NSLocalizedString(@"Cancel",
                                               @""),
-                            NSLocalizedString(@"Always Allow", @""))) {
+                            NSLocalizedString(@"Always Allow", @""), msg)) {
     case NSAlertOtherReturn:
         [X11App prefs_set_boolean:@PREFS_NO_RANDR_ALERT value:YES];
         [X11App prefs_synchronize];
@@ -1122,10 +1122,10 @@ X11ApplicationFatalError(const char *f, va_list args)
      */
     dispatch_sync(dispatch_get_main_queue(), ^{
                       if (NSAlertDefaultReturn ==
-                          NSRunAlertPanel (title, msg,
+                          NSRunAlertPanel (title, @"%@",
                                            NSLocalizedString (@"Quit", @""),
-                                           NSLocalizedString (
-                                               @"Report...", @""), nil)) {
+                                           NSLocalizedString (@"Report...", @""),
+                                           nil, msg)) {
                           exit (EXIT_FAILURE);
                       }
                   });
@@ -1160,9 +1160,8 @@ check_xinitrc(void)
             @"Startup xinitrc dialog");
 
     if (NSAlertDefaultReturn ==
-        NSRunAlertPanel(nil, msg, NSLocalizedString(@"Yes", @""),
-                        NSLocalizedString(@"No",
-                                          @""), nil)) {
+        NSRunAlertPanel(nil, @"%@", NSLocalizedString(@"Yes", @""),
+                        NSLocalizedString(@"No", @""), nil, msg)) {
         char buf2[1024];
         int i = -1;
 
diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m
index a5c5138..c75493c 100644
--- a/hw/xquartz/X11Controller.m
+++ b/hw/xquartz/X11Controller.m
@@ -929,9 +929,9 @@ extern char *bundle_id_prefix;
      *        and then run the alert on a timer? It seems to work here, so..
      */
 
-    return (NSRunAlertPanel(title, msg, NSLocalizedString(@"Quit", @""),
-                            NSLocalizedString(@"Cancel", @""), nil)
-            == NSAlertDefaultReturn) ? NSTerminateNow : NSTerminateCancel;
+    NSInteger result = NSRunAlertPanel(title, @"%@", NSLocalizedString(@"Quit", @""),
+                                       NSLocalizedString(@"Cancel", @""), nil, msg);
+    return (result == NSAlertDefaultReturn) ? NSTerminateNow : NSTerminateCancel;
 }
 
 - (void) applicationWillTerminate:(NSNotification *)aNotification _X_NORETURN
commit 3a6fa115759c787ec34483437021ad1e55c52423
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue Jun 9 23:34:50 2015 -0700

    XQuartz: Silence -Wunused-function
    
    quartzKeyboard.c:741:1: warning: unused function 'macroman2ucs' [-Wunused-function,Unused Entity Issue]
    macroman2ucs(unsigned char c)
    ^
    1 warning generated.
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/quartzKeyboard.c b/hw/xquartz/quartzKeyboard.c
index 84e34d9..2fed593 100644
--- a/hw/xquartz/quartzKeyboard.c
+++ b/hw/xquartz/quartzKeyboard.c
@@ -737,6 +737,7 @@ LegalModifier(unsigned int key, DeviceIntPtr pDev)
     return 1;
 }
 
+#if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050
 static inline UniChar
 macroman2ucs(unsigned char c)
 {
@@ -782,6 +783,7 @@ macroman2ucs(unsigned char c)
     if (c < 128) return c;
     else return table[c - 128];
 }
+#endif
 
 static KeySym
 make_dead_key(KeySym in)
commit 9fe7f5ccada37e2d2a2fa92064b92a0334a3fcdd
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue Jun 9 23:30:50 2015 -0700

    XQuartz: Silence -Wunused-variable
    
    X11Controller.m:939:9: warning: unused variable 'remain' [-Wunused-variable,Unused Entity Issue]
        int remain;
            ^
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m
index c3c6976..a5c5138 100644
--- a/hw/xquartz/X11Controller.m
+++ b/hw/xquartz/X11Controller.m
@@ -936,7 +936,6 @@ extern char *bundle_id_prefix;
 
 - (void) applicationWillTerminate:(NSNotification *)aNotification _X_NORETURN
 {
-    int remain;
     [X11App prefs_synchronize];
 
     /* shutdown the X server, it will exit () for us. */
commit 0b9c32489131a5723bd78decf5d2557b94207cf4
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue Jun 9 23:29:40 2015 -0700

    XQuartz: Silence -Wpointer-bool-conversion
    
    X11Controller.m:417:17: error: address of function 'asl_log_descriptor' will always evaluate to 'true'
          [-Werror,-Wpointer-bool-conversion,Value Conversion Issue]
                if (asl_log_descriptor) {
                ~~  ^~~~~~~~~~~~~~~~~~
    X11Controller.m:417:17: note: prefix with the address-of operator to silence this warning [Semantic Issue]
                if (asl_log_descriptor) {
                    ^
                    &
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m
index 022e832..c3c6976 100644
--- a/hw/xquartz/X11Controller.m
+++ b/hw/xquartz/X11Controller.m
@@ -364,7 +364,7 @@ extern char *bundle_id_prefix;
     }
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
-    if (asl_log_descriptor) {
+    if (&asl_log_descriptor) {
         char *asl_sender;
         aslmsg amsg = asl_new(ASL_TYPE_MSG);
         assert(amsg);
@@ -414,7 +414,7 @@ extern char *bundle_id_prefix;
 
         case 0:                                     /* child2 */
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
-            if (asl_log_descriptor) {
+            if (&asl_log_descriptor) {
                 /* Replace our stdout/stderr */
                 dup2(stdout_pipe[1], STDOUT_FILENO);
                 dup2(stderr_pipe[1], STDERR_FILENO);
@@ -443,7 +443,7 @@ extern char *bundle_id_prefix;
     }
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
-    if (asl_log_descriptor) {
+    if (&asl_log_descriptor) {
         /* Close the write ends of the pipe */
         close(stdout_pipe[1]);
         close(stderr_pipe[1]);
commit 77611066397747411f348e4a77871da5cff3b71e
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sun Jun 1 04:29:19 2014 -0700

    XQuartz: GLX: Use __glXEnableExtension to build extensions list
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 19b7d86..4e6ab3d 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -52,6 +52,7 @@
 
 #include "visualConfigs.h"
 #include "dri.h"
+#include "extension_string.h"
 
 #include "darwin.h"
 #define GLAQUA_DEBUG_MSG(msg, args ...) ASL_LOG(ASL_LEVEL_DEBUG, "GLXAqua", \
@@ -111,6 +112,10 @@ typedef struct __GLXAquaDrawable __GLXAquaDrawable;
  */
 struct __GLXAquaScreen {
     __GLXscreen base;
+
+    /* Supported GLX extensions */
+    unsigned char glx_enable_bits[__GLX_EXT_BYTES];
+
     int index;
     int num_vis;
 };
@@ -541,13 +546,33 @@ __glXAquaScreenProbe(ScreenPtr pScreen)
 
     screen->base.GLXmajor = 1;
     screen->base.GLXminor = 4;
-    screen->base.GLXextensions = strdup("GLX_SGIX_fbconfig "
-                                        "GLX_SGIS_multisample "
-                                        "GLX_ARB_multisample "
-                                        "GLX_EXT_visual_info "
-                                        "GLX_EXT_import_context ");
 
-    /*We may be able to add more GLXextensions at a later time. */
+    memset(screen->glx_enable_bits, 0, __GLX_EXT_BYTES);
+
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_info");
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_rating");
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_import_context");
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_OML_swap_method");
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_fbconfig");
+
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIS_multisample");
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_multisample");
+
+    //__glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context");
+    //__glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context_profile");
+
+    // Generate the GLX extensions string (overrides that set by __glXScreenInit())
+    {
+        unsigned int buffer_size =
+            __glXGetExtensionString(screen->glx_enable_bits, NULL);
+        if (buffer_size > 0) {
+            free(screen->base.GLXextensions);
+
+            screen->base.GLXextensions = xnfalloc(buffer_size);
+            __glXGetExtensionString(screen->glx_enable_bits,
+                                    screen->base.GLXextensions);
+        }
+    }
 
     return &screen->base;
 }
commit fa12f2c150b2f50de9dac4a2b09265f13af353af
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu May 28 16:21:37 2015 +1000

    glamor: don't do render ops with matching source/dest (v3)
    
    XRender defines this, GL really doesn't like it.
    
    kwin 4.x and qt 4.x seem to make this happen for the
    gradient in the titlebar, and on radeonsi/r600 hw
    this draws all kinds of wrong.
    
    v2: bump this up a level, and check it earlier.
    (I assume the XXXX was for this case.)
    v3: add same code to largepixmap paths (Keith)
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index 391f376..da3fb61 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -1055,6 +1055,15 @@ glamor_composite_largepixmap_region(CARD8 op,
     int source_repeat_type = 0, mask_repeat_type = 0;
     int ok = TRUE;
 
+    if (source_pixmap == dest_pixmap) {
+        glamor_fallback("source and dest pixmaps are the same\n");
+        return FALSE;
+    }
+    if (mask_pixmap == dest_pixmap) {
+        glamor_fallback("mask and dest pixmaps are the same\n");
+        return FALSE;
+    }
+
     if (source->repeat)
         source_repeat_type = source->repeatType;
     else
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index efca367..05eee91 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1481,7 +1481,14 @@ glamor_composite_clipped_region(CARD8 op,
         }
     }
 
-    /*XXXXX, self copy? */
+    if (temp_src_pixmap == dest_pixmap) {
+        glamor_fallback("source and dest pixmaps are the same\n");
+        goto out;
+    }
+    if (temp_mask_pixmap == dest_pixmap) {
+        glamor_fallback("mask and dest pixmaps are the same\n");
+        goto out;
+    }
 
     x_dest += dest->pDrawable->x;
     y_dest += dest->pDrawable->y;
commit cbb7eb73b5399e31a7afb800363504d539df0ecf
Author: Rui Matos <tiagomatos at gmail.com>
Date:   Wed May 27 12:08:45 2015 +0200

    xwayland: Throttle our cursor surface updates with a frame callback
    
    In some extreme cases with animated cursors at a high frame rate we
    could end up filling the wl_display outgoing buffer and end up with
    wl_display_flush() failing.
    
    In any case, using the frame callback to throttle ourselves is the
    right thing to do.
    
    Signed-off-by: Rui Matos <tiagomatos at gmail.com>
    Reviewed-by: Daniel Stone <daniels at collabora.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
index 5a9d1fe..c137e1e 100644
--- a/hw/xwayland/xwayland-cursor.c
+++ b/hw/xwayland/xwayland-cursor.c
@@ -82,6 +82,23 @@ xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
     return xwl_shm_destroy_pixmap(pixmap);
 }
 
+static void
+frame_callback(void *data,
+               struct wl_callback *callback,
+               uint32_t time)
+{
+    struct xwl_seat *xwl_seat = data;
+    xwl_seat->cursor_frame_cb = NULL;
+    if (xwl_seat->cursor_needs_update) {
+        xwl_seat->cursor_needs_update = FALSE;
+        xwl_seat_set_cursor(xwl_seat);
+    }
+}
+
+static const struct wl_callback_listener frame_listener = {
+    frame_callback
+};
+
 void
 xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
 {
@@ -98,6 +115,11 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
         return;
     }
 
+    if (xwl_seat->cursor_frame_cb) {
+        xwl_seat->cursor_needs_update = TRUE;
+        return;
+    }
+
     cursor = xwl_seat->x_cursor;
     pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
     stride = cursor->bits->width * 4;
@@ -117,6 +139,10 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
     wl_surface_damage(xwl_seat->cursor, 0, 0,
                       xwl_seat->x_cursor->bits->width,
                       xwl_seat->x_cursor->bits->height);
+
+    xwl_seat->cursor_frame_cb = wl_surface_frame(xwl_seat->cursor);
+    wl_callback_add_listener(xwl_seat->cursor_frame_cb, &frame_listener, xwl_seat);
+
     wl_surface_commit(xwl_seat->cursor);
 }
 
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 78d9702..a6fbab5 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -563,6 +563,8 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
     RemoveDevice(xwl_seat->keyboard, FALSE);
     wl_seat_destroy(xwl_seat->seat);
     wl_surface_destroy(xwl_seat->cursor);
+    if (xwl_seat->cursor_frame_cb)
+        wl_callback_destroy(xwl_seat->cursor_frame_cb);
     wl_array_release(&xwl_seat->keys);
     free(xwl_seat);
 }
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index cfb343d..28b0c99 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -115,12 +115,14 @@ struct xwl_seat {
     struct wl_pointer *wl_pointer;
     struct wl_keyboard *wl_keyboard;
     struct wl_array keys;
-    struct wl_surface *cursor;
     struct xwl_window *focus_window;
     uint32_t id;
     uint32_t pointer_enter_serial;
     struct xorg_list link;
     CursorPtr x_cursor;
+    struct wl_surface *cursor;
+    struct wl_callback *cursor_frame_cb;
+    Bool cursor_needs_update;
 
     size_t keymap_size;
     char *keymap;
commit 806470b9f623089dc81b985f250f0c3a4e8edbe8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Feb 6 08:25:42 2015 +0000

    present: Copy unflip contents back to the Screen Pixmap
    
    As we unflip after the flip Window no longer passes the pixel ownership
    test for the full Screen Pixmap, we can no longer utilize that Window to
    copy the contents back to the backing pixmap. To first flip means that
    the Window was originally backed by the Screen Pixmap and wholly covered
    the Pixmap, thus we need to copy the last frame contents to the Screen
    Pixmap when the flip chain is complete.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-and-Tested-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/present/present.c b/present/present.c
index 2a705a9..a634601 100644
--- a/present/present.c
+++ b/present/present.c
@@ -409,20 +409,20 @@ static void
 present_unflip(ScreenPtr screen)
 {
     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
+    PixmapPtr pixmap = (*screen->GetScreenPixmap)(screen);
 
     assert (!screen_priv->unflip_event_id);
     assert (!screen_priv->flip_pending);
 
     if (screen_priv->flip_window)
-        present_set_tree_pixmap(screen_priv->flip_window,
-                                  (*screen->GetScreenPixmap)(screen));
+        present_set_tree_pixmap(screen_priv->flip_window, pixmap);
 
-    present_set_tree_pixmap(screen->root, (*screen->GetScreenPixmap)(screen));
+    present_set_tree_pixmap(screen->root, pixmap);
 
     /* Update the screen pixmap with the current flip pixmap contents
      */
     if (screen_priv->flip_pixmap && screen_priv->flip_window) {
-        present_copy_region(&screen_priv->flip_window->drawable,
+        present_copy_region(&pixmap->drawable,
                             screen_priv->flip_pixmap,
                             NULL, 0, 0);
     }
commit baa50f60acd9e9f4293107435645ab072b6110e1
Author: Vicente Olivert Riera <Vincent.Riera at imgtec.com>
Date:   Mon Jan 12 17:10:02 2015 +0000

    backtrace.c: Fix word cast to a pointer
    
    backtrace.c uses a word size provided by libunwind. In some
    architectures like MIPS, libunwind makes that word size 64-bit for all
    variants of the architecture.
    
    In the lines #90 and #98, backtrace.c tries to do a cast to a pointer,
    which fails in all MIPS variants with 32-bit pointers, like MIPS32 or
    MIPS64 n32, because it's trying to do a cast from a 64-bit wide variable
    to a 32-bit pointer:
    
    Making all in os
    make[2]: Entering directory
    `/home/test/test/1/output/build/xserver_xorg-server-1.15.1/os'
      CC     WaitFor.lo
      CC     access.lo
      CC     auth.lo
      CC     backtrace.lo
    backtrace.c: In function 'xorg_backtrace':
    backtrace.c:90:20: error: cast to pointer from integer of different size
    [-Werror=int-to-pointer-cast]
    	 if (dladdr((void *)(pip.start_ip + off), &dlinfo) &&
    dlinfo.dli_fname &&
    		    ^
    backtrace.c:98:13: error: cast to pointer from integer of different size
    [-Werror=int-to-pointer-cast]
    	     (void *)(pip.start_ip + off));
    	     ^
    cc1: some warnings being treated as errors
    make[2]: *** [backtrace.lo] Error 1
    make[2]: *** Waiting for unfinished jobs....
    
    Making the cast to a pointer-sized integer, and then to a pointer fixes
    the problem.
    
    Related:
      https://bugs.freedesktop.org/show_bug.cgi?id=79939
    
    Signed-off-by: Vicente Olivert Riera <Vincent.Riera at imgtec.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/backtrace.c b/os/backtrace.c
index 3d1195b..fd129ef 100644
--- a/os/backtrace.c
+++ b/os/backtrace.c
@@ -87,7 +87,7 @@ xorg_backtrace(void)
             procname[1] = 0;
         }
 
-        if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&
+        if (dladdr((void *)(uintptr_t)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&
                 *dlinfo.dli_fname)
             filename = dlinfo.dli_fname;
         else
@@ -95,7 +95,7 @@ xorg_backtrace(void)
 
         ErrorFSigSafe("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
             ret == -UNW_ENOMEM ? "..." : "", (int)off,
-            (void *)(pip.start_ip + off));
+            (void *)(uintptr_t)(pip.start_ip + off));
 
         ret = unw_step(&cursor);
         if (ret < 0)
commit 76636ac12f2d1dbdf7be08222f80e7505d53c451
Author: Ray Strode <rstrode at redhat.com>
Date:   Tue May 5 16:43:44 2015 -0400

    xwayland: default to local user if no xauth file given. [CVE-2015-3164 3/3]
    
    Right now if "-auth" isn't passed on the command line, we let
    any user on the system connect to the Xwayland server.
    
    That's clearly suboptimal, given Xwayland is generally designed
    to be used by one user at a time.
    
    This commit changes the behavior, so only the user who started the
    X server can connect clients to it.
    
    Signed-off-by: Ray Strode <rstrode at redhat.com>
    Reviewed-by: Daniel Stone <daniels at collabora.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index c5bee77..bc92beb 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -702,4 +702,6 @@ InitOutput(ScreenInfo * screen_info, int argc, char **argv)
     if (AddScreen(xwl_screen_init, argc, argv) == -1) {
         FatalError("Couldn't add screen\n");
     }
+
+    LocalAccessScopeUser();
 }
commit 4b4b9086d02b80549981d205fb1f495edc373538
Author: Ray Strode <rstrode at redhat.com>
Date:   Tue May 5 16:43:43 2015 -0400

    os: support new implicit local user access mode [CVE-2015-3164 2/3]
    
    If the X server is started without a '-auth' argument, then
    it gets started wide open to all local users on the system.
    
    This isn't a great default access model, but changing it in
    Xorg at this point would break backward compatibility.
    
    Xwayland, on the other hand is new, and much more targeted
    in scope.  It could, in theory, be changed to allow the much
    more secure default of a "user who started X server can connect
    clients to that server."
    
    This commit paves the way for that change, by adding a mechanism
    for DDXs to opt-in to that behavior.  They merely need to call
    
    LocalAccessScopeUser()
    
    in their init functions.
    
    A subsequent commit will add that call for Xwayland.
    
    Signed-off-by: Ray Strode <rstrode at redhat.com>
    Reviewed-by: Daniel Stone <daniels at collabora.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/os.h b/include/os.h
index 6638c84..b2b96c8 100644
--- a/include/os.h
+++ b/include/os.h
@@ -431,11 +431,28 @@ extern _X_EXPORT void
 ResetHosts(const char *display);
 
 extern _X_EXPORT void
+EnableLocalAccess(void);
+
+extern _X_EXPORT void
+DisableLocalAccess(void);
+
+extern _X_EXPORT void
 EnableLocalHost(void);
 
 extern _X_EXPORT void
 DisableLocalHost(void);
 
+#ifndef NO_LOCAL_CLIENT_CRED
+extern _X_EXPORT void
+EnableLocalUser(void);
+
+extern _X_EXPORT void
+DisableLocalUser(void);
+
+extern _X_EXPORT void
+LocalAccessScopeUser(void);
+#endif
+
 extern _X_EXPORT void
 AccessUsingXdmcp(void);
 
diff --git a/os/access.c b/os/access.c
index 8fa028e..75e7a69 100644
--- a/os/access.c
+++ b/os/access.c
@@ -102,6 +102,10 @@ SOFTWARE.
 #include <sys/ioctl.h>
 #include <ctype.h>
 
+#ifndef NO_LOCAL_CLIENT_CRED
+#include <pwd.h>
+#endif
+
 #if defined(TCPCONN) || defined(STREAMSCONN)
 #include <netinet/in.h>
 #endif                          /* TCPCONN || STREAMSCONN */
@@ -225,6 +229,13 @@ static int LocalHostEnabled = FALSE;
 static int LocalHostRequested = FALSE;
 static int UsingXdmcp = FALSE;
 
+static enum {
+    LOCAL_ACCESS_SCOPE_HOST = 0,
+#ifndef NO_LOCAL_CLIENT_CRED
+    LOCAL_ACCESS_SCOPE_USER,
+#endif
+} LocalAccessScope;
+
 /* FamilyServerInterpreted implementation */
 static Bool siAddrMatch(int family, void *addr, int len, HOST * host,
                         ClientPtr client);
@@ -237,6 +248,21 @@ static void siTypesInitialize(void);
  */
 
 void
+EnableLocalAccess(void)
+{
+    switch (LocalAccessScope) {
+        case LOCAL_ACCESS_SCOPE_HOST:
+            EnableLocalHost();
+            break;
+#ifndef NO_LOCAL_CLIENT_CRED
+        case LOCAL_ACCESS_SCOPE_USER:
+            EnableLocalUser();
+            break;
+#endif
+    }
+}
+
+void
 EnableLocalHost(void)
 {
     if (!UsingXdmcp) {
@@ -249,6 +275,21 @@ EnableLocalHost(void)
  * called when authorization is enabled to keep us secure
  */
 void
+DisableLocalAccess(void)
+{
+    switch (LocalAccessScope) {
+        case LOCAL_ACCESS_SCOPE_HOST:
+            DisableLocalHost();
+            break;
+#ifndef NO_LOCAL_CLIENT_CRED
+        case LOCAL_ACCESS_SCOPE_USER:
+            DisableLocalUser();
+            break;
+#endif
+    }
+}
+
+void
 DisableLocalHost(void)
 {
     HOST *self;
@@ -262,6 +303,74 @@ DisableLocalHost(void)
     }
 }
 
+#ifndef NO_LOCAL_CLIENT_CRED
+static int GetLocalUserAddr(char **addr)
+{
+    static const char *type = "localuser";
+    static const char delimiter = '\0';
+    static const char *value;
+    struct passwd *pw;
+    int length = -1;
+
+    pw = getpwuid(getuid());
+
+    if (pw == NULL || pw->pw_name == NULL)
+        goto out;
+
+    value = pw->pw_name;
+
+    length = asprintf(addr, "%s%c%s", type, delimiter, value);
+
+    if (length == -1) {
+        goto out;
+    }
+
+    /* Trailing NUL */
+    length++;
+
+out:
+    return length;
+}
+
+void
+EnableLocalUser(void)
+{
+    char *addr = NULL;
+    int length = -1;
+
+    length = GetLocalUserAddr(&addr);
+
+    if (length == -1)
+        return;
+
+    NewHost(FamilyServerInterpreted, addr, length, TRUE);
+
+    free(addr);
+}
+
+void
+DisableLocalUser(void)
+{
+    char *addr = NULL;
+    int length = -1;
+
+    length = GetLocalUserAddr(&addr);
+
+    if (length == -1)
+        return;
+
+    RemoveHost(NULL, FamilyServerInterpreted, length, addr);
+
+    free(addr);
+}
+
+void
+LocalAccessScopeUser(void)
+{
+    LocalAccessScope = LOCAL_ACCESS_SCOPE_USER;
+}
+#endif
+
 /*
  * called at init time when XDMCP will be used; xdmcp always
  * adds local hosts manually when needed
diff --git a/os/auth.c b/os/auth.c
index 5fcb538..7da6fc6 100644
--- a/os/auth.c
+++ b/os/auth.c
@@ -181,11 +181,11 @@ CheckAuthorization(unsigned int name_length,
 
         /*
          * If the authorization file has at least one entry for this server,
-         * disable local host access. (loadauth > 0)
+         * disable local access. (loadauth > 0)
          *
          * If there are zero entries (either initially or when the
          * authorization file is later reloaded), or if a valid
-         * authorization file was never loaded, enable local host access.
+         * authorization file was never loaded, enable local access.
          * (loadauth == 0 || !loaded)
          *
          * If the authorization file was loaded initially (with valid
@@ -194,11 +194,11 @@ CheckAuthorization(unsigned int name_length,
          */
 
         if (loadauth > 0) {
-            DisableLocalHost(); /* got at least one */
+            DisableLocalAccess(); /* got at least one */
             loaded = TRUE;
         }
         else if (loadauth == 0 || !loaded)
-            EnableLocalHost();
+            EnableLocalAccess();
     }
     if (name_length) {
         for (i = 0; i < NUM_AUTHORIZATION; i++) {
commit c4534a38b68aa07fb82318040dc8154fb48a9588
Author: Ray Strode <rstrode at redhat.com>
Date:   Tue May 5 16:43:42 2015 -0400

    xwayland: Enable access control on open sockets [CVE-2015-3164 1/3]
    
    Xwayland currently allows wide-open access to the X sockets
    it listens on, ignoring Xauth access control.
    
    This commit makes sure to enable access control on the sockets,
    so one user can't snoop on another user's X-over-wayland
    applications.
    
    Signed-off-by: Ray Strode <rstrode at redhat.com>
    Reviewed-by: Daniel Stone <daniels at collabora.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 7e8d667..c5bee77 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -483,7 +483,7 @@ listen_on_fds(struct xwl_screen *xwl_screen)
     int i;
 
     for (i = 0; i < xwl_screen->listen_fd_count; i++)
-        ListenOnOpenFD(xwl_screen->listen_fds[i], TRUE);
+        ListenOnOpenFD(xwl_screen->listen_fds[i], FALSE);
 }
 
 static void
commit ad02d0df75318660c3f7cd6063eac409327fe560
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 6 15:25:28 2015 +1000

    test: add tests for new valuator mask features
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/test/input.c b/test/input.c
index a4615c9..91ee43c 100644
--- a/test/input.c
+++ b/test/input.c
@@ -1358,6 +1358,68 @@ dix_valuator_mode(void)
 }
 
 static void
+dix_input_valuator_masks_unaccel(void)
+{
+    ValuatorMask *mask = NULL;
+    double x, ux;
+
+    /* set mask normally */
+    mask = valuator_mask_new(MAX_VALUATORS);
+    assert(!valuator_mask_has_unaccelerated(mask));
+    valuator_mask_set_double(mask, 0, 1.0);
+    assert(!valuator_mask_has_unaccelerated(mask));
+    valuator_mask_unset(mask, 0);
+    assert(!valuator_mask_has_unaccelerated(mask));
+
+    /* all unset, now set accel mask */
+    valuator_mask_set_unaccelerated(mask, 0, 1.0, 2.0);
+    assert(valuator_mask_has_unaccelerated(mask));
+    assert(valuator_mask_isset(mask, 0));
+    assert(!valuator_mask_isset(mask, 1));
+    assert(valuator_mask_get_accelerated(mask, 0) ==  1.0);
+    assert(valuator_mask_get_unaccelerated(mask, 0) ==  2.0);
+    assert(valuator_mask_fetch_unaccelerated(mask, 0, &x, &ux));
+    assert(x == 1.0);
+    assert(ux == 2.0);
+    x = 0xff;
+    ux = 0xfe;
+    assert(!valuator_mask_fetch_unaccelerated(mask, 1, &x, &ux));
+    assert(x == 0xff);
+    assert(ux == 0xfe);
+
+    /* all unset, now set normally again */
+    valuator_mask_unset(mask, 0);
+    assert(!valuator_mask_has_unaccelerated(mask));
+    assert(!valuator_mask_isset(mask, 0));
+    valuator_mask_set_double(mask, 0, 1.0);
+    assert(!valuator_mask_has_unaccelerated(mask));
+    valuator_mask_unset(mask, 0);
+    assert(!valuator_mask_has_unaccelerated(mask));
+
+    valuator_mask_zero(mask);
+    assert(!valuator_mask_has_unaccelerated(mask));
+
+    valuator_mask_set_unaccelerated(mask, 0, 1.0, 2.0);
+    valuator_mask_set_unaccelerated(mask, 1, 3.0, 4.5);
+    assert(valuator_mask_isset(mask, 0));
+    assert(valuator_mask_isset(mask, 1));
+    assert(!valuator_mask_isset(mask, 2));
+    assert(valuator_mask_has_unaccelerated(mask));
+    assert(valuator_mask_get_accelerated(mask, 0) == 1.0);
+    assert(valuator_mask_get_accelerated(mask, 1) == 3.0);
+    assert(valuator_mask_get_unaccelerated(mask, 0) == 2.0);
+    assert(valuator_mask_get_unaccelerated(mask, 1) == 4.5);
+    assert(valuator_mask_fetch_unaccelerated(mask, 0, &x, &ux));
+    assert(x == 1.0);
+    assert(ux == 2.0);
+    assert(valuator_mask_fetch_unaccelerated(mask, 1, &x, &ux));
+    assert(x == 3.0);
+    assert(ux == 4.5);
+
+    valuator_mask_free(&mask);
+}
+
+static void
 include_bit_test_macros(void)
 {
     uint8_t mask[9] = { 0 };
@@ -1847,6 +1909,7 @@ main(int argc, char **argv)
     dix_enqueue_events();
     dix_double_fp_conversion();
     dix_input_valuator_masks();
+    dix_input_valuator_masks_unaccel();
     dix_input_attributes();
     dix_init_valuators();
     dix_event_to_core_conversion();
commit da10d0cb4283ad5a9c4290555751f61795d11b49
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 5 14:48:41 2015 +1000

    dix: hook up the unaccelerated valuator masks
    
    If present, access the unaccelerated valuator mask values for DGA and XI2 raw
    events.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index d0a87f7..fa5890e 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -208,14 +208,25 @@ init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail)
 }
 
 static void
-set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, double *data)
+set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask,
+                  BOOL use_unaccel, double *data)
 {
     int i;
 
+    use_unaccel = use_unaccel && valuator_mask_has_unaccelerated(mask);
+
     for (i = 0; i < valuator_mask_size(mask); i++) {
         if (valuator_mask_isset(mask, i)) {
+            double v;
+
             SetBit(event->valuators.mask, i);
-            data[i] = valuator_mask_get_double(mask, i);
+
+            if (use_unaccel)
+                v = valuator_mask_get_unaccelerated(mask, i);
+            else
+                v = valuator_mask_get_double(mask, i);
+
+            data[i] = v;
         }
     }
 }
@@ -1388,9 +1399,11 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
         num_events++;
 
         init_raw(pDev, raw, ms, type, buttons);
-        set_raw_valuators(raw, &mask, raw->valuators.data_raw);
+        set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw);
     }
 
+    valuator_mask_drop_unaccelerated(&mask);
+
     /* valuators are in driver-native format (rel or abs) */
 
     if (flags & POINTER_ABSOLUTE) {
@@ -1403,7 +1416,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
         transformAbsolute(pDev, &mask);
         clipAbsolute(pDev, &mask);
         if ((flags & POINTER_NORAW) == 0 && raw)
-            set_raw_valuators(raw, &mask, raw->valuators.data);
+            set_raw_valuators(raw, &mask, FALSE, raw->valuators.data);
     }
     else {
         transformRelative(pDev, &mask);
@@ -1411,7 +1424,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
         if (flags & POINTER_ACCELERATE)
             accelPointer(pDev, &mask, ms);
         if ((flags & POINTER_NORAW) == 0 && raw)
-            set_raw_valuators(raw, &mask, raw->valuators.data);
+            set_raw_valuators(raw, &mask, FALSE, raw->valuators.data);
 
         moveRelative(pDev, flags, &mask);
     }
@@ -1916,7 +1929,7 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
         events++;
         num_events++;
         init_raw(dev, raw, ms, type, client_id);
-        set_raw_valuators(raw, &mask, raw->valuators.data_raw);
+        set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw);
     }
 
     event = &events->device_event;
@@ -1978,7 +1991,7 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
         screeny = dev->spriteInfo->sprite->hotPhys.y;
     }
     if (need_rawevent)
-        set_raw_valuators(raw, &mask, raw->valuators.data);
+        set_raw_valuators(raw, &mask, FALSE, raw->valuators.data);
 
     /* Indirect device touch coordinates are not used for cursor positioning.
      * They are merely informational, and are provided in device coordinates.
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 55bf2bb..a5b0568 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -1138,12 +1138,16 @@ xf86CheckMotionEvent4DGA(DeviceIntPtr device, int is_absolute,
                 dx = valuator_mask_get(mask, 0);
                 if (is_absolute)
                     dx -= device->last.valuators[0];
+                else if (valuator_mask_has_unaccelerated(mask))
+                    dx = valuator_mask_get_unaccelerated(mask, 0);
             }
 
             if (valuator_mask_isset(mask, 1)) {
                 dy = valuator_mask_get(mask, 1);
                 if (is_absolute)
                     dy -= device->last.valuators[1];
+                else if (valuator_mask_has_unaccelerated(mask))
+                    dy = valuator_mask_get_unaccelerated(mask, 1);
             }
 
             if (DGAStealMotionEvent(device, idx, dx, dy))
commit 4c2f2cb4c8ca1ab894a65828fdd39aea9b014f69
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 5 14:18:54 2015 +1000

    dix: Add unaccelerated valuators to the ValuatorMask
    
    Allows a mask to carry both accelerated and unaccelerated motion at the same
    time.
    
    This is required for xf86-input-libinput where the pointer acceleration
    happens in libinput already, but parts of the server, specifically raw events
    and DGA rely on device-specific unaccelerated data.
    
    To ease integration add this as a second set to the ValuatorMask rather than
    extending all APIs to carry a second, possibly NULL set of valuators.
    
    Note that a valuator mask should only be used in either accel/unaccel or
    standard mode at any time. Switching requires either a valuator_mask_zero()
    call or unsetting all valuators one-by-one. Trying to mix the two will produce
    a warning.
    
    The server has a shortcut for changing a mask with the
    valuator_mask_drop_unaccelerated() call. This saves us from having to loop
    through all valuators on every event, we can just drop the bits we know we
    don't want.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/dix/inpututils.c b/dix/inpututils.c
index 5c2a32d..1363988 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -505,15 +505,23 @@ valuator_mask_isset(const ValuatorMask *mask, int valuator)
     return mask->last_bit >= valuator && BitIsOn(mask->mask, valuator);
 }
 
+static inline void
+_valuator_mask_set_double(ValuatorMask *mask, int valuator, double data)
+{
+    mask->last_bit = max(valuator, mask->last_bit);
+    SetBit(mask->mask, valuator);
+    mask->valuators[valuator] = data;
+}
+
 /**
  * Set the valuator to the given floating-point data.
  */
 void
 valuator_mask_set_double(ValuatorMask *mask, int valuator, double data)
 {
-    mask->last_bit = max(valuator, mask->last_bit);
-    SetBit(mask->mask, valuator);
-    mask->valuators[valuator] = data;
+    BUG_WARN_MSG(mask->has_unaccelerated,
+                 "Do not mix valuator types, zero mask first\n");
+    _valuator_mask_set_double(mask, valuator, data);
 }
 
 /**
@@ -594,11 +602,15 @@ valuator_mask_unset(ValuatorMask *mask, int valuator)
 
         ClearBit(mask->mask, valuator);
         mask->valuators[valuator] = 0.0;
+        mask->unaccelerated[valuator] = 0.0;
 
         for (i = 0; i <= mask->last_bit; i++)
             if (valuator_mask_isset(mask, i))
                 lastbit = max(lastbit, i);
         mask->last_bit = lastbit;
+
+        if (mask->last_bit == -1)
+            mask->has_unaccelerated = FALSE;
     }
 }
 
@@ -611,6 +623,66 @@ valuator_mask_copy(ValuatorMask *dest, const ValuatorMask *src)
         valuator_mask_zero(dest);
 }
 
+Bool
+valuator_mask_has_unaccelerated(const ValuatorMask *mask)
+{
+    return mask->has_unaccelerated;
+}
+
+void
+valuator_mask_drop_unaccelerated(ValuatorMask *mask)
+{
+    memset(mask->unaccelerated, 0, sizeof(mask->unaccelerated));
+    mask->has_unaccelerated = FALSE;
+}
+
+/**
+ * Set both accelerated and unaccelerated value for this mask.
+ */
+void
+valuator_mask_set_unaccelerated(ValuatorMask *mask,
+                                int valuator,
+                                double accel,
+                                double unaccel)
+{
+    BUG_WARN_MSG(mask->last_bit != -1 && !mask->has_unaccelerated,
+                 "Do not mix valuator types, zero mask first\n");
+    _valuator_mask_set_double(mask, valuator, accel);
+    mask->has_unaccelerated = TRUE;
+    mask->unaccelerated[valuator] = unaccel;
+}
+
+double
+valuator_mask_get_accelerated(const ValuatorMask *mask,
+                              int valuator)
+{
+    return valuator_mask_get_double(mask, valuator);
+}
+
+double
+valuator_mask_get_unaccelerated(const ValuatorMask *mask,
+                                int valuator)
+{
+    return mask->unaccelerated[valuator];
+}
+
+Bool
+valuator_mask_fetch_unaccelerated(const ValuatorMask *mask,
+                                  int valuator,
+                                  double *accel,
+                                  double *unaccel)
+{
+    if (valuator_mask_isset(mask, valuator)) {
+        if (accel)
+            *accel = valuator_mask_get_accelerated(mask, valuator);
+        if (unaccel)
+            *unaccel = valuator_mask_get_unaccelerated(mask, valuator);
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
 int
 CountBits(const uint8_t * mask, int len)
 {
diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index 25a8869..66c2bb5 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -81,7 +81,7 @@ typedef enum {
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
 #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(19, 0)
-#define ABI_XINPUT_VERSION	SET_ABI_VERSION(22, 0)
+#define ABI_XINPUT_VERSION	SET_ABI_VERSION(22, 1)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(9, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
diff --git a/include/input.h b/include/input.h
index 00a9cbd..d8bd9c6 100644
--- a/include/input.h
+++ b/include/input.h
@@ -673,6 +673,21 @@ extern _X_EXPORT Bool valuator_mask_fetch(const ValuatorMask *mask,
 extern _X_EXPORT Bool valuator_mask_fetch_double(const ValuatorMask *mask,
                                                  int valnum, double *val);
 
+extern _X_EXPORT Bool valuator_mask_has_unaccelerated(const ValuatorMask *mask);
+extern _X_EXPORT void valuator_mask_set_unaccelerated(ValuatorMask *mask,
+                                                      int valuator,
+                                                      double accel,
+                                                      double unaccel);
+extern _X_EXPORT double valuator_mask_get_accelerated(const ValuatorMask *mask,
+                                                      int valuator);
+extern _X_EXPORT double valuator_mask_get_unaccelerated(const ValuatorMask *mask,
+                                                        int valuator);
+extern _X_EXPORT Bool valuator_mask_fetch_unaccelerated(const ValuatorMask *mask,
+                                                        int valuator,
+                                                        double *accel,
+                                                        double *unaccel);
+extern _X_HIDDEN void valuator_mask_drop_unaccelerated(ValuatorMask *mask);
+
 /* InputOption handling interface */
 extern _X_EXPORT InputOption *input_option_new(InputOption *list,
                                                const char *key,
diff --git a/include/inpututils.h b/include/inpututils.h
index 53c96ba..4e90815 100644
--- a/include/inpututils.h
+++ b/include/inpututils.h
@@ -36,8 +36,10 @@ extern Mask event_filters[MAXDEVICES][MAXEVENTS];
 
 struct _ValuatorMask {
     int8_t last_bit;            /* highest bit set in mask */
+    int8_t has_unaccelerated;
     uint8_t mask[(MAX_VALUATORS + 7) / 8];
     double valuators[MAX_VALUATORS];    /* valuator data */
+    double unaccelerated[MAX_VALUATORS];    /* valuator data */
 };
 
 extern void verify_internal_event(const InternalEvent *ev);
commit 3f0d3201f38ef9d1651fcaf94e45c640786edcc0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Apr 13 13:52:28 2015 -0700

    dix: fix indentation
    
    from 9ff89a2e469ab0ac5af57d0fc115127feb1c0d99
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/devices.c b/dix/devices.c
index 1f8dabd..9b0c7d2 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -177,8 +177,8 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
             if (!isfinite(f[i]))
                 return BadValue;
 
-	if (!dev->valuator)
-		return BadMatch;
+        if (!dev->valuator)
+            return BadMatch;
 
         if (!checkonly)
             DeviceSetTransform(dev, f);
commit f82dc6bd91a545a844fb688ba3552e4f5df8a0d2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Mar 24 09:43:17 2015 +1000

    xfree86: drop if 0 hunk
    
    Disabled in 2005. bye bye.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c
index 9485307..a0e6782 100644
--- a/hw/xfree86/os-support/linux/lnx_init.c
+++ b/hw/xfree86/os-support/linux/lnx_init.c
@@ -190,18 +190,6 @@ xf86OpenConsole(void)
         else
             activeVT = vts.v_active;
 
-#if 0
-        if (!KeepTty) {
-            /*
-             * Detach from the controlling tty to avoid char loss
-             */
-            if ((i = open("/dev/tty", O_RDWR)) >= 0) {
-                SYSCALL(ioctl(i, TIOCNOTTY, 0));
-                close(i);
-            }
-        }
-#endif
-
         if (!xf86Info.ShareVTs) {
             struct termios nTty;
 
commit fc59c8fe8d941b0ec1e98c59bc57b1f97dba149d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 5 15:54:20 2015 +1000

    config: remove 10-evdev.conf, let the evdev driver install that file
    
    Now that we have two likely drivers that fight for control over the input
    devices (evdev and libinput) let's move the respective driver assignment to
    each package. So you get what you install.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=89023
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/config/10-evdev.conf b/config/10-evdev.conf
deleted file mode 100644
index cc83ab2..0000000
--- a/config/10-evdev.conf
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Catch-all evdev loader for udev-based systems
-# We don't simply match on any device since that also adds accelerometers
-# and other devices that we don't really want to use. The list below
-# matches everything but joysticks.
-
-Section "InputClass"
-        Identifier "evdev pointer catchall"
-        MatchIsPointer "on"
-        MatchDevicePath "/dev/input/event*"
-        Driver "evdev"
-EndSection
-
-Section "InputClass"
-        Identifier "evdev keyboard catchall"
-        MatchIsKeyboard "on"
-        MatchDevicePath "/dev/input/event*"
-        Driver "evdev"
-EndSection
-
-Section "InputClass"
-        Identifier "evdev touchpad catchall"
-        MatchIsTouchpad "on"
-        MatchDevicePath "/dev/input/event*"
-        Driver "evdev"
-EndSection
-
-Section "InputClass"
-        Identifier "evdev tablet catchall"
-        MatchIsTablet "on"
-        MatchDevicePath "/dev/input/event*"
-        Driver "evdev"
-EndSection
-
-Section "InputClass"
-        Identifier "evdev touchscreen catchall"
-        MatchIsTouchscreen "on"
-        MatchDevicePath "/dev/input/event*"
-        Driver "evdev"
-EndSection
diff --git a/config/Makefile.am b/config/Makefile.am
index 0e20e8b..51aae47 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -18,7 +18,7 @@ libconfig_la_LIBADD += $(UDEV_LIBS)
 
 if XORG
 xorgconfddir = $(datadir)/X11/$(XF86CONFIGDIR)
-xorgconfd_DATA = 10-evdev.conf 10-quirks.conf
+xorgconfd_DATA = 10-quirks.conf
 endif
 
 else
@@ -38,4 +38,4 @@ endif # !CONFIG_HAL
 
 endif # !CONFIG_UDEV
 
-EXTRA_DIST = x11-input.fdi 10-evdev.conf fdi2iclass.py 10-quirks.conf
+EXTRA_DIST = x11-input.fdi fdi2iclass.py 10-quirks.conf
commit bf6344e1913a5d24c2d68eaca999ea3d71e1b707
Author: Keith Packard <keithp at keithp.com>
Date:   Thu May 14 14:58:29 2015 -0700

    Revert "glx/dri2: Disable AIGLX if indirect GLX is disabled"
    
    This reverts commit d61ae18074e53c2cdfb13cc37693b526160d6ca7.
    
    If the DRI2 provider is disabled, then we don't advertise the correct
    GLX extensions to clients, and things like GLES fail.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90442
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index c0f29ea..bcd57a4 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -936,9 +936,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     size_t buffer_size;
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
 
-    if (!enableIndirectGLX)
-	    return NULL;
-
     screen = calloc(1, sizeof *screen);
     if (screen == NULL)
         return NULL;
commit b0d2e010316d710eb4052963de3a1e2dc7ba356e
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Oct 10 09:25:51 2014 +0200

    glamor: Replace CompositeGlyphs code [v2]
    
    New composite glyphs code uses the updated glamor program
    infrastructure to create efficient shaders for drawing render text.
    
    Glyphs are cached in two atlases (one 8-bit, one 32-bit) in a simple
    linear fashion. When the atlas fills, it is discarded and a new one
    constructed.
    
    v2: Eric Anholt changed the non-GLSL 130 path to use quads instead of
    two triangles for a significant performance improvement on hardware
    with quads. Someone can fix the GLES quads emulation if they want to
    make it faster there.
    
    v3: Eric found more dead code to delete
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index db72cb1..c488029 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -14,7 +14,7 @@ libglamor_la_SOURCES = \
 	glamor_font.c \
 	glamor_font.h \
 	glamor_glx.c \
-	glamor_glyphs.c \
+	glamor_composite_glyphs.c \
 	glamor_image.c \
 	glamor_lines.c \
 	glamor_segs.c \
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 9d40e3c..807f28e 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -288,16 +288,6 @@ glamor_create_screen_resources(ScreenPtr screen)
         ret = screen->CreateScreenResources(screen);
     screen->CreateScreenResources = glamor_create_screen_resources;
 
-    if (!glamor_glyphs_init(screen)) {
-        ErrorF("Failed to initialize glyphs\n");
-        ret = FALSE;
-    }
-
-    if (!glamor_realize_glyph_caches(screen)) {
-        ErrorF("Failed to initialize glyph cache\n");
-        ret = FALSE;
-    }
-
     return ret;
 }
 
@@ -509,6 +499,11 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_priv->saved_procs.block_handler = screen->BlockHandler;
     screen->BlockHandler = _glamor_block_handler;
 
+    if (!glamor_composite_glyphs_init(screen)) {
+        ErrorF("Failed to initialize composite masks\n");
+        goto fail;
+    }
+
     glamor_priv->saved_procs.create_gc = screen->CreateGC;
     screen->CreateGC = glamor_create_gc;
 
@@ -550,10 +545,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     ps->CompositeRects = miCompositeRects;
 
     glamor_priv->saved_procs.glyphs = ps->Glyphs;
-    ps->Glyphs = glamor_glyphs;
-
-    glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph;
-    ps->UnrealizeGlyph = glamor_glyph_unrealize;
+    ps->Glyphs = glamor_composite_glyphs;
 
     glamor_priv->saved_procs.create_picture = ps->CreatePicture;
     ps->CreatePicture = glamor_create_picture;
@@ -634,7 +626,7 @@ glamor_close_screen(ScreenPtr screen)
 
     glamor_priv = glamor_get_screen_private(screen);
     glamor_sync_close(screen);
-    glamor_glyphs_fini(screen);
+    glamor_composite_glyphs_fini(screen);
     screen->CloseScreen = glamor_priv->saved_procs.close_screen;
     screen->CreateScreenResources =
         glamor_priv->saved_procs.create_screen_resources;
@@ -655,7 +647,6 @@ glamor_close_screen(ScreenPtr screen)
     ps->CreatePicture = glamor_priv->saved_procs.create_picture;
     ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
     ps->Glyphs = glamor_priv->saved_procs.glyphs;
-    ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph;
     screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
 
     screen_pixmap = screen->GetScreenPixmap(screen);
diff --git a/glamor/glamor.h b/glamor/glamor.h
index d07182d..0d57fff 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -105,8 +105,6 @@ extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap,
 
 extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap);
 
-extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen);
-
 extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap,
                                                 unsigned int tex);
 
diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c
new file mode 100644
index 0000000..39ed854
--- /dev/null
+++ b/glamor/glamor_composite_glyphs.c
@@ -0,0 +1,551 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#include <stdlib.h>
+#include "Xprintf.h"
+
+#include "glamor_priv.h"
+#include "glamor_transform.h"
+#include "glamor_transfer.h"
+
+#include <mipict.h>
+
+#define DEFAULT_ATLAS_DIM       1024
+
+static DevPrivateKeyRec        glamor_glyph_private_key;
+
+struct glamor_glyph_private {
+    int16_t     x;
+    int16_t     y;
+    uint32_t    serial;
+};
+
+struct glamor_glyph_atlas {
+    PixmapPtr           atlas;
+    PictFormatPtr       format;
+    int                 x, y;
+    int                 row_height;
+    int                 nglyph;
+    uint32_t            serial;
+};
+
+static inline struct glamor_glyph_private *glamor_get_glyph_private(PixmapPtr pixmap) {
+    return dixLookupPrivate(&pixmap->devPrivates, &glamor_glyph_private_key);
+}
+
+static inline void
+glamor_copy_glyph(PixmapPtr     glyph_pixmap,
+                  DrawablePtr   atlas_draw,
+                  int16_t x,
+                  int16_t y)
+{
+    DrawablePtr glyph_draw = &glyph_pixmap->drawable;
+    BoxRec      box = {
+        .x1 = 0,
+        .y1 = 0,
+        .x2 = glyph_draw->width,
+        .y2 = glyph_draw->height,
+    };
+
+    if (glyph_pixmap->drawable.bitsPerPixel == atlas_draw->bitsPerPixel) {
+        glamor_upload_boxes((PixmapPtr) atlas_draw,
+                            &box, 1,
+                            0, 0,
+                            x, y,
+                            glyph_pixmap->devPrivate.ptr,
+                            glyph_pixmap->devKind);
+    } else {
+        GCPtr scratch_gc = GetScratchGC(atlas_draw->depth, atlas_draw->pScreen);
+        ChangeGCVal changes[2];
+        if (!scratch_gc)
+            return;
+
+        /* If we're dealing with 1-bit glyphs, we upload them to
+         * the cache as normal 8-bit alpha, since that's what GL
+         * can handle.
+         */
+        assert(glyph_draw->depth == 1);
+        assert(atlas_draw->depth == 8);
+
+        changes[0].val = 0xff;
+        changes[1].val = 0x00;
+        if (ChangeGC(NullClient, scratch_gc,
+                     GCForeground|GCBackground, changes) != Success)
+            goto bail_gc;
+        ValidateGC(atlas_draw, scratch_gc);
+
+        (*scratch_gc->ops->CopyPlane)(glyph_draw,
+                                      atlas_draw,
+                                      scratch_gc,
+                                      0, 0,
+                                      glyph_draw->width,
+                                      glyph_draw->height,
+                                      x, y, 0x1);
+
+    bail_gc:
+        FreeScratchGC(scratch_gc);
+    }
+}
+
+static Bool
+glamor_glyph_atlas_init(ScreenPtr screen, struct glamor_glyph_atlas *atlas)
+{
+    glamor_screen_private       *glamor_priv = glamor_get_screen_private(screen);
+    PictFormatPtr               format = atlas->format;
+
+    atlas->atlas = glamor_create_pixmap(screen, glamor_priv->glyph_atlas_dim,
+                                        glamor_priv->glyph_atlas_dim, format->depth, 0);
+    atlas->x = 0;
+    atlas->y = 0;
+    atlas->row_height = 0;
+    atlas->serial++;
+    atlas->nglyph = 0;
+    return TRUE;
+}
+
+static Bool
+glamor_glyph_can_add(struct glamor_glyph_atlas *atlas, int dim, DrawablePtr glyph_draw)
+{
+    /* Step down */
+    if (atlas->x + glyph_draw->width > dim) {
+        atlas->x = 0;
+        atlas->y += atlas->row_height;
+        atlas->row_height = 0;
+    }
+
+    /* Check for overfull */
+    if (atlas->y + glyph_draw->height > dim)
+        return FALSE;
+
+    return TRUE;
+}
+
+static Bool
+glamor_glyph_add(struct glamor_glyph_atlas *atlas, DrawablePtr glyph_draw)
+{
+    PixmapPtr                   glyph_pixmap = (PixmapPtr) glyph_draw;
+    struct glamor_glyph_private *glyph_priv = glamor_get_glyph_private(glyph_pixmap);
+
+    glamor_copy_glyph(glyph_pixmap, &atlas->atlas->drawable, atlas->x, atlas->y);
+
+    glyph_priv->x = atlas->x;
+    glyph_priv->y = atlas->y;
+    glyph_priv->serial = atlas->serial;
+
+    atlas->x += glyph_draw->width;
+    if (atlas->row_height < glyph_draw->height)
+        atlas->row_height = glyph_draw->height;
+
+    atlas->nglyph++;
+
+    return TRUE;
+}
+
+static const glamor_facet glamor_facet_composite_glyphs_130 = {
+    .name = "composite_glyphs",
+    .version = 130,
+    .vs_vars = ("attribute vec4 primitive;\n"
+                "attribute vec2 source;\n"
+                "varying vec2 glyph_pos;\n"),
+    .vs_exec = ("       vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
+                GLAMOR_POS(gl_Position, (primitive.xy + pos))
+                "       glyph_pos = (source + pos) * ATLAS_DIM_INV;\n"),
+    .fs_vars = ("varying vec2 glyph_pos;\n"),
+    .fs_exec = ("       vec4 mask = texture2D(atlas, glyph_pos);\n"),
+    .source_name = "source",
+    .locations = glamor_program_location_atlas,
+};
+
+static const glamor_facet glamor_facet_composite_glyphs_120 = {
+    .name = "composite_glyphs",
+    .vs_vars = ("attribute vec2 primitive;\n"
+                "attribute vec2 source;\n"
+                "varying vec2 glyph_pos;\n"),
+    .vs_exec = (GLAMOR_POS(gl_Position, primitive)
+                "       glyph_pos = source.xy * ATLAS_DIM_INV;\n"),
+    .fs_vars = ("varying vec2 glyph_pos;\n"),
+    .fs_exec = ("       vec4 mask = texture2D(atlas, glyph_pos);\n"),
+    .source_name = "source",
+    .locations = glamor_program_location_atlas,
+};
+
+static inline Bool
+glamor_glyph_use_130(glamor_screen_private *glamor_priv) {
+    return glamor_priv->glsl_version >= 130;
+}
+
+static Bool
+glamor_glyphs_init_facet(ScreenPtr screen)
+{
+    glamor_screen_private       *glamor_priv = glamor_get_screen_private(screen);
+
+    return asprintf(&glamor_priv->glyph_defines, "#define ATLAS_DIM_INV %20.18f\n", 1.0/glamor_priv->glyph_atlas_dim) > 0;
+}
+
+static void
+glamor_glyphs_fini_facet(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    free(glamor_priv->glyph_defines);
+}
+
+static void
+glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst,
+                   glamor_program *prog,
+                   struct glamor_glyph_atlas *atlas, int nglyph)
+{
+    DrawablePtr drawable = dst->pDrawable;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
+    PixmapPtr atlas_pixmap = atlas->atlas;
+    glamor_pixmap_private *atlas_priv = glamor_get_pixmap_private(atlas_pixmap);
+    glamor_pixmap_fbo *atlas_fbo = glamor_pixmap_fbo_at(atlas_priv, 0, 0);
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    int box_x, box_y;
+    int off_x, off_y;
+
+    glamor_put_vbo_space(drawable->pScreen);
+
+    glEnable(GL_SCISSOR_TEST);
+    glActiveTexture(GL_TEXTURE1);
+    glBindTexture(GL_TEXTURE_2D, atlas_fbo->tex);
+
+    for (;;) {
+        if (!glamor_use_program_render(prog, op, src, dst))
+            break;
+
+        glUniform1i(prog->atlas_uniform, 1);
+
+        glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+            BoxPtr box = RegionRects(dst->pCompositeClip);
+            int nbox = RegionNumRects(dst->pCompositeClip);
+
+            glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y);
+
+            /* Run over the clip list, drawing the glyphs
+             * in each box
+             */
+
+            while (nbox--) {
+                glScissor(box->x1 + off_x,
+                          box->y1 + off_y,
+                          box->x2 - box->x1,
+                          box->y2 - box->y1);
+                box++;
+
+                if (glamor_glyph_use_130(glamor_priv))
+                    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nglyph);
+                else
+                    glamor_glDrawArrays_GL_QUADS(glamor_priv, nglyph * 4);
+            }
+        }
+        if (prog->alpha != glamor_program_alpha_ca_first)
+            break;
+        prog++;
+    }
+
+    glDisable(GL_SCISSOR_TEST);
+
+    glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisable(GL_BLEND);
+}
+
+static GLshort *
+glamor_glyph_start(ScreenPtr screen, int count)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    GLshort *v;
+    char *vbo_offset;
+
+    /* Set up the vertex buffers for the font and destination */
+
+    if (glamor_glyph_use_130(glamor_priv)) {
+        v = glamor_get_vbo_space(screen, count * (6 * sizeof (GLshort)), &vbo_offset);
+
+        glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+        glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1);
+        glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE,
+                              6 * sizeof (GLshort), vbo_offset);
+
+        glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+        glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 1);
+        glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE,
+                              6 * sizeof (GLshort), vbo_offset + 4 * sizeof (GLshort));
+    } else {
+        v = glamor_get_vbo_space(screen, count * (16 * sizeof (GLshort)), &vbo_offset);
+
+        glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+        glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
+                              4 * sizeof (GLshort), vbo_offset);
+
+        glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+        glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE,
+                              4 * sizeof (GLshort), vbo_offset + 2 * sizeof (GLshort));
+    }
+    return v;
+}
+
+static inline struct glamor_glyph_atlas *
+glamor_atlas_for_glyph(glamor_screen_private *glamor_priv, DrawablePtr drawable)
+{
+    if (drawable->depth == 32)
+        return glamor_priv->glyph_atlas_argb;
+    else
+        return glamor_priv->glyph_atlas_a;
+}
+
+void
+glamor_composite_glyphs(CARD8 op,
+                        PicturePtr src,
+                        PicturePtr dst,
+                        PictFormatPtr glyph_format,
+                        INT16 x_src,
+                        INT16 y_src, int nlist, GlyphListPtr list,
+                        GlyphPtr *glyphs)
+{
+    int glyphs_queued;
+    GLshort *v = NULL;
+    DrawablePtr drawable = dst->pDrawable;
+    ScreenPtr screen = drawable->pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_program *prog = NULL;
+    PicturePtr glyph_pict = NULL;
+    DrawablePtr glyph_draw;
+    glamor_program_render       *glyphs_program = &glamor_priv->glyphs_program;
+    struct glamor_glyph_atlas    *glyph_atlas = NULL;
+    int x = 0, y = 0;
+    int n;
+    int glyph_atlas_dim = glamor_priv->glyph_atlas_dim;
+    int glyph_max_dim = glamor_priv->glyph_max_dim;
+    int nglyph = 0;
+    int screen_num = screen->myNum;
+
+    for (n = 0; n < nlist; n++)
+        nglyph += list[n].len;
+
+    glamor_make_current(glamor_priv);
+
+    glyphs_queued = 0;
+
+    while (nlist--) {
+        x += list->xOff;
+        y += list->yOff;
+        n = list->len;
+        list++;
+        while (n--) {
+            GlyphPtr glyph = *glyphs++;
+
+            /* Glyph not empty?
+             */
+            if (glyph->info.width && glyph->info.height) {
+                glamor_pixmap_private *glyph_pix_priv;
+
+                glyph_pict = GlyphPicture(glyph)[screen_num];
+                glyph_draw = glyph_pict->pDrawable;
+                glyph_pix_priv = glamor_get_pixmap_private((PixmapPtr) glyph_draw);
+
+                /* Need to draw with slow path?
+                 */
+                if (_X_UNLIKELY(glyph_draw->width > glyph_max_dim ||
+                                glyph_draw->height > glyph_max_dim ||
+                                (glyph_pix_priv != 0 && glyph_pix_priv->type != GLAMOR_MEMORY)))
+                {
+                    if (glyphs_queued) {
+                        glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued);
+                        glyphs_queued = 0;
+                    }
+                bail_one:
+                    glamor_composite(op, src, glyph_pict, dst,
+                                     x_src + (x - glyph->info.x), (y - glyph->info.y),
+                                     0, 0,
+                                     x - glyph->info.x, y - glyph->info.y,
+                                     glyph_draw->width, glyph_draw->height);
+                } else {
+                    struct glamor_glyph_private *glyph_priv = glamor_get_glyph_private((PixmapPtr)(glyph_draw));
+                    struct glamor_glyph_atlas *next_atlas = glamor_atlas_for_glyph(glamor_priv, glyph_draw);
+
+                    /* Switching source glyph format?
+                     */
+                    if (_X_UNLIKELY(next_atlas != glyph_atlas)) {
+                        if (glyphs_queued) {
+                            glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued);
+                            glyphs_queued = 0;
+                        }
+                        glyph_atlas = next_atlas;
+                    }
+
+                    /* Glyph not cached in current atlas?
+                     */
+                    if (_X_UNLIKELY(glyph_priv->serial != glyph_atlas->serial)) {
+                        if (!glamor_glyph_can_add(glyph_atlas, glyph_atlas_dim, glyph_draw)) {
+                            if (glyphs_queued) {
+                                glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued);
+                                glyphs_queued = 0;
+                            }
+                            if (glyph_atlas->atlas) {
+                                (*screen->DestroyPixmap)(glyph_atlas->atlas);
+                                glyph_atlas->atlas = NULL;
+                            }
+                        }
+                        if (!glyph_atlas->atlas)
+                            glamor_glyph_atlas_init(screen, glyph_atlas);
+                        glamor_glyph_add(glyph_atlas, glyph_draw);
+                    }
+
+                    /* First glyph in the current atlas?
+                     */
+                    if (_X_UNLIKELY(glyphs_queued == 0)) {
+                        if (glamor_glyph_use_130(glamor_priv))
+                            prog = glamor_setup_program_render(op, src, glyph_pict, dst,
+                                                               glyphs_program,
+                                                               &glamor_facet_composite_glyphs_130,
+                                                               glamor_priv->glyph_defines);
+                        else
+                            prog = glamor_setup_program_render(op, src, glyph_pict, dst,
+                                                               glyphs_program,
+                                                               &glamor_facet_composite_glyphs_120,
+                                                               glamor_priv->glyph_defines);
+                        if (!prog)
+                            goto bail_one;
+                        v = glamor_glyph_start(screen, nglyph);
+                    }
+
+                    /* Add the glyph
+                     */
+
+                    glyphs_queued++;
+                    if (_X_LIKELY(glamor_glyph_use_130(glamor_priv))) {
+                        v[0] = x - glyph->info.x;
+                        v[1] = y - glyph->info.y;
+                        v[2] = glyph_draw->width;
+                        v[3] = glyph_draw->height;
+                        v[4] = glyph_priv->x;
+                        v[5] = glyph_priv->y;
+                        v += 6;
+                    } else {
+                        v[0] = x - glyph->info.x;
+                        v[1] = y - glyph->info.y;
+                        v[2] = glyph_priv->x;
+                        v[3] = glyph_priv->y;
+                        v += 4;
+
+                        v[0] = x - glyph->info.x + glyph_draw->width;
+                        v[1] = y - glyph->info.y;
+                        v[2] = glyph_priv->x + glyph_draw->width;
+                        v[3] = glyph_priv->y;
+                        v += 4;
+
+                        v[0] = x - glyph->info.x + glyph_draw->width;
+                        v[1] = y - glyph->info.y + glyph_draw->height;
+                        v[2] = glyph_priv->x + glyph_draw->width;
+                        v[3] = glyph_priv->y + glyph_draw->height;
+                        v += 4;
+
+                        v[0] = x - glyph->info.x;
+                        v[1] = y - glyph->info.y + glyph_draw->height;
+                        v[2] = glyph_priv->x;
+                        v[3] = glyph_priv->y + glyph_draw->height;
+                        v += 4;
+                    }
+                }
+            }
+            x += glyph->info.xOff;
+            y += glyph->info.yOff;
+            nglyph--;
+        }
+    }
+
+    if (glyphs_queued)
+        glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued);
+
+    return;
+}
+
+static struct glamor_glyph_atlas *
+glamor_alloc_glyph_atlas(ScreenPtr screen, int depth, CARD32 f)
+{
+    PictFormatPtr               format;
+    struct glamor_glyph_atlas    *glyph_atlas;
+
+    format = PictureMatchFormat(screen, depth, f);
+    if (!format)
+        return NULL;
+    glyph_atlas = calloc (1, sizeof (struct glamor_glyph_atlas));
+    if (!glyph_atlas)
+        return NULL;
+    glyph_atlas->format = format;
+    glyph_atlas->serial = 1;
+
+    return glyph_atlas;
+}
+
+Bool
+glamor_composite_glyphs_init(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    if (!dixRegisterPrivateKey(&glamor_glyph_private_key, PRIVATE_PIXMAP, sizeof (struct glamor_glyph_private)))
+        return FALSE;
+
+    /* Make glyph atlases of a reasonable size, but no larger than the maximum
+     * supported by the hardware
+     */
+    glamor_priv->glyph_atlas_dim = MIN(DEFAULT_ATLAS_DIM, glamor_priv->max_fbo_size);
+
+    /* Don't stick huge glyphs in the atlases */
+    glamor_priv->glyph_max_dim = glamor_priv->glyph_atlas_dim / 8;
+
+    glamor_priv->glyph_atlas_a = glamor_alloc_glyph_atlas(screen, 8, PICT_a8);
+    if (!glamor_priv->glyph_atlas_a)
+        return FALSE;
+    glamor_priv->glyph_atlas_argb = glamor_alloc_glyph_atlas(screen, 32, PICT_a8r8g8b8);
+    if (!glamor_priv->glyph_atlas_argb) {
+        free (glamor_priv->glyph_atlas_a);
+        return FALSE;
+    }
+    if (!glamor_glyphs_init_facet(screen))
+        return FALSE;
+    return TRUE;
+}
+
+static void
+glamor_free_glyph_atlas(struct glamor_glyph_atlas *atlas)
+{
+    if (!atlas)
+        return;
+    if (atlas->atlas)
+        FreePicture(atlas->atlas, 0);
+    free (atlas);
+}
+
+void
+glamor_composite_glyphs_fini(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    glamor_glyphs_fini_facet(screen);
+    glamor_free_glyph_atlas(glamor_priv->glyph_atlas_a);
+    glamor_free_glyph_atlas(glamor_priv->glyph_atlas_argb);
+}
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
deleted file mode 100644
index 4f3f969..0000000
--- a/glamor/glamor_glyphs.c
+++ /dev/null
@@ -1,1769 +0,0 @@
-/*
- * Copyright © 2008 Red Hat, Inc.
- * Partly based on code Copyright © 2000 SuSE, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Red Hat not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  Red Hat makes no representations about the
- * suitability of this software for any purpose.  It is provided "as is"
- * without express or implied warranty.
- *
- * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  SuSE makes no representations about the
- * suitability of this software for any purpose.  It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Owen Taylor <otaylor at fishsoup.net>
- * Based on code by: Keith Packard
- */
-
-#include <stdlib.h>
-
-#include "glamor_priv.h"
-
-#include <mipict.h>
-
-#if DEBUG_GLYPH_CACHE
-#define DBG_GLYPH_CACHE(a) ErrorF a
-#else
-#define DBG_GLYPH_CACHE(a)
-#endif
-
-/* Width of the pixmaps we use for the caches; this should be less than
- * max texture size of the driver; this may need to actually come from
- * the driver.
- */
-
-/* Maximum number of glyphs we buffer on the stack before flushing
- * rendering to the mask or destination surface.
- */
-#define GLYPH_BUFFER_SIZE 1024
-
-typedef struct {
-    PicturePtr source;
-    glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE + 4];
-    int count;
-} glamor_glyph_buffer_t;
-
-struct glamor_glyph {
-    glamor_glyph_cache_t *cache;
-    uint16_t x, y;
-    uint16_t size, pos;
-    unsigned long long left_x1_map, left_x2_map;
-    unsigned long long right_x1_map, right_x2_map;      /* Use to check real intersect or not. */
-    Bool has_edge_map;
-    Bool cached;
-};
-
-typedef enum {
-    GLAMOR_GLYPH_SUCCESS,       /* Glyph added to render buffer */
-    GLAMOR_GLYPH_FAIL,          /* out of memory, etc */
-    GLAMOR_GLYPH_NEED_FLUSH,    /* would evict a glyph already in the buffer */
-} glamor_glyph_cache_result_t;
-
-#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
-static DevPrivateKeyRec glamor_glyph_key;
-
-static inline struct glamor_glyph *
-glamor_glyph_get_private(ScreenPtr screen, GlyphPtr glyph)
-{
-    struct glamor_glyph *privates = (struct glamor_glyph*)glyph->devPrivates;
-
-    return &privates[screen->myNum];
-}
-
-/*
- * Mask cache is located at the corresponding cache picture's last row.
- * and is deadicated for the mask picture when do the glyphs_via_mask.
- *
- * As we split the glyphs list according to its overlapped or non-overlapped,
- * we can reduce the length of glyphs to do the glyphs_via_mask to 2 or 3
- * glyphs one time for most cases. Thus it give us a case to allocate a
- * small portion of the corresponding cache directly as the mask picture.
- * Then we can rendering the glyphs to this mask picture, and latter we
- * can accumulate the second steps, composite the mask to the dest with
- * the other non-overlapped glyphs's rendering process.
- * Another major benefit is we now only need to clear a relatively small mask
- * region then before. It also make us implement a bunch mask picture clearing
- * algorithm to avoid too frequently small region clearing.
- *
- * If there is no any overlapping, this method will not get performance gain.
- * If there is some overlapping, then this algorithm can get about 15% performance
- * gain.
- */
-
-static void
-clear_mask_cache_bitmap(glamor_glyph_mask_cache_t *maskcache,
-                        unsigned int clear_mask_bits)
-{
-    unsigned int i = 0;
-    BoxRec box[MASK_CACHE_WIDTH];
-    int box_cnt = 0;
-
-    assert((clear_mask_bits & ~MASK_CACHE_MASK) == 0);
-    for (i = 0; i < MASK_CACHE_WIDTH; i++) {
-        if (clear_mask_bits & (1 << i)) {
-            box[box_cnt].x1 = maskcache->mcache[i].x;
-            box[box_cnt].x2 = maskcache->mcache[i].x + MASK_CACHE_MAX_SIZE;
-            box[box_cnt].y1 = maskcache->mcache[i].y;
-            box[box_cnt].y2 = maskcache->mcache[i].y + MASK_CACHE_MAX_SIZE;
-            box_cnt++;
-        }
-    }
-    glamor_solid_boxes(maskcache->pixmap, box, box_cnt, 0);
-    maskcache->cleared_bitmap |= clear_mask_bits;
-}
-
-static void
-clear_mask_cache(glamor_glyph_mask_cache_t *maskcache)
-{
-    int x = 0;
-    int cnt = MASK_CACHE_WIDTH;
-    unsigned int i = 0;
-    struct glamor_glyph_mask_cache_entry *mce;
-
-    glamor_solid(maskcache->pixmap, 0, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE,
-                 MASK_CACHE_MAX_SIZE, 0);
-    mce = &maskcache->mcache[0];
-    while (cnt--) {
-        mce->width = 0;
-        mce->height = 0;
-        mce->x = x;
-        mce->y = CACHE_PICTURE_SIZE;
-        mce->idx = i++;
-        x += MASK_CACHE_MAX_SIZE;
-        mce++;
-    }
-    maskcache->free_bitmap = MASK_CACHE_MASK;
-    maskcache->cleared_bitmap = MASK_CACHE_MASK;
-}
-
-static int
-find_continuous_bits(unsigned int bits, int bits_cnt, unsigned int *pbits_mask)
-{
-    int idx = 0;
-    unsigned int bits_mask;
-
-    bits_mask = ((1LL << bits_cnt) - 1);
-
-    if (_X_UNLIKELY(bits_cnt > 56)) {
-        while (bits) {
-            if ((bits & bits_mask) == bits_mask) {
-                *pbits_mask = bits_mask << idx;
-                return idx;
-            }
-            bits >>= 1;
-            idx++;
-        }
-    }
-    else {
-        idx = __fls(bits);
-        while (bits) {
-            unsigned int temp_bits;
-
-            temp_bits = bits_mask << (idx - bits_cnt + 1);
-            if ((bits & temp_bits) == temp_bits) {
-                *pbits_mask = temp_bits;
-                return (idx - bits_cnt + 1);
-            }
-            /* Find first zero. And clear the tested bit. */
-            bits &= ~(1LL << idx);
-            idx = __fls(~bits);
-            bits &= ~((1LL << idx) - 1);
-            idx--;
-        }
-    }
-    return -1;
-}
-
-static struct glamor_glyph_mask_cache_entry *
-get_mask_cache(glamor_glyph_mask_cache_t *maskcache, int blocks)
-{
-    int free_cleared_bit, idx = -1;
-    int retry_cnt = 0;
-    unsigned int bits_mask = 0;
-
-    if (maskcache->free_bitmap == 0)
-        return NULL;
- retry:
-    free_cleared_bit = maskcache->free_bitmap & maskcache->cleared_bitmap;
-    if (free_cleared_bit && blocks == 1) {
-        idx = __fls(free_cleared_bit);
-        bits_mask = 1 << idx;
-    }
-    else if (free_cleared_bit && blocks > 1) {
-        idx = find_continuous_bits(free_cleared_bit, blocks, &bits_mask);
-    }
-
-    if (idx < 0) {
-        clear_mask_cache_bitmap(maskcache, maskcache->free_bitmap);
-        if (retry_cnt++ > 2)
-            return NULL;
-        goto retry;
-    }
-
-    maskcache->cleared_bitmap &= ~bits_mask;
-    maskcache->free_bitmap &= ~bits_mask;
-    DEBUGF("get idx %d free %x clear %x \n",
-           idx, maskcache->free_bitmap, maskcache->cleared_bitmap);
-    return &maskcache->mcache[idx];
-}
-
-static void
-put_mask_cache_bitmap(glamor_glyph_mask_cache_t *maskcache,
-                      unsigned int bitmap)
-{
-    maskcache->free_bitmap |= bitmap;
-    DEBUGF("put bitmap %x free %x clear %x \n",
-           bitmap, maskcache->free_bitmap, maskcache->cleared_bitmap);
-}
-
-static void
-glamor_unrealize_glyph_caches(ScreenPtr pScreen)
-{
-    glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
-    int i;
-
-    if (!glamor->glyph_caches_realized)
-        return;
-
-    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHE_FORMATS; i++) {
-        glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
-
-        if (cache->picture)
-            FreePicture(cache->picture, 0);
-
-        if (cache->glyphs)
-            free(cache->glyphs);
-
-        if (glamor->mask_cache[i])
-            free(glamor->mask_cache[i]);
-    }
-    glamor->glyph_caches_realized = FALSE;
-}
-
-void
-glamor_glyphs_fini(ScreenPtr pScreen)
-{
-    glamor_unrealize_glyph_caches(pScreen);
-}
-
-/* All caches for a single format share a single pixmap for glyph storage,
- * allowing mixing glyphs of different sizes without paying a penalty
- * for switching between source pixmaps. (Note that for a size of font
- * right at the border between two sizes, we might be switching for almost
- * every glyph.)
- *
- * This function allocates the storage pixmap, and then fills in the
- * rest of the allocated structures for all caches with the given format.
- */
-
-Bool
-glamor_realize_glyph_caches(ScreenPtr pScreen)
-{
-    glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
-
-    unsigned int formats[] = {
-        PIXMAN_a8,
-        PIXMAN_a8r8g8b8,
-    };
-    int i;
-
-    if (glamor->glyph_caches_realized)
-        return TRUE;
-
-    memset(glamor->glyphCaches, 0, sizeof(glamor->glyphCaches));
-
-    for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
-        glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
-        PixmapPtr pixmap;
-        PicturePtr picture;
-        XID component_alpha;
-        int depth = PIXMAN_FORMAT_DEPTH(formats[i]);
-        int error;
-        PictFormatPtr pPictFormat =
-            PictureMatchFormat(pScreen, depth, formats[i]);
-        if (!pPictFormat)
-            goto bail;
-
-        /* Now allocate the pixmap and picture */
-        pixmap = pScreen->CreatePixmap(pScreen,
-                                       CACHE_PICTURE_SIZE,
-                                       CACHE_PICTURE_SIZE + MASK_CACHE_MAX_SIZE,
-                                       depth, GLAMOR_CREATE_NO_LARGE);
-        if (!pixmap)
-            goto bail;
-
-        component_alpha = NeedsComponent(pPictFormat->format);
-        picture = CreatePicture(0, &pixmap->drawable, pPictFormat,
-                                CPComponentAlpha, &component_alpha,
-                                serverClient, &error);
-
-        pScreen->DestroyPixmap(pixmap);
-        if (!picture)
-            goto bail;
-
-        ValidatePicture(picture);
-
-        cache->picture = picture;
-        cache->glyphs = calloc(sizeof(GlyphPtr), GLYPH_CACHE_SIZE);
-        if (!cache->glyphs)
-            goto bail;
-
-        cache->evict = rand() % GLYPH_CACHE_SIZE;
-        glamor->mask_cache[i] = calloc(1, sizeof(*glamor->mask_cache[i]));
-        glamor->mask_cache[i]->pixmap = pixmap;
-        clear_mask_cache(glamor->mask_cache[i]);
-    }
-    assert(i == GLAMOR_NUM_GLYPH_CACHE_FORMATS);
-
-    glamor->glyph_caches_realized = TRUE;
-    return TRUE;
-
- bail:
-    glamor_unrealize_glyph_caches(pScreen);
-    return FALSE;
-}
-
-/**
- * Called by glamor_create_screen_resources() to set up the glyph cache.
- *
- * This was previously required to be called by the drivers, but not
- * as of the xserver 1.16 ABI.
- */
-Bool
-glamor_glyphs_init(ScreenPtr pScreen)
-{
-    if (!dixRegisterPrivateKey(&glamor_glyph_key,
-                               PRIVATE_GLYPH,
-                               screenInfo.numScreens * sizeof(struct glamor_glyph)))
-        return FALSE;
-
-    return TRUE;
-}
-
-/* The most efficient thing to way to upload the glyph to the screen
- * is to use CopyArea; glamor pixmaps are always offscreen.
- */
-static void
-glamor_glyph_cache_upload_glyph(ScreenPtr screen,
-                                glamor_glyph_cache_t *cache,
-                                GlyphPtr glyph, int x, int y)
-{
-    PicturePtr pGlyphPicture = GlyphPicture(glyph)[screen->myNum];
-    PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable;
-    PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable;
-    PixmapPtr scratch;
-    BoxRec box;
-    GCPtr gc;
-
-    gc = GetScratchGC(pCachePixmap->drawable.depth, screen);
-    if (!gc)
-        return;
-
-    ValidateGC(&pCachePixmap->drawable, gc);
-
-    scratch = pGlyphPixmap;
-    if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) {
-
-        scratch = glamor_create_pixmap(screen,
-                                       glyph->info.width,
-                                       glyph->info.height,
-                                       pCachePixmap->drawable.depth, 0);
-        if (scratch) {
-            PicturePtr picture;
-            int error;
-
-            picture =
-                CreatePicture(0,
-                              &scratch->drawable,
-                              PictureMatchFormat
-                              (screen,
-                               pCachePixmap->drawable.depth,
-                               cache->picture->format),
-                              0, NULL, serverClient, &error);
-            if (picture) {
-                ValidatePicture(picture);
-                glamor_composite(PictOpSrc,
-                                 pGlyphPicture,
-                                 NULL, picture,
-                                 0, 0, 0, 0, 0,
-                                 0, glyph->info.width, glyph->info.height);
-                FreePicture(picture, 0);
-            }
-        }
-        else {
-            scratch = pGlyphPixmap;
-        }
-    }
-
-    box.x1 = x;
-    box.y1 = y;
-    box.x2 = x + glyph->info.width;
-    box.y2 = y + glyph->info.height;
-    glamor_copy(&scratch->drawable,
-                &pCachePixmap->drawable, NULL,
-                &box, 1, -x, -y, FALSE, FALSE, 0, NULL);
-    if (scratch != pGlyphPixmap)
-        screen->DestroyPixmap(scratch);
-
-    FreeScratchGC(gc);
-}
-
-void
-glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph)
-{
-    struct glamor_glyph *priv;
-
-    /* Use Lookup in case we have not attached to this glyph. */
-    priv = glamor_glyph_get_private(screen, glyph);
-
-    if (priv->cached)
-        priv->cache->glyphs[priv->pos] = NULL;
-}
-
-/* Cut and paste from render/glyph.c - probably should export it instead */
-static void
-glamor_glyph_extents(int nlist,
-                     GlyphListPtr list, GlyphPtr *glyphs, BoxPtr extents)
-{
-    int x1, x2, y1, y2;
-    int x, y, n;
-
-    x1 = y1 = MAXSHORT;
-    x2 = y2 = MINSHORT;
-    x = y = 0;
-    while (nlist--) {
-        x += list->xOff;
-        y += list->yOff;
-        n = list->len;
-        list++;
-        while (n--) {
-            GlyphPtr glyph = *glyphs++;
-            int v;
-
-            v = x - glyph->info.x;
-            if (v < x1)
-                x1 = v;
-            v += glyph->info.width;
-            if (v > x2)
-                x2 = v;
-
-            v = y - glyph->info.y;
-            if (v < y1)
-                y1 = v;
-            v += glyph->info.height;
-            if (v > y2)
-                y2 = v;
-
-            x += glyph->info.xOff;
-            y += glyph->info.yOff;
-        }
-    }
-
-    extents->x1 = x1 < MINSHORT ? MINSHORT : x1;
-    extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2;
-    extents->y1 = y1 < MINSHORT ? MINSHORT : y1;
-    extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2;
-}
-
-static void
-glamor_glyph_priv_get_edge_map(GlyphPtr glyph, struct glamor_glyph *priv,
-                               PicturePtr glyph_picture)
-{
-    PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable;
-    int j;
-    unsigned long long left_x1_map = 0, left_x2_map = 0;
-    unsigned long long right_x1_map = 0, right_x2_map = 0;
-    int bitsPerPixel;
-    int stride;
-    void *bits;
-    int width;
-    unsigned int left_x1_data = 0, left_x2_data = 0;
-    unsigned int right_x1_data = 0, right_x2_data = 0;
-
-    bitsPerPixel = glyph_pixmap->drawable.bitsPerPixel;
-    stride = glyph_pixmap->devKind;
-    bits = glyph_pixmap->devPrivate.ptr;
-    width = glyph->info.width;
-
-    if (glyph_pixmap->drawable.width < 2
-        || !(glyph_pixmap->drawable.depth == 8
-             || glyph_pixmap->drawable.depth == 1
-             || glyph_pixmap->drawable.depth == 32)) {
-        priv->has_edge_map = FALSE;
-        return;
-    }
-
-    left_x1_map = left_x2_map = 0;
-    right_x1_map = right_x2_map = 0;
-
-    for (j = 0; j < glyph_pixmap->drawable.height; j++) {
-        if (bitsPerPixel == 8) {
-            unsigned char *data;
-
-            data = (unsigned char *) ((unsigned char *) bits + stride * j);
-            left_x1_data = *data++;
-            left_x2_data = *data;
-            data =
-                (unsigned char *) ((unsigned char *) bits + stride * j + width -
-                                   2);
-            right_x1_data = *data++;
-            right_x2_data = *data;
-        }
-        else if (bitsPerPixel == 32) {
-            left_x1_data = *((unsigned int *) bits + stride / 4 * j);
-            left_x2_data = *((unsigned int *) bits + stride / 4 * j + 1);
-            right_x1_data =
-                *((unsigned int *) bits + stride / 4 * j + width - 2);
-            right_x2_data =
-                *((unsigned int *) bits + stride / 4 * j + width - 1);
-        }
-        else if (bitsPerPixel == 1) {
-            unsigned char temp;
-
-            temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr
-                     + glyph_pixmap->devKind * j) & 0x3;
-            left_x1_data = temp & 0x1;
-            left_x2_data = temp & 0x2;
-
-            temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr
-                     + glyph_pixmap->devKind * j
-                     + (glyph_pixmap->drawable.width - 2) / 8);
-            right_x1_data = temp
-                & (1 << ((glyph_pixmap->drawable.width - 2) % 8));
-            temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr
-                     + glyph_pixmap->devKind * j
-                     + (glyph_pixmap->drawable.width - 1) / 8);
-            right_x2_data = temp
-                & (1 << ((glyph_pixmap->drawable.width - 1) % 8));
-        }
-        left_x1_map |= (left_x1_data != 0) << j;
-        left_x2_map |= (left_x2_data != 0) << j;
-        right_x1_map |= (right_x1_data != 0) << j;
-        right_x2_map |= (right_x2_data != 0) << j;
-    }
-
-    priv->left_x1_map = left_x1_map;
-    priv->left_x2_map = left_x2_map;
-    priv->right_x1_map = right_x1_map;
-    priv->right_x2_map = right_x2_map;
-    priv->has_edge_map = TRUE;
-    return;
-}
-
-/**
- * Returns TRUE if the glyphs in the lists intersect.  Only checks based on
- * bounding box, which appears to be good enough to catch most cases at least.
- */
-
-#define INTERSECTED_TYPE_MASK 1
-#define NON_INTERSECTED 0
-#define INTERSECTED 1
-
-struct glamor_glyph_list {
-    int nlist;
-    GlyphListPtr list;
-    GlyphPtr *glyphs;
-    int type;
-};
-
-static Bool
-glyph_new_fixed_list(struct glamor_glyph_list *fixed_list,
-                     GlyphPtr *cur_glyphs,
-                     GlyphPtr ** head_glyphs,
-                     GlyphListPtr cur_list,
-                     int cur_pos, int cur_x, int cur_y,
-                     int x1, int y1, int x2, int y2,
-                     GlyphListPtr *head_list,
-                     int *head_pos,
-                     int *head_x,
-                     int *head_y, int *fixed_cnt, int type, BoxPtr prev_extents)
-{
-    int x_off = 0;
-    int y_off = 0;
-    int n_off = 0;
-    int list_cnt;
-
-    if (type == NON_INTERSECTED) {
-        if (x1 < prev_extents->x2 && x2 > prev_extents->x1
-            && y1 < prev_extents->y2 && y2 > prev_extents->y1)
-            return FALSE;
-        x_off = (*(cur_glyphs - 1))->info.xOff;
-        y_off = (*(cur_glyphs - 1))->info.yOff;
-        n_off = 1;
-    }
-
-    list_cnt = cur_list - *head_list + 1;
-    if (cur_pos <= n_off) {
-        DEBUGF("break at %d n_off %d\n", cur_pos, n_off);
-        list_cnt--;
-        if (cur_pos < n_off) {
-            /* we overlap with previous list's last glyph. */
-            x_off += cur_list->xOff;
-            y_off += cur_list->yOff;
-            cur_list--;
-            cur_pos = cur_list->len;
-            if (cur_pos <= n_off) {
-                list_cnt--;
-            }
-        }
-    }
-    DEBUGF("got %d lists\n", list_cnt);
-    if (list_cnt != 0) {
-        fixed_list->list = xallocarray(list_cnt, sizeof(*cur_list));
-        memcpy(fixed_list->list, *head_list, list_cnt * sizeof(*cur_list));
-        fixed_list->list[0].xOff = *head_x;
-        fixed_list->list[0].yOff = *head_y;
-        fixed_list->glyphs = *head_glyphs;
-        fixed_list->type = type & INTERSECTED_TYPE_MASK;
-        fixed_list->nlist = list_cnt;
-        if (cur_list != *head_list) {
-            fixed_list->list[0].len = (*head_list)->len - *head_pos;
-            if (cur_pos != n_off)
-                fixed_list->list[list_cnt - 1].len = cur_pos - n_off;
-        }
-        else
-            fixed_list->list[0].len = cur_pos - *head_pos - n_off;
-        (*fixed_cnt)++;
-    }
-
-    if (type <= INTERSECTED) {
-        *head_list = cur_list;
-        *head_pos = cur_pos - n_off;
-        *head_x = cur_x - x_off;
-        *head_y = cur_y - y_off;
-        *head_glyphs = cur_glyphs - n_off;
-    }
-    return TRUE;
-}
-
-/*
- * This function detects glyph lists's overlapping.
- *
- * If check_fake_overlap is set, then it will check the glyph's left
- * and right small boxes's real overlapping pixels. And if there is
- * no real pixel overlapping, then it will not be treated as overlapped
- * case. And we also can configured it to ignore less than 2 pixels
- * overlappig.
- *
- * This function analyzes all the lists and split the list to multiple
- * lists which are pure overlapped glyph lists or pure non-overlapped
- * list if the overlapping only ocurr on the two adjacent glyphs.
- * Otherwise, it return -1.
- *
- **/
-
-static int
-glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs,
-                        PictFormatShort mask_format,
-                        ScreenPtr screen, Bool check_fake_overlap,
-                        struct glamor_glyph_list *fixed_list, int fixed_size)
-{
-    int x1, x2, y1, y2;
-    int n;
-    int x, y;
-    BoxPtr extents;
-    BoxRec prev_extents;
-    Bool first = TRUE, first_list = TRUE;
-    Bool need_free_list_region = FALSE;
-    Bool need_free_fixed_list = FALSE;
-    struct glamor_glyph *priv = NULL;
-    Bool in_non_intersected_list = -1;
-    GlyphListPtr head_list;
-    int head_x, head_y, head_pos;
-    int fixed_cnt = 0;
-    GlyphPtr *head_glyphs;
-    GlyphListPtr cur_list = list;
-    RegionRec list_region;
-    RegionRec current_region;
-    BoxRec current_box;
-
-    if (nlist > 1) {
-        pixman_region_init(&list_region);
-        need_free_list_region = TRUE;
-    }
-
-    pixman_region_init(&current_region);
-
-    extents = pixman_region_extents(&current_region);
-
-    x = 0;
-    y = 0;
-    x1 = x2 = y1 = y2 = 0;
-    n = 0;
-    extents->x1 = 0;
-    extents->y1 = 0;
-    extents->x2 = 0;
-    extents->y2 = 0;
-
-    head_list = list;
-    DEBUGF("has %d lists.\n", nlist);
-    while (nlist--) {
-        BoxRec left_box, right_box = { 0 };
-        Bool has_left_edge_box = FALSE, has_right_edge_box = FALSE;
-        Bool left_to_right;
-        struct glamor_glyph *left_priv = NULL, *right_priv = NULL;
-
-        x += list->xOff;
-        y += list->yOff;
-        n = list->len;
-        left_to_right = TRUE;
-        cur_list = list++;
-
-        if (_X_UNLIKELY(!first_list)) {
-            pixman_region_init_with_extents(&current_region, extents);
-            pixman_region_union(&list_region, &list_region, &current_region);
-            first = TRUE;
-        }
-        else {
-            head_list = cur_list;
-            head_pos = cur_list->len - n;
-            head_x = x;
-            head_y = y;
-            head_glyphs = glyphs;
-        }
-
-        DEBUGF("current list %p has %d glyphs\n", cur_list, n);
-        while (n--) {
-            GlyphPtr glyph = *glyphs++;
-
-            DEBUGF("the %dth glyph\n", cur_list->len - n - 1);
-            if (glyph->info.width == 0 || glyph->info.height == 0) {
-                x += glyph->info.xOff;
-                y += glyph->info.yOff;
-                continue;
-            }
-            if (mask_format
-                && mask_format != GlyphPicture(glyph)[screen->myNum]->format) {
-                need_free_fixed_list = TRUE;
-                goto done;
-            }
-
-            x1 = x - glyph->info.x;
-            if (x1 < MINSHORT)
-                x1 = MINSHORT;
-            y1 = y - glyph->info.y;
-            if (y1 < MINSHORT)
-                y1 = MINSHORT;
-            if (check_fake_overlap)
-                priv = glamor_glyph_get_private(screen, glyph);
-
-            x2 = x1 + glyph->info.width;
-            y2 = y1 + glyph->info.height;
-
-            if (x2 > MAXSHORT)
-                x2 = MAXSHORT;
-            if (y2 > MAXSHORT)
-                y2 = MAXSHORT;
-
-            if (first) {
-                extents->x1 = x1;
-                extents->y1 = y1;
-                extents->x2 = x2;
-                extents->y2 = y2;
-
-                prev_extents = *extents;
-
-                first = FALSE;
-                if (check_fake_overlap && priv
-                    && priv->has_edge_map && glyph->info.yOff == 0) {
-                    left_box.x1 = x1;
-                    left_box.x2 = x1 + 1;
-                    left_box.y1 = y1;
-
-                    right_box.x1 = x2 - 2;
-                    right_box.x2 = x2 - 1;
-                    right_box.y1 = y1;
-                    left_priv = right_priv = priv;
-                    has_left_edge_box = TRUE;
-                    has_right_edge_box = TRUE;
-                }
-            }
-            else {
-                if (_X_UNLIKELY(!first_list)) {
-                    current_box.x1 = x1;
-                    current_box.y1 = y1;
-                    current_box.x2 = x2;
-                    current_box.y2 = y2;
-                    if (pixman_region_contains_rectangle
-                        (&list_region, &current_box) != PIXMAN_REGION_OUT) {
-                        need_free_fixed_list = TRUE;
-                        goto done;
-                    }
-                }
-
-                if (x1 < extents->x2 && x2 > extents->x1
-                    && y1 < extents->y2 && y2 > extents->y1) {
-
-                    if (check_fake_overlap &&
-                        (has_left_edge_box || has_right_edge_box)
-                        && priv->has_edge_map && glyph->info.yOff == 0) {
-                        int left_dx, right_dx;
-                        unsigned long long intersected;
-
-                        left_dx = has_left_edge_box ? 1 : 0;
-                        right_dx = has_right_edge_box ? 1 : 0;
-                        if (x1 + 1 < extents->x2 - right_dx &&
-                            x2 - 1 > extents->x1 + left_dx)
-                            goto real_intersected;
-
-                        if (left_to_right && has_right_edge_box) {
-                            if (x1 == right_box.x1) {
-                                intersected =
-                                    ((priv->left_x1_map & right_priv->
-                                      right_x1_map)
-                                     | (priv->left_x2_map & right_priv->
-                                        right_x2_map));
-                                if (intersected)
-                                    goto real_intersected;
-                            }
-                            else if (x1 == right_box.x2) {
-                                intersected =
-                                    (priv->left_x1_map & right_priv->
-                                     right_x2_map);
-                                if (intersected) {
-#ifdef  GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
-                                    /* tolerate with two pixels overlap. */
-                                    intersected &= ~(1 << __fls(intersected));
-                                    if ((intersected & (intersected - 1)))
-#endif
-                                        goto real_intersected;
-                                }
-                            }
-                        }
-                        else if (!left_to_right && has_left_edge_box) {
-                            if (x2 - 1 == left_box.x1) {
-                                intersected =
-                                    (priv->right_x2_map & left_priv->
-                                     left_x1_map);
-                                if (intersected) {
-#ifdef  GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
-                                    /* tolerate with two pixels overlap. */
-                                    intersected &= ~(1 << __fls(intersected));
-                                    if ((intersected & (intersected - 1)))
-#endif
-                                        goto real_intersected;
-                                }
-                            }
-                            else if (x2 - 1 == right_box.x2) {
-                                if ((priv->right_x1_map & left_priv->
-                                     left_x1_map)
-                                    || (priv->right_x2_map & left_priv->
-                                        left_x2_map))
-                                    goto real_intersected;
-                            }
-                        }
-                        else {
-                            if (x1 < extents->x2 && x1 + 2 > extents->x1)
-                                goto real_intersected;
-                        }
-                        goto non_intersected;
-                    }
-                    else {
- real_intersected:
-                        DEBUGF("overlap with previous glyph.\n");
-                        if (in_non_intersected_list == 1) {
-                            if (fixed_cnt >= fixed_size) {
-                                need_free_fixed_list = TRUE;
-                                goto done;
-                            }
-                            if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
-                                                      glyphs - 1,
-                                                      &head_glyphs,
-                                                      cur_list,
-                                                      cur_list->len - (n + 1),
-                                                      x, y, x1, y1, x2, y2,
-                                                      &head_list, &head_pos,
-                                                      &head_x, &head_y,
-                                                      &fixed_cnt,
-                                                      NON_INTERSECTED,
-                                                      &prev_extents)) {
-                                need_free_fixed_list = TRUE;
-                                goto done;
-                            }
-                        }
-
-                        in_non_intersected_list = 0;
-
-                    }
-                }
-                else {
- non_intersected:
-                    DEBUGF("doesn't overlap with previous glyph.\n");
-                    if (in_non_intersected_list == 0) {
-                        if (fixed_cnt >= fixed_size) {
-                            need_free_fixed_list = TRUE;
-                            goto done;
-                        }
-                        if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
-                                                  glyphs - 1,
-                                                  &head_glyphs,
-                                                  cur_list,
-                                                  cur_list->len - (n + 1), x, y,
-                                                  x1, y1, x2, y2,
-                                                  &head_list,
-                                                  &head_pos,
-                                                  &head_x,
-                                                  &head_y, &fixed_cnt,
-                                                  INTERSECTED, &prev_extents)) {
-                            need_free_fixed_list = TRUE;
-                            goto done;
-                        }
-                    }
-                    in_non_intersected_list = 1;
-                }
-                prev_extents = *extents;
-            }
-
-            if (check_fake_overlap && priv
-                && priv->has_edge_map && glyph->info.yOff == 0) {
-                if (!has_left_edge_box || x1 < extents->x1) {
-                    left_box.x1 = x1;
-                    left_box.x2 = x1 + 1;
-                    left_box.y1 = y1;
-                    has_left_edge_box = TRUE;
-                    left_priv = priv;
-                }
-
-                if (!has_right_edge_box || x2 > extents->x2) {
-                    right_box.x1 = x2 - 2;
-                    right_box.x2 = x2 - 1;
-                    right_box.y1 = y1;
-                    has_right_edge_box = TRUE;
-                    right_priv = priv;
-                }
-            }
-
-            if (x1 < extents->x1)
-                extents->x1 = x1;
-            if (x2 > extents->x2)
-                extents->x2 = x2;
-
-            if (y1 < extents->y1)
-                extents->y1 = y1;
-            if (y2 > extents->y2)
-                extents->y2 = y2;
-
-            x += glyph->info.xOff;
-            y += glyph->info.yOff;
-        }
-        first_list = FALSE;
-    }
-
-    if (in_non_intersected_list == 0 && fixed_cnt == 0) {
-        fixed_cnt = -1;
-        goto done;
-    }
-
-    if ((in_non_intersected_list != -1 || head_pos != n) && (fixed_cnt > 0)) {
-        if (fixed_cnt >= fixed_size) {
-            need_free_fixed_list = TRUE;
-            goto done;
-        }
-        if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
-                                  glyphs - 1,
-                                  &head_glyphs,
-                                  cur_list,
-                                  cur_list->len - (n + 1), x, y,
-                                  x1, y1, x2, y2,
-                                  &head_list,
-                                  &head_pos,
-                                  &head_x,
-                                  &head_y, &fixed_cnt,
-                                  (!in_non_intersected_list) | 0x80,
-                                  &prev_extents)) {
-            need_free_fixed_list = TRUE;
-            goto done;
-        }
-    }
-
- done:
-    if (need_free_list_region)
-        pixman_region_fini(&list_region);
-    pixman_region_fini(&current_region);
-
-    if (need_free_fixed_list && fixed_cnt >= 0) {
-        while (fixed_cnt--) {
-            free(fixed_list[fixed_cnt].list);
-        }
-    }
-
-    DEBUGF("Got %d fixed list \n", fixed_cnt);
-    return fixed_cnt;
-}
-
-static inline unsigned int
-glamor_glyph_size_to_count(int size)
-{
-    size /= GLYPH_MIN_SIZE;
-    return size * size;
-}
-
-static inline unsigned int
-glamor_glyph_count_to_mask(int count)
-{
-    return ~(count - 1);
-}
-
-static inline unsigned int
-glamor_glyph_size_to_mask(int size)
-{
-    return glamor_glyph_count_to_mask(glamor_glyph_size_to_count(size));
-}
-
-static PicturePtr
-glamor_glyph_cache(glamor_screen_private *glamor, GlyphPtr glyph, int *out_x,
-                   int *out_y)
-{
-    ScreenPtr screen = glamor->screen;
-    PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum];
-    glamor_glyph_cache_t *cache =
-        &glamor->glyphCaches[PICT_FORMAT_RGB(glyph_picture->format) != 0];
-    struct glamor_glyph *priv = NULL, *evicted_priv = NULL;
-    int size, mask, pos, s;
-
-    if (glyph->info.width > GLYPH_MAX_SIZE
-        || glyph->info.height > GLYPH_MAX_SIZE)
-        return NULL;
-
-    for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2)
-        if (glyph->info.width <= size && glyph->info.height <= size)
-            break;
-
-    s = glamor_glyph_size_to_count(size);
-    mask = glamor_glyph_count_to_mask(s);
-    pos = (cache->count + s - 1) & mask;
-
-    priv = glamor_glyph_get_private(screen, glyph);
-    if (pos < GLYPH_CACHE_SIZE) {
-        cache->count = pos + s;
-    }
-    else {
-        for (s = size; s <= GLYPH_MAX_SIZE; s *= 2) {
-            int i = cache->evict & glamor_glyph_size_to_mask(s);
-            GlyphPtr evicted = cache->glyphs[i];
-
-            if (evicted == NULL)
-                continue;
-
-            evicted_priv = glamor_glyph_get_private(screen, evicted);
-            assert(evicted_priv->pos == i);
-            if (evicted_priv->size >= s) {
-                cache->glyphs[i] = NULL;
-                evicted_priv->cached = FALSE;
-                pos = cache->evict & glamor_glyph_size_to_mask(size);
-            }
-            else
-                evicted_priv = NULL;
-            break;
-        }
-        if (evicted_priv == NULL) {
-            int count = glamor_glyph_size_to_count(size);
-
-            mask = glamor_glyph_count_to_mask(count);
-            pos = cache->evict & mask;
-            for (s = 0; s < count; s++) {
-                GlyphPtr evicted = cache->glyphs[pos + s];
-
-                if (evicted != NULL) {
-
-                    evicted_priv = glamor_glyph_get_private(screen, evicted);
-
-                    assert(evicted_priv->pos == pos + s);
-                    evicted_priv->cached = FALSE;
-                    cache->glyphs[pos + s] = NULL;
-                }
-            }
-
-        }
-        /* And pick a new eviction position */
-        cache->evict = rand() % GLYPH_CACHE_SIZE;
-    }
-
-    cache->glyphs[pos] = glyph;
-
-    priv->cache = cache;
-    priv->size = size;
-    priv->pos = pos;
-    s = pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) *
-               (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE));
-    priv->x = s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE;
-    priv->y = (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE;
-    for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2) {
-        if (pos & 1)
-            priv->x += s;
-        if (pos & 2)
-            priv->y += s;
-        pos >>= 2;
-    }
-
-    glamor_glyph_cache_upload_glyph(screen, cache, glyph, priv->x, priv->y);
-#ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
-    if (priv->has_edge_map == FALSE && glyph->info.width >= 2)
-        glamor_glyph_priv_get_edge_map(glyph, priv, glyph_picture);
-#endif
-    priv->cached = TRUE;
-
-    *out_x = priv->x;
-    *out_y = priv->y;
-    return cache->picture;
-}
-
-typedef void (*glyphs_flush_func) (void *arg);
-struct glyphs_flush_dst_arg {
-    CARD8 op;
-    PicturePtr src;
-    PicturePtr dst;
-    glamor_glyph_buffer_t *buffer;
-    int x_src, y_src;
-    int x_dst, y_dst;
-};
-
-static struct glyphs_flush_dst_arg dst_arg;
-static struct glyphs_flush_mask_arg mask_arg;
-static glamor_glyph_buffer_t dst_buffer;
-static glamor_glyph_buffer_t mask_buffer;
-unsigned long long mask_glyphs_cnt = 0;
-unsigned long long dst_glyphs_cnt = 0;
-
-#define GLYPHS_DST_MODE_VIA_MASK		0
-#define GLYPHS_DST_MODE_VIA_MASK_CACHE		1
-#define GLYPHS_DST_MODE_TO_DST			2
-#define GLYPHS_DST_MODE_MASK_TO_DST		3
-
-struct glyphs_flush_mask_arg {
-    PicturePtr mask;
-    glamor_glyph_buffer_t *buffer;
-    glamor_glyph_mask_cache_t *maskcache;
-    unsigned int used_bitmap;
-};
-
-static void
-glamor_glyphs_flush_mask(struct glyphs_flush_mask_arg *arg)
-{
-    if (arg->buffer->count > 0) {
-        glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source,
-                                     NULL, arg->mask,
-                                     arg->buffer->count, arg->buffer->rects);
-    }
-    arg->buffer->count = 0;
-    arg->buffer->source = NULL;
-
-}
-
-static void
-glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg *arg)
-{
-    if (!arg->buffer)
-        return;
-
-    if (mask_buffer.count > 0) {
-        glamor_glyphs_flush_mask(&mask_arg);
-    }
-    if (mask_arg.used_bitmap) {
-        put_mask_cache_bitmap(mask_arg.maskcache, mask_arg.used_bitmap);
-        mask_arg.used_bitmap = 0;
-    }
-
-    if (arg->buffer->count > 0) {
-        glamor_composite_glyph_rects(arg->op, arg->src,
-                                     arg->buffer->source, arg->dst,
-                                     arg->buffer->count,
-                                     &arg->buffer->rects[0]);
-        arg->buffer->count = 0;
-        arg->buffer->source = NULL;
-    }
-}
-
-static glamor_glyph_cache_result_t
-glamor_buffer_glyph(glamor_screen_private *glamor_priv,
-                    glamor_glyph_buffer_t *buffer,
-                    PictFormatShort format,
-                    GlyphPtr glyph, struct glamor_glyph *priv,
-                    int x_glyph, int y_glyph,
-                    int dx, int dy, int w, int h,
-                    int glyphs_dst_mode,
-                    glyphs_flush_func glyphs_flush, void *flush_arg)
-{
-    ScreenPtr screen = glamor_priv->screen;
-    glamor_composite_rect_t *rect;
-    PicturePtr source;
-    int x, y;
-    glamor_glyph_cache_t *cache;
-
-    if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST)
-        priv = glamor_glyph_get_private(screen, glyph);
-
-    if (PICT_FORMAT_BPP(format) == 1)
-        format = PICT_a8;
-
-    cache = &glamor_priv->glyphCaches[PICT_FORMAT_RGB(format) != 0];
-
-    if (buffer->source && buffer->source != cache->picture && glyphs_flush) {
-        (*glyphs_flush) (flush_arg);
-        glyphs_flush = NULL;
-    }
-
-    if (buffer->count == GLYPH_BUFFER_SIZE && glyphs_flush) {
-        (*glyphs_flush) (flush_arg);
-        glyphs_flush = NULL;
-    }
-
-    if (priv && priv->cached) {
-        rect = &buffer->rects[buffer->count++];
-        rect->x_src = priv->x + dx;
-        rect->y_src = priv->y + dy;
-        if (buffer->source == NULL)
-            buffer->source = priv->cache->picture;
-        if (glyphs_dst_mode <= GLYPHS_DST_MODE_VIA_MASK_CACHE)
-            assert(priv->cache->glyphs[priv->pos] == glyph);
-    }
-    else {
-        assert(glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST);
-        if (glyphs_flush)
-            (*glyphs_flush) (flush_arg);
-        source = glamor_glyph_cache(glamor_priv, glyph, &x, &y);
-
-        if (source != NULL) {
-            rect = &buffer->rects[buffer->count++];
-            rect->x_src = x + dx;
-            rect->y_src = y + dy;
-            if (buffer->source == NULL)
-                buffer->source = source;
-            if (glyphs_dst_mode == GLYPHS_DST_MODE_VIA_MASK_CACHE) {
-                /* mode 1 means we are using global mask cache,
-                 * thus we have to composite from the cache picture
-                 * to the cache picture, we need a flush here to make
-                 * sure latter we get the corret glyphs data.*/
-                glamor_make_current(glamor_priv);
-                glFlush();
-            }
-        }
-        else {
-            /* Couldn't find the glyph in the cache, use the glyph picture directly */
-            source = GlyphPicture(glyph)[screen->myNum];
-            if (buffer->source && buffer->source != source && glyphs_flush)
-                (*glyphs_flush) (flush_arg);
-            buffer->source = source;
-
-            rect = &buffer->rects[buffer->count++];
-            rect->x_src = 0 + dx;
-            rect->y_src = 0 + dy;
-        }
-        priv = glamor_glyph_get_private(screen, glyph);
-    }
-
-    rect->x_dst = x_glyph;
-    rect->y_dst = y_glyph;
-    if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST) {
-        rect->x_dst -= glyph->info.x;
-        rect->y_dst -= glyph->info.y;
-    }
-    rect->width = w;
-    rect->height = h;
-    if (glyphs_dst_mode > GLYPHS_DST_MODE_VIA_MASK_CACHE) {
-        rect->x_mask = rect->x_src;
-        rect->y_mask = rect->y_src;
-        rect->x_src = dst_arg.x_src + rect->x_dst - dst_arg.x_dst;
-        rect->y_src = dst_arg.y_src + rect->y_dst - dst_arg.y_dst;
-    }
-
-    return GLAMOR_GLYPH_SUCCESS;
-}
-
-static void
-glamor_buffer_glyph_clip(glamor_screen_private *glamor_priv,
-                         BoxPtr rects,
-                         int nrect, PictFormatShort format,
-                         GlyphPtr glyph, struct glamor_glyph *priv,
-                         int glyph_x, int glyph_y,
-                         int glyph_dx, int glyph_dy,
-                         int width, int height,
-                         int glyphs_mode,
-                         glyphs_flush_func flush_func, void *arg)
-{
-    int i;
-
-    for (i = 0; i < nrect; i++) {
-        int dst_x, dst_y;
-        int dx, dy;
-        int x2, y2;
-
-        dst_x = glyph_x - glyph_dx;
-        dst_y = glyph_y - glyph_dy;
-        x2 = dst_x + width;
-        y2 = dst_y + height;
-        dx = dy = 0;
-        if (rects[i].y1 >= y2)
-            break;
-
-        if (dst_x < rects[i].x1)
-            dx = rects[i].x1 - dst_x, dst_x = rects[i].x1;
-        if (x2 > rects[i].x2)
-            x2 = rects[i].x2;
-        if (dst_y < rects[i].y1)
-            dy = rects[i].y1 - dst_y, dst_y = rects[i].y1;
-        if (y2 > rects[i].y2)
-            y2 = rects[i].y2;
-        if (dst_x < x2 && dst_y < y2) {
-
-            glamor_buffer_glyph(glamor_priv,
-                                &dst_buffer,
-                                format,
-                                glyph, priv,
-                                dst_x + glyph_dx,
-                                dst_y + glyph_dy,
-                                dx, dy,
-                                x2 - dst_x, y2 - dst_y,
-                                glyphs_mode, flush_func, arg);
-        }
-    }
-}
-
-static void
-glamor_glyphs_via_mask(CARD8 op,
-                       PicturePtr src,
-                       PicturePtr dst,
-                       PictFormatPtr mask_format,
-                       INT16 x_src,
-                       INT16 y_src,
-                       int nlist, GlyphListPtr list, GlyphPtr *glyphs,
-                       Bool use_mask_cache)
-{
-    PixmapPtr mask_pixmap = 0;
-    PicturePtr mask;
-    ScreenPtr screen = dst->pDrawable->pScreen;
-    int width = 0, height = 0;
-    int x, y;
-    int x_dst = list->xOff, y_dst = list->yOff;
-    int n;
-    GlyphPtr glyph;
-    int error;
-    BoxRec extents = { 0, 0, 0, 0 };
-    XID component_alpha;
-    glamor_screen_private *glamor_priv;
-    int need_free_mask = FALSE;
-    glamor_glyph_buffer_t buffer;
-    struct glyphs_flush_mask_arg arg;
-    glamor_glyph_buffer_t *pmask_buffer;
-    struct glyphs_flush_mask_arg *pmask_arg;
-    struct glamor_glyph_mask_cache_entry *mce = NULL;
-    glamor_glyph_mask_cache_t *maskcache;
-    glamor_glyph_cache_t *cache;
-    int glyphs_dst_mode;
-
-    glamor_glyph_extents(nlist, list, glyphs, &extents);
-
-    if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
-        return;
-    glamor_priv = glamor_get_screen_private(screen);
-    width = extents.x2 - extents.x1;
-    height = extents.y2 - extents.y1;
-
-    if (mask_format->depth == 1) {
-        PictFormatPtr a8Format = PictureMatchFormat(screen, 8, PICT_a8);
-
-        if (a8Format)
-            mask_format = a8Format;
-    }
-
-    cache = &glamor_priv->glyphCaches
-        [PICT_FORMAT_RGB(mask_format->format) != 0];
-    maskcache = glamor_priv->mask_cache[PICT_FORMAT_RGB(mask_format->format) != 0];
-
-    x = -extents.x1;
-    y = -extents.y1;
-    if (!use_mask_cache || width > (CACHE_PICTURE_SIZE / 4)
-        || height > MASK_CACHE_MAX_SIZE) {
- new_mask_pixmap:
-        mask_pixmap = glamor_create_pixmap(screen, width, height,
-                                           mask_format->depth,
-                                           CREATE_PIXMAP_USAGE_SCRATCH);
-        if (!mask_pixmap) {
-            glamor_destroy_pixmap(mask_pixmap);
-            return;
-        }
-        glamor_solid(mask_pixmap, 0, 0, width, height, 0);
-        component_alpha = NeedsComponent(mask_format->format);
-        mask = CreatePicture(0, &mask_pixmap->drawable,
-                             mask_format, CPComponentAlpha,
-                             &component_alpha, serverClient, &error);
-        if (!mask)
-            return;
-        need_free_mask = TRUE;
-        pmask_arg = &arg;
-        pmask_buffer = &buffer;
-        pmask_buffer->count = 0;
-        pmask_buffer->source = NULL;
-        pmask_arg->used_bitmap = 0;
-        glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK;
-    }
-    else {
-        int retry_cnt = 0;
-
- retry:
-        mce = get_mask_cache(maskcache,
-                             (width + MASK_CACHE_MAX_SIZE -
-                              1) / MASK_CACHE_MAX_SIZE);
-
-        if (mce == NULL) {
-            glamor_glyphs_flush_dst(&dst_arg);
-            retry_cnt++;
-            if (retry_cnt > 2) {
-                assert(0);
-                goto new_mask_pixmap;
-            }
-            goto retry;
-        }
-
-        mask = cache->picture;
-        x += mce->x;
-        y += mce->y;
-        mce->width = (width + MASK_CACHE_MAX_SIZE - 1) / MASK_CACHE_MAX_SIZE;
-        mce->height = 1;
-        if (mask_arg.mask && mask_arg.mask != mask && mask_buffer.count != 0)
-            glamor_glyphs_flush_dst(&dst_arg);
-        pmask_arg = &mask_arg;
-        pmask_buffer = &mask_buffer;
-        pmask_arg->maskcache = maskcache;
-        glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK_CACHE;
-    }
-    pmask_arg->mask = mask;
-    pmask_arg->buffer = pmask_buffer;
-    while (nlist--) {
-        x += list->xOff;
-        y += list->yOff;
-        n = list->len;
-        mask_glyphs_cnt += n;
-        while (n--) {
-            glyph = *glyphs++;
-            if (glyph->info.width > 0 && glyph->info.height > 0) {
-                glyphs_flush_func flush_func;
-                void *temp_arg;
-
-                if (need_free_mask) {
-                    if (pmask_buffer->count)
-                        flush_func =
-                            (glyphs_flush_func) glamor_glyphs_flush_mask;
-                    else
-                        flush_func = NULL;
-                    temp_arg = pmask_arg;
-                }
-                else {
-                    /* If we are using global mask cache, then we need to
-                     * flush dst instead of mask. As some dst depends on the
-                     * previous mask result. Just flush mask can't get all previous's
-                     * overlapped glyphs.*/
-                    if (dst_buffer.count || mask_buffer.count)
-                        flush_func =
-                            (glyphs_flush_func) glamor_glyphs_flush_dst;
-                    else
-                        flush_func = NULL;
-                    temp_arg = &dst_arg;
-                }
-                glamor_buffer_glyph(glamor_priv, pmask_buffer,
-                                    mask_format->format,
-                                    glyph, NULL, x, y,
-                                    0, 0,
-                                    glyph->info.width, glyph->info.height,
-                                    glyphs_dst_mode,
-                                    flush_func, (void *) temp_arg);
-            }
-            x += glyph->info.xOff;
-            y += glyph->info.yOff;
-        }
-        list++;
-    }
-
-    x = extents.x1;
-    y = extents.y1;
-    if (need_free_mask) {
-        glamor_glyphs_flush_mask(pmask_arg);
-        CompositePicture(op,
-                         src,
-                         mask,
-                         dst,
-                         x_src + x - x_dst,
-                         y_src + y - y_dst, 0, 0, x, y, width, height);
-        FreePicture(mask, 0);
-        glamor_destroy_pixmap(mask_pixmap);
-    }
-    else {
-        struct glamor_glyph priv;
-        glyphs_flush_func flush_func;
-        BoxPtr rects;
-        int nrect;
-
-        priv.cache = cache;
-        priv.x = mce->x;
-        priv.y = mce->y;
-        priv.cached = TRUE;
-        rects = REGION_RECTS(dst->pCompositeClip);
-        nrect = REGION_NUM_RECTS(dst->pCompositeClip);
-
-        pmask_arg->used_bitmap |= ((1 << mce->width) - 1) << mce->idx;
-        dst_arg.op = op;
-        dst_arg.src = src;
-        dst_arg.dst = dst;
-        dst_arg.buffer = &dst_buffer;
-        dst_arg.x_src = x_src;
-        dst_arg.y_src = y_src;
-        dst_arg.x_dst = x_dst;
-        dst_arg.y_dst = y_dst;
-
-        if (dst_buffer.source == NULL) {
-            dst_buffer.source = cache->picture;
-        }
-        else if (dst_buffer.source != cache->picture) {
-            glamor_glyphs_flush_dst(&dst_arg);
-            dst_buffer.source = cache->picture;
-        }
-
-        x += dst->pDrawable->x;
-        y += dst->pDrawable->y;
-
-        if (dst_buffer.count || mask_buffer.count)
-            flush_func = (glyphs_flush_func) glamor_glyphs_flush_dst;
-        else
-            flush_func = NULL;
-
-        glamor_buffer_glyph_clip(glamor_priv,
-                                 rects, nrect,
-                                 mask_format->format,
-                                 NULL, &priv,
-                                 x, y,
-                                 0, 0,
-                                 width, height,
-                                 GLYPHS_DST_MODE_MASK_TO_DST,
-                                 flush_func, (void *) &dst_arg);
-    }
-}
-
-static void
-glamor_glyphs_to_dst(CARD8 op,
-                     PicturePtr src,
-                     PicturePtr dst,
-                     INT16 x_src,
-                     INT16 y_src,
-                     int nlist, GlyphListPtr list, GlyphPtr *glyphs)
-{
-    ScreenPtr screen = dst->pDrawable->pScreen;
-    int x = 0, y = 0;
-    int x_dst = list->xOff, y_dst = list->yOff;
-    int n;
-    GlyphPtr glyph;
-    BoxPtr rects;
-    int nrect;
-    glamor_screen_private *glamor_priv;
-
-    rects = REGION_RECTS(dst->pCompositeClip);
-    nrect = REGION_NUM_RECTS(dst->pCompositeClip);
-
-    glamor_priv = glamor_get_screen_private(screen);
-
-    dst_arg.op = op;
-    dst_arg.src = src;
-    dst_arg.dst = dst;
-    dst_arg.buffer = &dst_buffer;
-    dst_arg.x_src = x_src;
-    dst_arg.y_src = y_src;
-    dst_arg.x_dst = x_dst;
-    dst_arg.y_dst = y_dst;
-
-    x = dst->pDrawable->x;
-    y = dst->pDrawable->y;
-
-    while (nlist--) {
-        x += list->xOff;
-        y += list->yOff;
-        n = list->len;
-        dst_glyphs_cnt += n;
-        while (n--) {
-            glyph = *glyphs++;
-
-            if (glyph->info.width > 0 && glyph->info.height > 0) {
-                glyphs_flush_func flush_func;
-
-                if (dst_buffer.count || mask_buffer.count)
-                    flush_func = (glyphs_flush_func) glamor_glyphs_flush_dst;
-                else
-                    flush_func = NULL;
-                glamor_buffer_glyph_clip(glamor_priv,
-                                         rects, nrect,
-                                         (GlyphPicture(glyph)[screen->myNum])->
-                                         format, glyph, NULL, x, y,
-                                         glyph->info.x, glyph->info.y,
-                                         glyph->info.width, glyph->info.height,
-                                         GLYPHS_DST_MODE_TO_DST, flush_func,
-                                         (void *) &dst_arg);
-            }
-
-            x += glyph->info.xOff;
-            y += glyph->info.yOff;
-        }
-        list++;
-    }
-}
-
-#define MAX_FIXED_SIZE
-static void
-glamor_glyphs_reset_buffer(glamor_glyph_buffer_t *buffer)
-{
-    buffer->count = 0;
-    buffer->source = NULL;
-}
-
-static Bool
-_glamor_glyphs(CARD8 op,
-               PicturePtr src,
-               PicturePtr dst,
-               PictFormatPtr mask_format,
-               INT16 x_src,
-               INT16 y_src, int nlist, GlyphListPtr list,
-               GlyphPtr *glyphs, Bool fallback)
-{
-    PictFormatShort format;
-    int fixed_size, fixed_cnt = 0;
-    struct glamor_glyph_list *fixed_list = NULL;
-    Bool need_free_list = FALSE;
-
-#ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
-    Bool check_fake_overlap = TRUE;
-
-    if (!(op == PictOpOver || op == PictOpAdd || op == PictOpXor)) {
-        /* C = (0,0,0,0) D = glyphs , SRC = A, DEST = B (faked overlapped glyphs, overlapped with (0,0,0,0)).
-         * For those op, (A IN (C ADD D)) OP B !=  (A IN D) OP ((A IN C) OP B)
-         *              or (A IN (D ADD C)) OP B != (A IN C) OP ((A IN D) OP B)
-         * We need to split the faked regions to three or two, and composite the disoverlapped small
-         * boxes one by one. For other Ops, it's safe to composite the whole box.  */
-        check_fake_overlap = FALSE;
-    }
-#else
-    Bool check_fake_overlap = FALSE;
-#endif
-    if (mask_format)
-        format = mask_format->depth << 24 | mask_format->format;
-    else
-        format = 0;
-
-    fixed_size = 32;
-    glamor_glyphs_reset_buffer(&dst_buffer);
-
-    if (!mask_format || (((nlist == 1 && list->len == 1) || op == PictOpAdd)
-                         && (dst->format ==
-                             ((mask_format->depth << 24) | mask_format->
-                              format)))) {
-        glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist, list, glyphs);
-        goto last_flush;
-    }
-
-    glamor_glyphs_reset_buffer(&mask_buffer);
-
-    /* We have mask_format. Need to check the real overlap or not. */
-    format = mask_format->depth << 24 | mask_format->format;
-
-    fixed_list = calloc(fixed_size, sizeof(*fixed_list));
-    if (_X_UNLIKELY(fixed_list == NULL))
-        fixed_size = 0;
-    fixed_cnt = glamor_glyphs_intersect(nlist, list, glyphs,
-                                        format, dst->pDrawable->pScreen,
-                                        check_fake_overlap,
-                                        fixed_list, fixed_size);
-    if (fixed_cnt == 0)
-        mask_format = NULL;
-    need_free_list = TRUE;
-
-    if (fixed_cnt <= 0) {
-        if (mask_format == NULL) {
-            glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
-                                 list, glyphs);
-            goto last_flush;
-        }
-        else {
-            glamor_glyphs_via_mask(op, src, dst, mask_format,
-                                   x_src, y_src, nlist, list, glyphs, FALSE);
-            goto free_fixed_list;
-        }
-    }
-    else {
-
-        /* We have splitted the original list to serval list, some are overlapped
-         * and some are non-overlapped. For the non-overlapped, we render it to
-         * dst directly. For the overlapped, we render it to mask picture firstly,
-         * then render the mask to dst. If we can use mask cache which is in the
-         * glyphs cache's last row, we can accumulate the rendering of mask to dst
-         * with the other dst_buffer's rendering operations thus can reduce the call
-         * of glDrawElements.
-         *
-         * */
-        struct glamor_glyph_list *saved_list;
-
-        saved_list = fixed_list;
-        mask_arg.used_bitmap = 0;
-        while (fixed_cnt--) {
-            if (fixed_list->type == NON_INTERSECTED) {
-                glamor_glyphs_to_dst(op, src, dst,
-                                     x_src, y_src,
-                                     fixed_list->nlist,
-                                     fixed_list->list, fixed_list->glyphs);
-            }
-            else
-                glamor_glyphs_via_mask(op, src, dst,
-                                       mask_format, x_src, y_src,
-                                       fixed_list->nlist,
-                                       fixed_list->list,
-                                       fixed_list->glyphs, TRUE);
-
-            free(fixed_list->list);
-            fixed_list++;
-        }
-        free(saved_list);
-        need_free_list = FALSE;
-    }
-
- last_flush:
-    if (dst_buffer.count || mask_buffer.count)
-        glamor_glyphs_flush_dst(&dst_arg);
- free_fixed_list:
-    if (need_free_list) {
-        assert(fixed_cnt <= 0);
-        free(fixed_list);
-    }
-    return TRUE;
-}
-
-void
-glamor_glyphs(CARD8 op,
-              PicturePtr src,
-              PicturePtr dst,
-              PictFormatPtr mask_format,
-              INT16 x_src,
-              INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr *glyphs)
-{
-    _glamor_glyphs(op, src, dst, mask_format, x_src,
-                   y_src, nlist, list, glyphs, TRUE);
-}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index e586fcc..480d13b 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -154,41 +154,8 @@ enum glamor_gl_flavor {
     GLAMOR_GL_ES2               // OPENGL ES2.0 API
 };
 
-#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
-
 #define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024)
 
-typedef struct {
-    PicturePtr picture;         /* Where the glyphs of the cache are stored */
-    GlyphPtr *glyphs;
-    uint16_t count;
-    uint16_t evict;
-} glamor_glyph_cache_t;
-
-#define CACHE_PICTURE_SIZE 1024
-#define GLYPH_MIN_SIZE 8
-#define GLYPH_MAX_SIZE	64
-#define GLYPH_CACHE_SIZE ((CACHE_PICTURE_SIZE) * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE))
-
-#define MASK_CACHE_MAX_SIZE 32
-#define MASK_CACHE_WIDTH (CACHE_PICTURE_SIZE / MASK_CACHE_MAX_SIZE)
-#define MASK_CACHE_MASK ((1LL << (MASK_CACHE_WIDTH)) - 1)
-
-struct glamor_glyph_mask_cache_entry {
-    int idx;
-    int width;
-    int height;
-    int x;
-    int y;
-};
-
-typedef struct {
-    PixmapPtr pixmap;
-    struct glamor_glyph_mask_cache_entry mcache[MASK_CACHE_WIDTH];
-    unsigned int free_bitmap;
-    unsigned int cleared_bitmap;
-} glamor_glyph_mask_cache_t;
-
 struct glamor_saved_procs {
     CloseScreenProcPtr close_screen;
     CreateScreenResourcesProcPtr create_screen_resources;
@@ -208,7 +175,6 @@ struct glamor_saved_procs {
     AddTrapsProcPtr addtraps;
     CreatePictureProcPtr create_picture;
     DestroyPictureProcPtr destroy_picture;
-    UnrealizeGlyphProcPtr unrealize_glyph;
     SetWindowPixmapProcPtr set_window_pixmap;
 #if XSYNC
     SyncScreenFuncsRec sync_screen_funcs;
@@ -274,6 +240,14 @@ typedef struct glamor_screen_private {
     glamor_program_fill on_off_dash_line_progs;
     glamor_program      double_dash_line_prog;
 
+    /* glamor composite_glyphs shaders */
+    glamor_program_render       glyphs_program;
+    struct glamor_glyph_atlas   *glyph_atlas_a;
+    struct glamor_glyph_atlas   *glyph_atlas_argb;
+    int                         glyph_atlas_dim;
+    int                         glyph_max_dim;
+    char                        *glyph_defines;
+
     /* vertext/elment_index buffer object for render */
     GLuint vbo, ebo;
     /** Next offset within the VBO that glamor_get_vbo_space() will use. */
@@ -292,9 +266,6 @@ typedef struct glamor_screen_private {
     glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
         [SHADER_MASK_COUNT]
         [SHADER_IN_COUNT];
-    glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
-    glamor_glyph_mask_cache_t *mask_cache[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
-    Bool glyph_caches_realized;
 
     /* shaders to restore a texture to another texture. */
     GLint finish_access_prog[2];
@@ -707,17 +678,6 @@ RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
 void
 glamor_track_stipple(GCPtr gc);
 
-/* glamor_glyphs.c */
-Bool glamor_realize_glyph_caches(ScreenPtr screen);
-void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
-void glamor_glyphs_fini(ScreenPtr screen);
-void glamor_glyphs(CARD8 op,
-                   PicturePtr pSrc,
-                   PicturePtr pDst,
-                   PictFormatPtr maskFormat,
-                   INT16 xSrc,
-                   INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs);
-
 /* glamor_render.c */
 Bool glamor_composite_clipped_region(CARD8 op,
                                      PicturePtr source,
@@ -744,10 +704,6 @@ void glamor_composite(CARD8 op,
 
 void glamor_init_composite_shaders(ScreenPtr screen);
 void glamor_fini_composite_shaders(ScreenPtr screen);
-void glamor_composite_glyph_rects(CARD8 op,
-                                  PicturePtr src, PicturePtr mask,
-                                  PicturePtr dst, int nrect,
-                                  glamor_composite_rect_t *rects);
 void glamor_composite_rects(CARD8 op,
                             PicturePtr pDst,
                             xRenderColor *color, int nRect, xRectangle *rects);
@@ -994,6 +950,22 @@ void glamor_composite_rectangles(CARD8 op,
                                  xRenderColor *color,
                                  int num_rects, xRectangle *rects);
 
+/* glamor_composite_glyphs.c */
+Bool
+glamor_composite_glyphs_init(ScreenPtr pScreen);
+
+void
+glamor_composite_glyphs_fini(ScreenPtr pScreen);
+
+void
+glamor_composite_glyphs(CARD8 op,
+                        PicturePtr src,
+                        PicturePtr dst,
+                        PictFormatPtr mask_format,
+                        INT16 x_src,
+                        INT16 y_src, int nlist,
+                        GlyphListPtr list, GlyphPtr *glyphs);
+
 /* glamor_sync.c */
 Bool
 glamor_sync_init(ScreenPtr screen);
@@ -1077,8 +1049,6 @@ void glamor_xv_render(glamor_port_private *port_priv);
 #if 0
 #define MAX_FBO_SIZE 32         /* For test purpose only. */
 #endif
-//#define GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
-#define GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
 
 #include "glamor_font.h"
 
diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index d091287..1dc5f19 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -139,6 +139,10 @@ static glamor_location_var location_vars[] = {
         .vs_vars = "uniform float dash_length;\n",
         .fs_vars = "uniform sampler2D dash;\n",
     },
+    {
+        .location = glamor_program_location_atlas,
+        .fs_vars = "uniform sampler2D atlas;\n",
+    },
 };
 
 #define NUM_LOCATION_VARS       (sizeof location_vars / sizeof location_vars[0])
@@ -355,6 +359,7 @@ glamor_build_program(ScreenPtr          screen,
     prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul");
     prog->dash_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash");
     prog->dash_length_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash_length");
+    prog->atlas_uniform = glamor_get_uniform(prog, glamor_program_location_atlas, "atlas");
 
     free(version_string);
     free(fs_vars);
diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h
index ad1e9fd..9e561cd 100644
--- a/glamor/glamor_program.h
+++ b/glamor/glamor_program.h
@@ -81,6 +81,7 @@ struct _glamor_program {
     GLint                       bitmul_uniform;
     GLint                       dash_uniform;
     GLint                       dash_length_uniform;
+    GLint                       atlas_uniform;
     glamor_program_location     locations;
     glamor_program_flag         flags;
     glamor_use                  prim_use;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 27c09fd..efca367 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1701,139 +1701,3 @@ glamor_composite(CARD8 op,
     glamor_finish_access_picture(source);
     glamor_finish_access_picture(dest);
 }
-
-static void
-glamor_get_src_rect_extent(int nrect,
-                           glamor_composite_rect_t *rects, BoxPtr extent)
-{
-    extent->x1 = MAXSHORT;
-    extent->y1 = MAXSHORT;
-    extent->x2 = MINSHORT;
-    extent->y2 = MINSHORT;
-
-    while (nrect--) {
-        if (extent->x1 > rects->x_src)
-            extent->x1 = rects->x_src;
-        if (extent->y1 > rects->y_src)
-            extent->y1 = rects->y_src;
-        if (extent->x2 < rects->x_src + rects->width)
-            extent->x2 = rects->x_src + rects->width;
-        if (extent->y2 < rects->y_src + rects->height)
-            extent->y2 = rects->y_src + rects->height;
-        rects++;
-    }
-}
-
-static void
-glamor_composite_src_rect_translate(int nrect,
-                                    glamor_composite_rect_t *rects,
-                                    int x, int y)
-{
-    while (nrect--) {
-        rects->x_src += x;
-        rects->y_src += y;
-        rects++;
-    }
-}
-
-void
-glamor_composite_glyph_rects(CARD8 op,
-                             PicturePtr src, PicturePtr mask, PicturePtr dst,
-                             int nrect, glamor_composite_rect_t *rects)
-{
-    int n;
-    PicturePtr temp_src = NULL;
-    glamor_composite_rect_t *r;
-
-    ValidatePicture(src);
-    ValidatePicture(dst);
-    if (!(glamor_is_large_picture(src)
-          || (mask && glamor_is_large_picture(mask))
-          || glamor_is_large_picture(dst))) {
-        PixmapPtr src_pixmap = NULL;
-        PixmapPtr mask_pixmap = NULL;
-        PixmapPtr dst_pixmap = NULL;
-        PixmapPtr temp_src_pixmap = NULL;
-        glamor_pixmap_private *src_pixmap_priv = NULL;
-        glamor_pixmap_private *mask_pixmap_priv = NULL;
-        glamor_pixmap_private *dst_pixmap_priv;
-        glamor_pixmap_private *temp_src_priv = NULL;
-        BoxRec src_extent;
-
-        dst_pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
-        dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
-
-        if (mask && mask->pDrawable) {
-            mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
-            mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-        }
-        if (src->pDrawable) {
-            src_pixmap = glamor_get_drawable_pixmap(src->pDrawable);
-            src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-        }
-
-        if (!src->pDrawable
-            && (src->pSourcePict->type != SourcePictTypeSolidFill)) {
-            glamor_get_src_rect_extent(nrect, rects, &src_extent);
-            temp_src = glamor_convert_gradient_picture(dst->pDrawable->pScreen,
-                                                       src,
-                                                       src_extent.x1,
-                                                       src_extent.y1,
-                                                       src_extent.x2 -
-                                                       src_extent.x1,
-                                                       src_extent.y2 -
-                                                       src_extent.y1);
-            if (!temp_src)
-                goto fallback;
-
-            temp_src_pixmap = (PixmapPtr) (temp_src->pDrawable);
-            temp_src_priv = glamor_get_pixmap_private(temp_src_pixmap);
-            glamor_composite_src_rect_translate(nrect, rects,
-                                                -src_extent.x1, -src_extent.y1);
-        }
-        else {
-            temp_src = src;
-            temp_src_pixmap = src_pixmap;
-            temp_src_priv = src_pixmap_priv;
-        }
-
-        if (mask && mask->componentAlpha) {
-            if (op == PictOpOver) {
-                if (glamor_composite_with_shader(PictOpOutReverse,
-                                                 temp_src, mask, dst,
-                                                 temp_src_pixmap, mask_pixmap, dst_pixmap,
-                                                 temp_src_priv,
-                                                 mask_pixmap_priv,
-                                                 dst_pixmap_priv, nrect, rects,
-                                                 TRUE))
-                    goto done;
-            }
-        }
-        else {
-            if (glamor_composite_with_shader
-                (op, temp_src, mask, dst,
-                 temp_src_pixmap, mask_pixmap, dst_pixmap,
-                 temp_src_priv, mask_pixmap_priv,
-                 dst_pixmap_priv, nrect, rects, FALSE))
-                goto done;
-        }
-    }
- fallback:
-    n = nrect;
-    r = rects;
-
-    while (n--) {
-        CompositePicture(op,
-                         temp_src ? temp_src : src,
-                         mask,
-                         dst,
-                         r->x_src, r->y_src,
-                         r->x_mask, r->y_mask,
-                         r->x_dst, r->y_dst, r->width, r->height);
-        r++;
-    }
-
- done:
-    if (temp_src && temp_src != src)
-        FreePicture(temp_src, 0);
-}
commit 1b745e0c1ff45e014aa21c3d8edf93227bec99bf
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 13 11:40:06 2014 -0700

    glamor: Adapt glamor_program API  to handle render acceleration
    
    This extends the existing API to support options needed for render
    accleration, including an additional fragment, 'combine', (which
    provides a place to perform the source IN mask operation before the
    final OP dest state) and an additional 'defines' parameter which
    provides a way to add target-dependent values without using a uniform.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index 921e80e..028acf2 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -53,7 +53,7 @@ static const glamor_facet glamor_facet_copyarea = {
     .vs_exec = (GLAMOR_POS(gl_Position, primitive.xy)
                 "       fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"),
     .fs_exec = "       gl_FragColor = texture2D(sampler, fill_pos);\n",
-    .locations = glamor_program_location_fill,
+    .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos,
     .use = use_copyarea,
 };
 
@@ -140,7 +140,7 @@ static const glamor_facet glamor_facet_copyplane = {
                 "               gl_FragColor = fg;\n"
                 "       else\n"
                 "               gl_FragColor = bg;\n"),
-    .locations = glamor_program_location_fill|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane,
+    .locations = glamor_program_location_fillsamp|glamor_program_location_fillpos|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane,
     .use = use_copyplane,
 };
 
@@ -338,7 +338,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
 
     if (!prog->prog) {
         if (!glamor_build_program(screen, prog,
-                                  copy_facet, NULL))
+                                  copy_facet, NULL, NULL, NULL))
             goto bail_ctx;
     }
 
diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c
index 4281ff0..101228e 100644
--- a/glamor/glamor_dash.c
+++ b/glamor/glamor_dash.c
@@ -170,7 +170,7 @@ glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
         if (!prog->prog) {
             if (!glamor_build_program(screen, prog,
                                       &glamor_facet_double_dash_lines,
-                                      NULL))
+                                      NULL, NULL, NULL))
                 goto bail;
         }
 
diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c
index df7e5a2..3ba4a69 100644
--- a/glamor/glamor_points.c
+++ b/glamor/glamor_points.c
@@ -60,7 +60,8 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
     if (!prog->prog) {
         if (!glamor_build_program(screen, prog,
                                   &glamor_facet_point,
-                                  &glamor_fill_solid))
+                                  &glamor_fill_solid,
+                                  NULL, NULL))
             goto bail;
     }
 
diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index 8aab53f..d091287 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -47,7 +47,7 @@ static const glamor_facet glamor_fill_tile = {
     .name = "tile",
     .vs_exec =  "       fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
     .fs_exec =  "       gl_FragColor = texture2D(sampler, fill_pos);\n",
-    .locations = glamor_program_location_fill,
+    .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos,
     .use = use_tile,
 };
 
@@ -66,7 +66,7 @@ static const glamor_facet glamor_fill_stipple = {
                 "       if (a == 0.0)\n"
                 "               discard;\n"
                 "       gl_FragColor = fg;\n"),
-    .locations = glamor_program_location_fg | glamor_program_location_fill,
+    .locations = glamor_program_location_fg | glamor_program_location_fillsamp | glamor_program_location_fillpos,
     .use = use_stipple,
 };
 
@@ -87,7 +87,7 @@ static const glamor_facet glamor_fill_opaque_stipple = {
                 "               gl_FragColor = bg;\n"
                 "       else\n"
                 "               gl_FragColor = fg;\n"),
-    .locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fill,
+    .locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fillsamp | glamor_program_location_fillpos,
     .use = use_opaque_stipple
 };
 
@@ -114,12 +114,15 @@ static glamor_location_var location_vars[] = {
         .fs_vars = "uniform vec4 bg;\n"
     },
     {
-        .location = glamor_program_location_fill,
+        .location = glamor_program_location_fillsamp,
+        .fs_vars = "uniform sampler2D sampler;\n"
+    },
+    {
+        .location = glamor_program_location_fillpos,
         .vs_vars = ("uniform vec2 fill_offset;\n"
                     "uniform vec2 fill_size_inv;\n"
                     "varying vec2 fill_pos;\n"),
-        .fs_vars = ("uniform sampler2D sampler;\n"
-                    "uniform vec2 fill_size_inv;\n"
+        .fs_vars = ("uniform vec2 fill_size_inv;\n"
                     "varying vec2 fill_pos;\n")
     },
     {
@@ -183,6 +186,7 @@ fs_location_vars(glamor_program_location locations)
 
 static const char vs_template[] =
     "%s"                                /* version */
+    "%s"                                /* defines */
     "%s"                                /* prim vs_vars */
     "%s"                                /* fill vs_vars */
     "%s"                                /* location vs_vars */
@@ -195,12 +199,14 @@ static const char vs_template[] =
 static const char fs_template[] =
     "%s"                                /* version */
     GLAMOR_DEFAULT_PRECISION
+    "%s"                                /* defines */
     "%s"                                /* prim fs_vars */
     "%s"                                /* fill fs_vars */
     "%s"                                /* location fs_vars */
     "void main() {\n"
     "%s"                                /* prim fs_exec */
     "%s"                                /* fill fs_exec */
+    "%s"                                /* combine */
     "}\n";
 
 static const char *
@@ -236,7 +242,9 @@ Bool
 glamor_build_program(ScreenPtr          screen,
                      glamor_program     *prog,
                      const glamor_facet *prim,
-                     const glamor_facet *fill)
+                     const glamor_facet *fill,
+                     const char         *combine,
+                     const char         *defines)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
@@ -282,6 +290,7 @@ glamor_build_program(ScreenPtr          screen,
     if (asprintf(&vs_prog_string,
                  vs_template,
                  str(version_string),
+                 str(defines),
                  str(prim->vs_vars),
                  str(fill->vs_vars),
                  vs_vars,
@@ -292,26 +301,30 @@ glamor_build_program(ScreenPtr          screen,
     if (asprintf(&fs_prog_string,
                  fs_template,
                  str(version_string),
+                 str(defines),
                  str(prim->fs_vars),
                  str(fill->fs_vars),
                  fs_vars,
                  str(prim->fs_exec),
-                 str(fill->fs_exec)) < 0)
+                 str(fill->fs_exec),
+                 str(combine)) < 0)
         fs_prog_string = NULL;
 
     if (!vs_prog_string || !fs_prog_string)
         goto fail;
 
+    prog->prog = glCreateProgram();
 #if DBG
-    ErrorF("\nPrograms for %s %s\nVertex shader:\n\n%s\n\nFragment Shader:\n\n%s",
-           prim->name, fill->name, vs_prog_string, fs_prog_string);
+    ErrorF("\n\tProgram %d for %s %s\n\tVertex shader:\n\n\t================\n%s\n\n\tFragment Shader:\n\n%s\t================\n",
+           prog->prog, prim->name, fill->name, vs_prog_string, fs_prog_string);
 #endif
 
-    prog->prog = glCreateProgram();
     prog->flags = flags;
     prog->locations = locations;
     prog->prim_use = prim->use;
+    prog->prim_use_render = prim->use_render;
     prog->fill_use = fill->use;
+    prog->fill_use_render = fill->use_render;
 
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_prog_string);
     fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_prog_string);
@@ -335,8 +348,8 @@ glamor_build_program(ScreenPtr          screen,
     prog->matrix_uniform = glamor_get_uniform(prog, glamor_program_location_none, "v_matrix");
     prog->fg_uniform = glamor_get_uniform(prog, glamor_program_location_fg, "fg");
     prog->bg_uniform = glamor_get_uniform(prog, glamor_program_location_bg, "bg");
-    prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_offset");
-    prog->fill_size_inv_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size_inv");
+    prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fillpos, "fill_offset");
+    prog->fill_size_inv_uniform = glamor_get_uniform(prog, glamor_program_location_fillpos, "fill_size_inv");
     prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font");
     prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane");
     prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul");
@@ -396,7 +409,7 @@ glamor_use_program_fill(PixmapPtr               pixmap,
         if (!fill)
             return NULL;
 
-        if (!glamor_build_program(screen, prog, prim, fill))
+        if (!glamor_build_program(screen, prog, prim, fill, NULL, NULL))
             return NULL;
     }
 
@@ -405,3 +418,238 @@ glamor_use_program_fill(PixmapPtr               pixmap,
 
     return prog;
 }
+
+static struct blendinfo composite_op_info[] = {
+    [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO},
+    [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO},
+    [PictOpDst] = {0, 0, GL_ZERO, GL_ONE},
+    [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE},
+    [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO},
+    [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA},
+    [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
+    [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA},
+    [PictOpXor] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpAdd] = {0, 0, GL_ONE, GL_ONE},
+};
+
+static void
+glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst)
+{
+    GLenum src_blend, dst_blend;
+    struct blendinfo *op_info;
+
+    switch (alpha) {
+    case glamor_program_alpha_ca_first:
+        op = PictOpOutReverse;
+        break;
+    case glamor_program_alpha_ca_second:
+        op = PictOpAdd;
+        break;
+    default:
+        break;
+    }
+
+    if (op == PictOpSrc)
+        return;
+
+    op_info = &composite_op_info[op];
+
+    src_blend = op_info->source_blend;
+    dst_blend = op_info->dest_blend;
+
+    /* If there's no dst alpha channel, adjust the blend op so that we'll treat
+     * it as always 1.
+     */
+    if (PICT_FORMAT_A(dst->format) == 0 && op_info->dest_alpha) {
+        if (src_blend == GL_DST_ALPHA)
+            src_blend = GL_ONE;
+        else if (src_blend == GL_ONE_MINUS_DST_ALPHA)
+            src_blend = GL_ZERO;
+    }
+
+    /* Set up the source alpha value for blending in component alpha mode. */
+    if (alpha != glamor_program_alpha_normal && op_info->source_alpha) {
+        if (dst_blend == GL_SRC_ALPHA)
+            dst_blend = GL_SRC_COLOR;
+        else if (dst_blend == GL_ONE_MINUS_SRC_ALPHA)
+            dst_blend = GL_ONE_MINUS_SRC_COLOR;
+    }
+
+    glEnable(GL_BLEND);
+    glBlendFunc(src_blend, dst_blend);
+}
+
+static Bool
+use_source_solid(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog)
+{
+
+    glamor_set_blend(op, prog->alpha, dst);
+
+    glamor_set_color(glamor_get_drawable_pixmap(dst->pDrawable),
+                     src->pSourcePict->solidFill.color,
+                     prog->fg_uniform);
+    return TRUE;
+}
+
+const glamor_facet glamor_source_solid = {
+    .name = "render_solid",
+    .fs_exec = "       vec4 source = fg;\n",
+    .locations = glamor_program_location_fg,
+    .use_render = use_source_solid,
+};
+
+static Bool
+use_source_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog)
+{
+    glamor_set_blend(op, prog->alpha, dst);
+
+    return glamor_set_texture((PixmapPtr) src->pDrawable,
+                              0, 0,
+                              prog->fill_offset_uniform,
+                              prog->fill_size_inv_uniform);
+}
+
+const glamor_facet glamor_source_picture = {
+    .name = "render_picture",
+    .vs_exec =  "       fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
+    .fs_exec =  "       vec4 source = texture2D(sampler, fill_pos);\n",
+    .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos,
+    .use_render = use_source_picture,
+};
+
+static Bool
+use_source_1x1_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog)
+{
+    glamor_set_blend(op, prog->alpha, dst);
+
+    return glamor_set_texture_pixmap((PixmapPtr) src->pDrawable);
+}
+
+const glamor_facet glamor_source_1x1_picture = {
+    .name = "render_picture",
+    .fs_exec =  "       vec4 source = texture2D(sampler, vec2(0.5));\n",
+    .locations = glamor_program_location_fillsamp,
+    .use_render = use_source_1x1_picture,
+};
+
+const glamor_facet *glamor_facet_source[glamor_program_source_count] = {
+    [glamor_program_source_solid] = &glamor_source_solid,
+    [glamor_program_source_picture] = &glamor_source_picture,
+    [glamor_program_source_1x1_picture] = &glamor_source_1x1_picture,
+};
+
+static const char *glamor_combine[] = {
+    [glamor_program_alpha_normal]    = "       gl_FragColor = source * mask.a;\n",
+    [glamor_program_alpha_ca_first]  = "       gl_FragColor = source.a * mask;\n",
+    [glamor_program_alpha_ca_second] = "       gl_FragColor = source * mask;\n"
+};
+
+static Bool
+glamor_setup_one_program_render(ScreenPtr               screen,
+                                glamor_program          *prog,
+                                glamor_program_source   source_type,
+                                glamor_program_alpha    alpha,
+                                const glamor_facet      *prim,
+                                const char              *defines)
+{
+    if (prog->failed)
+        return FALSE;
+
+    if (!prog->prog) {
+        const glamor_facet      *fill = glamor_facet_source[source_type];
+
+        if (!fill)
+            return FALSE;
+
+        if (!glamor_build_program(screen, prog, prim, fill, glamor_combine[alpha], defines))
+            return FALSE;
+        prog->alpha = alpha;
+    }
+
+    return TRUE;
+}
+
+glamor_program *
+glamor_setup_program_render(CARD8                 op,
+                            PicturePtr            src,
+                            PicturePtr            mask,
+                            PicturePtr            dst,
+                            glamor_program_render *program_render,
+                            const glamor_facet    *prim,
+                            const char            *defines)
+{
+    ScreenPtr                   screen = dst->pDrawable->pScreen;
+    glamor_program_alpha        alpha;
+    glamor_program_source       source_type;
+    glamor_program              *prog;
+
+    if (op > ARRAY_SIZE(composite_op_info))
+        return NULL;
+
+    if (glamor_is_component_alpha(mask)) {
+        /* This only works for PictOpOver */
+        if (op != PictOpOver)
+            return NULL;
+        alpha = glamor_program_alpha_ca_first;
+    } else
+        alpha = glamor_program_alpha_normal;
+
+    if (src->pDrawable) {
+
+        /* Can't do transforms, alphamaps or sourcing from non-pixmaps yet */
+        if (src->transform || src->alphaMap || src->pDrawable->type != DRAWABLE_PIXMAP)
+            return NULL;
+
+        if (src->pDrawable->width == 1 && src->pDrawable->height == 1 && src->repeat)
+            source_type = glamor_program_source_1x1_picture;
+        else
+            source_type = glamor_program_source_picture;
+    } else {
+        SourcePictPtr   sp = src->pSourcePict;
+        if (!sp)
+            return NULL;
+        switch (sp->type) {
+        case SourcePictTypeSolidFill:
+            source_type = glamor_program_source_solid;
+            break;
+        default:
+            return NULL;
+        }
+    }
+
+    prog = &program_render->progs[source_type][alpha];
+    if (!glamor_setup_one_program_render(screen, prog, source_type, alpha, prim, defines))
+        return NULL;
+
+    if (alpha == glamor_program_alpha_ca_first) {
+
+	  /* Make sure we can also build the second program before
+	   * deciding to use this path.
+	   */
+	  if (!glamor_setup_one_program_render(screen,
+					       &program_render->progs[source_type][glamor_program_alpha_ca_second],
+					       source_type, glamor_program_alpha_ca_second, prim,
+					       defines))
+	      return NULL;
+    }
+    return prog;
+}
+
+Bool
+glamor_use_program_render(glamor_program        *prog,
+                          CARD8                 op,
+                          PicturePtr            src,
+                          PicturePtr            dst)
+{
+    glUseProgram(prog->prog);
+
+    if (prog->prim_use_render && !prog->prim_use_render(op, src, dst, prog))
+        return FALSE;
+
+    if (prog->fill_use_render && !prog->fill_use_render(op, src, dst, prog))
+        return FALSE;
+    return TRUE;
+}
diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h
index fa3877c..ad1e9fd 100644
--- a/glamor/glamor_program.h
+++ b/glamor/glamor_program.h
@@ -27,23 +27,36 @@ typedef enum {
     glamor_program_location_none = 0,
     glamor_program_location_fg = 1,
     glamor_program_location_bg = 2,
-    glamor_program_location_fill = 4,
-    glamor_program_location_font = 8,
-    glamor_program_location_bitplane = 16,
-    glamor_program_location_dash = 32,
+    glamor_program_location_fillsamp = 4,
+    glamor_program_location_fillpos = 8,
+    glamor_program_location_font = 16,
+    glamor_program_location_bitplane = 32,
+    glamor_program_location_dash = 64,
+    glamor_program_location_atlas = 128,
 } glamor_program_location;
 
 typedef enum {
     glamor_program_flag_none = 0,
 } glamor_program_flag;
 
+typedef enum {
+    glamor_program_alpha_normal,
+    glamor_program_alpha_ca_first,
+    glamor_program_alpha_ca_second,
+    glamor_program_alpha_count
+} glamor_program_alpha;
+
 typedef struct _glamor_program glamor_program;
 
 typedef Bool (*glamor_use) (PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg);
 
+typedef Bool (*glamor_use_render) (CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog);
+
 typedef struct {
     const char                          *name;
     const int                           version;
+    char                                *vs_defines;
+    char                                *fs_defines;
     const char                          *vs_vars;
     const char                          *vs_exec;
     const char                          *fs_vars;
@@ -52,6 +65,7 @@ typedef struct {
     const glamor_program_flag           flags;
     const char                          *source_name;
     glamor_use                          use;
+    glamor_use_render                   use_render;
 } glamor_facet;
 
 struct _glamor_program {
@@ -71,6 +85,9 @@ struct _glamor_program {
     glamor_program_flag         flags;
     glamor_use                  prim_use;
     glamor_use                  fill_use;
+    glamor_program_alpha        alpha;
+    glamor_use_render           prim_use_render;
+    glamor_use_render           fill_use_render;
 };
 
 typedef struct {
@@ -83,7 +100,9 @@ Bool
 glamor_build_program(ScreenPtr          screen,
                      glamor_program     *prog,
                      const glamor_facet *prim,
-                     const glamor_facet *fill);
+                     const glamor_facet *fill,
+                     const char         *combine,
+                     const char         *defines);
 
 Bool
 glamor_use_program(PixmapPtr            pixmap,
@@ -97,4 +116,37 @@ glamor_use_program_fill(PixmapPtr               pixmap,
                         glamor_program_fill     *program_fill,
                         const glamor_facet      *prim);
 
+typedef enum {
+    glamor_program_source_solid,
+    glamor_program_source_picture,
+    glamor_program_source_1x1_picture,
+    glamor_program_source_count,
+} glamor_program_source;
+
+typedef struct {
+    glamor_program      progs[glamor_program_source_count][glamor_program_alpha_count];
+} glamor_program_render;
+
+static inline Bool
+glamor_is_component_alpha(PicturePtr mask) {
+    if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format))
+        return TRUE;
+    return FALSE;
+}
+
+glamor_program *
+glamor_setup_program_render(CARD8                 op,
+                            PicturePtr            src,
+                            PicturePtr            mask,
+                            PicturePtr            dst,
+                            glamor_program_render *program_render,
+                            const glamor_facet    *prim,
+                            const char            *defines);
+
+Bool
+glamor_use_program_render(glamor_program        *prog,
+                          CARD8                 op,
+                          PicturePtr            src,
+                          PicturePtr            dst);
+
 #endif /* _GLAMOR_PROGRAM_H_ */
diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
index 8d8c970..81a22a5 100644
--- a/glamor/glamor_text.c
+++ b/glamor/glamor_text.c
@@ -417,7 +417,7 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
             fill_facet = &glamor_facet_image_fill;
         }
 
-        if (!glamor_build_program(screen, prog, prim_facet, fill_facet))
+        if (!glamor_build_program(screen, prog, prim_facet, fill_facet, NULL, NULL))
             goto bail;
     }
 
diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index e94bca8..f476a99 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -155,11 +155,7 @@ glamor_set_solid(PixmapPtr      pixmap,
 }
 
 Bool
-glamor_set_texture(PixmapPtr    texture,
-                   int          off_x,
-                   int          off_y,
-                   GLint        offset_uniform,
-                   GLint        size_inv_uniform)
+glamor_set_texture_pixmap(PixmapPtr texture)
 {
     glamor_pixmap_private *texture_priv;
 
@@ -174,6 +170,23 @@ glamor_set_texture(PixmapPtr    texture,
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, texture_priv->fbo->tex);
 
+    /* we're not setting the sampler uniform here as we always use
+     * GL_TEXTURE0, and the default value for uniforms is zero. So,
+     * save a bit of CPU time by taking advantage of that.
+     */
+    return TRUE;
+}
+
+Bool
+glamor_set_texture(PixmapPtr    texture,
+                   int          off_x,
+                   int          off_y,
+                   GLint        offset_uniform,
+                   GLint        size_inv_uniform)
+{
+    if (!glamor_set_texture_pixmap(texture))
+        return FALSE;
+
     glUniform2f(offset_uniform, off_x, off_y);
     glUniform2f(size_inv_uniform, 1.0f/texture->drawable.width, 1.0f/texture->drawable.height);
     return TRUE;
diff --git a/glamor/glamor_transform.h b/glamor/glamor_transform.h
index 1d8eed4..dca6a26 100644
--- a/glamor/glamor_transform.h
+++ b/glamor/glamor_transform.h
@@ -39,6 +39,9 @@ glamor_set_color(PixmapPtr      pixmap,
                  GLint          uniform);
 
 Bool
+glamor_set_texture_pixmap(PixmapPtr    texture);
+
+Bool
 glamor_set_texture(PixmapPtr    texture,
                    int          off_x,
                    int          off_y,
commit ff3195aadde95c8e89f77f389a7dfb418dd2426c
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 20 21:31:56 2014 -0700

    glamor: Compute GLSL version from GL_SHADING_LANGUAGE_VERSION (v3)
    
    Use code from Piglit project to compute GLSL version for either GL or
    GLES. The Piglit code was originally written by Chad Versace.
    
    v2: bail if the parse fails (requested by Eric Anholt)
    v3: Use version 1.20 for GLES until we fix our programs (Eric Anholt)
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 6f4f309..9d40e3c 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2008 Intel Corporation
+ * Copyright © 2008,2011 Intel Corporation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -23,7 +23,7 @@
  * Authors:
  *    Eric Anholt <eric at anholt.net>
  *    Zhigang Gong <zhigang.gong at linux.intel.com>
- *
+ *    Chad Versace <chad.versace at linux.intel.com>
  */
 
 /** @file glamor.c
@@ -336,7 +336,11 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 {
     glamor_screen_private *glamor_priv;
     int gl_version;
+    int glsl_major, glsl_minor;
     int max_viewport_size[2];
+    const char *shading_version_string;
+    int shading_version_offset;
+
     PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 
     if (flags & ~GLAMOR_VALID_FLAGS) {
@@ -380,14 +384,40 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
     gl_version = epoxy_gl_version();
 
-    /* Would be nice to have a cleaner test for GLSL 1.30 support,
-     * but for now this should suffice
-     */
-    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && gl_version >= 30)
-        glamor_priv->glsl_version = 130;
-    else
-        glamor_priv->glsl_version = 120;
+    shading_version_string = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
+
+    if (!shading_version_string) {
+        LogMessage(X_WARNING,
+                   "glamor%d: Failed to get GLSL version\n",
+                   screen->myNum);
+        goto fail;
+    }
 
+    shading_version_offset = 0;
+    if (strncmp("OpenGL ES GLSL ES ", shading_version_string, 18) == 0)
+        shading_version_offset = 18;
+
+    if (sscanf(shading_version_string + shading_version_offset,
+               "%i.%i",
+               &glsl_major,
+               &glsl_minor) != 2) {
+        LogMessage(X_WARNING,
+                   "glamor%d: Failed to parse GLSL version string %s\n",
+                   screen->myNum, shading_version_string);
+        goto fail;
+    }
+    glamor_priv->glsl_version = glsl_major * 100 + glsl_minor;
+
+    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+        /* Force us back to the base version of our programs on an ES
+         * context, anyway.  Basically glamor only uses desktop 1.20
+         * or 1.30 currently.  1.30's new features are also present in
+         * ES 3.0, but our glamor_program.c constructions use a lot of
+         * compatibility features (to reduce the diff between 1.20 and
+         * 1.30 programs).
+         */
+        glamor_priv->glsl_version = 120;
+    }
 
     /* We'd like to require GL_ARB_map_buffer_range or
      * GL_OES_map_buffer_range, since it offers more information to
commit dcb3d74ba8861e7b0a592e92b5b2247b84e843f3
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 13 12:35:40 2014 -0700

    glamor: Remove destination drawable argument from glamor_set_texture
    
    This argument wasn't used at all.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index 3036a06..e94bca8 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -155,8 +155,7 @@ glamor_set_solid(PixmapPtr      pixmap,
 }
 
 Bool
-glamor_set_texture(PixmapPtr    pixmap,
-                   PixmapPtr    texture,
+glamor_set_texture(PixmapPtr    texture,
                    int          off_x,
                    int          off_y,
                    GLint        offset_uniform,
@@ -192,8 +191,7 @@ glamor_set_tiled(PixmapPtr      pixmap,
     if (!glamor_set_planemask(gc->depth, gc->planemask))
         return FALSE;
 
-    return glamor_set_texture(pixmap,
-                              gc->tile.pixmap,
+    return glamor_set_texture(gc->tile.pixmap,
                               -gc->patOrg.x,
                               -gc->patOrg.y,
                               offset_uniform,
@@ -274,8 +272,7 @@ glamor_set_stippled(PixmapPtr      pixmap,
     if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
         return FALSE;
 
-    return glamor_set_texture(pixmap,
-                              stipple,
+    return glamor_set_texture(stipple,
                               -gc->patOrg.x,
                               -gc->patOrg.y,
                               offset_uniform,
diff --git a/glamor/glamor_transform.h b/glamor/glamor_transform.h
index 36b789a..1d8eed4 100644
--- a/glamor/glamor_transform.h
+++ b/glamor/glamor_transform.h
@@ -39,8 +39,7 @@ glamor_set_color(PixmapPtr      pixmap,
                  GLint          uniform);
 
 Bool
-glamor_set_texture(PixmapPtr    pixmap,
-                   PixmapPtr    texture,
+glamor_set_texture(PixmapPtr    texture,
                    int          off_x,
                    int          off_y,
                    GLint        offset_uniform,
commit 2bf34fe8d9b7628d164392c2d11ace78f7cf17b9
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 13 12:32:27 2014 -0700

    glamor: Pass depth to glamor_pm_is_solid and glamor_set_planemask
    
    Instead of passing the destination drawable, just pass the depth, as
    the underlying functions need only that to check whether the planemask
    is going to work.
    
    This API change will allow higher level functions to not need the
    destination pixmap.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index 75fe8a7..921e80e 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -212,7 +212,7 @@ glamor_copy_cpu_fbo(DrawablePtr src,
     if (gc && gc->alu != GXcopy)
         goto bail;
 
-    if (gc && !glamor_pm_is_solid(dst, gc->planemask))
+    if (gc && !glamor_pm_is_solid(gc->depth, gc->planemask))
         goto bail;
 
     glamor_make_current(glamor_priv);
@@ -262,7 +262,7 @@ glamor_copy_fbo_cpu(DrawablePtr src,
     if (gc && gc->alu != GXcopy)
         goto bail;
 
-    if (gc && !glamor_pm_is_solid(dst, gc->planemask))
+    if (gc && !glamor_pm_is_solid(gc->depth, gc->planemask))
         goto bail;
 
     glamor_make_current(glamor_priv);
@@ -319,7 +319,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
 
     glamor_make_current(glamor_priv);
 
-    if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask))
+    if (gc && !glamor_set_planemask(gc->depth, gc->planemask))
         goto bail_ctx;
 
     if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy))
@@ -419,7 +419,6 @@ glamor_copy_fbo_fbo_temp(DrawablePtr src,
 {
     ScreenPtr screen = dst->pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
     PixmapPtr tmp_pixmap;
     BoxRec bounds;
     int n;
@@ -434,7 +433,7 @@ glamor_copy_fbo_fbo_temp(DrawablePtr src,
      */
     glamor_make_current(glamor_priv);
 
-    if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask))
+    if (gc && !glamor_set_planemask(gc->depth, gc->planemask))
         goto bail_ctx;
 
     if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy))
diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c
index 5633da6..a272d5e 100644
--- a/glamor/glamor_image.c
+++ b/glamor/glamor_image.c
@@ -49,7 +49,7 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     if (gc->alu != GXcopy)
         goto bail;
 
-    if (!glamor_pm_is_solid(&pixmap->drawable, gc->planemask))
+    if (!glamor_pm_is_solid(gc->depth, gc->planemask))
         goto bail;
 
     if (format == XYPixmap && drawable->depth == 1 && leftPad == 0)
@@ -116,7 +116,7 @@ glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h,
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
         goto bail;
 
-    if (format != ZPixmap || !glamor_pm_is_solid(drawable, plane_mask))
+    if (format != ZPixmap || !glamor_pm_is_solid(drawable->depth, plane_mask))
         goto bail;
 
     glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 6235747..4e87371 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -109,9 +109,9 @@ glamor_set_destination_pixmap(PixmapPtr pixmap)
 }
 
 Bool
-glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
+glamor_set_planemask(int depth, unsigned long planemask)
 {
-    if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
+    if (glamor_pm_is_solid(depth, planemask)) {
         return GL_TRUE;
     }
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 4b9ba4d..e586fcc 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -638,10 +638,10 @@ glamor_get_gc_private(GCPtr gc)
  * pixel values for pDrawable.
  */
 static inline Bool
-glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask)
+glamor_pm_is_solid(int depth, unsigned long planemask)
 {
-    return (planemask & FbFullMask(drawable->depth)) ==
-        FbFullMask(drawable->depth);
+    return (planemask & FbFullMask(depth)) ==
+        FbFullMask(depth);
 }
 
 extern int glamor_debug_level;
@@ -701,7 +701,7 @@ glamor_pixmap_fbo *glamor_es2_pixmap_read_prepare(PixmapPtr source, int x,
                                                   int swap_rb);
 
 Bool glamor_set_alu(ScreenPtr screen, unsigned char alu);
-Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
+Bool glamor_set_planemask(int depth, unsigned long planemask);
 RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
 
 void
diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
index b358c60..58da3ed 100644
--- a/glamor/glamor_spans.c
+++ b/glamor/glamor_spans.c
@@ -279,7 +279,7 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
     if (gc->alu != GXcopy)
         goto bail;
 
-    if (!glamor_pm_is_solid(&pixmap->drawable, gc->planemask))
+    if (!glamor_pm_is_solid(gc->depth, gc->planemask))
         goto bail;
 
     glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
index c7c1ab7..8d8c970 100644
--- a/glamor/glamor_text.c
+++ b/glamor/glamor_text.c
@@ -431,7 +431,7 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
         /* Check planemask before drawing background to
          * bail early if it's not OK
          */
-        if (!glamor_set_planemask(pixmap, gc->planemask))
+        if (!glamor_set_planemask(gc->depth, gc->planemask))
             goto bail;
         for (c = 0; c < count; c++)
             if (charinfo[c])
diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index 6d29e9e..3036a06 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -129,7 +129,7 @@ glamor_set_solid(PixmapPtr      pixmap,
     CARD32      pixel;
     int         alu = use_alu ? gc->alu : GXcopy;
 
-    if (!glamor_set_planemask(pixmap, gc->planemask))
+    if (!glamor_set_planemask(gc->depth, gc->planemask))
         return FALSE;
 
     pixel = gc->fgPixel;
@@ -189,7 +189,7 @@ glamor_set_tiled(PixmapPtr      pixmap,
     if (!glamor_set_alu(pixmap->drawable.pScreen, gc->alu))
         return FALSE;
 
-    if (!glamor_set_planemask(pixmap, gc->planemask))
+    if (!glamor_set_planemask(gc->depth, gc->planemask))
         return FALSE;
 
     return glamor_set_texture(pixmap,
commit 910ddf85219f114744e8996a4ac044c4eafc62ac
Author: Egbert Eich <eich at freedesktop.org>
Date:   Tue May 12 09:52:48 2015 -0700

    Xephyr: Fix broken image when endianess of client machine and host-Xserver differ
    
    The image is created in the native byte order of the machine Xephyr is
    rendered on however drawn in the image byte order of the Xephyr server.
    Correct byte order in the xcb_image_t structure and convert to native
    before updating the window.
    If depths of Xephyr and host server differ this is already taken care of
    by the depth conversion routine.
    It is a terrible wase to always convert and transmit the entire image
    no matter of the size of the damaged area. One should probably use
    sub-images here. For now we leave this as an exercise.
    
    Signed-off-by: Egbert Eich <eich at freedesktop.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 7f6fdc4..dc265d5 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -866,6 +866,11 @@ hostx_screen_init(KdScreenInfo *screen,
                                                     ~0,
                                                     NULL);
 
+        /* Match server byte order so that the image can be converted to
+         * the native byte order by xcb_image_put() before drawing */
+        if (host_depth_matches_server(scrpriv))
+            scrpriv->ximg->byte_order = IMAGE_BYTE_ORDER;
+
         scrpriv->ximg->data =
             xallocarray(scrpriv->ximg->stride, buffer_height);
     }
@@ -1034,8 +1039,11 @@ hostx_paint_rect(KdScreenInfo *screen,
                           sx, sy, dx, dy, width, height, FALSE);
     }
     else {
-        xcb_image_put(HostX.conn, scrpriv->win, HostX.gc, scrpriv->ximg,
-                      0, 0, 0);
+        /* This is slow and could be done better */
+        xcb_image_t *img = xcb_image_native (HostX.conn, scrpriv->ximg, 1);
+        xcb_image_put(HostX.conn, scrpriv->win, HostX.gc, img, 0, 0, 0);
+        if (scrpriv->ximg != img)
+            xcb_image_destroy(img);
     }
 
     xcb_aux_sync(HostX.conn);
commit c65eda5e6676d942e80eaf2650a670174c8bd84a
Author: Egbert Eich <eich at freedesktop.org>
Date:   Tue Mar 31 09:14:28 2015 +0200

    Xephyr: Fix screen image draw for the non-Glamor & non-XHSM case
    
    xcb_image_put() prints the entire image, therefore don't use an offset.
    
    Signed-off-by: Egbert Eich <eich at freedesktop.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index f5a6f65..7f6fdc4 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -1035,7 +1035,7 @@ hostx_paint_rect(KdScreenInfo *screen,
     }
     else {
         xcb_image_put(HostX.conn, scrpriv->win, HostX.gc, scrpriv->ximg,
-                      dx, dy, 0);
+                      0, 0, 0);
     }
 
     xcb_aux_sync(HostX.conn);
commit 66212ca0d2f194fd16db65e863f0a2d613e180ea
Author: Egbert Eich <eich at freedesktop.org>
Date:   Tue Mar 31 09:14:27 2015 +0200

    Xephyr: Fix compile when debugging is enabled
    
    Signed-off-by: Egbert Eich <eich at freedesktop.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 14c4904..f5a6f65 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -798,7 +798,7 @@ hostx_screen_init(KdScreenInfo *screen,
     }
 
     EPHYR_DBG("host_screen=%p x=%d, y=%d, wxh=%dx%d, buffer_height=%d",
-              host_screen, x, y, width, height, buffer_height);
+              screen, x, y, width, height, buffer_height);
 
     if (scrpriv->ximg != NULL) {
         /* Free up the image data if previously used
commit b536d56aef21739b6da44693bbf19d0e7541392d
Author: Egbert Eich <eich at freedesktop.org>
Date:   Tue Mar 31 09:14:26 2015 +0200

    Xephyr: Print default server display number if none is specified
    
    Signed-off-by: Egbert Eich <eich at freedesktop.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 7163af0..14c4904 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -177,7 +177,7 @@ hostx_set_win_title(KdScreenInfo *screen, const char *extra_text)
 
         memset(buf, 0, BUF_LEN + 1);
         snprintf(buf, BUF_LEN, "Xephyr on %s.%d %s",
-                 HostX.server_dpy_name,
+                 HostX.server_dpy_name ? HostX.server_dpy_name : ":0",
                  scrpriv->mynum, (extra_text != NULL) ? extra_text : "");
 
         xcb_icccm_set_wm_name(HostX.conn,
commit 5af73f490870da9265eeb9b3ce59a2be026be0c8
Author: Egbert Eich <eich at suse.de>
Date:   Tue Mar 31 09:14:25 2015 +0200

    Xephyr: Don't crash when no command line argument is specified
    
    The DDX specific command line parsing function only gets called
    if command line arguments are present. Therefore this function
    is not suitable to initialize mandatory global variables.
    Replace main() instead.
    
    Signed-off-by: Egbert Eich <eich at freedesktop.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 0d85578..f760730 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2404,7 +2404,8 @@ if test "$KDRIVE" = yes; then
 	    fi
 	    ;;
     esac
-    KDRIVE_LOCAL_LIBS="$MAIN_LIB $DIX_LIB $KDRIVE_LIB"
+    KDRIVE_MAIN_LIB="$MAIN_LIB"
+    KDRIVE_LOCAL_LIBS="$DIX_LIB $KDRIVE_LIB"
     KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
     KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB"
     KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $GLX_SYS_LIBS $DLOPEN_LIBS $TSLIB_LIBS"
@@ -2416,6 +2417,7 @@ AC_SUBST([KDRIVE_INCS])
 AC_SUBST([KDRIVE_PURE_INCS])
 AC_SUBST([KDRIVE_CFLAGS])
 AC_SUBST([KDRIVE_PURE_LIBS])
+AC_SUBST([KDRIVE_MAIN_LIB])
 AC_SUBST([KDRIVE_LOCAL_LIBS])
 AC_SUBST([KDRIVE_LIBS])
 AM_CONDITIONAL(KDRIVELINUX, [test "x$KDRIVELINUX" = xyes])
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 897aa19..8fbaf1d 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -52,6 +52,13 @@ void processScreenOrOutputArg(const char *screen_size, const char *output, char
 void processOutputArg(const char *output, char *parent_id);
 void processScreenArg(const char *screen_size, char *parent_id);
 
+int
+main(int argc, char *argv[], char *envp[])
+{
+    hostx_use_resname(basename(argv[0]), 0);
+    return dix_main(argc, argv, envp);
+}
+
 void
 InitCard(char *name)
 {
@@ -209,10 +216,6 @@ ddxProcessArgument(int argc, char **argv, int i)
 
     EPHYR_DBG("mark argv[%d]='%s'", i, argv[i]);
 
-    if (i == 1) {
-        hostx_use_resname(basename(argv[0]), 0);
-    }
-
     if (!strcmp(argv[i], "-parent")) {
         if (i + 1 < argc) {
             int j;
diff --git a/hw/kdrive/fake/Makefile.am b/hw/kdrive/fake/Makefile.am
index 14c99c3..d28bd27 100644
--- a/hw/kdrive/fake/Makefile.am
+++ b/hw/kdrive/fake/Makefile.am
@@ -18,6 +18,7 @@ Xfake_SOURCES = \
 
 Xfake_LDADD = 						\
 	libfake.la					\
+	@KDRIVE_MAIN_LIB@				\
 	@KDRIVE_LIBS@
 
 Xfake_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
diff --git a/hw/kdrive/fbdev/Makefile.am b/hw/kdrive/fbdev/Makefile.am
index 7e8ba02..d550c13 100644
--- a/hw/kdrive/fbdev/Makefile.am
+++ b/hw/kdrive/fbdev/Makefile.am
@@ -16,6 +16,7 @@ Xfbdev_SOURCES = \
 
 Xfbdev_LDADD = 						\
 	libfbdev.la					\
+	@KDRIVE_MAIN_LIB@				\
 	@KDRIVE_LIBS@
 
 Xfbdev_DEPENDENCIES =	\
commit 00f79416b19f0cde68291aced44ab07b9b76f7b8
Author: Jonathan Gray <jsg at jsg.id.au>
Date:   Wed Apr 15 21:29:58 2015 +1000

    glamor: fix build when DRI3 is not defined
    
    Signed-off-by: Jonathan Gray <jsg at jsg.id.au>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 6033780..dc54561 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -595,6 +595,7 @@ glamor_egl_close_screen(ScreenPtr screen)
     return screen->CloseScreen(screen);
 }
 
+#ifdef DRI3
 static int
 glamor_dri3_open_client(ClientPtr client,
                         ScreenPtr screen,
@@ -651,12 +652,12 @@ static dri3_screen_info_rec glamor_dri3_info = {
     .pixmap_from_fd = glamor_pixmap_from_fd,
     .fd_from_pixmap = glamor_fd_from_pixmap,
 };
+#endif /* DRI3 */
 
 void
 glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
 {
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     struct glamor_egl_screen_private *glamor_egl =
         glamor_egl_get_screen_private(scrn);
 
@@ -668,7 +669,9 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
 
     glamor_ctx->make_current = glamor_egl_make_current;
 
+#ifdef DRI3
     if (glamor_egl->dri3_capable) {
+    	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
         /* Tell the core that we have the interfaces for import/export
          * of pixmaps.
          */
@@ -691,6 +694,7 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
             }
         }
     }
+#endif
 }
 
 static void
commit 7c609c911a3a33b7e4ddad46b8fc42878a073ee7
Author: Jonathan Gray <jsg at jsg.id.au>
Date:   Wed Apr 15 21:29:07 2015 +1000

    glamor: remove const from the return type of glamor_get_drawable_location()
    
    Fixes a build error with gcc 4.2.1 on OpenBSD due to
    -Werror=return-type from xorg-macros.
    
    error: type qualifiers ignored on function return type
    
    Signed-off-by: Jonathan Gray <jsg at jsg.id.au>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 5517454..965024e 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -35,7 +35,7 @@
 
 #include "glamor_priv.h"
 
-const Bool
+Bool
 glamor_get_drawable_location(const DrawablePtr drawable)
 {
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 898a934..4b9ba4d 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -676,7 +676,7 @@ glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv,
 void glamor_init_finish_access_shaders(ScreenPtr screen);
 void glamor_fini_finish_access_shaders(ScreenPtr screen);
 
-const Bool glamor_get_drawable_location(const DrawablePtr drawable);
+Bool glamor_get_drawable_location(const DrawablePtr drawable);
 void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
                                 int *x, int *y);
 GLint glamor_compile_glsl_prog(GLenum type, const char *source);
commit 145ae03814cb3b700b6fe1fd19f8fb15da84d1c8
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Mar 17 10:21:13 2015 +0900

    modesetting: Include dix-config.h from dumb_bo.c
    
    Fixes mmap failures with 32-bit builds.
    
    Signed-off-by: Michel Dänzer <michel at daenzer.net>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/dumb_bo.c b/hw/xfree86/drivers/modesetting/dumb_bo.c
index 58d420e..cf13f0a 100644
--- a/hw/xfree86/drivers/modesetting/dumb_bo.c
+++ b/hw/xfree86/drivers/modesetting/dumb_bo.c
@@ -25,6 +25,10 @@
  *
  */
 
+#ifdef HAVE_DIX_CONFIG_H
+#include "dix-config.h"
+#endif
+
 #include "dumb_bo.h"
 
 #include <errno.h>
commit 4962c8c08842d9d3ca66d254b1ce4cacc4fb3756
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Mar 17 10:21:12 2015 +0900

    Add AC_SYS_LARGEFILE defines to dix-config.h
    
    Without this, AC_SYS_LARGEFILE doesn't actually have any effect.
    
    Signed-off-by: Michel Dänzer <michel at daenzer.net>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 78c2010..76f45f5 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -391,9 +391,15 @@
 /* Vendor name */
 #undef XVENDORNAME
 
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
 /* Enable GNU and other extensions to the C environment for GLIBC */
 #undef _GNU_SOURCE
 
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const
 
commit 0409b6e6d63e9cfb5dc71bb27de4b1ed0152dd9b
Merge: c39c3a9 23702dd
Author: Keith Packard <keithp at keithp.com>
Date:   Mon May 11 16:50:43 2015 -0700

    Merge remote-tracking branch 'evelikov/master'

commit c39c3a97508dc384c0757a0990c07b5d7b2fe97a
Merge: 6b65e96 7470578
Author: Keith Packard <keithp at keithp.com>
Date:   Mon May 11 16:34:48 2015 -0700

    Merge remote-tracking branch 'ajax/xserver-next'

commit 6b65e961894b9ed53066d22cfd218b12c3f361ca
Author: Robert Ancell <robert.ancell at canonical.com>
Date:   Wed May 6 15:07:21 2015 +1200

    xwayland: Fix error strings
    
    Fix missing newlines from error string and fix grammar.
    
    Signed-off-by: Robert Ancell <robert.ancell at canonical.com>
    Reviewed-by: Daniel Stone <daniels at collabora.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index d06006c..6b6e597 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -310,7 +310,7 @@ xwl_drm_init_egl(struct xwl_screen *xwl_screen)
     }
 
     if (!epoxy_has_gl_extension("GL_OES_EGL_image")) {
-        ErrorF("GL_OES_EGL_image no available");
+        ErrorF("GL_OES_EGL_image not available\n");
         return;
     }
 
@@ -329,7 +329,7 @@ xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
 
    xwl_screen->drm_fd = open(xwl_screen->device_name, O_RDWR | O_CLOEXEC);
    if (xwl_screen->drm_fd == -1) {
-       ErrorF("wayland-egl: could not open %s (%s)",
+       ErrorF("wayland-egl: could not open %s (%s)\n",
 	      xwl_screen->device_name, strerror(errno));
        return;
    }
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 9d8c28e..78d9702 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -540,7 +540,7 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id)
 
     xwl_seat = calloc(sizeof *xwl_seat, 1);
     if (xwl_seat == NULL) {
-        ErrorF("create_input ENOMEM");
+        ErrorF("create_input ENOMEM\n");
         return;
     }
 
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 778914c..155cbc1 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -159,7 +159,7 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
 
     xwl_output = calloc(sizeof *xwl_output, 1);
     if (xwl_output == NULL) {
-        ErrorF("create_output ENOMEM");
+        ErrorF("create_output ENOMEM\n");
         return NULL;
     }
 
@@ -168,7 +168,7 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
     wl_output_add_listener(xwl_output->output, &output_listener, xwl_output);
 
     if (snprintf(name, sizeof name, "XWAYLAND%d", serial++) < 0) {
-        ErrorF("create_output ENOMEM");
+        ErrorF("create_output ENOMEM\n");
         free(xwl_output);
         return NULL;
     }
commit d7091a21d90cf463ae39ec5e8741123218ec5686
Merge: c3ce9d8 8fb8bbb
Author: Keith Packard <keithp at keithp.com>
Date:   Mon May 11 15:49:34 2015 -0700

    Merge remote-tracking branch 'airlied/for-keithp'

diff --cc hw/xfree86/common/xf86Helper.c
index 6a35250,7321a1a..359bac7
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@@ -1410,9 -1408,20 +1410,20 @@@ xf86MatchDevice(const char *drivername
              /*
               * we have a matching driver that wasn't claimed, yet
               */
 -            pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
 +            pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr));
              pgdp[i++] = screensecptr->device;
          }
+         for (k = 0; k < screensecptr->num_gpu_devices; k++) {
+             if ((screensecptr->gpu_devices[k]->driver != NULL)
+             && (xf86NameCmp(screensecptr->gpu_devices[k]->driver, drivername) == 0)
+                 && (!screensecptr->gpu_devices[k]->claimed)) {
+                 /*
+                  * we have a matching driver that wasn't claimed, yet
+                  */
+                 pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
+                 pgdp[i++] = screensecptr->gpu_devices[k];
+             }
+         }
      }
  
      /* Then handle the inactive devices */
commit c3ce9d8fd404ca1d4697a104ce4899525dd43c51
Author: Adel Gadllah <adel.gadllah at gmail.com>
Date:   Fri May 1 17:43:41 2015 +0200

    modesetting: Fix software cursor fallback
    
    The code in drmmode_set_cursor does not properly handle the case where
    drmModeSetCursor2 returns any other error than EINVAL and silently fails to set
    a cursor.
    
    So only return when the drmModeSetCursor2 succeeds (i.e returns 0) and disable
    the cursor2 usage on EINVAL.
    
    References: https://bugzilla.redhat.com/show_bug.cgi?id=1205725
    Signed-off-by: Adel Gadllah <adel.gadllah at gmail.com>
    Reviewed-by: Michel Dänzer <michel at daenzer.net>
    Reviewed-by: Rob Clark <robdclark at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 1ea799b..a8de5f9 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -427,10 +427,10 @@ drmmode_set_cursor(xf86CrtcPtr crtc)
             drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
                               handle, ms->cursor_width, ms->cursor_height,
                               cursor->bits->xhot, cursor->bits->yhot);
+        if (!ret)
+            return;
         if (ret == -EINVAL)
             use_set_cursor2 = FALSE;
-        else
-            return;
     }
 
     ret = drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle,
commit 81a51a6cace6fdb54999ccdf1533dc28a2222bb9
Author: Dima Ryazanov <dima at gmail.com>
Date:   Wed Apr 29 22:39:18 2015 -0700

    xwayland: Implement smooth scrolling
    
    We don't even need to simulate button clicks; it's done automatically.
    This also fixes scrolling in Qt5 apps.
    
    Signed-off-by: Dima Ryazanov <dima at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index cc3bc53..9d8c28e 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -43,7 +43,7 @@ static int
 xwl_pointer_proc(DeviceIntPtr device, int what)
 {
 #define NBUTTONS 10
-#define NAXES 2
+#define NAXES 4
     BYTE map[NBUTTONS + 1];
     int i = 0;
     Atom btn_labels[NBUTTONS] = { 0 };
@@ -67,8 +67,10 @@ xwl_pointer_proc(DeviceIntPtr device, int what)
 
         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
+        axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL);
+        axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL);
 
-        if (!InitValuatorClassDeviceStruct(device, 2, btn_labels,
+        if (!InitValuatorClassDeviceStruct(device, NAXES, btn_labels,
                                            GetMotionHistorySize(), Absolute))
             return BadValue;
 
@@ -77,6 +79,13 @@ xwl_pointer_proc(DeviceIntPtr device, int what)
                                0, 0xFFFF, 10000, 0, 10000, Absolute);
         InitValuatorAxisStruct(device, 1, axes_labels[1],
                                0, 0xFFFF, 10000, 0, 10000, Absolute);
+        InitValuatorAxisStruct(device, 2, axes_labels[2],
+                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
+        InitValuatorAxisStruct(device, 3, axes_labels[3],
+                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
+
+        SetScrollValuator(device, 2, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE);
+        SetScrollValuator(device, 3, SCROLL_TYPE_VERTICAL, 1.0, SCROLL_FLAG_PREFERRED);
 
         if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
             return BadValue;
@@ -259,54 +268,24 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
                     uint32_t time, uint32_t axis, wl_fixed_t value)
 {
     struct xwl_seat *xwl_seat = data;
-    int index, count;
-    int i, val;
+    int index;
     const int divisor = 10;
     ValuatorMask mask;
 
-    if (time - xwl_seat->scroll_time > 2000) {
-        xwl_seat->vertical_scroll = 0;
-        xwl_seat->horizontal_scroll = 0;
-    }
-    xwl_seat->scroll_time = time;
-
-    /* FIXME: Need to do proper smooth scrolling here! */
     switch (axis) {
     case WL_POINTER_AXIS_VERTICAL_SCROLL:
-        xwl_seat->vertical_scroll += value / divisor;
-        val = wl_fixed_to_int(xwl_seat->vertical_scroll);
-        xwl_seat->vertical_scroll -= wl_fixed_from_int(val);
-
-        if (val <= -1)
-            index = 4;
-        else if (val >= 1)
-            index = 5;
-        else
-            return;
+        index = 3;
         break;
     case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
-        xwl_seat->horizontal_scroll += value / divisor;
-        val = wl_fixed_to_int(xwl_seat->horizontal_scroll);
-        xwl_seat->horizontal_scroll -= wl_fixed_from_int(val);
-
-        if (val <= -1)
-            index = 6;
-        else if (val >= 1)
-            index = 7;
-        else
-            return;
+        index = 2;
         break;
     default:
         return;
     }
 
     valuator_mask_zero(&mask);
-
-    count = abs(val);
-    for (i = 0; i < count; i++) {
-        QueuePointerEvents(xwl_seat->pointer, ButtonPress, index, 0, &mask);
-        QueuePointerEvents(xwl_seat->pointer, ButtonRelease, index, 0, &mask);
-    }
+    valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor);
+    QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0, POINTER_RELATIVE, &mask);
 }
 
 static const struct wl_pointer_listener pointer_listener = {
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index bfffa71..cfb343d 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -122,10 +122,6 @@ struct xwl_seat {
     struct xorg_list link;
     CursorPtr x_cursor;
 
-    wl_fixed_t horizontal_scroll;
-    wl_fixed_t vertical_scroll;
-    uint32_t scroll_time;
-
     size_t keymap_size;
     char *keymap;
     struct wl_surface *keyboard_focus;
commit 9ff89a2e469ab0ac5af57d0fc115127feb1c0d99
Author: Jason Gerecke <killertofu at gmail.com>
Date:   Wed Apr 29 15:08:58 2015 +1000

    dix: Do not allow device transform to be set on valuatorless devices
    
    If a device does not have any valuators, it makes no sense to set the
    device transformation. Return a BadMatch error to let the caller know
    that they're trying something stupid.
    
    Signed-off-by: Jason Gerecke <jason.gerecke at wacom.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/devices.c b/dix/devices.c
index b2de6f1..1f8dabd 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -177,6 +177,9 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
             if (!isfinite(f[i]))
                 return BadValue;
 
+	if (!dev->valuator)
+		return BadMatch;
+
         if (!checkonly)
             DeviceSetTransform(dev, f);
     }
commit fa62ca68ef8be7f63cd0b899dfae3366ca9350cf
Author: Rui Matos <tiagomatos at gmail.com>
Date:   Sat Apr 25 21:19:25 2015 +0200

    dix/events: Set currentTime to the given time stamp in NoticeTime
    
    The refactoring in commit efc1035ca958f2c9d266338a308518a0834b1773
    removed the actual update of currentTime.
    
    Signed-off-by: Rui Matos <tiagomatos at gmail.com>
    Acked-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/events.c b/dix/events.c
index 7d2bb6b..efaf91d 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1057,6 +1057,7 @@ MonthChangedOrBadTime(CARD32 *ms)
 void
 NoticeTime(const DeviceIntPtr dev, TimeStamp time)
 {
+    currentTime = time;
     lastDeviceEventTime[XIAllDevices].time = currentTime;
     lastDeviceEventTime[dev->id].time = currentTime;
 
commit 26e50e8b2cbd01d050b5ecc02d47488b53ecc08b
Merge: 28ff661 c7b49bd
Author: Keith Packard <keithp at keithp.com>
Date:   Mon May 11 15:36:53 2015 -0700

    Merge remote-tracking branch 'jturney/mingw-build-fixes'

commit 7470578520e90b6402b2509cd0c51fd4fd84849f
Author: Brent Collins <bcollins at trustedcs.com>
Date:   Thu May 7 15:10:19 2015 -0400

    shm: Fix xselinux resource initialization for xinerama pixmaps
    
    This is necessary to avoid a NULL pointer deference when the pixmap is
    used later.
    
    [ajax: massaged commit message, fixed it to compile]
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89748
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Brent Collins <bcollins at trustedcs.com>

diff --git a/Xext/shm.c b/Xext/shm.c
index 52d9974..b359a90 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -971,6 +971,12 @@ ProcPanoramiXShmCreatePixmap(ClientPtr client)
                                                        stuff->offset);
 
         if (pMap) {
+            result = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid,
+                              RT_PIXMAP, pMap, RT_NONE, NULL, DixCreateAccess);
+            if (result != Success) {
+                pDraw->pScreen->DestroyPixmap(pMap);
+                return result;
+            }
             dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc);
             shmdesc->refcnt++;
             pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
commit bcec9f867d19e954a46c2654a79782bff6c65fce
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Feb 14 10:36:44 2015 +0000

    shm: Fix use-after-free in ShmDestroyPixmap
    
    We pass the pPixmap->drawable.id to the ShmDetachSegment function after
    the pPixmap is freed. Fortunately, we don't use the value inside
    ShmDetachSegment and can simply pass zero instead.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Michel Dänzer <michel at daenzer.net>

diff --git a/Xext/shm.c b/Xext/shm.c
index db9d474..52d9974 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -260,7 +260,7 @@ ShmDestroyPixmap(PixmapPtr pPixmap)
     pScreen->DestroyPixmap = ShmDestroyPixmap;
 
     if (shmdesc)
-	ShmDetachSegment(shmdesc, pPixmap->drawable.id);
+	ShmDetachSegment(shmdesc, 0);
 
     return ret;
 }
@@ -427,7 +427,7 @@ ProcShmAttach(ClientPtr client)
 
  /*ARGSUSED*/ static int
 ShmDetachSegment(void *value, /* must conform to DeleteType */
-                 XID shmseg)
+                 XID unused)
 {
     ShmDescPtr shmdesc = (ShmDescPtr) value;
     ShmDescPtr *prev;
commit d61ae18074e53c2cdfb13cc37693b526160d6ca7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Mar 4 12:16:29 2015 +0000

    glx/dri2: Disable AIGLX if indirect GLX is disabled
    
    There is no point in setting up the acceleration for indirect GLX if
    indirect GLX is itself disabled.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index bcd57a4..c0f29ea 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -936,6 +936,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     size_t buffer_size;
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
 
+    if (!enableIndirectGLX)
+	    return NULL;
+
     screen = calloc(1, sizeof *screen);
     if (screen == NULL)
         return NULL;
commit 1af15aaf278edcf6f6de94774350e34a80883c24
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Apr 10 10:07:38 2015 +0200

    dix: Fix image byte order on big endian hardware
    
    Make sure X_BIG_ENDIAN/X_LITTLE_ENDIAN are defined before actually using
    them.
    
    Otherwise, image byte order could be wrong on big endian hardware even
    though endianess detection is correct.
    
    Reported-by: Tim Waugh <twaugh at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/include/servermd.h b/include/servermd.h
index a3b5c3a..087826f 100644
--- a/include/servermd.h
+++ b/include/servermd.h
@@ -52,6 +52,8 @@ SOFTWARE.
 #error xserver code must include dix-config.h before any other headers
 #endif
 
+#include <X11/Xarch.h>		/* for X_LITTLE_ENDIAN/X_BIG_ENDIAN */
+
 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
 #define IMAGE_BYTE_ORDER        LSBFirst
 #define BITMAP_BIT_ORDER        LSBFirst
commit 28159eff6badf6181b255f26d1f444abe81c05b7
Author: Jason Gerecke <killertofu at gmail.com>
Date:   Thu Apr 30 18:06:14 2015 -0700

    xfree86: Return NULL from xf86CompatOutput if no compat_output is defined
    
    If no compat_output is defined, we inadvertently (attempt to) return
    whatever data is at index -1. Instead, return NULL since that's what
    callers are expecting.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Jason Gerecke <jason.gerecke at wacom.com>

diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 3c5bbcf..8b01608 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -745,6 +745,8 @@ xf86CompatOutput(ScrnInfoPtr pScrn)
 {
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
 
+    if (config->compat_output < 0)
+        return NULL;
     return config->output[config->compat_output];
 }
 
commit cad831f39861435cb94f4c90a73f7f0b62d1a4a1
Author: Robert Ancell <robert.ancell at canonical.com>
Date:   Wed May 6 15:07:21 2015 +1200

    xwayland: Fix error strings
    
    Fix missing newlines from error string and fix grammar.
    
    Signed-off-by: Robert Ancell <robert.ancell at canonical.com>
    Reviewed-by: Daniel Stone <daniels at collabora.com>

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index d06006c..6b6e597 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -310,7 +310,7 @@ xwl_drm_init_egl(struct xwl_screen *xwl_screen)
     }
 
     if (!epoxy_has_gl_extension("GL_OES_EGL_image")) {
-        ErrorF("GL_OES_EGL_image no available");
+        ErrorF("GL_OES_EGL_image not available\n");
         return;
     }
 
@@ -329,7 +329,7 @@ xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
 
    xwl_screen->drm_fd = open(xwl_screen->device_name, O_RDWR | O_CLOEXEC);
    if (xwl_screen->drm_fd == -1) {
-       ErrorF("wayland-egl: could not open %s (%s)",
+       ErrorF("wayland-egl: could not open %s (%s)\n",
 	      xwl_screen->device_name, strerror(errno));
        return;
    }
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index cc3bc53..488b839 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -561,7 +561,7 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id)
 
     xwl_seat = calloc(sizeof *xwl_seat, 1);
     if (xwl_seat == NULL) {
-        ErrorF("create_input ENOMEM");
+        ErrorF("create_input ENOMEM\n");
         return;
     }
 
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 778914c..155cbc1 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -159,7 +159,7 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
 
     xwl_output = calloc(sizeof *xwl_output, 1);
     if (xwl_output == NULL) {
-        ErrorF("create_output ENOMEM");
+        ErrorF("create_output ENOMEM\n");
         return NULL;
     }
 
@@ -168,7 +168,7 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
     wl_output_add_listener(xwl_output->output, &output_listener, xwl_output);
 
     if (snprintf(name, sizeof name, "XWAYLAND%d", serial++) < 0) {
-        ErrorF("create_output ENOMEM");
+        ErrorF("create_output ENOMEM\n");
         free(xwl_output);
         return NULL;
     }
commit 8fb8bbb3062f1a06621ab7030a9e89d5e8367b35
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Mar 23 11:33:23 2015 +1000

    modesetting: add tile property support (v2.1)
    
    This adds tiling support to the server modesetting driver,
    it retrieves the tile info from the kernel and translates
    it into the server format and exposes the property.
    
    v2.1: fix resetting tile property (Chris)
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 7f7b560..cae057c 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -749,6 +749,46 @@ drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
     return MODE_OK;
 }
 
+static void
+drmmode_output_attach_tile(xf86OutputPtr output)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    drmModeConnectorPtr koutput = drmmode_output->mode_output;
+    drmmode_ptr drmmode = drmmode_output->drmmode;
+    int i;
+    struct xf86CrtcTileInfo tile_info, *set = NULL;
+
+    if (!koutput) {
+        xf86OutputSetTile(output, NULL);
+        return;
+    }
+
+    /* look for a TILE property */
+    for (i = 0; i < koutput->count_props; i++) {
+        drmModePropertyPtr props;
+        props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+        if (!props)
+            continue;
+
+        if (!(props->flags & DRM_MODE_PROP_BLOB)) {
+            drmModeFreeProperty(props);
+            continue;
+        }
+
+        if (!strcmp(props->name, "TILE")) {
+            drmModeFreePropertyBlob(drmmode_output->tile_blob);
+            drmmode_output->tile_blob =
+                drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
+        }
+        drmModeFreeProperty(props);
+    }
+    if (drmmode_output->tile_blob) {
+        if (xf86OutputParseKMSTile(drmmode_output->tile_blob->data, drmmode_output->tile_blob->length, &tile_info) == TRUE)
+            set = &tile_info;
+    }
+    xf86OutputSetTile(output, set);
+}
+
 static Bool
 has_panel_fitter(xf86OutputPtr output)
 {
@@ -857,6 +897,8 @@ drmmode_output_get_modes(xf86OutputPtr output)
     }
     xf86OutputSetEDID(output, mon);
 
+    drmmode_output_attach_tile(output);
+
     /* modes should already be available */
     for (i = 0; i < koutput->count_modes; i++) {
         Mode = xnfalloc(sizeof(DisplayModeRec));
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index f4989b8..b0e45b6 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -120,6 +120,7 @@ typedef struct {
     drmModeConnectorPtr mode_output;
     drmModeEncoderPtr *mode_encoders;
     drmModePropertyBlobPtr edid_blob;
+    drmModePropertyBlobPtr tile_blob;
     int dpms_enum_id;
     int num_props;
     drmmode_prop_ptr props;
commit 9257b1252da9092ddc676fec9aabe2b33dfad272
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jan 28 17:35:21 2015 +1000

    modesetting: add dynamic connector hotplug support (MST) (v3)
    
    This is ported from the same code in the ati and intel drivers,
    
    It uses the same option name as nvidia and the other DDXes to
    disable tearing down outputs as it is hard to avoid racing with clients.
    
    v2: address two issues with DeleteUnusedDP12 enabled, reported
    by Daniel Martin,
    a) check we have a mode_output before destroying it
    b) only delete *unused* displays (thanks Aaron for clarifying)
    so we check if the output has a crtc and if it does we don't
    delete it.
    
    v3: drop the option to delete unused displays, just encode
    behaviour into the randr spec.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 8dc6b32..7f7b560 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -326,6 +326,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
                 continue;
 
             drmmode_output = output->driver_private;
+            if (drmmode_output->output_id == -1)
+                continue;
             output_ids[output_count] =
                 drmmode_output->mode_output->connector_id;
             output_count++;
@@ -366,10 +368,14 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
         /* go through all the outputs and force DPMS them back on? */
         for (i = 0; i < xf86_config->num_output; i++) {
             xf86OutputPtr output = xf86_config->output[i];
+            drmmode_output_private_ptr drmmode_output;
 
             if (output->crtc != crtc)
                 continue;
 
+            drmmode_output = output->driver_private;
+            if (drmmode_output->output_id == -1)
+                continue;
             output->funcs->dpms(output, DPMSModeOn);
         }
     }
@@ -712,6 +718,9 @@ drmmode_output_detect(xf86OutputPtr output)
     drmmode_ptr drmmode = drmmode_output->drmmode;
     xf86OutputStatus status;
 
+    if (drmmode_output->output_id == -1)
+        return XF86OutputStatusDisconnected;
+
     drmModeFreeConnector(drmmode_output->mode_output);
 
     drmmode_output->mode_output =
@@ -873,11 +882,13 @@ drmmode_output_destroy(xf86OutputPtr output)
         free(drmmode_output->props[i].atoms);
     }
     free(drmmode_output->props);
-    for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) {
-        drmModeFreeEncoder(drmmode_output->mode_encoders[i]);
+    if (drmmode_output->mode_output) {
+        for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) {
+            drmModeFreeEncoder(drmmode_output->mode_encoders[i]);
+        }
+        drmModeFreeConnector(drmmode_output->mode_output);
     }
     free(drmmode_output->mode_encoders);
-    drmModeFreeConnector(drmmode_output->mode_output);
     free(drmmode_output);
     output->driver_private = NULL;
 }
@@ -1111,22 +1122,134 @@ static const char *const output_names[] = {
     "DSI",
 };
 
+static xf86OutputPtr find_output(ScrnInfoPtr pScrn, int id)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int i;
+    for (i = 0; i < xf86_config->num_output; i++) {
+        xf86OutputPtr output = xf86_config->output[i];
+        drmmode_output_private_ptr drmmode_output;
+
+        drmmode_output = output->driver_private;
+        if (drmmode_output->output_id == id)
+            return output;
+    }
+    return NULL;
+}
+
+static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, char **path)
+{
+    char *conn;
+    char conn_id[5];
+    int id, len;
+    char *blob_data;
+
+    if (!path_blob)
+        return -1;
+
+    blob_data = path_blob->data;
+    /* we only handle MST paths for now */
+    if (strncmp(blob_data, "mst:", 4))
+        return -1;
+
+    conn = strchr(blob_data + 4, '-');
+    if (!conn)
+        return -1;
+    len = conn - (blob_data + 4);
+    if (len + 1> 5)
+        return -1;
+    memcpy(conn_id, blob_data + 4, len);
+    conn_id[len + 1] = '\0';
+    id = strtoul(conn_id, NULL, 10);
+
+    *conn_base_id = id;
+
+    *path = conn + 1;
+    return 0;
+}
+
+static void
+drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name,
+		    drmModePropertyBlobPtr path_blob)
+{
+    int ret;
+    char *extra_path;
+    int conn_id;
+    xf86OutputPtr output;
+
+    ret = parse_path_blob(path_blob, &conn_id, &extra_path);
+    if (ret == -1)
+        goto fallback;
+
+    output = find_output(pScrn, conn_id);
+    if (!output)
+        goto fallback;
+
+    snprintf(name, 32, "%s-%s", output->name, extra_path);
+    return;
+
+ fallback:
+    if (koutput->connector_type >= MS_ARRAY_SIZE(output_names))
+        snprintf(name, 32, "Unknown-%d", koutput->connector_type_id - 1);
+#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT
+    else if (pScrn->is_gpu)
+        snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id - 1);
+#endif
+    else
+        snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1);
+}
+
 static void
-drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num)
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, Bool dynamic)
 {
     xf86OutputPtr output;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     drmModeConnectorPtr koutput;
     drmModeEncoderPtr *kencoders = NULL;
     drmmode_output_private_ptr drmmode_output;
     drmModePropertyPtr props;
     char name[32];
     int i;
+    drmModePropertyBlobPtr path_blob = NULL;
 
     koutput =
         drmModeGetConnector(drmmode->fd, mode_res->connectors[num]);
     if (!koutput)
         return;
 
+    for (i = 0; i < koutput->count_props; i++) {
+        props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+        if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
+            if (!strcmp(props->name, "PATH")) {
+                path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
+                drmModeFreeProperty(props);
+                break;
+            }
+            drmModeFreeProperty(props);
+        }
+    }
+
+    drmmode_create_name(pScrn, koutput, name, path_blob);
+
+    if (path_blob)
+        drmModeFreePropertyBlob(path_blob);
+
+    if (path_blob && dynamic) {
+        /* see if we have an output with this name already
+           and hook stuff up */
+        for (i = 0; i < xf86_config->num_output; i++) {
+            output = xf86_config->output[i];
+
+            if (strncmp(output->name, name, 32))
+                continue;
+
+            drmmode_output = output->driver_private;
+            drmmode_output->output_id = mode_res->connectors[num];
+            drmmode_output->mode_output = koutput;
+            return;
+        }
+    }
+
     kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders);
     if (!kencoders) {
         goto out_free_encoders;
@@ -1139,17 +1262,6 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
         }
     }
 
-    /* need to do smart conversion here for compat with non-kms ATI driver */
-    if (koutput->connector_type >= MS_ARRAY_SIZE(output_names))
-        snprintf(name, 32, "Unknown-%d", koutput->connector_type_id - 1);
-    else if (pScrn->is_gpu)
-        snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type],
-                 pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1,
-                 koutput->connector_type_id - 1);
-    else
-        snprintf(name, 32, "%s-%d", output_names[koutput->connector_type],
-                 koutput->connector_type_id - 1);
-
     output = xf86OutputCreate(pScrn, &drmmode_output_funcs, name);
     if (!output) {
         goto out_free_encoders;
@@ -1192,6 +1304,8 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
         }
     }
 
+    if (dynamic)
+        output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output);
     return;
  out_free_encoders:
     if (kencoders) {
@@ -1451,7 +1565,7 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
             drmmode_crtc_init(pScrn, drmmode, mode_res, i);
 
     for (i = 0; i < mode_res->count_connectors; i++)
-        drmmode_output_init(pScrn, drmmode, mode_res, i);
+        drmmode_output_init(pScrn, drmmode, mode_res, i, FALSE);
 
     /* workout clones */
     drmmode_clones_init(pScrn, drmmode, mode_res);
@@ -1620,11 +1734,78 @@ drmmode_handle_uevents(int fd, void *closure)
     drmmode_ptr drmmode = closure;
     ScrnInfoPtr scrn = drmmode->scrn;
     struct udev_device *dev;
+    drmModeResPtr mode_res;
+    xf86CrtcConfigPtr  config = XF86_CRTC_CONFIG_PTR(scrn);
+    int i, j;
+    Bool found;
+    Bool changed = FALSE;
 
     dev = udev_monitor_receive_device(drmmode->uevent_monitor);
     if (!dev)
         return;
 
+    mode_res = drmModeGetResources(drmmode->fd);
+    if (!mode_res)
+        goto out;
+
+    if (mode_res->count_crtcs != config->num_crtc) {
+        ErrorF("number of CRTCs changed - failed to handle, %d vs %d\n", mode_res->count_crtcs, config->num_crtc);
+        goto out_free_res;
+    }
+
+    /* figure out if we have gotten rid of any connectors
+       traverse old output list looking for outputs */
+    for (i = 0; i < config->num_output; i++) {
+        xf86OutputPtr output = config->output[i];
+        drmmode_output_private_ptr drmmode_output;
+
+        drmmode_output = output->driver_private;
+        found = FALSE;
+        for (j = 0; j < mode_res->count_connectors; j++) {
+            if (mode_res->connectors[j] == drmmode_output->output_id) {
+                found = TRUE;
+                break;
+            }
+        }
+        if (found)
+            continue;
+
+        drmModeFreeConnector(drmmode_output->mode_output);
+        drmmode_output->mode_output = NULL;
+        drmmode_output->output_id = -1;
+
+        changed = TRUE;
+    }
+
+    /* find new output ids we don't have outputs for */
+    for (i = 0; i < mode_res->count_connectors; i++) {
+        found = FALSE;
+
+        for (j = 0; j < config->num_output; j++) {
+            xf86OutputPtr output = config->output[j];
+            drmmode_output_private_ptr drmmode_output;
+
+            drmmode_output = output->driver_private;
+            if (mode_res->connectors[i] == drmmode_output->output_id) {
+                found = TRUE;
+                break;
+            }
+        }
+        if (found)
+            continue;
+
+        changed = TRUE;
+        drmmode_output_init(scrn, drmmode, mode_res, i, 1);
+    }
+
+    if (changed) {
+        RRSetChanged(xf86ScrnToScreen(scrn));
+        RRTellChanged(xf86ScrnToScreen(scrn));
+    }
+
+out_free_res:
+    drmModeFreeResources(mode_res);
+out:
     RRGetInfo(xf86ScrnToScreen(scrn), TRUE);
     udev_device_unref(dev);
 }
commit 33422d160bff3117b413a62d82b168e84f1aa8f6
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jan 28 17:25:00 2015 +1000

    modesetting: stop caching mode resources
    
    There is no need to cache the mode resources and with dynamic
    connectors for mst support we don't want to. So first clean that
    up before adding dynamic connector support.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 1ea799b..8dc6b32 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -687,7 +687,7 @@ drmmode_crtc_vblank_pipe(int crtc_id)
 }
 
 static void
-drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num)
 {
     xf86CrtcPtr crtc;
     drmmode_crtc_private_ptr drmmode_crtc;
@@ -698,7 +698,7 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 
     drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
     drmmode_crtc->mode_crtc =
-        drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
+        drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]);
     drmmode_crtc->drmmode = drmmode;
     drmmode_crtc->vblank_pipe = drmmode_crtc_vblank_pipe(num);
     crtc->driver_private = drmmode_crtc;
@@ -1112,7 +1112,7 @@ static const char *const output_names[] = {
 };
 
 static void
-drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num)
 {
     xf86OutputPtr output;
     drmModeConnectorPtr koutput;
@@ -1123,7 +1123,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
     int i;
 
     koutput =
-        drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
+        drmModeGetConnector(drmmode->fd, mode_res->connectors[num]);
     if (!koutput)
         return;
 
@@ -1161,7 +1161,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
         goto out_free_encoders;
     }
 
-    drmmode_output->output_id = drmmode->mode_res->connectors[num];
+    drmmode_output->output_id = mode_res->connectors[num];
     drmmode_output->mode_output = koutput;
     drmmode_output->mode_encoders = kencoders;
     drmmode_output->drmmode = drmmode;
@@ -1231,7 +1231,7 @@ find_clones(ScrnInfoPtr scrn, xf86OutputPtr output)
 }
 
 static void
-drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
+drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, drmModeResPtr mode_res)
 {
     int i, j;
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -1246,8 +1246,8 @@ drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
         for (j = 0; j < drmmode_output->mode_output->count_encoders; j++) {
             int k;
 
-            for (k = 0; k < drmmode->mode_res->count_encoders; k++) {
-                if (drmmode->mode_res->encoders[k] ==
+            for (k = 0; k < mode_res->count_encoders; k++) {
+                if (mode_res->encoders[k] ==
                     drmmode_output->mode_encoders[j]->encoder_id)
                     drmmode_output->enc_mask |= (1 << k);
             }
@@ -1425,6 +1425,7 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
     int i;
     int ret;
     uint64_t value = 0;
+    drmModeResPtr mode_res;
 
     /* check for dumb capability */
     ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_BUFFER, &value);
@@ -1438,23 +1439,24 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 
     drmmode->scrn = pScrn;
     drmmode->cpp = cpp;
-    drmmode->mode_res = drmModeGetResources(drmmode->fd);
-    if (!drmmode->mode_res)
+    mode_res = drmModeGetResources(drmmode->fd);
+    if (!mode_res)
         return FALSE;
 
-    xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width,
-                         drmmode->mode_res->max_height);
-    for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
+    xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width,
+                         mode_res->max_height);
+    for (i = 0; i < mode_res->count_crtcs; i++)
         if (!xf86IsEntityShared(pScrn->entityList[0]) ||
             pScrn->confScreen->device->screen == i)
-            drmmode_crtc_init(pScrn, drmmode, i);
+            drmmode_crtc_init(pScrn, drmmode, mode_res, i);
 
-    for (i = 0; i < drmmode->mode_res->count_connectors; i++)
-        drmmode_output_init(pScrn, drmmode, i);
+    for (i = 0; i < mode_res->count_connectors; i++)
+        drmmode_output_init(pScrn, drmmode, mode_res, i);
 
     /* workout clones */
-    drmmode_clones_init(pScrn, drmmode);
+    drmmode_clones_init(pScrn, drmmode, mode_res);
 
+    drmModeFreeResources(mode_res);
 #if XF86_CRTC_VERSION >= 5
     xf86ProviderSetup(pScrn, NULL, "modesetting");
 #endif
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 3a8959a..f4989b8 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -47,7 +47,6 @@ typedef struct {
     int fd;
     unsigned fb_id;
     unsigned old_fb_id;
-    drmModeResPtr mode_res;
     drmModeFBPtr mode_fb;
     int cpp;
     ScrnInfoPtr scrn;
commit a9ac02f6949357619684dd98ff6cf05489e62e55
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Apr 1 12:13:51 2015 +1000

    xf86Crtc/monitors: create initial monitors for tiled outputs
    
    This creates an automatic monitor for a tiled monitor at startup.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index b1c306a..642127e 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1564,6 +1564,70 @@ xf86RandR12CreateObjects12(ScreenPtr pScreen)
     return TRUE;
 }
 
+static void
+xf86RandR12CreateMonitors(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int o, ot;
+    int ht, vt;
+    int ret;
+    char buf[25];
+
+    for (o = 0; o < config->num_output; o++) {
+        xf86OutputPtr output = config->output[o];
+        struct xf86CrtcTileInfo *tile_info = &output->tile_info, *this_tile;
+        RRMonitorPtr monitor;
+        int output_num, num_outputs;
+        if (!tile_info->group_id)
+            continue;
+
+        if (tile_info->tile_h_loc ||
+            tile_info->tile_v_loc)
+            continue;
+
+        num_outputs = tile_info->num_h_tile * tile_info->num_v_tile;
+
+        monitor = RRMonitorAlloc(num_outputs);
+        if (!monitor)
+            return;
+        monitor->pScreen = pScreen;
+        snprintf(buf, 25, "Auto-Monitor-%d", tile_info->group_id);
+        monitor->name = MakeAtom(buf, strlen(buf), TRUE);
+        monitor->primary = 0;
+        monitor->automatic = TRUE;
+        memset(&monitor->geometry.box, 0, sizeof(monitor->geometry.box));
+
+        output_num = 0;
+        for (ht = 0; ht < tile_info->num_h_tile; ht++) {
+            for (vt = 0; vt < tile_info->num_v_tile; vt++) {
+
+                for (ot = 0; ot < config->num_output; ot++) {
+                    this_tile = &config->output[ot]->tile_info;
+
+                    if (this_tile->group_id != tile_info->group_id)
+                        continue;
+
+                    if (this_tile->tile_h_loc != ht ||
+                        this_tile->tile_v_loc != vt)
+                        continue;
+
+                    monitor->outputs[output_num] = config->output[ot]->randr_output->id;
+                    output_num++;
+
+                }
+
+            }
+        }
+
+        ret = RRMonitorAdd(serverClient, pScreen, monitor);
+        if (ret) {
+            RRMonitorFree(monitor);
+            return;
+        }
+    }
+}
+
 static Bool
 xf86RandR12CreateScreenResources12(ScreenPtr pScreen)
 {
@@ -1579,6 +1643,8 @@ xf86RandR12CreateScreenResources12(ScreenPtr pScreen)
 
     RRScreenSetSizeRange(pScreen, config->minWidth, config->minHeight,
                          config->maxWidth, config->maxHeight);
+
+    xf86RandR12CreateMonitors(pScreen);
     return TRUE;
 }
 
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 438a52a..03974fd 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -1016,6 +1016,15 @@ RRMonitorFreeList(RRMonitorPtr monitors, int nmon);
 void
 RRMonitorClose(ScreenPtr screen);
 
+RRMonitorPtr
+RRMonitorAlloc(int noutput);
+
+int
+RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor);
+
+void
+RRMonitorFree(RRMonitorPtr monitor);
+
 int
 ProcRRGetMonitors(ClientPtr client);
 
diff --git a/randr/rrmonitor.c b/randr/rrmonitor.c
index fbdd352..7e96263 100644
--- a/randr/rrmonitor.c
+++ b/randr/rrmonitor.c
@@ -389,13 +389,13 @@ RRMonitorCountList(ScreenPtr screen)
     return nmon;
 }
 
-static void
+void
 RRMonitorFree(RRMonitorPtr monitor)
 {
     free(monitor);
 }
 
-static RRMonitorPtr
+RRMonitorPtr
 RRMonitorAlloc(int noutput)
 {
     RRMonitorPtr        monitor;
@@ -451,7 +451,7 @@ RRMonitorMatchesOutputName(ScreenPtr screen, Atom name)
     return FALSE;
 }
 
-static int
+int
 RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor)
 {
     rrScrPrivPtr        pScrPriv = rrGetScrPriv(screen);
commit afd18bce6a81106a12fd750d5fa09d05c09d37a8
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Apr 1 14:32:00 2015 +1000

    xf86Crtc: setup tiled monitors correctly in right of
    
    This puts the tiles of the monitor in the right place at
    X server startup.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 8a4ef5e..585bd98 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2128,6 +2128,8 @@ xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
 {
     int o;
     int w = 0;
+    Bool has_tile = FALSE;
+    uint32_t configured_outputs;
 
     if (scrn->preferClone)
         return FALSE;
@@ -2149,16 +2151,75 @@ xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
         return FALSE;
 
     w = 0;
+    configured_outputs = 0;
+
     for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
         DisplayModePtr mode =
             xf86OutputHasPreferredMode(config->output[o], width, height);
 
+        if (configured_outputs & (1 << o))
+            continue;
+
+        if (config->output[o]->tile_info.group_id) {
+            has_tile = TRUE;
+            continue;
+        }
+
         config->output[o]->initial_x = w;
         w += mode->HDisplay;
 
+        configured_outputs |= (1 << o);
         modes[o] = mode;
     }
 
+    if (has_tile) {
+        for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+            int ht, vt, ot;
+            int add_x, cur_x = w;
+            struct xf86CrtcTileInfo *tile_info = &config->output[o]->tile_info, *this_tile;
+            if (configured_outputs & (1 << o))
+                continue;
+            if (!tile_info->group_id)
+                continue;
+
+            if (tile_info->tile_h_loc != 0 && tile_info->tile_v_loc != 0)
+                continue;
+
+            for (ht = 0; ht < tile_info->num_h_tile; ht++) {
+                int cur_y = 0;
+                add_x = 0;
+                for (vt = 0; vt < tile_info->num_v_tile; vt++) {
+
+                    for (ot = -1; nextEnabledOutput(config, enabled, &ot); ) {
+
+                        DisplayModePtr mode =
+                            xf86OutputHasPreferredMode(config->output[ot], width, height);
+                        if (!config->output[ot]->tile_info.group_id)
+                            continue;
+
+                        this_tile = &config->output[ot]->tile_info;
+                        if (this_tile->group_id != tile_info->group_id)
+                            continue;
+
+                        if (this_tile->tile_h_loc != ht ||
+                            this_tile->tile_v_loc != vt)
+                            continue;
+
+                        config->output[ot]->initial_x = cur_x;
+                        config->output[ot]->initial_y = cur_y;
+
+                        if (vt == 0)
+                            add_x = this_tile->tile_h_size;
+                        cur_y += this_tile->tile_v_size;
+                        configured_outputs |= (1 << ot);
+                        modes[ot] = mode;
+                    }
+                }
+                cur_x += add_x;
+            }
+            w = cur_x;
+        }
+    }
     return TRUE;
 }
 
commit e472dd89420f671685c11b06d376ff146d54c3b8
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Jul 28 11:07:13 2009 -0400

    xf86Crtc: right-of placement by default.
    
    Change the X server default to do right-of placement
    at startup. This gives an option to allow drivers to
    override this placement, which has been used for server
    drivers where both heads are not in the same physical
    place.
    
    Been in Fedora for a few years, but for tiled monitors
    we really want something along these lines.
    
    This is an ABI break.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 62c0ce9..a58fafe 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -516,6 +516,9 @@ typedef struct _confdrirec {
 #define NUM_RESERVED_POINTERS		14
 #define NUM_RESERVED_FUNCS		10
 
+/* let clients know they can use this */
+#define XF86_SCRN_HAS_PREFER_CLONE 1
+
 typedef void *(*funcPointer) (void);
 
 /* flags for depth 24 pixmap options */
@@ -772,6 +775,9 @@ typedef struct _ScrnInfoRec {
     ClockRangePtr clockRanges;
     int adjustFlags;
 
+    /* initial rightof support disable */
+    int                 preferClone;
+
     /*
      * These can be used when the minor ABI version is incremented.
      * The NUM_* parameters must be reduced appropriately to keep the
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index a194724..8a4ef5e 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1123,6 +1123,15 @@ xf86InitialOutputPositions(ScrnInfoPtr scrn, DisplayModePtr * modes)
     int o;
     int min_x, min_y;
 
+    /* check for initial right-of heuristic */
+    for (o = 0; o < config->num_output; o++)
+    {
+        xf86OutputPtr output = config->output[o];
+
+        if (output->initial_x || output->initial_y)
+            return TRUE;
+    }
+
     for (o = 0; o < config->num_output; o++) {
         xf86OutputPtr output = config->output[o];
 
@@ -2102,6 +2111,57 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
     return match;
 }
 
+static int
+numEnabledOutputs(xf86CrtcConfigPtr config, Bool *enabled)
+{
+    int i = 0, p;
+
+    for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
+
+    return i;
+}
+
+static Bool
+xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+                  DisplayModePtr *modes, Bool *enabled,
+                  int width, int height)
+{
+    int o;
+    int w = 0;
+
+    if (scrn->preferClone)
+        return FALSE;
+
+    if (numEnabledOutputs(config, enabled) < 2)
+        return FALSE;
+
+    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+        DisplayModePtr mode =
+            xf86OutputHasPreferredMode(config->output[o], width, height);
+
+        if (!mode)
+            return FALSE;
+
+        w += mode->HDisplay;
+    }
+
+    if (w > width)
+        return FALSE;
+
+    w = 0;
+    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+        DisplayModePtr mode =
+            xf86OutputHasPreferredMode(config->output[o], width, height);
+
+        config->output[o]->initial_x = w;
+        w += mode->HDisplay;
+
+        modes[o] = mode;
+    }
+
+    return TRUE;
+}
+
 static Bool
 xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
                     DisplayModePtr * modes, Bool *enabled,
@@ -2178,14 +2238,10 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
      */
     if (!ret)
         do {
-            int i = 0;
             float aspect = 0.0;
             DisplayModePtr a = NULL, b = NULL;
 
-            /* count the number of enabled outputs */
-            for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++);
-
-            if (i != 1)
+            if (numEnabledOutputs(config, enabled) != 1)
                 break;
 
             p = -1;
@@ -2491,6 +2547,8 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
     else {
         if (xf86TargetUserpref(scrn, config, modes, enabled, width, height))
             xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n");
+        else if (xf86TargetRightOf(scrn, config, modes, enabled, width, height))
+            xf86DrvMsg(i, X_INFO, "Using spanning desktop for initial modes\n");
         else if (xf86TargetPreferred
                  (scrn, config, modes, enabled, width, height))
             xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n");
@@ -2510,9 +2568,11 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
                        "Output %s enabled but has no modes\n",
                        config->output[o]->name);
         else
-            xf86DrvMsg(scrn->scrnIndex, X_INFO,
-                       "Output %s using initial mode %s\n",
-                       config->output[o]->name, modes[o]->name);
+            xf86DrvMsg (scrn->scrnIndex, X_INFO,
+                        "Output %s using initial mode %s +%d+%d\n",
+                        config->output[o]->name, modes[o]->name,
+                        config->output[o]->initial_x,
+                        config->output[o]->initial_y);
     }
 
     /*
commit 69e4b8e602ecc7b69c75988a447ec5b509b22402
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Mar 31 16:56:42 2015 +1000

    xfree86: attempt to autoconfig gpu slave devices (v3)
    
    This allows us to skip the screen section, the first
    Device section will get assigned to the screen,
    any remaining ones will get assigned to the GPUDevice
    sections for the screen.
    
    v2: fix the skipping unsuitable screen logic (Aaron)
    v3: fix segfault if not conf file (me, 5s after sending v2)
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 88225a2..7d4ec3d 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1825,13 +1825,34 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
         screenp->device = NULL;
     }
 
-    for (i = 0; i < conf_screen->num_gpu_devices; i++) {
-        screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
-        if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
-            screenp->gpu_devices[i]->myScreenSection = screenp;
+    if (conf_screen->num_gpu_devices == 0 && xf86configptr->conf_device_lst) {
+        XF86ConfDevicePtr sdevice = xf86configptr->conf_device_lst->list.next;
+
+        for (i = 0; i < MAX_GPUDEVICES; i++) {
+            if (!sdevice)
+                break;
+
+            FIND_SUITABLE (XF86ConfDevicePtr, sdevice, conf_screen->scrn_gpu_devices[i]);
+            if (!conf_screen->scrn_gpu_devices[i])
+                break;
+            screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
+            if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
+                screenp->gpu_devices[i]->myScreenSection = screenp;
+            }
+            sdevice = conf_screen->scrn_gpu_devices[i]->list.next;
         }
+        screenp->num_gpu_devices = i;
+
+    } else {
+        for (i = 0; i < conf_screen->num_gpu_devices; i++) {
+            screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
+            if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
+                screenp->gpu_devices[i]->myScreenSection = screenp;
+            }
+        }
+        screenp->num_gpu_devices = conf_screen->num_gpu_devices;
     }
-    screenp->num_gpu_devices = conf_screen->num_gpu_devices;
+
     screenp->options = conf_screen->scrn_option_lst;
 
     /*
commit 3b6930c5d02d8fc0d22fe7955e1ef2af61727705
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Mar 31 16:42:36 2015 +1000

    xserver: add xorg.conf support for gpu devices. (v2.1)
    
    This allows gpu devices to be specified in xorg.conf Screen sections.
    
    Section "Device"
            Driver "intel"
            Identifier "intel0"
            Option "AccelMethod" "uxa"
    EndSection
    
    Section "Device"
            Driver "modesetting"
            Identifier "usb0"
    EndSection
    
    Section "Screen"
            Identifier "screen"
            Device "intel0"
            GPUDevice "usb0"
    EndSection
    
    This should allow for easier tweaking of driver options which
    currently mess up the GPU device discovery process.
    
    v2: add error handling for more than 4 devices, (Emil)
    fixup CONF_ defines to consistency
    add MAX_GPUDEVICES define
    (yes there is two defines, this is consistent
    with everywhere else).
    remove braces around slp (Mark Kettenis)
    man page fixups (Aaron)
    v2.1: fixup whitespace (Aaron)
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index d42572f..88225a2 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -126,7 +126,7 @@ static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
                          int scrnum, MessageType from);
 static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
 static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
-                         Bool active);
+                         Bool active, Bool gpu);
 static Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input,
                         MessageType from);
 static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
@@ -390,7 +390,7 @@ const char **
 xf86DriverlistFromConfig(void)
 {
     int count = 0;
-    int j;
+    int j, k;
     const char **modulearray;
     screenLayoutPtr slp;
 
@@ -411,8 +411,10 @@ xf86DriverlistFromConfig(void)
      */
     if (xf86ConfigLayout.screens) {
         slp = xf86ConfigLayout.screens;
-        while ((slp++)->screen) {
+        while (slp->screen) {
             count++;
+            count += slp->screen->num_gpu_devices;
+            slp++;
         }
     }
 
@@ -435,6 +437,10 @@ xf86DriverlistFromConfig(void)
     while (slp->screen) {
         modulearray[count] = slp->screen->device->driver;
         count++;
+        for (k = 0; k < slp->screen->num_gpu_devices; k++) {
+            modulearray[count] = slp->screen->gpu_devices[k]->driver;
+            count++;
+        }
         slp++;
     }
 
@@ -1631,7 +1637,7 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
     idp = conf_layout->lay_inactive_lst;
     count = 0;
     while (idp) {
-        if (!configDevice(&gdp[count], idp->inactive_device, FALSE))
+        if (!configDevice(&gdp[count], idp->inactive_device, FALSE, FALSE))
             goto bail;
         count++;
         idp = (XF86ConfInactivePtr) idp->list.next;
@@ -1769,6 +1775,7 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
     XF86ConfAdaptorLinkPtr conf_adaptor;
     Bool defaultMonitor = FALSE;
     XF86ConfScreenRec local_conf_screen;
+    int i;
 
     if (!conf_screen) {
         memset(&local_conf_screen, 0, sizeof(local_conf_screen));
@@ -1811,12 +1818,20 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
         xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
                 "\tUsing the first device section listed.\n", screenp->id);
     }
-    if (configDevice(screenp->device, conf_screen->scrn_device, TRUE)) {
+    if (configDevice(screenp->device, conf_screen->scrn_device, TRUE, FALSE)) {
         screenp->device->myScreenSection = screenp;
     }
     else {
         screenp->device = NULL;
     }
+
+    for (i = 0; i < conf_screen->num_gpu_devices; i++) {
+        screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
+        if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
+            screenp->gpu_devices[i]->myScreenSection = screenp;
+        }
+    }
+    screenp->num_gpu_devices = conf_screen->num_gpu_devices;
     screenp->options = conf_screen->scrn_option_lst;
 
     /*
@@ -2110,7 +2125,7 @@ configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
 }
 
 static Bool
-configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
+configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active, Bool gpu)
 {
     int i;
 
@@ -2118,10 +2133,14 @@ configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
         return FALSE;
     }
 
-    if (active)
-        xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
-                conf_device->dev_identifier);
-    else
+    if (active) {
+        if (gpu)
+            xf86Msg(X_CONFIG, "|   |-->GPUDevice \"%s\"\n",
+                    conf_device->dev_identifier);
+        else
+            xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
+                    conf_device->dev_identifier);
+    } else
         xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
                 conf_device->dev_identifier);
 
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index e2b32a0..7321a1a 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -1367,7 +1367,7 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
 {
     GDevPtr gdp, *pgdp = NULL;
     confScreenPtr screensecptr;
-    int i, j;
+    int i, j, k;
 
     if (sectlist)
         *sectlist = NULL;
@@ -1411,6 +1411,17 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
             pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
             pgdp[i++] = screensecptr->device;
         }
+        for (k = 0; k < screensecptr->num_gpu_devices; k++) {
+            if ((screensecptr->gpu_devices[k]->driver != NULL)
+            && (xf86NameCmp(screensecptr->gpu_devices[k]->driver, drivername) == 0)
+                && (!screensecptr->gpu_devices[k]->claimed)) {
+                /*
+                 * we have a matching driver that wasn't claimed, yet
+                 */
+                pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
+                pgdp[i++] = screensecptr->gpu_devices[k];
+            }
+        }
     }
 
     /* Then handle the inactive devices */
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 643a65d..62c0ce9 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -440,6 +440,7 @@ typedef struct _confxvadaptrec {
     void *options;
 } confXvAdaptorRec, *confXvAdaptorPtr;
 
+#define MAX_GPUDEVICES 4
 typedef struct _confscreenrec {
     const char *id;
     int screennum;
@@ -453,6 +454,9 @@ typedef struct _confscreenrec {
     int numxvadaptors;
     confXvAdaptorPtr xvadaptors;
     void *options;
+
+    int num_gpu_devices;
+    GDevPtr gpu_devices[MAX_GPUDEVICES];
 } confScreenRec, *confScreenPtr;
 
 typedef enum {
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
index d26c3cc..e9b6d99 100644
--- a/hw/xfree86/man/xorg.conf.man
+++ b/hw/xfree86/man/xorg.conf.man
@@ -1906,6 +1906,7 @@ sections have the following format:
 .B  "Section \*qScreen\*q"
 .BI "    Identifier \*q" name \*q
 .BI "    Device     \*q" devid \*q
+.BI "    GPUDevice  \*q" devid \*q
 .BI "    Monitor    \*q" monid \*q
 .I  "    entries"
 .I  "    ..."
@@ -1949,6 +1950,18 @@ of a
 .B Device
 section in the config file.
 .TP 7
+.BI "GPUDevice  \*q" device\-id \*q
+This entry specifies the
+.B Device
+section to be used as a secondary GPU device for this screen.  When multiple graphics cards are
+present, this is what ties a specific secondary card to a screen.  The
+.I device\-id
+must match the
+.B Identifier
+of a
+.B Device
+section in the config file. This can be specified up to 4 times for a single screen.
+.TP 7
 .BI "Monitor  \*q" monitor\-id \*q
 specifies which monitor description is to be used for this screen.
 If a
diff --git a/hw/xfree86/parser/Configint.h b/hw/xfree86/parser/Configint.h
index 31035ae..e5fa6ce 100644
--- a/hw/xfree86/parser/Configint.h
+++ b/hw/xfree86/parser/Configint.h
@@ -204,6 +204,8 @@ else\
 "Multiple \"%s\" lines."
 #define MUST_BE_OCTAL_MSG \
 "The number \"%d\" given in this section must be in octal (0xxx) format."
+#define GPU_DEVICE_TOO_MANY \
+"More than %d GPU devices defined."
 
 /* Warning messages */
 #define OBSOLETE_MSG \
diff --git a/hw/xfree86/parser/Screen.c b/hw/xfree86/parser/Screen.c
index 9d8eda2..b5b454f 100644
--- a/hw/xfree86/parser/Screen.c
+++ b/hw/xfree86/parser/Screen.c
@@ -211,6 +211,7 @@ static xf86ConfigSymTabRec ScreenTab[] = {
     {DEFAULTFBBPP, "defaultfbbpp"},
     {VIRTUAL, "virtual"},
     {OPTION, "option"},
+    {GDEVICE, "gpudevice"},
     {-1, ""},
 };
 
@@ -270,6 +271,13 @@ xf86parseScreenSection(void)
                 Error(QUOTE_MSG, "Device");
             ptr->scrn_device_str = xf86_lex_val.str;
             break;
+        case GDEVICE:
+            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
+                Error(QUOTE_MSG, "GPUDevice");
+            if (ptr->num_gpu_devices == CONF_MAXGPUDEVICES)
+                Error(GPU_DEVICE_TOO_MANY, CONF_MAXGPUDEVICES);
+            ptr->scrn_gpu_device_str[ptr->num_gpu_devices++] = xf86_lex_val.str;
+            break;
         case MONITOR:
             if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
                 Error(QUOTE_MSG, "Monitor");
@@ -342,7 +350,7 @@ xf86printScreenSection(FILE * cf, XF86ConfScreenPtr ptr)
     XF86ConfAdaptorLinkPtr aptr;
     XF86ConfDisplayPtr dptr;
     XF86ModePtr mptr;
-
+    int i;
     while (ptr) {
         fprintf(cf, "Section \"Screen\"\n");
         if (ptr->scrn_comment)
@@ -353,6 +361,9 @@ xf86printScreenSection(FILE * cf, XF86ConfScreenPtr ptr)
             fprintf(cf, "\tDriver     \"%s\"\n", ptr->scrn_obso_driver);
         if (ptr->scrn_device_str)
             fprintf(cf, "\tDevice     \"%s\"\n", ptr->scrn_device_str);
+        for (i = 0; i < ptr->num_gpu_devices; i++)
+            if (ptr->scrn_gpu_device_str[i])
+                fprintf(cf, "\tGPUDevice     \"%s\"\n", ptr->scrn_gpu_device_str[i]);
         if (ptr->scrn_monitor_str)
             fprintf(cf, "\tMonitor    \"%s\"\n", ptr->scrn_monitor_str);
         if (ptr->scrn_defaultdepth)
@@ -426,11 +437,13 @@ void
 xf86freeScreenList(XF86ConfScreenPtr ptr)
 {
     XF86ConfScreenPtr prev;
-
+    int i;
     while (ptr) {
         TestFree(ptr->scrn_identifier);
         TestFree(ptr->scrn_monitor_str);
         TestFree(ptr->scrn_device_str);
+        for (i = 0; i < ptr->num_gpu_devices; i++)
+            TestFree(ptr->scrn_gpu_device_str[i]);
         TestFree(ptr->scrn_comment);
         xf86optionListFree(ptr->scrn_option_lst);
         xf86freeAdaptorLinkList(ptr->scrn_adaptor_lst);
@@ -487,6 +500,7 @@ xf86validateScreen(XF86ConfigPtr p)
     XF86ConfScreenPtr screen = p->conf_screen_lst;
     XF86ConfMonitorPtr monitor;
     XF86ConfAdaptorLinkPtr adaptor;
+    int i;
 
     while (screen) {
         if (screen->scrn_obso_driver && !screen->scrn_identifier)
@@ -505,6 +519,10 @@ xf86validateScreen(XF86ConfigPtr p)
         screen->scrn_device =
             xf86findDevice(screen->scrn_device_str, p->conf_device_lst);
 
+        for (i = 0; i < screen->num_gpu_devices; i++) {
+            screen->scrn_gpu_devices[i] =
+                xf86findDevice(screen->scrn_gpu_device_str[i], p->conf_device_lst);
+        }
         adaptor = screen->scrn_adaptor_lst;
         while (adaptor) {
             adaptor->al_adaptor =
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index 43e1755..b3a50e5 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -259,6 +259,7 @@ typedef struct {
     XF86ConfVideoAdaptorPtr al_adaptor;
 } XF86ConfAdaptorLinkRec, *XF86ConfAdaptorLinkPtr;
 
+#define CONF_MAXGPUDEVICES 4
 typedef struct {
     GenericListRec list;
     const char *scrn_identifier;
@@ -276,6 +277,10 @@ typedef struct {
     char *scrn_comment;
     int scrn_virtualX, scrn_virtualY;
     char *match_seat;
+
+    int num_gpu_devices;
+    const char *scrn_gpu_device_str[CONF_MAXGPUDEVICES];
+    XF86ConfDevicePtr scrn_gpu_devices[CONF_MAXGPUDEVICES];
 } XF86ConfScreenRec, *XF86ConfScreenPtr;
 
 typedef struct {
diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
index 9c44970..bbd6b90 100644
--- a/hw/xfree86/parser/xf86tokens.h
+++ b/hw/xfree86/parser/xf86tokens.h
@@ -143,6 +143,7 @@ typedef enum {
     /* Screen tokens */
     OBSDRIVER,
     MDEVICE,
+    GDEVICE,
     MONITOR,
     SCREENNO,
     DEFAULTDEPTH,
commit c7b49bdbb9321fe9a7dc35f47b91cac85516988f
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Fri Mar 20 14:25:17 2015 +0000

    os/utils.c: Fix prototype for Win32TempDir()
    
    xorg/xserver/os/utils.c: In function ‘Win32TempDir’:
    xorg/xserver/os/utils.c:1643:1: warning: old-style function definition [-Wold-style-definition]
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>

diff --git a/os/utils.c b/os/utils.c
index 74d73b3..6116697 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1640,7 +1640,7 @@ Fclose(void *iop)
 #include <X11/Xwindows.h>
 
 const char *
-Win32TempDir()
+Win32TempDir(void)
 {
     static char buffer[PATH_MAX];
 
commit a9b4b7b79682dd367ce26c29aa5dc85807201851
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Fri Mar 20 14:25:53 2015 +0000

    os/utils.c: Don't try to build os_move_fd() for WIN32
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>

diff --git a/os/utils.c b/os/utils.c
index 75769f1..74d73b3 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -2091,6 +2091,7 @@ FormatUInt64Hex(uint64_t num, char *string)
     string[len] = '\0';
 }
 
+#if !defined(WIN32) || defined(__CYGWIN__)
 /* Move a file descriptor out of the way of our select mask; this
  * is useful for file descriptors which will never appear in the
  * select mask to avoid reducing the number of clients that can
@@ -2114,3 +2115,4 @@ os_move_fd(int fd)
     close(fd);
     return newfd;
 }
+#endif
commit 2b114d6a516ee584ff89b96b12acf91799b6d677
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Fri Mar 20 14:29:58 2015 +0000

    hw/xnest: Fix build for MinGW
    
    Include the wrapped windows.h via X11/Xwindows.h before xcb_keysyms.h to avoid
    type clashes caused by the unwrapped windows.h that includes.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c
index ee3f68e..ae8375e 100644
--- a/hw/xnest/Keyboard.c
+++ b/hw/xnest/Keyboard.c
@@ -16,6 +16,10 @@ is" without express or implied warranty.
 #include <xnest-config.h>
 #endif
 
+#ifdef WIN32
+#include <X11/Xwindows.h>
+#endif
+
 #include <X11/X.h>
 #include <X11/Xproto.h>
 #include <xcb/xcb_keysyms.h>
commit 5bf3e5c8326fb81655827dbd4c527f1a2ba09511
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Mar 18 13:29:22 2015 +0000

    hw/xwin/winclipboard: Link xwinclip with -lpthread
    
    Link xwinclip with -lpthread to fix build for MinGW
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winclipboard/Makefile.am b/hw/xwin/winclipboard/Makefile.am
index b1c95f4..a1079ae 100644
--- a/hw/xwin/winclipboard/Makefile.am
+++ b/hw/xwin/winclipboard/Makefile.am
@@ -19,7 +19,7 @@ xwinclip_SOURCES = xwinclip.c debug.c
 
 xwinclip_CFLAGS = $(XWINMODULES_CFLAGS)
 
-xwinclip_LDADD = libXWinclipboard.la $(XWINMODULES_LIBS) -lgdi32
+xwinclip_LDADD = libXWinclipboard.la $(XWINMODULES_LIBS) -lgdi32 -lpthread
 
 include $(top_srcdir)/manpages.am
 appman_PRE = xwinclip.man
commit 8363ef2764fe9c6877d1cb21d3ce7b6cf869f00d
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Fri Mar 20 14:06:49 2015 +0000

    os/xdmcp.c: Include Xtrans.h when building for WIN32
    
    Xtrans.h must be included on WIN32 to prototype _XSERVTransWSAStartup()
    
    xserver/os/xdmcp.c: In function ‘get_addr_by_name’:
    xserver/os/xdmcp.c:1483:5: error: implicit declaration of function ‘_XSERVTransWSAStartup’ [-Werror=implicit-function-declaration]
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>

diff --git a/os/xdmcp.c b/os/xdmcp.c
index bc5a707..b265db3 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -19,6 +19,10 @@
 
 #ifdef WIN32
 #include <X11/Xwinsock.h>
+#define XSERV_t
+#define TRANS_SERVER
+#define TRANS_REOPEN
+#include <X11/Xtrans/Xtrans.h>
 #endif
 
 #include <X11/Xos.h>
commit 28ff661e73f4bdf0a9b7c84e70fa0a08fd30e482
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Apr 3 19:06:21 2015 -0700

    Remove empty stub of $host_cpu case statement in configure.ac
    
    Left behind when commit 5c12399b6c3a8d moved the xorg_bus_* settings
    elsewhere.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Thomas Klausner <wiz at NetBSD.org>

diff --git a/configure.ac b/configure.ac
index 3028e12..fc15460 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2006,11 +2006,6 @@ if test "x$XORG" = xyes; then
 		;;
 	esac
 
-	case $host_cpu in
-	  i*86)
-		;;
-	esac
-
 	if test "x$DGA" = xauto; then
 		PKG_CHECK_MODULES(DGA, $DGAPROTO, [DGA=yes], [DGA=no])
 	fi
commit d4e85afac6578d5babc8bf97e00e85b00746fca9
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Apr 3 19:01:40 2015 -0700

    Accept x86_64 as well as i*86 for $host_cpu in Solaris on x86
    
    Needed when using a compiler that defaults to 64-bit output when
    configure is checking for $host_cpu.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Thomas Klausner <wiz at NetBSD.org>

diff --git a/configure.ac b/configure.ac
index a5bdbbf..3028e12 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1976,7 +1976,7 @@ if test "x$XORG" = xyes; then
 		  sparc*)	
 			SOLARIS_INOUT_ARCH="sparcv8plus"
 			;;
-		  i*86)	
+		  i*86|x86_64*)
 			if test x$SOLARIS_64 = xyes ; then
 				SOLARIS_INOUT_ARCH="amd64"
 			else
commit 0018784cdde19444a8f970bc414796fc2a523a51
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 17:59:13 2015 -0700

    Convert hw/dmx to new *allocarray functions
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/hw/dmx/config/dmxconfig.c b/hw/dmx/config/dmxconfig.c
index 2cc9ab3..1d10ec0 100644
--- a/hw/dmx/config/dmxconfig.c
+++ b/hw/dmx/config/dmxconfig.c
@@ -204,8 +204,8 @@ dmxConfigAddDisplay(const char *name,
 {
     DMXScreenInfo *dmxScreen;
 
-    if (!(dmxScreens = realloc(dmxScreens,
-                               (dmxNumScreens + 1) * sizeof(*dmxScreens))))
+    if (!(dmxScreens = reallocarray(dmxScreens, dmxNumScreens + 1,
+                                    sizeof(*dmxScreens))))
         dmxLog(dmxFatal,
                "dmxConfigAddDisplay: realloc failed for screen %d (%s)\n",
                dmxNumScreens, name);
@@ -234,8 +234,8 @@ dmxConfigAddInput(const char *name, int core)
 {
     DMXInputInfo *dmxInput;
 
-    if (!(dmxInputs = realloc(dmxInputs,
-                              (dmxNumInputs + 1) * sizeof(*dmxInputs))))
+    if (!(dmxInputs = reallocarray(dmxInputs, dmxNumInputs + 1,
+                                   sizeof(*dmxInputs))))
         dmxLog(dmxFatal,
                "dmxConfigAddInput: realloc failed for input %d (%s)\n",
                dmxNumInputs, name);
@@ -341,7 +341,7 @@ dmxConfigCopyFromOption(DMXConfigOptionPtr o)
     for (pt = o->option; pt; pt = pt->next) {
         if (pt->string) {
             ++argc;
-            argv = realloc(argv, (argc + 1) * sizeof(*argv));
+            argv = reallocarray(argv, argc + 1, sizeof(*argv));
             argv[argc] = (char *) pt->string;
         }
     }
diff --git a/hw/dmx/dmx.c b/hw/dmx/dmx.c
index 2988df3..9729963 100644
--- a/hw/dmx/dmx.c
+++ b/hw/dmx/dmx.c
@@ -427,7 +427,7 @@ ProcDMXChangeScreensAttributes(ClientPtr client)
     if (!_DMXXineramaActive())
         goto noxinerama;
 
-    if (!(attribs = malloc(stuff->screenCount * sizeof(*attribs))))
+    if (!(attribs = xallocarray(stuff->screenCount, sizeof(*attribs))))
         return BadAlloc;
 
     for (i = 0; i < stuff->screenCount; i++) {
@@ -624,18 +624,18 @@ ProcDMXGetWindowAttributes(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
 
-    if (!(screens = malloc(count * sizeof(*screens))))
+    if (!(screens = xallocarray(count, sizeof(*screens))))
         return BadAlloc;
-    if (!(windows = malloc(count * sizeof(*windows)))) {
+    if (!(windows = xallocarray(count, sizeof(*windows)))) {
         free(screens);
         return BadAlloc;
     }
-    if (!(pos = malloc(count * sizeof(*pos)))) {
+    if (!(pos = xallocarray(count, sizeof(*pos)))) {
         free(windows);
         free(screens);
         return BadAlloc;
     }
-    if (!(vis = malloc(count * sizeof(*vis)))) {
+    if (!(vis = xallocarray(count, sizeof(*vis)))) {
         free(pos);
         free(windows);
         free(screens);
diff --git a/hw/dmx/dmxcmap.c b/hw/dmx/dmxcmap.c
index 450627b..7a87a98 100644
--- a/hw/dmx/dmxcmap.c
+++ b/hw/dmx/dmxcmap.c
@@ -177,7 +177,7 @@ dmxStoreColors(ColormapPtr pColormap, int ndef, xColorItem * pdef)
     dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
 
     if (dmxScreen->beDisplay && (pColormap->pVisual->class & DynamicClass)) {
-        XColor *color = malloc(sizeof(*color) * ndef);
+        XColor *color = xallocarray(ndef, sizeof(*color));
         int i;
 
         if (color) {
diff --git a/hw/dmx/dmxcursor.c b/hw/dmx/dmxcursor.c
index 70f2bc4..0ef800e 100644
--- a/hw/dmx/dmxcursor.c
+++ b/hw/dmx/dmxcursor.c
@@ -203,7 +203,7 @@ miPointerScreenFuncRec dmxPointerCursorFuncs = {
 static int *
 dmxSLCreate(void)
 {
-    int *list = malloc(dmxNumScreens * sizeof(*list));
+    int *list = xallocarray(dmxNumScreens, sizeof(*list));
     int i;
 
     for (i = 0; i < dmxNumScreens; i++)
diff --git a/hw/dmx/dmxextension.c b/hw/dmx/dmxextension.c
index fcc97e3..75d7166 100644
--- a/hw/dmx/dmxextension.c
+++ b/hw/dmx/dmxextension.c
@@ -1188,8 +1188,8 @@ dmxBERestoreRenderGlyph(void *value, XID id, void *n)
 
     /* Now allocate the memory we need */
     images = calloc(len_images, sizeof(char));
-    gids = malloc(glyphSet->hash.tableEntries * sizeof(Glyph));
-    glyphs = malloc(glyphSet->hash.tableEntries * sizeof(XGlyphInfo));
+    gids = xallocarray(glyphSet->hash.tableEntries, sizeof(Glyph));
+    glyphs = xallocarray(glyphSet->hash.tableEntries, sizeof(XGlyphInfo));
 
     pos = images;
     ctr = 0;
diff --git a/hw/dmx/dmxfont.c b/hw/dmx/dmxfont.c
index 115422d..25a04a6 100644
--- a/hw/dmx/dmxfont.c
+++ b/hw/dmx/dmxfont.c
@@ -72,7 +72,7 @@ dmxGetFontPath(int *npaths)
 
     newfp = malloc(*npaths + len);
     c = (unsigned char *) newfp;
-    fp = malloc(*npaths * sizeof(*fp));
+    fp = xallocarray(*npaths, sizeof(*fp));
 
     memmove(newfp, paths + 1, *npaths + len - 1);
     l = *paths;
@@ -306,7 +306,7 @@ dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
         if (!dmxFontPath)
             dmxLog(dmxWarning, "No default font path is set.\n");
 
-        goodfps = malloc(npaths * sizeof(*goodfps));
+        goodfps = xallocarray(npaths, sizeof(*goodfps));
 
         dmxLog(dmxError,
                "The DMX server failed to set the following font paths on "
@@ -354,7 +354,7 @@ dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
                 return FALSE;
             }
 
-            newfp = malloc(len * sizeof(*newfp));
+            newfp = xallocarray(len, sizeof(*newfp));
             for (i = 0; i < npaths; i++) {
                 if (goodfps[i]) {
                     int n = strlen(fp[i]);
diff --git a/hw/dmx/dmxgc.c b/hw/dmx/dmxgc.c
index ec15d27..c4789a6 100644
--- a/hw/dmx/dmxgc.c
+++ b/hw/dmx/dmxgc.c
@@ -397,7 +397,7 @@ dmxChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
     } else {
         if (dmxScreen->beDisplay) {
             nRects = RegionNumRects((RegionPtr) pGC->clientClip);
-            pRects = malloc(nRects * sizeof(*pRects));
+            pRects = xallocarray(nRects, sizeof(*pRects));
             pBox = RegionRects((RegionPtr) pGC->clientClip);
 
             for (i = 0; i < nRects; i++) {
diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c
index 025dc86..3d394c5 100644
--- a/hw/dmx/dmxinit.c
+++ b/hw/dmx/dmxinit.c
@@ -438,7 +438,7 @@ dmxGetColormaps(DMXScreenInfo * dmxScreen)
     int i;
 
     dmxScreen->beNumDefColormaps = dmxScreen->beNumVisuals;
-    dmxScreen->beDefColormaps = malloc(dmxScreen->beNumDefColormaps *
+    dmxScreen->beDefColormaps = xallocarray(dmxScreen->beNumDefColormaps,
                                        sizeof(*dmxScreen->beDefColormaps));
 
     for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
@@ -793,7 +793,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
                 nconfigs = dmxScreen->numGlxVisuals;
             }
 
-            configprivs = malloc(nconfigs * sizeof(dmxGlxVisualPrivate *));
+            configprivs = xallocarray(nconfigs, sizeof(dmxGlxVisualPrivate *));
 
             if (configs != NULL && configprivs != NULL) {
                 int j;
diff --git a/hw/dmx/dmxpict.c b/hw/dmx/dmxpict.c
index aaca178..1f1022e 100644
--- a/hw/dmx/dmxpict.c
+++ b/hw/dmx/dmxpict.c
@@ -390,7 +390,7 @@ dmxProcRenderAddGlyphs(ClientPtr client)
                   sizeof(xRenderAddGlyphsReq) -
                   (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs);
 
-        gidsCopy = malloc(sizeof(*gidsCopy) * nglyphs);
+        gidsCopy = xallocarray(nglyphs, sizeof(*gidsCopy));
         for (i = 0; i < nglyphs; i++)
             gidsCopy[i] = gids[i];
 
@@ -434,7 +434,7 @@ dmxProcRenderFreeGlyphs(ClientPtr client)
 
         nglyphs = ((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq)) >> 2;
         if (nglyphs) {
-            gids = malloc(sizeof(*gids) * nglyphs);
+            gids = xallocarray(nglyphs, sizeof(*gids));
             for (i = 0; i < nglyphs; i++)
                 gids[i] = ((CARD32 *) (stuff + 1))[i];
 
@@ -569,11 +569,11 @@ dmxProcRenderCompositeGlyphs(ClientPtr client)
         /* The following only works for Render version > 0.2 */
 
         /* All of the XGlyphElt* structure sizes are identical */
-        elts = malloc(nelt * sizeof(XGlyphElt8));
+        elts = xallocarray(nelt, sizeof(XGlyphElt8));
         if (!elts)
             return BadAlloc;
 
-        glyphs = malloc(nglyph * size);
+        glyphs = xallocarray(nglyph, size);
         if (!glyphs) {
             free(elts);
             return BadAlloc;
@@ -925,7 +925,7 @@ dmxChangePictureClip(PicturePtr pPicture, int clipType, void *value, int n)
             int nRects;
 
             nRects = nBox;
-            pRects = pRect = malloc(nRects * sizeof(*pRect));
+            pRects = pRect = xallocarray(nRects, sizeof(*pRect));
 
             while (nBox--) {
                 pRect->x = pBox->x1;
diff --git a/hw/dmx/dmxprop.c b/hw/dmx/dmxprop.c
index 5e306d2..4c85268 100644
--- a/hw/dmx/dmxprop.c
+++ b/hw/dmx/dmxprop.c
@@ -171,7 +171,7 @@ dmxPropertyCheckOtherServers(DMXScreenInfo * dmxScreen, Atom atom)
                     dmxLogOutputWarning(dmxScreen,
                                         "%s also running on %s\n",
                                         tp.value, dmxScreen->name);
-                    list = realloc(list, ++count * sizeof(*list));
+                    list = reallocarray(list, ++count, sizeof(*list));
                     list[count - 1] = malloc(tp.nitems + 2);
                     strncpy(list[count - 1], (char *) tp.value, tp.nitems + 1);
                 }
diff --git a/hw/dmx/dmxwindow.c b/hw/dmx/dmxwindow.c
index c157e10..dcdb9ac 100644
--- a/hw/dmx/dmxwindow.c
+++ b/hw/dmx/dmxwindow.c
@@ -969,7 +969,7 @@ dmxDoSetShape(WindowPtr pWindow)
     if (wBoundingShape(pWindow)) {
         pBox = RegionRects(wBoundingShape(pWindow));
         nRect = nBox = RegionNumRects(wBoundingShape(pWindow));
-        pRectFirst = pRect = malloc(nRect * sizeof(*pRect));
+        pRectFirst = pRect = xallocarray(nRect, sizeof(*pRect));
         while (nBox--) {
             pRect->x = pBox->x1;
             pRect->y = pBox->y1;
@@ -992,7 +992,7 @@ dmxDoSetShape(WindowPtr pWindow)
     if (wClipShape(pWindow)) {
         pBox = RegionRects(wClipShape(pWindow));
         nRect = nBox = RegionNumRects(wClipShape(pWindow));
-        pRectFirst = pRect = malloc(nRect * sizeof(*pRect));
+        pRectFirst = pRect = xallocarray(nRect, sizeof(*pRect));
         while (nBox--) {
             pRect->x = pBox->x1;
             pRect->y = pBox->y1;
diff --git a/hw/dmx/glxProxy/glxcmds.c b/hw/dmx/glxProxy/glxcmds.c
index 4c500c9..ddcb981 100644
--- a/hw/dmx/glxProxy/glxcmds.c
+++ b/hw/dmx/glxProxy/glxcmds.c
@@ -284,11 +284,11 @@ CreateContext(__GLXclientState * cl,
      * allocate memory for back-end servers info
      */
     num_be_screens = to_screen - from_screen + 1;
-    glxc->real_ids = (XID *) malloc(sizeof(XID) * num_be_screens);
+    glxc->real_ids = xallocarray(num_be_screens, sizeof(XID));
     if (!glxc->real_ids) {
         return BadAlloc;
     }
-    glxc->real_vids = (XID *) malloc(sizeof(XID) * num_be_screens);
+    glxc->real_vids = xallocarray(num_be_screens, sizeof(XID));
     if (!glxc->real_vids) {
         return BadAlloc;
     }
@@ -685,22 +685,16 @@ AddCurrentContext(__GLXclientState * cl, __GLXcontext * glxc, DrawablePtr pDraw)
     if (!num) {
         table = (__GLXcontext **) malloc(sizeof(__GLXcontext *));
         cl->currentDrawables = (DrawablePtr *) malloc(sizeof(DrawablePtr));
-        cl->be_currentCTag =
-            (GLXContextTag *) malloc(screenInfo.numScreens *
-                                     sizeof(GLXContextTag));
+        cl->be_currentCTag = xallocarray(screenInfo.numScreens,
+                                         sizeof(GLXContextTag));
     }
     else {
-        table = (__GLXcontext **) realloc(table,
-                                          (num + 1) * sizeof(__GLXcontext *));
-        cl->currentDrawables = (DrawablePtr *) realloc(cl->currentDrawables,
-                                                       (num +
-                                                        1) *
-                                                       sizeof(DrawablePtr));
-        cl->be_currentCTag =
-            (GLXContextTag *) realloc(cl->be_currentCTag,
-                                      (num +
-                                       1) * screenInfo.numScreens *
-                                      sizeof(GLXContextTag));
+        table = reallocarray(table, num + 1, sizeof(__GLXcontext *));
+        cl->currentDrawables = reallocarray(cl->currentDrawables, num + 1,
+                                            sizeof(DrawablePtr));
+        cl->be_currentCTag = reallocarray(cl->be_currentCTag,
+                                          (num + 1) * screenInfo.numScreens,
+                                          sizeof(GLXContextTag));
     }
     table[num] = glxc;
     cl->currentDrawables[num] = pDraw;
@@ -1896,7 +1890,7 @@ CreateGLXPixmap(__GLXclientState * cl,
     if (!pGlxPixmap) {
         return BadAlloc;
     }
-    pGlxPixmap->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens);
+    pGlxPixmap->be_xids = xallocarray(screenInfo.numScreens, sizeof(XID));
     if (!pGlxPixmap->be_xids) {
         free(pGlxPixmap);
         return BadAlloc;
@@ -3356,7 +3350,7 @@ __glXCreatePbuffer(__GLXclientState * cl, GLbyte * pc)
         return BadAlloc;
     }
 
-    pGlxPbuffer->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens);
+    pGlxPbuffer->be_xids = xallocarray(screenInfo.numScreens, sizeof(XID));
     if (!pGlxPbuffer->be_xids) {
         free(pGlxPbuffer);
         return BadAlloc;
@@ -3617,13 +3611,13 @@ __glXGetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
     }
 
     if (reply.numAttribs) {
-        attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32;
-        attribs = (CARD32 *) malloc(attribs_size);
+        attribs = xallocarray(reply.numAttribs, 2 * __GLX_SIZE_CARD32);
         if (attribs == NULL) {
             UnlockDisplay(dpy);
             SyncHandle();
             return BadAlloc;
         }
+        attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32;
 
         _XRead(dpy, (char *) attribs, attribs_size);
     }
diff --git a/hw/dmx/glxProxy/glxscreens.c b/hw/dmx/glxProxy/glxscreens.c
index 15bb1e8..508e67e 100644
--- a/hw/dmx/glxProxy/glxscreens.c
+++ b/hw/dmx/glxProxy/glxscreens.c
@@ -129,7 +129,7 @@ CalcServerVersionAndExtensions(void)
     /*
      * read extensions strings of all back-end servers
      */
-    be_extensions = (char **) malloc(__glXNumActiveScreens * sizeof(char *));
+    be_extensions = xallocarray(__glXNumActiveScreens, sizeof(char *));
     if (!be_extensions)
         return;
 
@@ -237,10 +237,9 @@ __glXScreenInit(GLint numscreens)
            // find the set of FBConfigs that are present on all back-end
            // servers - only those configs will be supported
          */
-        __glXFBConfigs = (__GLXFBConfig **) malloc(dmxScreen0->numFBConfigs *
-                                                   (numscreens +
-                                                    1) *
-                                                   sizeof(__GLXFBConfig *));
+        __glXFBConfigs =
+            xallocarray(dmxScreen0->numFBConfigs * (numscreens + 1),
+                        sizeof(__GLXFBConfig *));
         __glXNumFBConfigs = 0;
 
         for (c = 0; c < dmxScreen0->numFBConfigs; c++) {
diff --git a/hw/dmx/input/dmxarg.c b/hw/dmx/input/dmxarg.c
index 4a74b4c..6c21ae9 100644
--- a/hw/dmx/input/dmxarg.c
+++ b/hw/dmx/input/dmxarg.c
@@ -86,7 +86,7 @@ void
 dmxArgAdd(dmxArg a, const char *string)
 {
     if (a->argm <= a->argc + 2)
-        a->argv = realloc(a->argv, sizeof(*a->argv) * (a->argm *= 2));
+        a->argv = reallocarray(a->argv, (a->argm *= 2), sizeof(*a->argv));
     a->argv[a->argc++] = strdup(string);
     a->argv[a->argc] = NULL;
 }
diff --git a/hw/dmx/input/dmxinputinit.c b/hw/dmx/input/dmxinputinit.c
index 56a39df..cdefd9a 100644
--- a/hw/dmx/input/dmxinputinit.c
+++ b/hw/dmx/input/dmxinputinit.c
@@ -814,8 +814,8 @@ dmxInputCopyLocal(DMXInputInfo * dmxInput, DMXLocalInputInfoPtr s)
     dmxLocal->deviceId = -1;
 
     ++dmxInput->numDevs;
-    dmxInput->devs = realloc(dmxInput->devs,
-                             dmxInput->numDevs * sizeof(*dmxInput->devs));
+    dmxInput->devs = reallocarray(dmxInput->devs,
+                                  dmxInput->numDevs, sizeof(*dmxInput->devs));
     dmxInput->devs[dmxInput->numDevs - 1] = dmxLocal;
 
     return dmxLocal;
diff --git a/hw/dmx/input/dmxmotion.c b/hw/dmx/input/dmxmotion.c
index 1642894..7f2cb8e 100644
--- a/hw/dmx/input/dmxmotion.c
+++ b/hw/dmx/input/dmxmotion.c
@@ -113,9 +113,8 @@ dmxPointerPutMotionEvent(DeviceIntPtr pDevice,
     int i;
 
     if (!dmxLocal->history) {
-        dmxLocal->history = malloc(sizeof(*dmxLocal->history)
-                                   * (numAxes + 1)
-                                   * DMX_MOTION_SIZE);
+        dmxLocal->history = xallocarray(numAxes + 1,
+                                 sizeof(*dmxLocal->history) * DMX_MOTION_SIZE);
         dmxLocal->head = 0;
         dmxLocal->tail = 0;
         dmxLocal->valuators = calloc(sizeof(*dmxLocal->valuators), numAxes);
commit dc5acaa28ab9ed091f087e56046400d63f1f192a
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 17:30:05 2015 -0700

    Convert hw/kdrive to new *allocarray functions
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index 3d5cf77..748b608 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -431,8 +431,8 @@ EphyrDuplicateVisual(unsigned int a_screen,
          * extend the list of visual IDs in that entry,
          * so to add a_new_id in there.
          */
-        vids = realloc(cur_depth->vids,
-                       (cur_depth->numVids + 1) * sizeof(VisualID));
+        vids = reallocarray(cur_depth->vids,
+                            cur_depth->numVids + 1, sizeof(VisualID));
         if (!vids) {
             EPHYR_LOG_ERROR("failed to realloc numids\n");
             goto out;
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index c67ff60..7163af0 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -129,8 +129,8 @@ hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num, Boo
     int index = HostX.n_screens;
 
     HostX.n_screens += 1;
-    HostX.screens = realloc(HostX.screens,
-                            HostX.n_screens * sizeof(HostX.screens[0]));
+    HostX.screens = reallocarray(HostX.screens,
+                                 HostX.n_screens, sizeof(HostX.screens[0]));
     HostX.screens[index] = screen;
 
     scrpriv->screen = screen;
@@ -867,7 +867,7 @@ hostx_screen_init(KdScreenInfo *screen,
                                                     NULL);
 
         scrpriv->ximg->data =
-            malloc(scrpriv->ximg->stride * buffer_height);
+            xallocarray(scrpriv->ximg->stride, buffer_height);
     }
 
     {
@@ -933,7 +933,7 @@ hostx_screen_init(KdScreenInfo *screen,
         *bits_per_pixel = scrpriv->server_depth;
 
         EPHYR_DBG("server bpp %i", bytes_per_pixel);
-        scrpriv->fb_data = malloc (stride * buffer_height);
+        scrpriv->fb_data = xallocarray (stride, buffer_height);
         return scrpriv->fb_data;
     }
 }
@@ -1148,9 +1148,9 @@ hostx_get_visuals_info(EphyrHostVisualInfo ** a_visuals, int *a_num_entries)
         for (; depths.rem; xcb_depth_next(&depths)) {
             xcb_visualtype_t *visuals = xcb_depth_visuals(depths.data);
             EphyrHostVisualInfo *tmp_visuals =
-                realloc(host_visuals,
-                        (nb_items + depths.data->visuals_len)
-                        * sizeof(EphyrHostVisualInfo));
+                reallocarray(host_visuals,
+                             nb_items + depths.data->visuals_len,
+                             sizeof(EphyrHostVisualInfo));
             if (!tmp_visuals) {
                 goto out;
             }
diff --git a/hw/kdrive/fake/fake.c b/hw/kdrive/fake/fake.c
index 90e3ec9..04a7278 100644
--- a/hw/kdrive/fake/fake.c
+++ b/hw/kdrive/fake/fake.c
@@ -158,7 +158,7 @@ fakeMapFramebuffer(KdScreenInfo * screen)
     priv->bytes_per_line =
         ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2;
     free(priv->base);
-    priv->base = malloc(priv->bytes_per_line * screen->height);
+    priv->base = xallocarray(priv->bytes_per_line, screen->height);
 
     if (scrpriv->shadow) {
         if (!KdShadowFbAlloc
diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c
index 95f64cb..23f7509 100644
--- a/hw/kdrive/fbdev/fbdev.c
+++ b/hw/kdrive/fbdev/fbdev.c
@@ -677,7 +677,7 @@ fbdevCreateColormap(ColormapPtr pmap)
     case FB_VISUAL_STATIC_PSEUDOCOLOR:
         pVisual = pmap->pVisual;
         nent = pVisual->ColormapEntries;
-        pdefs = malloc(nent * sizeof(xColorItem));
+        pdefs = xallocarray(nent, sizeof(xColorItem));
         if (!pdefs)
             return FALSE;
         for (i = 0; i < nent; i++)
diff --git a/hw/kdrive/src/kshadow.c b/hw/kdrive/src/kshadow.c
index 828ea19..7f1e2ee 100644
--- a/hw/kdrive/src/kshadow.c
+++ b/hw/kdrive/src/kshadow.c
@@ -36,7 +36,7 @@ KdShadowFbAlloc(KdScreenInfo * screen, Bool rotate)
 
     /* use fb computation for width */
     paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
-    buf = malloc(paddedWidth * height);
+    buf = xallocarray(paddedWidth, height);
     if (!buf)
         return FALSE;
     if (screen->fb.shadow)
diff --git a/hw/kdrive/src/kxv.c b/hw/kdrive/src/kxv.c
index 369db33..844deca 100644
--- a/hw/kdrive/src/kxv.c
+++ b/hw/kdrive/src/kxv.c
@@ -327,8 +327,8 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr infoPtr, int number)
                         void *moreSpace;
 
                         totFormat *= 2;
-                        moreSpace = realloc(pFormat,
-                                            totFormat * sizeof(XvFormatRec));
+                        moreSpace = reallocarray(pFormat, totFormat,
+                                                 sizeof(XvFormatRec));
                         if (!moreSpace)
                             break;
                         pFormat = moreSpace;
commit ae2dc01cf1a371db69d5deb987f4185e7c3ccedd
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 17:23:33 2015 -0700

    Convert hw/xnest & hw/vfb to new *allocarray functions
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index bcaaa85..8b867e3 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -292,7 +292,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
 
         if (vfbNumScreens <= screenNum) {
             vfbScreens =
-                realloc(vfbScreens, sizeof(*vfbScreens) * (screenNum + 1));
+                reallocarray(vfbScreens, screenNum + 1, sizeof(*vfbScreens));
             if (!vfbScreens)
                 FatalError("Not enough memory for screen %d\n", screenNum);
             for (; vfbNumScreens <= screenNum; ++vfbNumScreens)
@@ -407,9 +407,9 @@ vfbInstallColormap(ColormapPtr pmap)
         swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
         swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
 
-        ppix = (Pixel *) malloc(entries * sizeof(Pixel));
-        prgb = (xrgb *) malloc(entries * sizeof(xrgb));
-        defs = (xColorItem *) malloc(entries * sizeof(xColorItem));
+        ppix = xallocarray(entries, sizeof(Pixel));
+        prgb = xallocarray(entries, sizeof(xrgb));
+        defs = xallocarray(entries, sizeof(xColorItem));
 
         for (i = 0; i < entries; i++)
             ppix[i] = i;
diff --git a/hw/xnest/Color.c b/hw/xnest/Color.c
index 8d9d356..3a9e422 100644
--- a/hw/xnest/Color.c
+++ b/hw/xnest/Color.c
@@ -62,7 +62,7 @@ xnestCreateColormap(ColormapPtr pCmap)
 
     switch (pVisual->class) {
     case StaticGray:           /* read only */
-        colors = (XColor *) malloc(ncolors * sizeof(XColor));
+        colors = xallocarray(ncolors, sizeof(XColor));
         for (i = 0; i < ncolors; i++)
             colors[i].pixel = i;
         XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
@@ -75,7 +75,7 @@ xnestCreateColormap(ColormapPtr pCmap)
         break;
 
     case StaticColor:          /* read only */
-        colors = (XColor *) malloc(ncolors * sizeof(XColor));
+        colors = xallocarray(ncolors, sizeof(XColor));
         for (i = 0; i < ncolors; i++)
             colors[i].pixel = i;
         XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
@@ -88,7 +88,7 @@ xnestCreateColormap(ColormapPtr pCmap)
         break;
 
     case TrueColor:            /* read only */
-        colors = (XColor *) malloc(ncolors * sizeof(XColor));
+        colors = xallocarray(ncolors, sizeof(XColor));
         red = green = blue = 0L;
         redInc = lowbit(pVisual->redMask);
         greenInc = lowbit(pVisual->greenMask);
@@ -194,14 +194,12 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
     xnestInstalledColormapWindows icws;
     int numWindows;
 
-    icws.cmapIDs = (Colormap *) malloc(pScreen->maxInstalledCmaps *
-                                       sizeof(Colormap));
+    icws.cmapIDs = xallocarray(pScreen->maxInstalledCmaps, sizeof(Colormap));
     icws.numCmapIDs = xnestListInstalledColormaps(pScreen, icws.cmapIDs);
     icws.numWindows = 0;
     WalkTree(pScreen, xnestCountInstalledColormapWindows, (void *) &icws);
     if (icws.numWindows) {
-        icws.windows =
-            (Window *) malloc((icws.numWindows + 1) * sizeof(Window));
+        icws.windows = xallocarray(icws.numWindows + 1, sizeof(Window));
         icws.index = 0;
         WalkTree(pScreen, xnestGetInstalledColormapWindows, (void *) &icws);
         icws.windows[icws.numWindows] = xnestDefaultWindows[pScreen->myNum];
@@ -220,8 +218,7 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
 #ifdef _XSERVER64
         {
             int i;
-            Window64 *windows =
-                (Window64 *) malloc(numWindows * sizeof(Window64));
+            Window64 *windows = xallocarray(numWindows, sizeof(Window64));
 
             for (i = 0; i < numWindows; ++i)
                 windows[i] = icws.windows[i];
@@ -393,7 +390,7 @@ xnestStoreColors(ColormapPtr pCmap, int nColors, xColorItem * pColors)
 #ifdef _XSERVER64
     {
         int i;
-        XColor *pColors64 = (XColor *) malloc(nColors * sizeof(XColor));
+        XColor *pColors64 = xallocarray(nColors, sizeof(XColor));
 
         for (i = 0; i < nColors; ++i) {
             pColors64[i].pixel = pColors[i].pixel;
diff --git a/hw/xnest/Display.c b/hw/xnest/Display.c
index a2f8acb..e6d07df 100644
--- a/hw/xnest/Display.c
+++ b/hw/xnest/Display.c
@@ -121,8 +121,8 @@ xnestOpenDisplay(int argc, char *argv[])
     }
 
     xnestNumDefaultColormaps = xnestNumVisuals;
-    xnestDefaultColormaps = (Colormap *) malloc(xnestNumDefaultColormaps *
-                                                sizeof(Colormap));
+    xnestDefaultColormaps = xallocarray(xnestNumDefaultColormaps,
+                                        sizeof(Colormap));
     for (i = 0; i < xnestNumDefaultColormaps; i++)
         xnestDefaultColormaps[i] = XCreateColormap(xnestDisplay,
                                                    DefaultRootWindow
diff --git a/hw/xnest/GC.c b/hw/xnest/GC.c
index 96af6eb..ecfa61e 100644
--- a/hw/xnest/GC.c
+++ b/hw/xnest/GC.c
@@ -190,7 +190,7 @@ xnestDestroyGC(GCPtr pGC)
 void
 xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects)
 {
-    int i, size;
+    int i;
     BoxPtr pBox;
     XRectangle *pRects;
 
@@ -204,8 +204,7 @@ xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects)
 
     case CT_REGION:
         nRects = RegionNumRects((RegionPtr) pValue);
-        size = nRects * sizeof(*pRects);
-        pRects = (XRectangle *) malloc(size);
+        pRects = xallocarray(nRects, sizeof(*pRects));
         pBox = RegionRects((RegionPtr) pValue);
         for (i = nRects; i-- > 0;) {
             pRects[i].x = pBox[i].x1;
diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c
index ee3f68e..002885f 100644
--- a/hw/xnest/Keyboard.c
+++ b/hw/xnest/Keyboard.c
@@ -134,7 +134,7 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
                                            max_keycode - min_keycode + 1,
                                            &mapWidth);
             len = (max_keycode - min_keycode + 1) * mapWidth;
-            keymap = (KeySym *) malloc(len * sizeof(KeySym));
+            keymap = xallocarray(len, sizeof(KeySym));
             for (i = 0; i < len; ++i)
                 keymap[i] = keymap64[i];
             XFree(keymap64);
diff --git a/hw/xnest/Screen.c b/hw/xnest/Screen.c
index abb4d37..214b550 100644
--- a/hw/xnest/Screen.c
+++ b/hw/xnest/Screen.c
@@ -158,7 +158,7 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
     if (!dixRegisterPrivateKey(&xnestCursorScreenKeyRec, PRIVATE_SCREEN, 0))
         return FALSE;
 
-    visuals = (VisualPtr) malloc(xnestNumVisuals * sizeof(VisualRec));
+    visuals = xallocarray(xnestNumVisuals, sizeof(VisualRec));
     numVisuals = 0;
 
     depths = (DepthPtr) malloc(MAXDEPTH * sizeof(DepthRec));
@@ -224,7 +224,7 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
 
         numVisuals++;
     }
-    visuals = (VisualPtr) realloc(visuals, numVisuals * sizeof(VisualRec));
+    visuals = reallocarray(visuals, numVisuals, sizeof(VisualRec));
 
     defaultVisual = visuals[xnestDefaultVisualIndex].vid;
     rootDepth = visuals[xnestDefaultVisualIndex].nplanes;
commit 4cb1034906eeec8c8442d70918bea0f4eb1f6e44
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 17:12:06 2015 -0700

    Convert hw/xfree86 to new *allocarray functions
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 1450afb..6b8d0eb 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -105,7 +105,7 @@ AppendToList(const char *s, const char ***list, int *lines)
     str = xnfstrdup(s);
     for (p = strtok(str, "\n"); p; p = strtok(NULL, "\n")) {
         (*lines)++;
-        *list = xnfrealloc(*list, (*lines + 1) * sizeof(**list));
+        *list = xnfreallocarray(*list, *lines + 1, sizeof(**list));
         newstr = xnfalloc(strlen(p) + 2);
         strcpy(newstr, p);
         strcat(newstr, "\n");
diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 02f7bf2..bd36fc5 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -256,8 +256,8 @@ int
 xf86AllocateEntity(void)
 {
     xf86NumEntities++;
-    xf86Entities = xnfrealloc(xf86Entities,
-                              sizeof(EntityPtr) * xf86NumEntities);
+    xf86Entities = xnfreallocarray(xf86Entities,
+                                   xf86NumEntities, sizeof(EntityPtr));
     xf86Entities[xf86NumEntities - 1] = xnfcalloc(1, sizeof(EntityRec));
     xf86Entities[xf86NumEntities - 1]->entityPrivates =
         xnfcalloc(xf86EntityPrivateCount, sizeof(DevUnion));
@@ -326,12 +326,13 @@ xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)
     }
 
     pScrn->numEntities++;
-    pScrn->entityList = xnfrealloc(pScrn->entityList,
-                                   pScrn->numEntities * sizeof(int));
+    pScrn->entityList = xnfreallocarray(pScrn->entityList,
+                                        pScrn->numEntities, sizeof(int));
     pScrn->entityList[pScrn->numEntities - 1] = entityIndex;
     xf86Entities[entityIndex]->inUse = TRUE;
-    pScrn->entityInstanceList = xnfrealloc(pScrn->entityInstanceList,
-                                           pScrn->numEntities * sizeof(int));
+    pScrn->entityInstanceList = xnfreallocarray(pScrn->entityInstanceList,
+                                                pScrn->numEntities,
+                                                sizeof(int));
     pScrn->entityInstanceList[pScrn->numEntities - 1] = 0;
 }
 
@@ -427,8 +428,8 @@ xf86AddDevToEntity(int entityIndex, GDevPtr dev)
 
     pEnt = xf86Entities[entityIndex];
     pEnt->numInstances++;
-    pEnt->devices = xnfrealloc(pEnt->devices,
-                               pEnt->numInstances * sizeof(GDevPtr));
+    pEnt->devices = xnfreallocarray(pEnt->devices,
+                                    pEnt->numInstances, sizeof(GDevPtr));
     pEnt->devices[pEnt->numInstances - 1] = dev;
     dev->claimed = TRUE;
 }
@@ -670,8 +671,8 @@ xf86AllocateEntityPrivateIndex(void)
     idx = xf86EntityPrivateCount++;
     for (i = 0; i < xf86NumEntities; i++) {
         pEnt = xf86Entities[i];
-        nprivs = xnfrealloc(pEnt->entityPrivates,
-                            xf86EntityPrivateCount * sizeof(DevUnion));
+        nprivs = xnfreallocarray(pEnt->entityPrivates,
+                                 xf86EntityPrivateCount, sizeof(DevUnion));
         /* Zero the new private */
         memset(&nprivs[idx], 0, sizeof(DevUnion));
         pEnt->entityPrivates = nprivs;
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 098d2dd..7edac0b 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -363,8 +363,8 @@ xf86ModulelistFromConfig(void ***optlist)
     /*
      * allocate the memory and walk the list again to fill in the pointers
      */
-    modulearray = xnfalloc((count + 1) * sizeof(char *));
-    optarray = xnfalloc((count + 1) * sizeof(void *));
+    modulearray = xnfallocarray(count + 1, sizeof(char *));
+    optarray = xnfallocarray(count + 1, sizeof(void *));
     count = 0;
     if (xf86configptr->conf_modules) {
         modp = xf86configptr->conf_modules->mod_load_lst;
@@ -429,7 +429,7 @@ xf86DriverlistFromConfig(void)
     /*
      * allocate the memory and walk the list again to fill in the pointers
      */
-    modulearray = xnfalloc((count + 1) * sizeof(char *));
+    modulearray = xnfallocarray(count + 1, sizeof(char *));
     count = 0;
     slp = xf86ConfigLayout.screens;
     while (slp->screen) {
@@ -493,7 +493,7 @@ xf86InputDriverlistFromConfig(void)
     /*
      * allocate the memory and walk the list again to fill in the pointers
      */
-    modulearray = xnfalloc((count + 1) * sizeof(char *));
+    modulearray = xnfallocarray(count + 1, sizeof(char *));
     count = 0;
     idp = xf86ConfigLayout.inputs;
     while (idp && *idp) {
@@ -1086,7 +1086,7 @@ addDevice(InputInfoPtr * list, InputInfoPtr pInfo)
     for (devs = list; devs && *devs; devs++)
         count++;
 
-    list = xnfrealloc(list, (count + 1) * sizeof(InputInfoPtr));
+    list = xnfreallocarray(list, count + 1, sizeof(InputInfoPtr));
     list[count] = NULL;
 
     list[count - 1] = pInfo;
@@ -1626,7 +1626,7 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
     }
     DebugF("Found %d inactive devices in the layout section %s\n",
            count, conf_layout->lay_identifier);
-    gdp = xnfalloc((count + 1) * sizeof(GDevRec));
+    gdp = xnfallocarray(count + 1, sizeof(GDevRec));
     gdp[count].identifier = NULL;
     idp = conf_layout->lay_inactive_lst;
     count = 0;
@@ -1746,7 +1746,7 @@ configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
         count++;
         conf_port = (XF86ConfVideoPortPtr) conf_port->list.next;
     }
-    adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec));
+    adaptor->ports = xnfallocarray(count, sizeof(confXvPortRec));
     adaptor->numports = count;
     count = 0;
     conf_port = conf_adaptor->va_port_lst;
@@ -1827,7 +1827,7 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
         count++;
         dispptr = (XF86ConfDisplayPtr) dispptr->list.next;
     }
-    screenp->displays = xnfalloc((count) * sizeof(DispRec));
+    screenp->displays = xnfallocarray(count, sizeof(DispRec));
     screenp->numdisplays = count;
 
     /* Fill in the default Virtual size, if any */
@@ -1857,7 +1857,7 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
         count++;
         conf_adaptor = (XF86ConfAdaptorLinkPtr) conf_adaptor->list.next;
     }
-    screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
+    screenp->xvadaptors = xnfallocarray(count, sizeof(confXvAdaptorRec));
     screenp->numxvadaptors = 0;
     conf_adaptor = conf_screen->scrn_adaptor_lst;
     while (conf_adaptor) {
@@ -2096,7 +2096,7 @@ configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
         count++;
         modep = (XF86ModePtr) modep->list.next;
     }
-    displayp->modes = xnfalloc((count + 1) * sizeof(char *));
+    displayp->modes = xnfallocarray(count + 1, sizeof(char *));
     modep = conf_display->disp_mode_lst;
     count = 0;
     while (modep) {
diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c
index 7ab378f..1271010 100644
--- a/hw/xfree86/common/xf86Configure.c
+++ b/hw/xfree86/common/xf86Configure.c
@@ -109,7 +109,7 @@ xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData,
     /* Allocate new structure occurrence */
     i = nDevToConfig++;
     DevToConfig =
-        xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
+        xnfreallocarray(DevToConfig, nDevToConfig, sizeof(DevToConfigRec));
     memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
 
     DevToConfig[i].GDev.chipID =
diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index b9e1e3f..9533e1c 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -1349,7 +1349,7 @@ ProcXDGAQueryModes(ClientPtr client)
         return Success;
     }
 
-    if (!(mode = (XDGAModePtr) malloc(num * sizeof(XDGAModeRec))))
+    if (!(mode = xallocarray(num, sizeof(XDGAModeRec))))
         return BadAlloc;
 
     for (i = 0; i < num; i++)
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index e2b32a0..6a35250 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -77,8 +77,8 @@ xf86AddDriver(DriverPtr driver, void *module, int flags)
         xf86NumDrivers = 0;
 
     xf86NumDrivers++;
-    xf86DriverList = xnfrealloc(xf86DriverList,
-                                xf86NumDrivers * sizeof(DriverPtr));
+    xf86DriverList = xnfreallocarray(xf86DriverList,
+                                     xf86NumDrivers, sizeof(DriverPtr));
     xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec));
     if (flags & HaveDriverFuncs)
         *xf86DriverList[xf86NumDrivers - 1] = *driver;
@@ -117,9 +117,9 @@ xf86AddInputDriver(InputDriverPtr driver, void *module, int flags)
         xf86NumInputDrivers = 0;
 
     xf86NumInputDrivers++;
-    xf86InputDriverList = xnfrealloc(xf86InputDriverList,
-                                     xf86NumInputDrivers *
-                                     sizeof(InputDriverPtr));
+    xf86InputDriverList = xnfreallocarray(xf86InputDriverList,
+                                          xf86NumInputDrivers,
+                                          sizeof(InputDriverPtr));
     xf86InputDriverList[xf86NumInputDrivers - 1] =
         xnfalloc(sizeof(InputDriverRec));
     *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver;
@@ -173,7 +173,8 @@ xf86AllocateScreen(DriverPtr drv, int flags)
         if (xf86GPUScreens == NULL)
             xf86NumGPUScreens = 0;
         i = xf86NumGPUScreens++;
-        xf86GPUScreens = xnfrealloc(xf86GPUScreens, xf86NumGPUScreens * sizeof(ScrnInfoPtr));
+        xf86GPUScreens = xnfreallocarray(xf86GPUScreens, xf86NumGPUScreens,
+                                         sizeof(ScrnInfoPtr));
         xf86GPUScreens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
         pScrn = xf86GPUScreens[i];
         pScrn->scrnIndex = i + GPU_SCREEN_OFFSET;      /* Changes when a screen is removed */
@@ -183,7 +184,8 @@ xf86AllocateScreen(DriverPtr drv, int flags)
             xf86NumScreens = 0;
 
         i = xf86NumScreens++;
-        xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
+        xf86Screens = xnfreallocarray(xf86Screens, xf86NumScreens,
+                                      sizeof(ScrnInfoPtr));
         xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
         pScrn = xf86Screens[i];
 
@@ -293,16 +295,16 @@ xf86AllocateScrnInfoPrivateIndex(void)
     idx = xf86ScrnInfoPrivateCount++;
     for (i = 0; i < xf86NumScreens; i++) {
         pScr = xf86Screens[i];
-        nprivs = xnfrealloc(pScr->privates,
-                            xf86ScrnInfoPrivateCount * sizeof(DevUnion));
+        nprivs = xnfreallocarray(pScr->privates,
+                                 xf86ScrnInfoPrivateCount, sizeof(DevUnion));
         /* Zero the new private */
         memset(&nprivs[idx], 0, sizeof(DevUnion));
         pScr->privates = nprivs;
     }
     for (i = 0; i < xf86NumGPUScreens; i++) {
         pScr = xf86GPUScreens[i];
-        nprivs = xnfrealloc(pScr->privates,
-                            xf86ScrnInfoPrivateCount * sizeof(DevUnion));
+        nprivs = xnfreallocarray(pScr->privates,
+                                 xf86ScrnInfoPrivateCount, sizeof(DevUnion));
         /* Zero the new private */
         memset(&nprivs[idx], 0, sizeof(DevUnion));
         pScr->privates = nprivs;
@@ -636,8 +638,8 @@ xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
     if (i == scrp->confScreen->numdisplays) {
         scrp->confScreen->numdisplays++;
         scrp->confScreen->displays =
-            xnfrealloc(scrp->confScreen->displays,
-                       scrp->confScreen->numdisplays * sizeof(DispRec));
+            xnfreallocarray(scrp->confScreen->displays,
+                            scrp->confScreen->numdisplays, sizeof(DispRec));
         xf86DrvMsg(scrp->scrnIndex, X_INFO,
                    "Creating default Display subsection in Screen section\n"
                    "\t\"%s\" for depth/fbbpp %d/%d\n",
@@ -1408,7 +1410,7 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
             /*
              * we have a matching driver that wasn't claimed, yet
              */
-            pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
+            pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr));
             pgdp[i++] = screensecptr->device;
         }
     }
@@ -1420,7 +1422,7 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
         if (gdp->driver && !gdp->claimed &&
             !xf86NameCmp(gdp->driver, drivername)) {
             /* we have a matching driver that wasn't claimed yet */
-            pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
+            pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr));
             pgdp[i++] = gdp;
         }
         j++;
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 9fa3dc4..55bf2bb 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -867,8 +867,9 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
         if (fd != -1) {
             if (paused) {
                 /* Put on new_input_devices list for delayed probe */
-                new_input_devices = xnfrealloc(new_input_devices,
-                            sizeof(pInfo) * (new_input_devices_count + 1));
+                new_input_devices = xnfreallocarray(new_input_devices,
+                                                    new_input_devices_count + 1,
+                                                    sizeof(pInfo));
                 new_input_devices[new_input_devices_count] = pInfo;
                 new_input_devices_count++;
                 systemd_logind_release_fd(pInfo->major, pInfo->minor, fd);
diff --git a/hw/xfree86/common/xf86cmap.c b/hw/xfree86/common/xf86cmap.c
index ab51f96..704e353 100644
--- a/hw/xfree86/common/xf86cmap.c
+++ b/hw/xfree86/common/xf86cmap.c
@@ -166,10 +166,10 @@ xf86HandleColormaps(ScreenPtr pScreen,
 
     elements = 1 << sigRGBbits;
 
-    if (!(gamma = malloc(elements * sizeof(LOCO))))
+    if (!(gamma = xallocarray(elements, sizeof(LOCO))))
         return FALSE;
 
-    if (!(indices = malloc(maxColors * sizeof(int)))) {
+    if (!(indices = xallocarray(maxColors, sizeof(int)))) {
         free(gamma);
         return FALSE;
     }
@@ -270,7 +270,7 @@ CMapAllocateColormapPrivate(ColormapPtr pmap)
     else
         numColors = 1 << pmap->pVisual->nplanes;
 
-    if (!(colors = malloc(numColors * sizeof(LOCO))))
+    if (!(colors = xallocarray(numColors, sizeof(LOCO))))
         return FALSE;
 
     if (!(pColPriv = malloc(sizeof(CMapColormapRec)))) {
diff --git a/hw/xfree86/common/xf86fbman.c b/hw/xfree86/common/xf86fbman.c
index 1b2cb57..91ddedc 100644
--- a/hw/xfree86/common/xf86fbman.c
+++ b/hw/xfree86/common/xf86fbman.c
@@ -317,16 +317,17 @@ localRegisterFreeBoxCallback(ScreenPtr pScreen,
 
     offman = (FBManagerPtr) dixLookupPrivate(&pScreen->devPrivates,
                                              xf86FBScreenKey);
-    newCallbacks = realloc(offman->FreeBoxesUpdateCallback,
-                           sizeof(FreeBoxCallbackProcPtr) *
-                           (offman->NumCallbacks + 1));
+    newCallbacks = reallocarray(offman->FreeBoxesUpdateCallback,
+                                offman->NumCallbacks + 1,
+                                sizeof(FreeBoxCallbackProcPtr));
     if (!newCallbacks)
         return FALSE;
     else
         offman->FreeBoxesUpdateCallback = newCallbacks;
 
-    newPrivates = realloc(offman->devPrivates,
-                          sizeof(DevUnion) * (offman->NumCallbacks + 1));
+    newPrivates = reallocarray(offman->devPrivates,
+                               offman->NumCallbacks + 1,
+                               sizeof(DevUnion));
     if (!newPrivates)
         return FALSE;
     else
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index e86ecb9..8158c2b 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -103,9 +103,9 @@ xf86PciProbe(void)
     while ((info = pci_device_next(iter)) != NULL) {
         if (PCIINFOCLASSES(info->device_class)) {
             num++;
-            xf86PciVideoInfo = xnfrealloc(xf86PciVideoInfo,
-                                          (sizeof(struct pci_device *)
-                                           * (num + 1)));
+            xf86PciVideoInfo = xnfreallocarray(xf86PciVideoInfo,
+                                               num + 1,
+                                               sizeof(struct pci_device *));
             xf86PciVideoInfo[num] = NULL;
             xf86PciVideoInfo[num - 1] = info;
 
@@ -679,7 +679,7 @@ xf86MatchPciInstances(const char *driverName, int vendorID,
         }
 
         pci_iterator_destroy(iter);
-        instances = xnfalloc(max_entries * sizeof(struct Inst));
+        instances = xnfallocarray(max_entries, sizeof(struct Inst));
     }
 
     iter = pci_slot_match_iterator_create(NULL);
@@ -976,7 +976,7 @@ xf86MatchPciInstances(const char *driverName, int vendorID,
 
         /* Allocate an entry in the lists to be returned */
         numFound++;
-        retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
+        retEntities = xnfreallocarray(retEntities, numFound, sizeof(int));
         retEntities[numFound - 1] = xf86ClaimPciSlot(pPci, drvp,
                                                      instances[i].chip,
                                                      instances[i].dev,
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index c1aaba4..f1e9423 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -59,9 +59,9 @@ struct xf86_platform_device *xf86_platform_devices;
 int
 xf86_add_platform_device(struct OdevAttributes *attribs, Bool unowned)
 {
-    xf86_platform_devices = xnfrealloc(xf86_platform_devices,
-                                   (sizeof(struct xf86_platform_device)
-                                    * (xf86_num_platform_devices + 1)));
+    xf86_platform_devices = xnfreallocarray(xf86_platform_devices,
+                                            xf86_num_platform_devices + 1,
+                                            sizeof(struct xf86_platform_device));
 
     xf86_platform_devices[xf86_num_platform_devices].attribs = attribs;
     xf86_platform_devices[xf86_num_platform_devices].pdev = NULL;
diff --git a/hw/xfree86/common/xf86sbusBus.c b/hw/xfree86/common/xf86sbusBus.c
index 07eb71e..119211d 100644
--- a/hw/xfree86/common/xf86sbusBus.c
+++ b/hw/xfree86/common/xf86sbusBus.c
@@ -68,7 +68,7 @@ CheckSbusDevice(const char *device, int fbNum)
     if (!sbusDeviceTable[i].devId)
         return;
     xf86SbusInfo =
-        xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1));
+        xnfreallocarray(xf86SbusInfo, ++xf86nSbusInfo + 1, sizeof(psdp));
     xf86SbusInfo[xf86nSbusInfo] = NULL;
     xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof(sbusDevice), 1);
     psdp->devId = sbusDeviceTable[i].devId;
@@ -406,8 +406,8 @@ xf86MatchSbusInstances(const char *driverName, int sbusDevId,
         if (psdp->fd == -2)
             continue;
         ++allocatedInstances;
-        instances = xnfrealloc(instances,
-                               allocatedInstances * sizeof(struct Inst));
+        instances = xnfreallocarray(instances,
+                                    allocatedInstances, sizeof(struct Inst));
         instances[allocatedInstances - 1].sbus = psdp;
         instances[allocatedInstances - 1].dev = NULL;
         instances[allocatedInstances - 1].claimed = FALSE;
@@ -532,7 +532,7 @@ xf86MatchSbusInstances(const char *driverName, int sbusDevId,
 
         /* Allocate an entry in the lists to be returned */
         numFound++;
-        retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
+        retEntities = xnfreallocarray(retEntities, numFound, sizeof(int));
         retEntities[numFound - 1]
             = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,
                                 instances[i].dev->active ? TRUE : FALSE);
@@ -648,7 +648,7 @@ xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
         return;
     fbcmap.count = 0;
     fbcmap.index = indices[0];
-    fbcmap.red = data = malloc(numColors * 3);
+    fbcmap.red = data = xallocarray(numColors, 3);
     if (!data)
         return;
     fbcmap.green = data + numColors;
diff --git a/hw/xfree86/common/xf86vmode.c b/hw/xfree86/common/xf86vmode.c
index 0ce58e3..818e7dc 100644
--- a/hw/xfree86/common/xf86vmode.c
+++ b/hw/xfree86/common/xf86vmode.c
@@ -1240,11 +1240,11 @@ ProcXF86VidModeGetMonitor(ClientPtr client)
                        pad_to_int32(rep.modelLength));
     rep.nhsync = nHsync;
     rep.nvsync = nVrefresh;
-    hsyncdata = malloc(nHsync * sizeof(CARD32));
+    hsyncdata = xallocarray(nHsync, sizeof(CARD32));
     if (!hsyncdata) {
         return BadAlloc;
     }
-    vsyncdata = malloc(nVrefresh * sizeof(CARD32));
+    vsyncdata = xallocarray(nVrefresh, sizeof(CARD32));
 
     if (!vsyncdata) {
         free(hsyncdata);
@@ -1512,9 +1512,9 @@ ProcXF86VidModeGetGammaRamp(ClientPtr client)
     length = (stuff->size + 1) & ~1;
 
     if (stuff->size) {
-        ramplen = length * 3 * sizeof(CARD16);
-        if (!(ramp = malloc(ramplen)))
+        if (!(ramp = xallocarray(length, 3 * sizeof(CARD16))))
             return BadAlloc;
+        ramplen = length * 3 * sizeof(CARD16);
 
         if (!VidModeGetGammaRamp(stuff->screen, stuff->size,
                                  ramp, ramp + length, ramp + (length * 2))) {
diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index b974cd2..d613d71 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -131,8 +131,8 @@ xf86XVRegisterGenericAdaptorDriver(xf86XVInitGenericAdaptorPtr InitFunc)
 {
     xf86XVInitGenericAdaptorPtr *newdrivers;
 
-    newdrivers = realloc(GenDrivers, sizeof(xf86XVInitGenericAdaptorPtr) *
-                         (1 + NumGenDrivers));
+    newdrivers = reallocarray(GenDrivers, 1 + NumGenDrivers,
+                              sizeof(xf86XVInitGenericAdaptorPtr));
     if (!newdrivers)
         return 0;
     GenDrivers = newdrivers;
@@ -159,7 +159,7 @@ xf86XVListGenericAdaptors(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr ** adaptors)
         n = (*GenDrivers[i]) (pScrn, &DrivAdap);
         if (0 == n)
             continue;
-        new = realloc(*adaptors, sizeof(XF86VideoAdaptorPtr) * (num + n));
+        new = reallocarray(*adaptors, num + n, sizeof(XF86VideoAdaptorPtr));
         if (NULL == new)
             continue;
         *adaptors = new;
@@ -436,8 +436,8 @@ xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number)
                         void *moreSpace;
 
                         totFormat *= 2;
-                        moreSpace = realloc(pFormat,
-                                            totFormat * sizeof(XvFormatRec));
+                        moreSpace = reallocarray(pFormat, totFormat,
+                                                 sizeof(XvFormatRec));
                         if (!moreSpace)
                             break;
                         pFormat = moreSpace;
diff --git a/hw/xfree86/common/xf86xvmc.c b/hw/xfree86/common/xf86xvmc.c
index 3169c05..a0a94c7 100644
--- a/hw/xfree86/common/xf86xvmc.c
+++ b/hw/xfree86/common/xf86xvmc.c
@@ -155,7 +155,7 @@ xf86XvMCScreenInit(ScreenPtr pScreen,
     if (noXvExtension)
         return FALSE;
 
-    if (!(pAdapt = malloc(sizeof(XvMCAdaptorRec) * num_adaptors)))
+    if (!(pAdapt = xallocarray(num_adaptors, sizeof(XvMCAdaptorRec))))
         return FALSE;
 
     if (!dixRegisterPrivateKey(&XF86XvMCScreenKeyRec, PRIVATE_SCREEN, 0)) {
diff --git a/hw/xfree86/ddc/ddc.c b/hw/xfree86/ddc/ddc.c
index 29185ad..ee533db 100644
--- a/hw/xfree86/ddc/ddc.c
+++ b/hw/xfree86/ddc/ddc.c
@@ -437,7 +437,7 @@ xf86DoEEDID(ScrnInfoPtr pScrn, I2CBusPtr pBus, Bool complete)
         int i, n = EDID_block[0x7e];
 
         if (complete && n) {
-            EDID_block = realloc(EDID_block, EDID1_LEN * (1 + n));
+            EDID_block = reallocarray(EDID_block, 1 + n, EDID1_LEN);
 
             for (i = 0; i < n; i++)
                 DDC2Read(dev, i + 1, EDID_block + (EDID1_LEN * (1 + i)));
diff --git a/hw/xfree86/dri/xf86dri.c b/hw/xfree86/dri/xf86dri.c
index 086e833..68f8b7e 100644
--- a/hw/xfree86/dri/xf86dri.c
+++ b/hw/xfree86/dri/xf86dri.c
@@ -422,7 +422,7 @@ ProcXF86DRIGetDrawableInfo(register ClientPtr client)
 
     if (rep.numClipRects) {
         /* Clip cliprects to screen dimensions (redirected windows) */
-        pClippedRects = malloc(rep.numClipRects * sizeof(drm_clip_rect_t));
+        pClippedRects = xallocarray(rep.numClipRects, sizeof(drm_clip_rect_t));
 
         if (pClippedRects) {
             ScreenPtr pScreen = screenInfo.screens[stuff->screen];
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 0c038b3..60ea6dd 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -1577,7 +1577,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     if (info->version == 3 || info->numDrivers == 0) {
         /* Driver too old: use the old-style driverName field */
         ds->numDrivers = info->driverName ? 1 : 2;
-        ds->driverNames = malloc(ds->numDrivers * sizeof(*ds->driverNames));
+        ds->driverNames = xallocarray(ds->numDrivers, sizeof(*ds->driverNames));
         if (!ds->driverNames)
             goto err_out;
 
@@ -1591,7 +1591,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     }
     else {
         ds->numDrivers = info->numDrivers;
-        ds->driverNames = malloc(info->numDrivers * sizeof(*ds->driverNames));
+        ds->driverNames = xallocarray(info->numDrivers, sizeof(*ds->driverNames));
         if (!ds->driverNames)
             goto err_out;
         memcpy(ds->driverNames, info->driverNames,
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index e2f3846..e90e4b8 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -451,7 +451,7 @@ dispatch_dirty_region(ScrnInfoPtr scrn,
     int ret = 0;
 
     if (num_cliprects) {
-        drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip));
+        drmModeClip *clip = xallocarray(num_cliprects, sizeof(drmModeClip));
         BoxPtr rect = REGION_RECTS(dirty);
         int i;
 
diff --git a/hw/xfree86/i2c/xf86i2c.c b/hw/xfree86/i2c/xf86i2c.c
index cf2cd09..2a8b8df 100644
--- a/hw/xfree86/i2c/xf86i2c.c
+++ b/hw/xfree86/i2c/xf86i2c.c
@@ -872,7 +872,7 @@ xf86I2CGetScreenBuses(int scrnIndex, I2CBusPtr ** pppI2CBus)
         if (!pppI2CBus)
             continue;
 
-        *pppI2CBus = xnfrealloc(*pppI2CBus, n * sizeof(I2CBusPtr));
+        *pppI2CBus = xnfreallocarray(*pppI2CBus, n, sizeof(I2CBusPtr));
         (*pppI2CBus)[n - 1] = pI2CBus;
     }
 
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index fdf5bd8..73dc1b8 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -142,7 +142,7 @@ InitPathList(const char *path)
             if (addslash)
                 len++;
             save = list;
-            list = realloc(list, (n + 2) * sizeof(char *));
+            list = reallocarray(list, n + 2, sizeof(char *));
             if (!list) {
                 if (save) {
                     save[n] = NULL;
@@ -244,7 +244,7 @@ InitPatterns(const char **patternlist)
         for (i = 0, s = patternlist; *s; i++, s++)
             if (*s == DEFAULT_LIST)
                 i += sizeof(stdPatterns) / sizeof(stdPatterns[0]) - 1 - 1;
-        patterns = malloc((i + 1) * sizeof(PatternRec));
+        patterns = xallocarray(i + 1, sizeof(PatternRec));
         if (!patterns) {
             return NULL;
         }
@@ -323,7 +323,7 @@ InitSubdirs(const char **subdirlist)
                 }
             }
         }
-        subdirs = malloc((i * 2 + 1) * sizeof(char *));
+        subdirs = xallocarray(i * 2 + 1, sizeof(char *));
         if (!subdirs) {
             free(tmp_subdirlist);
             return NULL;
@@ -530,8 +530,8 @@ LoaderListDirs(const char **subdirlist, const char **patternlist)
                             match[1].rm_so != -1) {
                             len = match[1].rm_eo - match[1].rm_so;
                             save = listing;
-                            listing = realloc(listing,
-                                              (n + 2) * sizeof(char *));
+                            listing = reallocarray(listing, n + 2,
+                                                   sizeof(char *));
                             if (!listing) {
                                 if (save) {
                                     save[n] = NULL;
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index a194724..127e543 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -118,7 +118,7 @@ xf86CrtcCreate(ScrnInfoPtr scrn, const xf86CrtcFuncsRec * funcs)
 
     /* Preallocate gamma at a sensible size. */
     crtc->gamma_size = 256;
-    crtc->gamma_red = malloc(3 * crtc->gamma_size * sizeof(CARD16));
+    crtc->gamma_red = xallocarray(crtc->gamma_size, 3 * sizeof(CARD16));
     if (!crtc->gamma_red) {
         free(crtc);
         return NULL;
@@ -127,10 +127,10 @@ xf86CrtcCreate(ScrnInfoPtr scrn, const xf86CrtcFuncsRec * funcs)
     crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
 
     if (xf86_config->crtc)
-        crtcs = realloc(xf86_config->crtc,
-                        (xf86_config->num_crtc + 1) * sizeof(xf86CrtcPtr));
+        crtcs = reallocarray(xf86_config->crtc,
+                             xf86_config->num_crtc + 1, sizeof(xf86CrtcPtr));
     else
-        crtcs = malloc((xf86_config->num_crtc + 1) * sizeof(xf86CrtcPtr));
+        crtcs = xallocarray(xf86_config->num_crtc + 1, sizeof(xf86CrtcPtr));
     if (!crtcs) {
         free(crtc->gamma_red);
         free(crtc);
@@ -620,11 +620,12 @@ xf86OutputCreate(ScrnInfoPtr scrn,
     }
 
     if (xf86_config->output)
-        outputs = realloc(xf86_config->output,
-                          (xf86_config->num_output +
-                           1) * sizeof(xf86OutputPtr));
+        outputs = reallocarray(xf86_config->output,
+                               xf86_config->num_output + 1,
+                               sizeof(xf86OutputPtr));
     else
-        outputs = malloc((xf86_config->num_output + 1) * sizeof(xf86OutputPtr));
+        outputs = xallocarray(xf86_config->num_output + 1,
+                              sizeof(xf86OutputPtr));
     if (!outputs) {
         free(output);
         return NULL;
@@ -942,7 +943,7 @@ xf86PickCrtcs(ScrnInfoPtr scrn,
     if (modes[n] == NULL)
         return best_score;
 
-    crtcs = malloc(config->num_output * sizeof(xf86CrtcPtr));
+    crtcs = xallocarray(config->num_output, sizeof(xf86CrtcPtr));
     if (!crtcs)
         return best_score;
 
@@ -2334,7 +2335,7 @@ xf86CrtcSetInitialGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green,
     int i, size = 256;
     CARD16 *red, *green, *blue;
 
-    red = malloc(3 * size * sizeof(CARD16));
+    red = xallocarray(size, 3 * sizeof(CARD16));
     green = red + size;
     blue = green + size;
 
diff --git a/hw/xfree86/modes/xf86DiDGA.c b/hw/xfree86/modes/xf86DiDGA.c
index 3f1a330..6457274 100644
--- a/hw/xfree86/modes/xf86DiDGA.c
+++ b/hw/xfree86/modes/xf86DiDGA.c
@@ -60,7 +60,7 @@ xf86_dga_get_modes(ScreenPtr pScreen)
     if (!num)
         return FALSE;
 
-    modes = malloc(num * sizeof(DGAModeRec));
+    modes = xallocarray(num, sizeof(DGAModeRec));
     if (!modes)
         return FALSE;
 
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index b1c306a..fb73128 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1058,7 +1058,7 @@ xf86RandR12CrtcNotify(RRCrtcPtr randr_crtc)
     DisplayModePtr mode = &crtc->mode;
     Bool ret;
 
-    randr_outputs = malloc(config->num_output * sizeof(RROutputPtr));
+    randr_outputs = xallocarray(config->num_output, sizeof(RROutputPtr));
     if (!randr_outputs)
         return FALSE;
     x = crtc->x;
@@ -1150,7 +1150,7 @@ xf86RandR12CrtcSet(ScreenPtr pScreen,
     if (!crtc->scrn->vtSema)
         return FALSE;
 
-    save_crtcs = malloc(config->num_output * sizeof(xf86CrtcPtr));
+    save_crtcs = xallocarray(config->num_output, sizeof(xf86CrtcPtr));
     if ((randr_mode != NULL) != crtc->enabled)
         changed = TRUE;
     else if (randr_mode && !xf86RandRModeMatches(randr_mode, &crtc->mode))
@@ -1255,9 +1255,8 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
     if (randr_crtc->gammaSize != crtc->gamma_size) {
         CARD16 *tmp_ptr;
 
-        tmp_ptr =
-            realloc(crtc->gamma_red,
-                    3 * randr_crtc->gammaSize * sizeof(CARD16));
+        tmp_ptr = reallocarray(crtc->gamma_red,
+                               randr_crtc->gammaSize, 3 * sizeof(CARD16));
         if (!tmp_ptr)
             return FALSE;
         crtc->gamma_red = tmp_ptr;
@@ -1298,9 +1297,8 @@ xf86RandR12CrtcGetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
     if (randr_crtc->gammaSize != crtc->gamma_size) {
         CARD16 *tmp_ptr;
 
-        tmp_ptr =
-            realloc(randr_crtc->gammaRed,
-                    3 * crtc->gamma_size * sizeof(CARD16));
+        tmp_ptr = reallocarray(randr_crtc->gammaRed,
+                               crtc->gamma_size, 3 * sizeof(CARD16));
         if (!tmp_ptr)
             return FALSE;
         randr_crtc->gammaRed = tmp_ptr;
@@ -1394,7 +1392,7 @@ xf86RROutputSetModes(RROutputPtr randr_output, DisplayModePtr modes)
         nmode++;
 
     if (nmode) {
-        rrmodes = malloc(nmode * sizeof(RRModePtr));
+        rrmodes = xallocarray(nmode, sizeof(RRModePtr));
 
         if (!rrmodes)
             return FALSE;
@@ -1449,8 +1447,8 @@ xf86RandR12SetInfo12(ScreenPtr pScreen)
     int o, c, l;
     int nclone;
 
-    clones = malloc(config->num_output * sizeof(RROutputPtr));
-    crtcs = malloc(config->num_crtc * sizeof(RRCrtcPtr));
+    clones = xallocarray(config->num_output, sizeof(RROutputPtr));
+    crtcs = xallocarray(config->num_crtc, sizeof(RRCrtcPtr));
     for (o = 0; o < config->num_output; o++) {
         xf86OutputPtr output = config->output[o];
 
diff --git a/hw/xfree86/os-support/bus/Sbus.c b/hw/xfree86/os-support/bus/Sbus.c
index 16ce5b5..86b4d68 100644
--- a/hw/xfree86/os-support/bus/Sbus.c
+++ b/hw/xfree86/os-support/bus/Sbus.c
@@ -440,7 +440,7 @@ sparcPromAssignNodes(void)
     for (i = 0, j = 0; i < 32; i++)
         if (devicePtrs[i] && devicePtrs[i]->fbNum == -1)
             j++;
-    xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (n + j + 1));
+    xf86SbusInfo = xnfreallocarray(xf86SbusInfo, n + j + 1, sizeof(psdp));
     for (i = 0, psdpp = xf86SbusInfo; i < 32; i++)
         if (devicePtrs[i]) {
             if (devicePtrs[i]->fbNum == -1) {
diff --git a/hw/xfree86/vbe/vbe.c b/hw/xfree86/vbe/vbe.c
index 5ea0197..ef12cb8 100644
--- a/hw/xfree86/vbe/vbe.c
+++ b/hw/xfree86/vbe/vbe.c
@@ -397,7 +397,7 @@ VBEGetVBEInfo(vbeInfoPtr pVbe)
     i = 0;
     while (modes[i] != 0xffff)
         i++;
-    block->VideoModePtr = malloc(sizeof(CARD16) * (i + 1));
+    block->VideoModePtr = xallocarray(i + 1, sizeof(CARD16));
     memcpy(block->VideoModePtr, modes, sizeof(CARD16) * i);
     block->VideoModePtr[i] = 0xffff;
 
@@ -825,7 +825,7 @@ VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num,
     if (set)
         return data;
 
-    data = malloc(num * sizeof(CARD32));
+    data = xallocarray(num, sizeof(CARD32));
     memcpy(data, pVbe->memory, num * sizeof(CARD32));
 
     return data;
commit f59236c2865d22c6f0b2d1ba303213afd10cd02e
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 15:05:30 2015 -0700

    Convert glamor & glx to new *allocarray functions
    
    v2: fixup whitespace
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
index e188d8a..885a6c0 100644
--- a/glamor/glamor_compositerects.c
+++ b/glamor/glamor_compositerects.c
@@ -57,7 +57,7 @@ _pixman_region_init_clipped_rectangles(pixman_region16_t * region,
     unsigned int i, j;
 
     if (num_rects > ARRAY_SIZE(stack_boxes)) {
-        boxes = malloc(sizeof(pixman_box16_t) * num_rects);
+        boxes = xallocarray(num_rects, sizeof(pixman_box16_t));
         if (boxes == NULL)
             return FALSE;
     }
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 2cf0c7d..4f3f969 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -634,7 +634,7 @@ glyph_new_fixed_list(struct glamor_glyph_list *fixed_list,
     }
     DEBUGF("got %d lists\n", list_cnt);
     if (list_cnt != 0) {
-        fixed_list->list = malloc(list_cnt * sizeof(*cur_list));
+        fixed_list->list = xallocarray(list_cnt, sizeof(*cur_list));
         memcpy(fixed_list->list, *head_list, list_cnt * sizeof(*cur_list));
         fixed_list->list[0].xOff = *head_x;
         fixed_list->list[0].yOff = *head_y;
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 8ea645e..d34131d 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -997,13 +997,13 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
 
     /* Set all the stops and colors to shader. */
     if (stops_count > RADIAL_SMALL_STOPS) {
-        stop_colors = malloc(4 * stops_count * sizeof(float));
+        stop_colors = xallocarray(stops_count, 4 * sizeof(float));
         if (stop_colors == NULL) {
             ErrorF("Failed to allocate stop_colors memory.\n");
             goto GRADIENT_FAIL;
         }
 
-        n_stops = malloc(stops_count * sizeof(float));
+        n_stops = xallocarray(stops_count, sizeof(float));
         if (n_stops == NULL) {
             ErrorF("Failed to allocate n_stops memory.\n");
             goto GRADIENT_FAIL;
@@ -1338,13 +1338,13 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
 
     /* Set all the stops and colors to shader. */
     if (stops_count > LINEAR_SMALL_STOPS) {
-        stop_colors = malloc(4 * stops_count * sizeof(float));
+        stop_colors = xallocarray(stops_count, 4 * sizeof(float));
         if (stop_colors == NULL) {
             ErrorF("Failed to allocate stop_colors memory.\n");
             goto GRADIENT_FAIL;
         }
 
-        n_stops = malloc(stops_count * sizeof(float));
+        n_stops = xallocarray(stops_count, sizeof(float));
         if (n_stops == NULL) {
             ErrorF("Failed to allocate n_stops memory.\n");
             goto GRADIENT_FAIL;
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 89b4c36..6235747 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -775,7 +775,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
         if (pixmap->drawable.depth == 1)
             stride = (((w * 8 + 7) / 8) + 3) & ~3;
 
-        converted_bits = malloc(h * stride);
+        converted_bits = xallocarray(h, stride);
 
         if (converted_bits == NULL)
             return FALSE;
@@ -966,7 +966,7 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
         void *sub_bits;
         int i, j;
 
-        sub_bits = malloc(h * stride);
+        sub_bits = xallocarray(h, stride);
         if (sub_bits == NULL)
             return FALSE;
         box.x1 = x;
diff --git a/glamor/glamor_prepare.c b/glamor/glamor_prepare.c
index 83ba7f1..9bfc557 100644
--- a/glamor/glamor_prepare.c
+++ b/glamor/glamor_prepare.c
@@ -91,8 +91,8 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
                          pixmap->devKind * pixmap->drawable.height, NULL,
                          gl_usage);
         } else {
-            pixmap->devPrivate.ptr = malloc(pixmap->devKind *
-                                            pixmap->drawable.height);
+            pixmap->devPrivate.ptr = xallocarray(pixmap->devKind,
+                                                 pixmap->drawable.height);
             if (!pixmap->devPrivate.ptr)
                 return FALSE;
         }
diff --git a/glamor/glamor_utils.c b/glamor/glamor_utils.c
index f068960..d3e6fd3 100644
--- a/glamor/glamor_utils.c
+++ b/glamor/glamor_utils.c
@@ -31,7 +31,7 @@ glamor_solid_boxes(PixmapPtr pixmap,
     xRectangle *rect;
     int n;
 
-    rect = malloc(nbox * sizeof (xRectangle));
+    rect = xallocarray(nbox, sizeof(xRectangle));
     if (!rect)
         return;
     for (n = 0; n < nbox; n++) {
diff --git a/glx/single2.c b/glx/single2.c
index a6ea614..acc66ac 100644
--- a/glx/single2.c
+++ b/glx/single2.c
@@ -62,9 +62,8 @@ __glXDisp_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
     size = *(GLsizei *) (pc + 0);
     type = *(GLenum *) (pc + 4);
     if (cx->feedbackBufSize < size) {
-        cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf,
-                                              (size_t) size
-                                              * __GLX_SIZE_FLOAT32);
+        cx->feedbackBuf = reallocarray(cx->feedbackBuf,
+                                       (size_t) size, __GLX_SIZE_FLOAT32);
         if (!cx->feedbackBuf) {
             cl->client->errorValue = size;
             return BadAlloc;
@@ -94,8 +93,8 @@ __glXDisp_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
     pc += __GLX_SINGLE_HDR_SIZE;
     size = *(GLsizei *) (pc + 0);
     if (cx->selectBufSize < size) {
-        cx->selectBuf = (GLuint *) realloc(cx->selectBuf,
-                                           (size_t) size * __GLX_SIZE_CARD32);
+        cx->selectBuf = reallocarray(cx->selectBuf,
+                                     (size_t) size, __GLX_SIZE_CARD32);
         if (!cx->selectBuf) {
             cl->client->errorValue = size;
             return BadAlloc;
diff --git a/glx/single2swap.c b/glx/single2swap.c
index 5349069..d5bb1c0 100644
--- a/glx/single2swap.c
+++ b/glx/single2swap.c
@@ -63,9 +63,8 @@ __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
     size = *(GLsizei *) (pc + 0);
     type = *(GLenum *) (pc + 4);
     if (cx->feedbackBufSize < size) {
-        cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf,
-                                              (size_t) size
-                                              * __GLX_SIZE_FLOAT32);
+        cx->feedbackBuf = reallocarray(cx->feedbackBuf,
+                                       (size_t) size, __GLX_SIZE_FLOAT32);
         if (!cx->feedbackBuf) {
             cl->client->errorValue = size;
             return BadAlloc;
@@ -99,8 +98,8 @@ __glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
     __GLX_SWAP_INT(pc + 0);
     size = *(GLsizei *) (pc + 0);
     if (cx->selectBufSize < size) {
-        cx->selectBuf = (GLuint *) realloc(cx->selectBuf,
-                                           (size_t) size * __GLX_SIZE_CARD32);
+        cx->selectBuf = reallocarray(cx->selectBuf,
+                                     (size_t) size, __GLX_SIZE_CARD32);
         if (!cx->selectBuf) {
             cl->client->errorValue = size;
             return BadAlloc;
commit 7ac280287491fe06127d9fefc504217e21c780e6
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 14:58:50 2015 -0700

    Convert mi & miext to new *allocarray functions
    
    v2: remove now useless parentheses
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/mi/miarc.c b/mi/miarc.c
index e8bc87e..5e854b3 100644
--- a/mi/miarc.c
+++ b/mi/miarc.c
@@ -1187,9 +1187,9 @@ miFillSppPoly(DrawablePtr dst, GCPtr pgc, int count,    /* number of points */
     y = ymax - ymin + 1;
     if ((count < 3) || (y <= 0))
         return;
-    ptsOut = FirstPoint = malloc(sizeof(DDXPointRec) * y);
-    width = FirstWidth = malloc(sizeof(int) * y);
-    Marked = malloc(sizeof(int) * count);
+    ptsOut = FirstPoint = xallocarray(y, sizeof(DDXPointRec));
+    width = FirstWidth = xallocarray(y, sizeof(int));
+    Marked = xallocarray(count, sizeof(int));
 
     if (!ptsOut || !width || !Marked) {
         free(Marked);
@@ -1679,8 +1679,7 @@ miGetArcPts(SppArcPtr parc,     /* points to an arc */
     count++;
 
     cdt = 2 * miDcos(dt);
-    if (!(poly = (SppPointPtr) realloc((void *) *ppPts,
-                                       (cpt + count) * sizeof(SppPointRec))))
+    if (!(poly = reallocarray(*ppPts, cpt + count, sizeof(SppPointRec))))
         return 0;
     *ppPts = poly;
 
@@ -1737,7 +1736,7 @@ addCap(miArcCapPtr * capsp, int *ncapsp, int *sizep, int end, int arcIndex)
 
     if (*ncapsp == *sizep) {
         newsize = *sizep + ADD_REALLOC_STEP;
-        cap = (miArcCapPtr) realloc(*capsp, newsize * sizeof(**capsp));
+        cap = reallocarray(*capsp, newsize, sizeof(**capsp));
         if (!cap)
             return;
         *sizep = newsize;
@@ -1760,7 +1759,7 @@ addJoin(miArcJoinPtr * joinsp,
 
     if (*njoinsp == *sizep) {
         newsize = *sizep + ADD_REALLOC_STEP;
-        join = (miArcJoinPtr) realloc(*joinsp, newsize * sizeof(**joinsp));
+        join = reallocarray(*joinsp, newsize, sizeof(**joinsp));
         if (!join)
             return;
         *sizep = newsize;
@@ -1784,7 +1783,7 @@ addArc(miArcDataPtr * arcsp, int *narcsp, int *sizep, xArc * xarc)
 
     if (*narcsp == *sizep) {
         newsize = *sizep + ADD_REALLOC_STEP;
-        arc = (miArcDataPtr) realloc(*arcsp, newsize * sizeof(**arcsp));
+        arc = reallocarray(*arcsp, newsize, sizeof(**arcsp));
         if (!arc)
             return NULL;
         *sizep = newsize;
@@ -1890,10 +1889,10 @@ miComputeArcs(xArc * parcs, int narcs, GCPtr pGC)
     isDoubleDash = (pGC->lineStyle == LineDoubleDash);
     dashOffset = pGC->dashOffset;
 
-    data = malloc(narcs * sizeof(struct arcData));
+    data = xallocarray(narcs, sizeof(struct arcData));
     if (!data)
         return NULL;
-    arcs = malloc(sizeof(*arcs) * (isDoubleDash ? 2 : 1));
+    arcs = xallocarray(isDoubleDash ? 2 : 1, sizeof(*arcs));
     if (!arcs) {
         free(data);
         return NULL;
@@ -3081,8 +3080,8 @@ fillSpans(DrawablePtr pDrawable, GCPtr pGC)
 
     if (nspans == 0)
         return;
-    xSpan = xSpans = malloc(nspans * sizeof(DDXPointRec));
-    xWidth = xWidths = malloc(nspans * sizeof(int));
+    xSpan = xSpans = xallocarray(nspans, sizeof(DDXPointRec));
+    xWidth = xWidths = xallocarray(nspans, sizeof(int));
     if (xSpans && xWidths) {
         i = 0;
         f = finalSpans;
@@ -3136,7 +3135,7 @@ realFindSpan(int y)
         else
             change = SPAN_REALLOC;
         newSize = finalSize + change;
-        newSpans = malloc(newSize * sizeof(struct finalSpan *));
+        newSpans = xallocarray(newSize, sizeof(struct finalSpan *));
         if (!newSpans)
             return NULL;
         newMiny = finalMiny;
diff --git a/mi/mibitblt.c b/mi/mibitblt.c
index 7243963..28296a4 100644
--- a/mi/mibitblt.c
+++ b/mi/mibitblt.c
@@ -136,11 +136,11 @@ miCopyArea(DrawablePtr pSrcDrawable,
         dsty += pDstDrawable->y;
     }
 
-    pptFirst = ppt = malloc(heightSrc * sizeof(DDXPointRec));
-    pwidthFirst = pwidth = malloc(heightSrc * sizeof(unsigned int));
+    pptFirst = ppt = xallocarray(heightSrc, sizeof(DDXPointRec));
+    pwidthFirst = pwidth = xallocarray(heightSrc, sizeof(unsigned int));
     numRects = RegionNumRects(prgnSrcClip);
     boxes = RegionRects(prgnSrcClip);
-    ordering = malloc(numRects * sizeof(unsigned int));
+    ordering = xallocarray(numRects, sizeof(unsigned int));
     if (!pptFirst || !pwidthFirst || !ordering) {
         free(ordering);
         free(pwidthFirst);
@@ -221,7 +221,7 @@ miCopyArea(DrawablePtr pSrcDrawable,
             ppt++->y = y++;
             *pwidth++ = width;
         }
-        pbits = malloc(height * PixmapBytePad(width, pSrcDrawable->depth));
+        pbits = xallocarray(height, PixmapBytePad(width, pSrcDrawable->depth));
         if (pbits) {
             (*pSrcDrawable->pScreen->GetSpans) (pSrcDrawable, width, pptFirst,
                                                 (int *) pwidthFirst, height,
@@ -398,8 +398,8 @@ miOpqStipDrawable(DrawablePtr pDraw, GCPtr pGC, RegionPtr prgnSrc,
     ChangeGC(NullClient, pGCT, GCBackground, gcv);
     ValidateGC((DrawablePtr) pPixmap, pGCT);
     miClearDrawable((DrawablePtr) pPixmap, pGCT);
-    ppt = pptFirst = malloc(h * sizeof(DDXPointRec));
-    pwidth = pwidthFirst = malloc(h * sizeof(int));
+    ppt = pptFirst = xallocarray(h, sizeof(DDXPointRec));
+    pwidth = pwidthFirst = xallocarray(h, sizeof(int));
     if (!pptFirst || !pwidthFirst) {
         free(pwidthFirst);
         free(pptFirst);
@@ -746,8 +746,8 @@ miPutImage(DrawablePtr pDraw, GCPtr pGC, int depth,
         break;
 
     case ZPixmap:
-        ppt = pptFirst = malloc(h * sizeof(DDXPointRec));
-        pwidth = pwidthFirst = malloc(h * sizeof(int));
+        ppt = pptFirst = xallocarray(h, sizeof(DDXPointRec));
+        pwidth = pwidthFirst = xallocarray(h, sizeof(int));
         if (!pptFirst || !pwidthFirst) {
             free(pwidthFirst);
             free(pptFirst);
diff --git a/mi/micmap.c b/mi/micmap.c
index 1aeb359..5743adb 100644
--- a/mi/micmap.c
+++ b/mi/micmap.c
@@ -458,9 +458,9 @@ miInitVisuals(VisualPtr * visualp, DepthPtr * depthp, int *nvisualp,
         ndepth++;
         nvisual += visuals->count;
     }
-    depth = malloc(ndepth * sizeof(DepthRec));
-    visual = malloc(nvisual * sizeof(VisualRec));
-    preferredCVCs = malloc(ndepth * sizeof(int));
+    depth = xallocarray(ndepth, sizeof(DepthRec));
+    visual = xallocarray(nvisual, sizeof(VisualRec));
+    preferredCVCs = xallocarray(ndepth, sizeof(int));
     if (!depth || !visual || !preferredCVCs) {
         free(depth);
         free(visual);
@@ -481,7 +481,7 @@ miInitVisuals(VisualPtr * visualp, DepthPtr * depthp, int *nvisualp,
         prefp++;
         vid = NULL;
         if (nvtype) {
-            vid = malloc(nvtype * sizeof(VisualID));
+            vid = xallocarray(nvtype, sizeof(VisualID));
             if (!vid) {
                 free(depth);
                 free(visual);
diff --git a/mi/micopy.c b/mi/micopy.c
index 2409c78..12cdad4 100644
--- a/mi/micopy.c
+++ b/mi/micopy.c
@@ -62,7 +62,7 @@ miCopyRegion(DrawablePtr pSrcDrawable,
 
         if (nbox > 1) {
             /* keep ordering in each band, reverse order of bands */
-            pboxNew1 = (BoxPtr) malloc(sizeof(BoxRec) * nbox);
+            pboxNew1 = xallocarray(nbox, sizeof(BoxRec));
             if (!pboxNew1)
                 return;
             pboxBase = pboxNext = pbox + nbox - 1;
@@ -93,7 +93,7 @@ miCopyRegion(DrawablePtr pSrcDrawable,
 
         if (nbox > 1) {
             /* reverse order of rects in each band */
-            pboxNew2 = (BoxPtr) malloc(sizeof(BoxRec) * nbox);
+            pboxNew2 = xallocarray(nbox, sizeof(BoxRec));
             if (!pboxNew2) {
                 free(pboxNew1);
                 return;
diff --git a/mi/miexpose.c b/mi/miexpose.c
index fc4dbc0..c4118f1 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -535,7 +535,7 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
         gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
     }
 
-    prect = malloc(RegionNumRects(prgn) * sizeof(xRectangle));
+    prect = xallocarray(RegionNumRects(prgn), sizeof(xRectangle));
     if (!prect)
         return;
 
diff --git a/mi/mifillrct.c b/mi/mifillrct.c
index 28f2322..eb98a77 100644
--- a/mi/mifillrct.c
+++ b/mi/mifillrct.c
@@ -100,8 +100,8 @@ miPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, /* number of rec
             maxheight = max(maxheight, prect->height);
     }
 
-    pptFirst = malloc(maxheight * sizeof(DDXPointRec));
-    pwFirst = malloc(maxheight * sizeof(int));
+    pptFirst = xallocarray(maxheight, sizeof(DDXPointRec));
+    pwFirst = xallocarray(maxheight, sizeof(int));
     if (!pptFirst || !pwFirst) {
         free(pwFirst);
         free(pptFirst);
diff --git a/mi/miglblt.c b/mi/miglblt.c
index 0183e99..e9d3a1a 100644
--- a/mi/miglblt.c
+++ b/mi/miglblt.c
@@ -131,7 +131,7 @@ miPolyGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyp
              gcvals);
 
     nbyLine = BitmapBytePad(width);
-    pbits = malloc(height * nbyLine);
+    pbits = xallocarray(height, nbyLine);
     if (!pbits) {
         (*pDrawable->pScreen->DestroyPixmap) (pPixmap);
         FreeScratchGC(pGCtmp);
diff --git a/mi/miinitext.c b/mi/miinitext.c
index 086d2c3..5fc44e3 100644
--- a/mi/miinitext.c
+++ b/mi/miinitext.c
@@ -352,8 +352,8 @@ NewExtensionModuleList(int size)
         numExtensionModules = 0;
 
     n = numExtensionModules + size;
-    ExtensionModuleList = realloc(ExtensionModuleList,
-                                  n * sizeof(ExtensionModule));
+    ExtensionModuleList = reallocarray(ExtensionModuleList, n,
+                                       sizeof(ExtensionModule));
     if (ExtensionModuleList == NULL) {
         ExtensionModuleList = save;
         return NULL;
diff --git a/mi/mipoly.c b/mi/mipoly.c
index a332376..a97e2bb 100644
--- a/mi/mipoly.c
+++ b/mi/mipoly.c
@@ -412,8 +412,8 @@ miFillConvexPoly(DrawablePtr dst, GCPtr pgc, int count, DDXPointPtr ptsIn)
     dy = ymax - ymin + 1;
     if ((count < 3) || (dy < 0))
         return TRUE;
-    ptsOut = FirstPoint = malloc(sizeof(DDXPointRec) * dy);
-    width = FirstWidth = malloc(sizeof(int) * dy);
+    ptsOut = FirstPoint = xallocarray(dy, sizeof(DDXPointRec));
+    width = FirstWidth = xallocarray(dy, sizeof(int));
     if (!FirstPoint || !FirstWidth) {
         free(FirstWidth);
         free(FirstPoint);
diff --git a/mi/mipolypnt.c b/mi/mipolypnt.c
index 4fa521d..1c4150d 100644
--- a/mi/mipolypnt.c
+++ b/mi/mipolypnt.c
@@ -67,7 +67,7 @@ miPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, /* Origin or Previous */
     int i;
     xPoint *ppt;
 
-    if (!(pwidthInit = malloc(npt * sizeof(int))))
+    if (!(pwidthInit = xallocarray(npt, sizeof(int))))
         return;
 
     /* make pointlist origin relative */
diff --git a/mi/mipolyrect.c b/mi/mipolyrect.c
index 8308225..7ebf9db 100644
--- a/mi/mipolyrect.c
+++ b/mi/mipolyrect.c
@@ -88,7 +88,7 @@ miPolyRectangle(DrawablePtr pDraw, GCPtr pGC, int nrects, xRectangle *pRects)
         offset2 = pGC->lineWidth;
         offset1 = offset2 >> 1;
         offset3 = offset2 - offset1;
-        tmp = malloc(ntmp * sizeof(xRectangle));
+        tmp = xallocarray(ntmp, sizeof(xRectangle));
         if (!tmp)
             return;
         t = tmp;
diff --git a/mi/miwideline.c b/mi/miwideline.c
index 452d74f..3baa99b 100644
--- a/mi/miwideline.c
+++ b/mi/miwideline.c
@@ -189,19 +189,16 @@ miSubtractSpans(SpanGroup * spanGroup, Spans * sub)
                                 int *newwid;
 
 #define EXTRA 8
-                                newPt =
-                                    (DDXPointPtr) realloc(spans->points,
-                                                          (spans->count +
-                                                           EXTRA) *
-                                                          sizeof(DDXPointRec));
+                                newPt = reallocarray(spans->points,
+                                                     spans->count + EXTRA,
+                                                     sizeof(DDXPointRec));
                                 if (!newPt)
                                     break;
                                 spansPt = newPt + (spansPt - spans->points);
                                 spans->points = newPt;
-                                newwid =
-                                    (int *) realloc(spans->widths,
-                                                    (spans->count +
-                                                     EXTRA) * sizeof(int));
+                                newwid = reallocarray(spans->widths,
+                                                      spans->count + EXTRA,
+                                                      sizeof(int));
                                 if (!newwid)
                                     break;
                                 spansWid = newwid + (spansWid - spans->widths);
@@ -240,8 +237,8 @@ miAppendSpans(SpanGroup * spanGroup, SpanGroup * otherGroup, Spans * spans)
     if (spansCount > 0) {
         if (spanGroup->size == spanGroup->count) {
             spanGroup->size = (spanGroup->size + 8) * 2;
-            spanGroup->group = (Spans *)
-                realloc(spanGroup->group, sizeof(Spans) * spanGroup->size);
+            spanGroup->group =
+                reallocarray(spanGroup->group, sizeof(Spans), spanGroup->size);
         }
 
         spanGroup->group[spanGroup->count] = *spans;
@@ -456,8 +453,8 @@ miFillUniqueSpanGroup(DrawablePtr pDraw, GCPtr pGC, SpanGroup * spanGroup)
         ylength = spanGroup->ymax - ymin + 1;
 
         /* Allocate Spans for y buckets */
-        yspans = malloc(ylength * sizeof(Spans));
-        ysizes = malloc(ylength * sizeof(int));
+        yspans = xallocarray(ylength, sizeof(Spans));
+        ysizes = xallocarray(ylength, sizeof(int));
 
         if (!yspans || !ysizes) {
             free(yspans);
@@ -491,12 +488,11 @@ miFillUniqueSpanGroup(DrawablePtr pDraw, GCPtr pGC, SpanGroup * spanGroup)
                         int *newwidths;
 
                         ysizes[index] = (ysizes[index] + 8) * 2;
-                        newpoints = (DDXPointPtr) realloc(newspans->points,
-                                                          ysizes[index] *
-                                                          sizeof(DDXPointRec));
-                        newwidths =
-                            (int *) realloc(newspans->widths,
-                                            ysizes[index] * sizeof(int));
+                        newpoints = reallocarray(newspans->points,
+                                                 ysizes[index],
+                                                 sizeof(DDXPointRec));
+                        newwidths = reallocarray(newspans->widths,
+                                                 ysizes[index], sizeof(int));
                         if (!newpoints || !newwidths) {
                             for (i = 0; i < ylength; i++) {
                                 free(yspans[i].points);
@@ -525,8 +521,8 @@ miFillUniqueSpanGroup(DrawablePtr pDraw, GCPtr pGC, SpanGroup * spanGroup)
         }                       /* for i thorough Spans */
 
         /* Now sort by x and uniquify each bucket into the final array */
-        points = malloc(count * sizeof(DDXPointRec));
-        widths = malloc(count * sizeof(int));
+        points = xallocarray(count, sizeof(DDXPointRec));
+        widths = xallocarray(count, sizeof(int));
         if (!points || !widths) {
             for (i = 0; i < ylength; i++) {
                 free(yspans[i].points);
@@ -573,10 +569,10 @@ miFillUniqueSpanGroup(DrawablePtr pDraw, GCPtr pGC, SpanGroup * spanGroup)
 static Bool
 InitSpans(Spans * spans, size_t nspans)
 {
-    spans->points = malloc(nspans * sizeof(*spans->points));
+    spans->points = xallocarray(nspans, sizeof(*spans->points));
     if (!spans->points)
         return FALSE;
-    spans->widths = malloc(nspans * sizeof(*spans->widths));
+    spans->widths = xallocarray(nspans, sizeof(*spans->widths));
     if (!spans->widths) {
         free(spans->points);
         return FALSE;
diff --git a/mi/miwindow.c b/mi/miwindow.c
index a1af3a7..7574239 100644
--- a/mi/miwindow.c
+++ b/mi/miwindow.c
@@ -777,9 +777,9 @@ miSpriteTrace(SpritePtr pSprite, int x, int y)
             ) {
             if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize) {
                 pSprite->spriteTraceSize += 10;
-                pSprite->spriteTrace = realloc(pSprite->spriteTrace,
-                                               pSprite->spriteTraceSize *
-                                               sizeof(WindowPtr));
+                pSprite->spriteTrace = reallocarray(pSprite->spriteTrace,
+                                                    pSprite->spriteTraceSize,
+                                                    sizeof(WindowPtr));
             }
             pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
             pWin = pWin->firstChild;
diff --git a/mi/mizerarc.c b/mi/mizerarc.c
index b216cf4..e1b5f0c 100644
--- a/mi/mizerarc.c
+++ b/mi/mizerarc.c
@@ -671,7 +671,7 @@ miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
     numPts = maxPts << 2;
     dospans = (pGC->fillStyle != FillSolid);
     if (dospans) {
-        widths = malloc(sizeof(int) * numPts);
+        widths = xallocarray(numPts, sizeof(int));
         if (!widths)
             return;
         maxw = 0;
@@ -687,7 +687,7 @@ miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
                    (unsigned char *) pGC->dash, (int) pGC->numInDashList,
                    &dinfo.dashOffsetInit);
     }
-    points = malloc(sizeof(DDXPointRec) * numPts);
+    points = xallocarray(numPts, sizeof(DDXPointRec));
     if (!points) {
         if (dospans) {
             free(widths);
diff --git a/mi/mizerline.c b/mi/mizerline.c
index 5a24470..2f22d23 100644
--- a/mi/mizerline.c
+++ b/mi/mizerline.c
@@ -150,8 +150,8 @@ miZeroLine(DrawablePtr pDraw, GCPtr pGC, int mode,      /* Origin or Previous */
     width = xright - xleft + 1;
     height = ybottom - ytop + 1;
     list_len = (height >= width) ? height : width;
-    pspanInit = malloc(list_len * sizeof(DDXPointRec));
-    pwidthInit = malloc(list_len * sizeof(int));
+    pspanInit = xallocarray(list_len, sizeof(DDXPointRec));
+    pwidthInit = xallocarray(list_len, sizeof(int));
     if (!pspanInit || !pwidthInit) {
         free(pspanInit);
         free(pwidthInit);
diff --git a/miext/damage/damage.c b/miext/damage/damage.c
index 6ef7f9d..ce20169 100644
--- a/miext/damage/damage.c
+++ b/miext/damage/damage.c
@@ -1293,7 +1293,7 @@ damageText(DrawablePtr pDrawable,
     if (!checkGCDamage(pDrawable, pGC))
         return;
 
-    charinfo = malloc(count * sizeof(CharInfoPtr));
+    charinfo = xallocarray(count, sizeof(CharInfoPtr));
     if (!charinfo)
         return;
 
diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c
index a8f296a..1f78e3f 100644
--- a/miext/rootless/rootlessWindow.c
+++ b/miext/rootless/rootlessWindow.c
@@ -949,7 +949,7 @@ StartFrameResize(WindowPtr pWin, Bool gravity,
             copy_rect_width = copy_rect.x2 - copy_rect.x1;
             copy_rect_height = copy_rect.y2 - copy_rect.y1;
             copy_rowbytes = ((copy_rect_width * Bpp) + 31) & ~31;
-            gResizeDeathBits = malloc(copy_rowbytes * copy_rect_height);
+            gResizeDeathBits = xallocarray(copy_rowbytes, copy_rect_height);
 
             if (copy_rect_width * copy_rect_height >
                 rootless_CopyBytes_threshold &&
@@ -998,7 +998,7 @@ StartFrameResize(WindowPtr pWin, Bool gravity,
 
         RootlessStartDrawing(pWin);
 
-        gResizeDeathBits = malloc(winRec->bytesPerRow * winRec->height);
+        gResizeDeathBits = xallocarray(winRec->bytesPerRow, winRec->height);
 
         memcpy(gResizeDeathBits, winRec->pixelData,
                winRec->bytesPerRow * winRec->height);
diff --git a/miext/shadow/shalloc.c b/miext/shadow/shalloc.c
index e555135..6a79085 100644
--- a/miext/shadow/shalloc.c
+++ b/miext/shadow/shalloc.c
@@ -44,6 +44,6 @@ shadowAlloc(int width, int height, int bpp)
 
     /* Cant use PixmapBytePad -- the structure is probably not initialized yet */
     stride = BitmapBytePad(width * bpp);
-    fb = malloc(stride * height);
+    fb = xallocarray(stride, height);
     return fb;
 }
commit 70f4a0e6bd18055cc9cb6685253bf5e07b125657
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 14:40:39 2015 -0700

    Convert exa & fb to new *allocarray functions
    
    v2: fixup whitespace
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 5aa7d10..b26d5c8 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -386,7 +386,7 @@ exaHWCopyNtoN(DrawablePtr pSrcDrawable,
     exaGetDrawableDeltas(pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
     exaGetDrawableDeltas(pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
 
-    rects = malloc(nbox * sizeof(xRectangle));
+    rects = xallocarray(nbox, sizeof(xRectangle));
 
     if (rects) {
         int i;
@@ -626,7 +626,7 @@ exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
         return;
     }
 
-    prect = malloc(sizeof(xRectangle) * npt);
+    prect = xallocarray(npt, sizeof(xRectangle));
     for (i = 0; i < npt; i++) {
         prect[i].x = ppt[i].x;
         prect[i].y = ppt[i].y;
@@ -667,7 +667,7 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
         return;
     }
 
-    prect = malloc(sizeof(xRectangle) * (npt - 1));
+    prect = xallocarray(npt - 1, sizeof(xRectangle));
     x1 = ppt[0].x;
     y1 = ppt[0].y;
     /* If we have any non-horizontal/vertical, fall back. */
@@ -738,7 +738,7 @@ exaPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg)
         }
     }
 
-    prect = malloc(sizeof(xRectangle) * nseg);
+    prect = xallocarray(nseg, sizeof(xRectangle));
     for (i = 0; i < nseg; i++) {
         if (pSeg[i].x1 < pSeg[i].x2) {
             prect[i].x = pSeg[i].x1;
diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
index 41f3694..cf21ea9 100644
--- a/exa/exa_glyphs.c
+++ b/exa/exa_glyphs.c
@@ -211,8 +211,8 @@ exaRealizeGlyphCaches(ScreenPtr pScreen, unsigned int format)
 
         cache->picture = pPicture;
         cache->picture->refcnt++;
-        cache->hashEntries = malloc(sizeof(int) * cache->hashSize);
-        cache->glyphs = malloc(sizeof(ExaCachedGlyphRec) * cache->size);
+        cache->hashEntries = xallocarray(cache->hashSize, sizeof(int));
+        cache->glyphs = xallocarray(cache->size, sizeof(ExaCachedGlyphRec));
         cache->glyphCount = 0;
 
         if (!cache->hashEntries || !cache->glyphs)
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index cf66327..7d3fca7 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -205,8 +205,8 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
 
         /* Do we need to allocate our system buffer? */
         if (!pExaPixmap->sys_ptr) {
-            pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch *
-                                         pPixmap->drawable.height);
+            pExaPixmap->sys_ptr = xallocarray(pExaPixmap->sys_pitch,
+                                              pPixmap->drawable.height);
             if (!pExaPixmap->sys_ptr)
                 FatalError("EXA: malloc failed for size %d bytes\n",
                            pExaPixmap->sys_pitch * pPixmap->drawable.height);
diff --git a/fb/fbcopy.c b/fb/fbcopy.c
index 5bbabc3..6af10cc 100644
--- a/fb/fbcopy.c
+++ b/fb/fbcopy.c
@@ -194,7 +194,7 @@ fbCopyNto1(DrawablePtr pSrcDrawable,
             height = pbox->y2 - pbox->y1;
 
             tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
-            tmp = malloc(tmpStride * height * sizeof(FbStip));
+            tmp = xallocarray(tmpStride * height, sizeof(FbStip));
             if (!tmp)
                 return;
 
diff --git a/fb/fbpict.c b/fb/fbpict.c
index c8378ad..021f178 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -124,7 +124,7 @@ fbGlyphs(CARD8 op,
     pixman_glyph_cache_freeze (glyphCache);
 
     if (n_glyphs > N_STACK_GLYPHS) {
-	if (!(pglyphs = malloc (n_glyphs * sizeof (pixman_glyph_t))))
+	if (!(pglyphs = xallocarray(n_glyphs, sizeof(pixman_glyph_t))))
 	    goto out;
     }
 
commit 4fe6b03b97ab8dbb32e4908e46be350d7f7d336f
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 14:36:07 2015 -0700

    Convert XKB to new *allocarray functions
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>
    Acked-by: Daniel Stone <daniels at collabora.com>

diff --git a/xkb/XKBAlloc.c b/xkb/XKBAlloc.c
index 78c9837..18557b8 100644
--- a/xkb/XKBAlloc.c
+++ b/xkb/XKBAlloc.c
@@ -56,8 +56,8 @@ XkbAllocCompatMap(XkbDescPtr xkb, unsigned which, unsigned nSI)
         if (compat->sym_interpret == NULL)
             compat->num_si = 0;
         prev_interpret = compat->sym_interpret;
-        compat->sym_interpret = realloc(compat->sym_interpret,
-                                        nSI * sizeof(XkbSymInterpretRec));
+        compat->sym_interpret = reallocarray(compat->sym_interpret,
+                                             nSI, sizeof(XkbSymInterpretRec));
         if (compat->sym_interpret == NULL) {
             free(prev_interpret);
             compat->size_si = compat->num_si = 0;
@@ -159,9 +159,9 @@ XkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases)
         else if (nTotalAliases > names->num_key_aliases) {
             XkbKeyAliasRec *prev_aliases = names->key_aliases;
 
-            names->key_aliases = realloc(names->key_aliases,
-                                         nTotalAliases *
-                                         sizeof(XkbKeyAliasRec));
+            names->key_aliases = reallocarray(names->key_aliases,
+                                              nTotalAliases,
+                                              sizeof(XkbKeyAliasRec));
             if (names->key_aliases != NULL) {
                 memset(&names->key_aliases[names->num_key_aliases], 0,
                        (nTotalAliases -
@@ -184,8 +184,8 @@ XkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases)
         else if (nTotalRG > names->num_rg) {
             Atom *prev_radio_groups = names->radio_groups;
 
-            names->radio_groups = realloc(names->radio_groups,
-                                          nTotalRG * sizeof(Atom));
+            names->radio_groups = reallocarray(names->radio_groups,
+                                               nTotalRG, sizeof(Atom));
             if (names->radio_groups != NULL) {
                 memset(&names->radio_groups[names->num_rg], 0,
                        (nTotalRG - names->num_rg) * sizeof(Atom));
diff --git a/xkb/XKBGAlloc.c b/xkb/XKBGAlloc.c
index 25917d3..e9f55fa 100644
--- a/xkb/XKBGAlloc.c
+++ b/xkb/XKBGAlloc.c
@@ -409,7 +409,7 @@ XkbGeomRealloc(void **buffer, int szItems, int nrItems,
         return FALSE;
     /* Check if there is need to resize. */
     if (nrItems != szItems)
-        if (!(items = realloc(items, nrItems * itemSize)))
+        if (!(items = reallocarray(items, nrItems, itemSize)))
             return FALSE;
     /* Clear specified items to zero. */
     switch (clearance) {
diff --git a/xkb/XKBMAlloc.c b/xkb/XKBMAlloc.c
index 37ed1a7..dbc1389 100644
--- a/xkb/XKBMAlloc.c
+++ b/xkb/XKBMAlloc.c
@@ -80,7 +80,7 @@ XkbAllocClientMap(XkbDescPtr xkb, unsigned which, unsigned nTotalTypes)
             XkbKeyTypeRec *prev_types = map->types;
 
             map->types =
-                realloc(map->types, nTotalTypes * sizeof(XkbKeyTypeRec));
+                reallocarray(map->types, nTotalTypes, sizeof(XkbKeyTypeRec));
             if (map->types == NULL) {
                 free(prev_types);
                 map->num_types = map->size_types = 0;
@@ -177,7 +177,7 @@ XkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions)
             XkbAction *prev_acts = map->acts;
 
             need = map->num_acts + nNewActions;
-            map->acts = realloc(map->acts, need * sizeof(XkbAction));
+            map->acts = reallocarray(map->acts, need, sizeof(XkbAction));
             if (map->acts == NULL) {
                 free(prev_acts);
                 map->num_acts = map->size_acts = 0;
@@ -309,7 +309,7 @@ XkbResizeKeyType(XkbDescPtr xkb,
 
         if ((map_count > type->map_count) || (type->map == NULL))
             type->map =
-                realloc(type->map, map_count * sizeof(XkbKTMapEntryRec));
+                reallocarray(type->map, map_count, sizeof(XkbKTMapEntryRec));
         if (!type->map) {
             free(prev_map);
             return BadAlloc;
@@ -318,8 +318,8 @@ XkbResizeKeyType(XkbDescPtr xkb,
             XkbModsRec *prev_preserve = type->preserve;
 
             if ((map_count > type->map_count) || (type->preserve == NULL)) {
-                type->preserve = realloc(type->preserve,
-                                         map_count * sizeof(XkbModsRec));
+                type->preserve = reallocarray(type->preserve,
+                                              map_count, sizeof(XkbModsRec));
             }
             if (!type->preserve) {
                 free(prev_preserve);
@@ -336,8 +336,8 @@ XkbResizeKeyType(XkbDescPtr xkb,
     if ((new_num_lvls > type->num_levels) || (type->level_names == NULL)) {
         Atom *prev_level_names = type->level_names;
 
-        type->level_names = realloc(type->level_names,
-                                    new_num_lvls * sizeof(Atom));
+        type->level_names = reallocarray(type->level_names,
+                                         new_num_lvls, sizeof(Atom));
         if (!type->level_names) {
             free(prev_level_names);
             return BadAlloc;
@@ -659,9 +659,9 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
             if (xkb->map->key_sym_map) {
                 XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map;
 
-                xkb->map->key_sym_map = realloc(xkb->map->key_sym_map,
-                                                (maxKC +
-                                                 1) * sizeof(XkbSymMapRec));
+                xkb->map->key_sym_map = reallocarray(xkb->map->key_sym_map,
+                                                     maxKC + 1,
+                                                     sizeof(XkbSymMapRec));
                 if (!xkb->map->key_sym_map) {
                     free(prev_key_sym_map);
                     return BadAlloc;
@@ -680,8 +680,9 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
             if (xkb->map->modmap) {
                 unsigned char *prev_modmap = xkb->map->modmap;
 
-                xkb->map->modmap = realloc(xkb->map->modmap,
-                                           (maxKC + 1) * sizeof(unsigned char));
+                xkb->map->modmap = reallocarray(xkb->map->modmap,
+                                                maxKC + 1,
+                                                sizeof(unsigned char));
                 if (!xkb->map->modmap) {
                     free(prev_modmap);
                     return BadAlloc;
@@ -702,9 +703,9 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
             if (xkb->server->behaviors) {
                 XkbBehavior *prev_behaviors = xkb->server->behaviors;
 
-                xkb->server->behaviors = realloc(xkb->server->behaviors,
-                                                 (maxKC +
-                                                  1) * sizeof(XkbBehavior));
+                xkb->server->behaviors = reallocarray(xkb->server->behaviors,
+                                                      maxKC + 1,
+                                                      sizeof(XkbBehavior));
                 if (!xkb->server->behaviors) {
                     free(prev_behaviors);
                     return BadAlloc;
@@ -724,9 +725,9 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
             if (xkb->server->key_acts) {
                 unsigned short *prev_key_acts = xkb->server->key_acts;
 
-                xkb->server->key_acts = realloc(xkb->server->key_acts,
-                                                (maxKC +
-                                                 1) * sizeof(unsigned short));
+                xkb->server->key_acts = reallocarray(xkb->server->key_acts,
+                                                     maxKC + 1,
+                                                     sizeof(unsigned short));
                 if (!xkb->server->key_acts) {
                     free(prev_key_acts);
                     return BadAlloc;
@@ -746,9 +747,9 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
             if (xkb->server->vmodmap) {
                 unsigned short *prev_vmodmap = xkb->server->vmodmap;
 
-                xkb->server->vmodmap = realloc(xkb->server->vmodmap,
-                                               (maxKC +
-                                                1) * sizeof(unsigned short));
+                xkb->server->vmodmap = reallocarray(xkb->server->vmodmap,
+                                                    maxKC + 1,
+                                                    sizeof(unsigned short));
                 if (!xkb->server->vmodmap) {
                     free(prev_vmodmap);
                     return BadAlloc;
@@ -769,8 +770,8 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
         if ((xkb->names) && (xkb->names->keys)) {
             XkbKeyNameRec *prev_keys = xkb->names->keys;
 
-            xkb->names->keys = realloc(xkb->names->keys,
-                                       (maxKC + 1) * sizeof(XkbKeyNameRec));
+            xkb->names->keys = reallocarray(xkb->names->keys,
+                                            maxKC + 1, sizeof(XkbKeyNameRec));
             if (!xkb->names->keys) {
                 free(prev_keys);
                 return BadAlloc;
diff --git a/xkb/maprules.c b/xkb/maprules.c
index 28148d9..8e22779 100644
--- a/xkb/maprules.c
+++ b/xkb/maprules.c
@@ -89,11 +89,11 @@ InputLineAddChar(InputLine * line, int ch)
 {
     if (line->num_line >= line->sz_line) {
         if (line->line == line->buf) {
-            line->line = malloc(line->sz_line * 2);
+            line->line = xallocarray(line->sz_line, 2);
             memcpy(line->line, line->buf, line->sz_line);
         }
         else {
-            line->line = realloc((char *) line->line, line->sz_line * 2);
+            line->line = reallocarray(line->line, line->sz_line, 2);
         }
         line->sz_line *= 2;
     }
@@ -897,8 +897,8 @@ XkbRF_AddRule(XkbRF_RulesPtr rules)
     }
     else if (rules->num_rules >= rules->sz_rules) {
         rules->sz_rules *= 2;
-        rules->rules = realloc(rules->rules,
-                               rules->sz_rules * sizeof(XkbRF_RuleRec));
+        rules->rules = reallocarray(rules->rules,
+                                    rules->sz_rules, sizeof(XkbRF_RuleRec));
     }
     if (!rules->rules) {
         rules->sz_rules = rules->num_rules = 0;
@@ -919,8 +919,8 @@ XkbRF_AddGroup(XkbRF_RulesPtr rules)
     }
     else if (rules->num_groups >= rules->sz_groups) {
         rules->sz_groups *= 2;
-        rules->groups = realloc(rules->groups,
-                                rules->sz_groups * sizeof(XkbRF_GroupRec));
+        rules->groups = reallocarray(rules->groups,
+                                     rules->sz_groups, sizeof(XkbRF_GroupRec));
     }
     if (!rules->groups) {
         rules->sz_groups = rules->num_groups = 0;
diff --git a/xkb/xkb.c b/xkb/xkb.c
index f3988f9..294cdf8 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -2216,12 +2216,11 @@ SetKeyBehaviors(XkbSrvInfoPtr xkbi,
     }
 
     if (maxRG > (int) xkbi->nRadioGroups) {
-        int sz = maxRG * sizeof(XkbRadioGroupRec);
-
         if (xkbi->radioGroups)
-            xkbi->radioGroups = realloc(xkbi->radioGroups, sz);
+            xkbi->radioGroups = reallocarray(xkbi->radioGroups, maxRG,
+                                             sizeof(XkbRadioGroupRec));
         else
-            xkbi->radioGroups = calloc(1, sz);
+            xkbi->radioGroups = calloc(maxRG, sizeof(XkbRadioGroupRec));
         if (xkbi->radioGroups) {
             if (xkbi->nRadioGroups)
                 memset(&xkbi->radioGroups[xkbi->nRadioGroups], 0,
@@ -2700,15 +2699,16 @@ XkbSendCompatMap(ClientPtr client,
     char *data;
     int size;
 
-    size = rep->length * 4;
-    if (size > 0) {
-        data = malloc(size);
+    if (rep->length > 0) {
+        data = xallocarray(rep->length, 4);
         if (data) {
             register unsigned i, bit;
             xkbModsWireDesc *grp;
             XkbSymInterpretPtr sym = &compat->sym_interpret[rep->firstSI];
             xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) data;
 
+            size = rep->length * 4;
+
             for (i = 0; i < rep->nSI; i++, sym++, wire++) {
                 wire->sym = sym->sym;
                 wire->mods = sym->mods;
@@ -2856,9 +2856,9 @@ _XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
 
         if ((unsigned) (req->firstSI + req->nSI) > compat->num_si) {
             compat->num_si = req->firstSI + req->nSI;
-            compat->sym_interpret = realloc(compat->sym_interpret,
-                                            compat->num_si *
-                                            sizeof(XkbSymInterpretRec));
+            compat->sym_interpret = reallocarray(compat->sym_interpret,
+                                                 compat->num_si,
+                                                 sizeof(XkbSymInterpretRec));
             if (!compat->sym_interpret) {
                 compat->num_si = 0;
                 return BadAlloc;
@@ -3086,14 +3086,15 @@ XkbSendIndicatorMap(ClientPtr client,
     register int i;
     register unsigned bit;
 
-    length = rep->length * 4;
-    if (length > 0) {
+    if (rep->length > 0) {
         CARD8 *to;
 
-        to = map = malloc(length);
+        to = map = xallocarray(rep->length, 4);
         if (map) {
             xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *) to;
 
+            length = rep->length * 4;
+
             for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
                 if (rep->which & bit) {
                     wire->flags = indicators->maps[i].flags;
@@ -4863,7 +4864,6 @@ XkbComputeGetGeometryReplySize(XkbGeometryPtr geom,
     }
     return Success;
 }
-
 static int
 XkbSendGeometry(ClientPtr client,
                 XkbGeometryPtr geom, xkbGetGeometryReply * rep, Bool freeGeom)
@@ -4872,10 +4872,10 @@ XkbSendGeometry(ClientPtr client,
     int len;
 
     if (geom != NULL) {
-        len = rep->length * 4;
-        start = desc = malloc(len);
+        start = desc = xallocarray(rep->length, 4);
         if (!start)
             return BadAlloc;
+        len = rep->length * 4;
         desc = XkbWriteCountedString(desc, geom->label_font, client->swapped);
         if (rep->nProperties > 0)
             desc = XkbWriteGeomProperties(desc, geom, client->swapped);
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 2a196f1..9dd1cbd 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1103,8 +1103,8 @@ _XkbNextFreeFilter(XkbSrvInfoPtr xkbi)
         }
     }
     xkbi->szFilters *= 2;
-    xkbi->filters = realloc(xkbi->filters,
-                            xkbi->szFilters * sizeof(XkbFilterRec));
+    xkbi->filters = reallocarray(xkbi->filters,
+                                 xkbi->szFilters, sizeof(XkbFilterRec));
     /* 6/21/93 (ef) -- XXX! deal with allocation failure */
     memset(&xkbi->filters[xkbi->szFilters / 2], 0,
            (xkbi->szFilters / 2) * sizeof(XkbFilterRec));
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 6019f0f..25b5a36 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -946,8 +946,8 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
 
         if (src->map->syms) {
             if (src->map->size_syms != dst->map->size_syms) {
-                tmp = realloc(dst->map->syms,
-                              src->map->size_syms * sizeof(KeySym));
+                tmp = reallocarray(dst->map->syms,
+                                   src->map->size_syms, sizeof(KeySym));
                 if (!tmp)
                     return FALSE;
                 dst->map->syms = tmp;
@@ -965,8 +965,8 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
 
         if (src->map->key_sym_map) {
             if (src->max_key_code != dst->max_key_code) {
-                tmp = realloc(dst->map->key_sym_map,
-                              (src->max_key_code + 1) * sizeof(XkbSymMapRec));
+                tmp = reallocarray(dst->map->key_sym_map,
+                                   src->max_key_code + 1, sizeof(XkbSymMapRec));
                 if (!tmp)
                     return FALSE;
                 dst->map->key_sym_map = tmp;
@@ -983,8 +983,8 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
             if (src->map->num_types > dst->map->size_types ||
                 !dst->map->types || !dst->map->size_types) {
                 if (dst->map->types && dst->map->size_types) {
-                    tmp = realloc(dst->map->types,
-                                  src->map->num_types * sizeof(XkbKeyTypeRec));
+                    tmp = reallocarray(dst->map->types, src->map->num_types,
+                                       sizeof(XkbKeyTypeRec));
                     if (!tmp)
                         return FALSE;
                     dst->map->types = tmp;
@@ -1020,8 +1020,8 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
                     if (stype->num_levels != dtype->num_levels &&
                         dtype->num_levels && dtype->level_names &&
                         i < dst->map->num_types) {
-                        tmp = realloc(dtype->level_names,
-                                      stype->num_levels * sizeof(Atom));
+                        tmp = reallocarray(dtype->level_names,
+                                           stype->num_levels, sizeof(Atom));
                         if (!tmp)
                             continue;
                         dtype->level_names = tmp;
@@ -1053,17 +1053,17 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
                         if (stype->map_count != dtype->map_count &&
                             dtype->map_count && dtype->map &&
                             i < dst->map->num_types) {
-                            tmp = realloc(dtype->map,
-                                          stype->map_count *
-                                          sizeof(XkbKTMapEntryRec));
+                            tmp = reallocarray(dtype->map,
+                                               stype->map_count,
+                                               sizeof(XkbKTMapEntryRec));
                             if (!tmp)
                                 return FALSE;
                             dtype->map = tmp;
                         }
                         else if (!dtype->map_count || !dtype->map ||
                                  i >= dst->map->num_types) {
-                            tmp = malloc(stype->map_count *
-                                         sizeof(XkbKTMapEntryRec));
+                            tmp = xallocarray(stype->map_count,
+                                              sizeof(XkbKTMapEntryRec));
                             if (!tmp)
                                 return FALSE;
                             dtype->map = tmp;
@@ -1082,16 +1082,17 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
                         if (stype->map_count != dtype->map_count &&
                             dtype->map_count && dtype->preserve &&
                             i < dst->map->num_types) {
-                            tmp = realloc(dtype->preserve,
-                                          stype->map_count *
-                                          sizeof(XkbModsRec));
+                            tmp = reallocarray(dtype->preserve,
+                                               stype->map_count,
+                                               sizeof(XkbModsRec));
                             if (!tmp)
                                 return FALSE;
                             dtype->preserve = tmp;
                         }
                         else if (!dtype->preserve || !dtype->map_count ||
                                  i >= dst->map->num_types) {
-                            tmp = malloc(stype->map_count * sizeof(XkbModsRec));
+                            tmp = xallocarray(stype->map_count,
+                                              sizeof(XkbModsRec));
                             if (!tmp)
                                 return FALSE;
                             dtype->preserve = tmp;
@@ -1192,8 +1193,8 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
 
         if (src->server->acts) {
             if (src->server->size_acts != dst->server->size_acts) {
-                tmp = realloc(dst->server->acts,
-                              src->server->size_acts * sizeof(XkbAction));
+                tmp = reallocarray(dst->server->acts,
+                                   src->server->size_acts, sizeof(XkbAction));
                 if (!tmp)
                     return FALSE;
                 dst->server->acts = tmp;
@@ -1210,8 +1211,8 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
 
         if (src->server->key_acts) {
             if (src->max_key_code != dst->max_key_code) {
-                tmp = realloc(dst->server->key_acts,
-                              (src->max_key_code + 1) * sizeof(unsigned short));
+                tmp = reallocarray(dst->server->key_acts,
+                                   src->max_key_code + 1, sizeof(unsigned short));
                 if (!tmp)
                     return FALSE;
                 dst->server->key_acts = tmp;
@@ -1226,8 +1227,8 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
 
         if (src->server->behaviors) {
             if (src->max_key_code != dst->max_key_code) {
-                tmp = realloc(dst->server->behaviors,
-                              (src->max_key_code + 1) * sizeof(XkbBehavior));
+                tmp = reallocarray(dst->server->behaviors,
+                                   src->max_key_code + 1, sizeof(XkbBehavior));
                 if (!tmp)
                     return FALSE;
                 dst->server->behaviors = tmp;
@@ -1244,8 +1245,8 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
 
         if (src->server->vmodmap) {
             if (src->max_key_code != dst->max_key_code) {
-                tmp = realloc(dst->server->vmodmap,
-                              (src->max_key_code + 1) * sizeof(unsigned short));
+                tmp = reallocarray(dst->server->vmodmap,
+                                   src->max_key_code + 1, sizeof(unsigned short));
                 if (!tmp)
                     return FALSE;
                 dst->server->vmodmap = tmp;
@@ -1281,8 +1282,8 @@ _XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
 
         if (src->names->keys) {
             if (src->max_key_code != dst->max_key_code) {
-                tmp = realloc(dst->names->keys,
-                              (src->max_key_code + 1) * sizeof(XkbKeyNameRec));
+                tmp = reallocarray(dst->names->keys, src->max_key_code + 1,
+                                   sizeof(XkbKeyNameRec));
                 if (!tmp)
                     return FALSE;
                 dst->names->keys = tmp;
@@ -1297,9 +1298,9 @@ _XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
 
         if (src->names->num_key_aliases) {
             if (src->names->num_key_aliases != dst->names->num_key_aliases) {
-                tmp = realloc(dst->names->key_aliases,
-                              src->names->num_key_aliases *
-                              sizeof(XkbKeyAliasRec));
+                tmp = reallocarray(dst->names->key_aliases,
+                                   src->names->num_key_aliases,
+                                   sizeof(XkbKeyAliasRec));
                 if (!tmp)
                     return FALSE;
                 dst->names->key_aliases = tmp;
@@ -1315,8 +1316,8 @@ _XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
 
         if (src->names->num_rg) {
             if (src->names->num_rg != dst->names->num_rg) {
-                tmp = realloc(dst->names->radio_groups,
-                              src->names->num_rg * sizeof(Atom));
+                tmp = reallocarray(dst->names->radio_groups,
+                                   src->names->num_rg, sizeof(Atom));
                 if (!tmp)
                     return FALSE;
                 dst->names->radio_groups = tmp;
@@ -1366,8 +1367,9 @@ _XkbCopyCompat(XkbDescPtr src, XkbDescPtr dst)
 
         if (src->compat->sym_interpret && src->compat->num_si) {
             if (src->compat->num_si != dst->compat->size_si) {
-                tmp = realloc(dst->compat->sym_interpret,
-                              src->compat->num_si * sizeof(XkbSymInterpretRec));
+                tmp = reallocarray(dst->compat->sym_interpret,
+                                   src->compat->num_si,
+                                   sizeof(XkbSymInterpretRec));
                 if (!tmp)
                     return FALSE;
                 dst->compat->sym_interpret = tmp;
@@ -1582,8 +1584,8 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
                          j < sshape->num_outlines;
                          j++, soutline++, doutline++) {
                         if (soutline->num_points) {
-                            tmp = malloc(soutline->num_points *
-                                         sizeof(XkbPointRec));
+                            tmp = xallocarray(soutline->num_points,
+                                              sizeof(XkbPointRec));
                             if (!tmp)
                                 return FALSE;
                             doutline->points = tmp;
@@ -1710,7 +1712,7 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
                 for (j = 0, srow = ssection->rows, drow = dsection->rows;
                      j < ssection->num_rows; j++, srow++, drow++) {
                     if (srow->num_keys) {
-                        tmp = malloc(srow->num_keys * sizeof(XkbKeyRec));
+                        tmp = xallocarray(srow->num_keys, sizeof(XkbKeyRec));
                         if (!tmp)
                             return FALSE;
                         drow->keys = tmp;
diff --git a/xkb/xkmread.c b/xkb/xkmread.c
index 0b9f0ef..1666e32 100644
--- a/xkb/xkmread.c
+++ b/xkb/xkmread.c
@@ -64,7 +64,7 @@ XkmInsureSize(void *oldPtr, int oldCount, int *newCountRtrn, int elemSize)
         oldPtr = calloc(newCount, elemSize);
     }
     else if (oldCount < newCount) {
-        oldPtr = realloc(oldPtr, newCount * elemSize);
+        oldPtr = reallocarray(oldPtr, newCount, elemSize);
         if (oldPtr != NULL) {
             char *tmp = (char *) oldPtr;
 
commit 1c56ac63c040280498c4a9d67b48c35b60070821
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 13:42:12 2015 -0700

    Convert top level extensions to new *allocarray functions
    
    v2: remove now useless parentheses
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/Xext/hashtable.c b/Xext/hashtable.c
index 471ecca..41b2e00 100644
--- a/Xext/hashtable.c
+++ b/Xext/hashtable.c
@@ -54,7 +54,7 @@ ht_create(int             keySize,
     ht->elements = 0;
     ht->bucketBits = INITHASHSIZE;
     numBuckets = 1 << ht->bucketBits;
-    ht->buckets = malloc(numBuckets * sizeof(*ht->buckets));
+    ht->buckets = xallocarray(numBuckets, sizeof(*ht->buckets));
     ht->cdata = cdata;
 
     if (ht->buckets) {
@@ -92,7 +92,7 @@ double_size(HashTable ht)
     int newNumBuckets = 1 << newBucketBits;
     int c;
 
-    newBuckets = malloc(newNumBuckets * sizeof(*ht->buckets));
+    newBuckets = xallocarray(newNumBuckets, sizeof(*ht->buckets));
     if (newBuckets) {
         for (c = 0; c < newNumBuckets; ++c) {
             xorg_list_init(&newBuckets[c]);
diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index 2bbae2f..209df29 100644
--- a/Xext/panoramiX.c
+++ b/Xext/panoramiX.c
@@ -747,13 +747,13 @@ PanoramiXMaybeAddDepth(DepthPtr pDepth)
 
     j = PanoramiXNumDepths;
     PanoramiXNumDepths++;
-    PanoramiXDepths = realloc(PanoramiXDepths,
-                              PanoramiXNumDepths * sizeof(DepthRec));
+    PanoramiXDepths = reallocarray(PanoramiXDepths,
+                                   PanoramiXNumDepths, sizeof(DepthRec));
     PanoramiXDepths[j].depth = pDepth->depth;
     PanoramiXDepths[j].numVids = 0;
     /* XXX suboptimal, should grow these dynamically */
     if (pDepth->numVids)
-        PanoramiXDepths[j].vids = malloc(sizeof(VisualID) * pDepth->numVids);
+        PanoramiXDepths[j].vids = xallocarray(pDepth->numVids, sizeof(VisualID));
     else
         PanoramiXDepths[j].vids = NULL;
 }
@@ -789,8 +789,8 @@ PanoramiXMaybeAddVisual(VisualPtr pVisual)
     /* found a matching visual on all screens, add it to the subset list */
     j = PanoramiXNumVisuals;
     PanoramiXNumVisuals++;
-    PanoramiXVisuals = realloc(PanoramiXVisuals,
-                               PanoramiXNumVisuals * sizeof(VisualRec));
+    PanoramiXVisuals = reallocarray(PanoramiXVisuals,
+                                    PanoramiXNumVisuals, sizeof(VisualRec));
 
     memcpy(&PanoramiXVisuals[j], pVisual, sizeof(VisualRec));
 
diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c
index 5291a4a..9eb29bd 100644
--- a/Xext/panoramiXprocs.c
+++ b/Xext/panoramiXprocs.c
@@ -1341,7 +1341,7 @@ PanoramiXPolyPoint(ClientPtr client)
     isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
     npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
     if (npoint > 0) {
-        origPts = malloc(npoint * sizeof(xPoint));
+        origPts = xallocarray(npoint, sizeof(xPoint));
         memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
         FOR_NSCREENS_FORWARD(j) {
 
@@ -1406,7 +1406,7 @@ PanoramiXPolyLine(ClientPtr client)
     isRoot = IS_ROOT_DRAWABLE(draw);
     npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
     if (npoint > 0) {
-        origPts = malloc(npoint * sizeof(xPoint));
+        origPts = xallocarray(npoint, sizeof(xPoint));
         memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
         FOR_NSCREENS_FORWARD(j) {
 
@@ -1475,7 +1475,7 @@ PanoramiXPolySegment(ClientPtr client)
         return BadLength;
     nsegs >>= 3;
     if (nsegs > 0) {
-        origSegs = malloc(nsegs * sizeof(xSegment));
+        origSegs = xallocarray(nsegs, sizeof(xSegment));
         memcpy((char *) origSegs, (char *) &stuff[1], nsegs * sizeof(xSegment));
         FOR_NSCREENS_FORWARD(j) {
 
@@ -1543,7 +1543,7 @@ PanoramiXPolyRectangle(ClientPtr client)
         return BadLength;
     nrects >>= 3;
     if (nrects > 0) {
-        origRecs = malloc(nrects * sizeof(xRectangle));
+        origRecs = xallocarray(nrects, sizeof(xRectangle));
         memcpy((char *) origRecs, (char *) &stuff[1],
                nrects * sizeof(xRectangle));
         FOR_NSCREENS_FORWARD(j) {
@@ -1610,7 +1610,7 @@ PanoramiXPolyArc(ClientPtr client)
         return BadLength;
     narcs /= sizeof(xArc);
     if (narcs > 0) {
-        origArcs = malloc(narcs * sizeof(xArc));
+        origArcs = xallocarray(narcs, sizeof(xArc));
         memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
         FOR_NSCREENS_FORWARD(j) {
 
@@ -1672,7 +1672,7 @@ PanoramiXFillPoly(ClientPtr client)
 
     count = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
     if (count > 0) {
-        locPts = malloc(count * sizeof(DDXPointRec));
+        locPts = xallocarray(count, sizeof(DDXPointRec));
         memcpy((char *) locPts, (char *) &stuff[1],
                count * sizeof(DDXPointRec));
         FOR_NSCREENS_FORWARD(j) {
@@ -1741,7 +1741,7 @@ PanoramiXPolyFillRectangle(ClientPtr client)
         return BadLength;
     things >>= 3;
     if (things > 0) {
-        origRects = malloc(things * sizeof(xRectangle));
+        origRects = xallocarray(things, sizeof(xRectangle));
         memcpy((char *) origRects, (char *) &stuff[1],
                things * sizeof(xRectangle));
         FOR_NSCREENS_FORWARD(j) {
@@ -1808,7 +1808,7 @@ PanoramiXPolyFillArc(ClientPtr client)
         return BadLength;
     narcs /= sizeof(xArc);
     if (narcs > 0) {
-        origArcs = malloc(narcs * sizeof(xArc));
+        origArcs = xallocarray(narcs, sizeof(xArc));
         memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
         FOR_NSCREENS_FORWARD(j) {
 
@@ -1988,8 +1988,7 @@ PanoramiXGetImage(ClientPtr client)
         if (linesPerBuf > h)
             linesPerBuf = h;
     }
-    length = linesPerBuf * widthBytesLine;
-    if (!(pBuf = malloc(length)))
+    if (!(pBuf = xallocarray(linesPerBuf, widthBytesLine)))
         return BadAlloc;
 
     WriteReplyToClient(client, sizeof(xGetImageReply), &xgi);
diff --git a/Xext/saver.c b/Xext/saver.c
index 2c14ea0..0e20467 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -853,7 +853,7 @@ ScreenSaverSetAttributes(ClientPtr client)
         goto bail;
     }
     /* over allocate for override redirect */
-    pAttr->values = values = malloc((len + 1) * sizeof(unsigned long));
+    pAttr->values = values = xallocarray(len + 1, sizeof(unsigned long));
     if (!values) {
         ret = BadAlloc;
         goto bail;
diff --git a/Xext/shape.c b/Xext/shape.c
index bb479b1..2fc789e 100644
--- a/Xext/shape.c
+++ b/Xext/shape.c
@@ -996,7 +996,7 @@ ProcShapeGetRectangles(ClientPtr client)
 
         nrects = RegionNumRects(region);
         box = RegionRects(region);
-        rects = malloc(nrects * sizeof(xRectangle));
+        rects = xallocarray(nrects, sizeof(xRectangle));
         if (!rects && nrects)
             return BadAlloc;
         for (i = 0; i < nrects; i++, box++) {
diff --git a/Xext/sync.c b/Xext/sync.c
index ba08cd1..4140561 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -620,7 +620,7 @@ SyncAwaitTriggerFired(SyncTrigger * pTrigger)
 
     pAwaitUnion = (SyncAwaitUnion *) pAwait->pHeader;
     numwaits = pAwaitUnion->header.num_waitconditions;
-    ppAwait = malloc(numwaits * sizeof(SyncAwait *));
+    ppAwait = xallocarray(numwaits, sizeof(SyncAwait *));
     if (!ppAwait)
         goto bail;
 
@@ -1514,7 +1514,7 @@ SyncAwaitPrologue(ClientPtr client, int items)
     /*  all the memory for the entire await list is allocated
      *  here in one chunk
      */
-    pAwaitUnion = malloc((items + 1) * sizeof(SyncAwaitUnion));
+    pAwaitUnion = xallocarray(items + 1, sizeof(SyncAwaitUnion));
     if (!pAwaitUnion)
         return NULL;
 
diff --git a/Xext/xcmisc.c b/Xext/xcmisc.c
index 1e91010..ed25650 100644
--- a/Xext/xcmisc.c
+++ b/Xext/xcmisc.c
@@ -101,7 +101,7 @@ ProcXCMiscGetXIDList(ClientPtr client)
     if (stuff->count > UINT32_MAX / sizeof(XID))
         return BadAlloc;
 
-    pids = (XID *) malloc(stuff->count * sizeof(XID));
+    pids = xallocarray(stuff->count, sizeof(XID));
     if (!pids) {
         return BadAlloc;
     }
diff --git a/Xext/xf86bigfont.c b/Xext/xf86bigfont.c
index 46b3242..95b5371 100644
--- a/Xext/xf86bigfont.c
+++ b/Xext/xf86bigfont.c
@@ -401,7 +401,7 @@ ProcXF86BigfontQueryFont(ClientPtr client)
             }
             else {
 #endif
-                pCI = malloc(nCharInfos * sizeof(xCharInfo));
+                pCI = xallocarray(nCharInfos, sizeof(xCharInfo));
                 if (!pCI)
                     return BadAlloc;
 #ifdef HAS_SHM
@@ -463,7 +463,7 @@ ProcXF86BigfontQueryFont(ClientPtr client)
             if (hashModulus > nCharInfos + 1)
                 hashModulus = nCharInfos + 1;
 
-            tmp = malloc((4 * nCharInfos + 1) * sizeof(CARD16));
+            tmp = xallocarray(4 * nCharInfos + 1, sizeof(CARD16));
             if (!tmp) {
                 if (!pDesc)
                     free(pCI);
diff --git a/Xext/xres.c b/Xext/xres.c
index 2737938..6b87c3d 100644
--- a/Xext/xres.c
+++ b/Xext/xres.c
@@ -223,7 +223,7 @@ ProcXResQueryClients(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xXResQueryClientsReq);
 
-    current_clients = malloc(currentMaxClients * sizeof(int));
+    current_clients = xallocarray(currentMaxClients, sizeof(int));
 
     num_clients = 0;
     for (i = 0; i < currentMaxClients; i++) {
diff --git a/Xext/xselinux_label.c b/Xext/xselinux_label.c
index 2c33d1c..8559385 100644
--- a/Xext/xselinux_label.c
+++ b/Xext/xselinux_label.c
@@ -64,7 +64,7 @@ SELinuxArraySet(SELinuxArrayRec * rec, unsigned key, void *val)
 {
     if (key >= rec->size) {
         /* Need to increase size of array */
-        rec->array = realloc(rec->array, (key + 1) * sizeof(val));
+        rec->array = reallocarray(rec->array, key + 1, sizeof(val));
         if (!rec->array)
             return FALSE;
         memset(rec->array + rec->size, 0, (key - rec->size + 1) * sizeof(val));
diff --git a/Xext/xvmain.c b/Xext/xvmain.c
index 0abf190..93e5f0c 100644
--- a/Xext/xvmain.c
+++ b/Xext/xvmain.c
@@ -1102,7 +1102,7 @@ XvFillColorKey(DrawablePtr pDraw, CARD32 key, RegionPtr region)
     (void) ChangeGC(NullClient, gc, GCForeground | GCSubwindowMode, pval);
     ValidateGC(pDraw, gc);
 
-    rects = malloc(nbox * sizeof(xRectangle));
+    rects = xallocarray(nbox, sizeof(xRectangle));
     if (rects) {
         for (i = 0; i < nbox; i++, pbox++) {
             rects[i].x = pbox->x1 - pDraw->x;
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 0857bce..1c586d0 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -471,9 +471,9 @@ DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to)
 
             oldTrace = to->focus->trace;
             memcpy(to->focus, from->focus, sizeof(FocusClassRec));
-            to->focus->trace = realloc(oldTrace,
-                                       to->focus->traceSize *
-                                       sizeof(WindowPtr));
+            to->focus->trace = reallocarray(oldTrace,
+                                            to->focus->traceSize,
+                                            sizeof(WindowPtr));
             if (!to->focus->trace && to->focus->traceSize)
                 FatalError("[Xi] no memory for trace.\n");
             memcpy(to->focus->trace, from->focus->trace,
diff --git a/Xi/getprop.c b/Xi/getprop.c
index 4d6ce63..19f18af 100644
--- a/Xi/getprop.c
+++ b/Xi/getprop.c
@@ -118,7 +118,7 @@ ProcXGetDeviceDontPropagateList(ClientPtr client)
             ClassFromMask(NULL, others->dontPropagateMask[i], i, &count, COUNT);
         if (count) {
             rep.count = count;
-            buf = (XEventClass *) malloc(rep.count * sizeof(XEventClass));
+            buf = xallocarray(rep.count, sizeof(XEventClass));
             rep.length = bytes_to_int32(rep.count * sizeof(XEventClass));
 
             tbuf = buf;
diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 8e8e4b0..e3b8f5a 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -221,7 +221,7 @@ list_atoms(DeviceIntPtr dev, int *natoms, Atom **atoms_return)
     if (nprops) {
         Atom *a;
 
-        atoms = malloc(nprops * sizeof(Atom));
+        atoms = xallocarray(nprops, sizeof(Atom));
         if (!atoms)
             return BadAlloc;
         a = atoms;
@@ -687,7 +687,6 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
 {
     XIPropertyPtr prop;
     int size_in_bytes;
-    int total_size;
     unsigned long total_len;
     XIPropertyValuePtr prop_value;
     XIPropertyValueRec new_value;
@@ -725,9 +724,8 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
     if (mode == PropModeReplace || len > 0) {
         void *new_data = NULL, *old_data = NULL;
 
-        total_size = total_len * size_in_bytes;
-        new_value.data = (void *) malloc(total_size);
-        if (!new_value.data && total_size) {
+        new_value.data = xallocarray(total_len, size_in_bytes);
+        if (!new_value.data && total_len && size_in_bytes) {
             if (add)
                 XIDestroyDeviceProperty(prop);
             return BadAlloc;
diff --git a/composite/compinit.c b/composite/compinit.c
index 3ac075a..cf61f2a 100644
--- a/composite/compinit.c
+++ b/composite/compinit.c
@@ -223,8 +223,8 @@ compRegisterAlternateVisuals(CompScreenPtr cs, VisualID * vids, int nVisuals)
 {
     VisualID *p;
 
-    p = realloc(cs->alternateVisuals,
-                sizeof(VisualID) * (cs->numAlternateVisuals + nVisuals));
+    p = reallocarray(cs->alternateVisuals,
+                     cs->numAlternateVisuals + nVisuals, sizeof(VisualID));
     if (p == NULL)
         return FALSE;
 
@@ -253,8 +253,8 @@ CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
     CompScreenPtr cs = GetCompScreen(pScreen);
     CompImplicitRedirectException *p;
 
-    p = realloc(cs->implicitRedirectExceptions,
-                sizeof(p[0]) * (cs->numImplicitRedirectExceptions + 1));
+    p = reallocarray(cs->implicitRedirectExceptions,
+                     cs->numImplicitRedirectExceptions + 1, sizeof(p[0]));
     if (p == NULL)
         return FALSE;
 
diff --git a/dbe/dbe.c b/dbe/dbe.c
index e5d928d..23f7e16 100644
--- a/dbe/dbe.c
+++ b/dbe/dbe.c
@@ -287,11 +287,10 @@ ProcDbeAllocateBackBufferName(ClientPtr client)
             }
 
             /* malloc/realloc a new array and initialize all elements to 0. */
-            pDbeWindowPriv->IDs = (XID *) realloc(pIDs,
-                                                  (pDbeWindowPriv->
-                                                   maxAvailableIDs +
-                                                   DBE_INCR_MAX_IDS) *
-                                                  sizeof(XID));
+            pDbeWindowPriv->IDs =
+                reallocarray(pIDs,
+                             pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS,
+                             sizeof(XID));
             if (!pDbeWindowPriv->IDs) {
                 return BadAlloc;
             }
@@ -470,7 +469,7 @@ ProcDbeSwapBuffers(ClientPtr client)
     dbeSwapInfo = (xDbeSwapInfo *) &stuff[1];
 
     /* Allocate array to record swap information. */
-    swapInfo = (DbeSwapInfoPtr) malloc(nStuff * sizeof(DbeSwapInfoRec));
+    swapInfo = xallocarray(nStuff, sizeof(DbeSwapInfoRec));
     if (swapInfo == NULL) {
         return BadAlloc;
     }
@@ -580,8 +579,7 @@ ProcDbeGetVisualInfo(ClientPtr client)
         return BadAlloc;
     /* Make sure any specified drawables are valid. */
     if (stuff->n != 0) {
-        if (!(pDrawables = (DrawablePtr *) malloc(stuff->n *
-                                                  sizeof(DrawablePtr)))) {
+        if (!(pDrawables = xallocarray(stuff->n, sizeof(DrawablePtr)))) {
             return BadAlloc;
         }
 
diff --git a/dbe/midbe.c b/dbe/midbe.c
index 8f75910..9684d45 100644
--- a/dbe/midbe.c
+++ b/dbe/midbe.c
@@ -87,7 +87,7 @@ miDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo * pScrVisInfo)
     }
 
     /* Allocate an array of XdbeVisualInfo items. */
-    if (!(visInfo = (XdbeVisualInfo *) malloc(count * sizeof(XdbeVisualInfo)))) {
+    if (!(visInfo = xallocarray(count, sizeof(XdbeVisualInfo)))) {
         return FALSE;           /* memory alloc failure */
     }
 
diff --git a/pseudoramiX/pseudoramiX.c b/pseudoramiX/pseudoramiX.c
index e59ca13..d8b2593 100644
--- a/pseudoramiX/pseudoramiX.c
+++ b/pseudoramiX/pseudoramiX.c
@@ -140,9 +140,9 @@ PseudoramiXAddScreen(int x, int y, int w, int h)
 
     if (pseudoramiXNumScreens == pseudoramiXScreensAllocated) {
         pseudoramiXScreensAllocated += pseudoramiXScreensAllocated + 1;
-        pseudoramiXScreens = realloc(pseudoramiXScreens,
-                                     pseudoramiXScreensAllocated *
-                                     sizeof(PseudoramiXScreenRec));
+        pseudoramiXScreens = reallocarray(pseudoramiXScreens,
+                                          pseudoramiXScreensAllocated,
+                                          sizeof(PseudoramiXScreenRec));
     }
 
     DEBUG_LOG("x: %d, y: %d, w: %d, h: %d\n", x, y, w, h);
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 69b3ecf..63d94e2 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -65,8 +65,8 @@ RRCrtcCreate(ScreenPtr pScreen, void *devPrivate)
 
     /* make space for the crtc pointer */
     if (pScrPriv->numCrtcs)
-        crtcs = realloc(pScrPriv->crtcs,
-                        (pScrPriv->numCrtcs + 1) * sizeof(RRCrtcPtr));
+        crtcs = reallocarray(pScrPriv->crtcs,
+                             pScrPriv->numCrtcs + 1, sizeof(RRCrtcPtr));
     else
         crtcs = malloc(sizeof(RRCrtcPtr));
     if (!crtcs)
@@ -176,10 +176,10 @@ RRCrtcNotify(RRCrtcPtr crtc,
 
         if (numOutputs) {
             if (crtc->numOutputs)
-                newoutputs = realloc(crtc->outputs,
-                                     numOutputs * sizeof(RROutputPtr));
+                newoutputs = reallocarray(crtc->outputs,
+                                          numOutputs, sizeof(RROutputPtr));
             else
-                newoutputs = malloc(numOutputs * sizeof(RROutputPtr));
+                newoutputs = xallocarray(numOutputs, sizeof(RROutputPtr));
             if (!newoutputs)
                 return FALSE;
         }
@@ -798,7 +798,7 @@ RRCrtcGammaSetSize(RRCrtcPtr crtc, int size)
     if (size == crtc->gammaSize)
         return TRUE;
     if (size) {
-        gamma = malloc(size * 3 * sizeof(CARD16));
+        gamma = xallocarray(size, 3 * sizeof(CARD16));
         if (!gamma)
             return FALSE;
     }
@@ -1027,7 +1027,7 @@ ProcRRSetCrtcConfig(ClientPtr client)
             return BadMatch;
     }
     if (numOutputs) {
-        outputs = malloc(numOutputs * sizeof(RROutputPtr));
+        outputs = xallocarray(numOutputs, sizeof(RROutputPtr));
         if (!outputs)
             return BadAlloc;
     }
diff --git a/randr/rrinfo.c b/randr/rrinfo.c
index fc57bd4..24245b7 100644
--- a/randr/rrinfo.c
+++ b/randr/rrinfo.c
@@ -55,8 +55,8 @@ RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh)
         }
 
     if (output->numModes)
-        modes = realloc(output->modes,
-                        (output->numModes + 1) * sizeof(RRModePtr));
+        modes = reallocarray(output->modes,
+                             output->numModes + 1, sizeof(RRModePtr));
     else
         modes = malloc(sizeof(RRModePtr));
     if (!modes) {
@@ -266,8 +266,8 @@ RRRegisterSize(ScreenPtr pScreen,
     for (i = 0; i < pScrPriv->nSizes; i++)
         if (RRScreenSizeMatches(&tmp, &pScrPriv->pSizes[i]))
             return &pScrPriv->pSizes[i];
-    pNew = realloc(pScrPriv->pSizes,
-                   (pScrPriv->nSizes + 1) * sizeof(RRScreenSize));
+    pNew = reallocarray(pScrPriv->pSizes,
+                        pScrPriv->nSizes + 1, sizeof(RRScreenSize));
     if (!pNew)
         return 0;
     pNew[pScrPriv->nSizes++] = tmp;
@@ -289,7 +289,7 @@ RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate)
         if (pSize->pRates[i].rate == rate)
             return TRUE;
 
-    pNew = realloc(pSize->pRates, (pSize->nRates + 1) * sizeof(RRScreenRate));
+    pNew = reallocarray(pSize->pRates, pSize->nRates + 1, sizeof(RRScreenRate));
     if (!pNew)
         return FALSE;
     pRate = &pNew[pSize->nRates++];
diff --git a/randr/rrmode.c b/randr/rrmode.c
index befac47..a7aa433 100644
--- a/randr/rrmode.c
+++ b/randr/rrmode.c
@@ -79,7 +79,7 @@ RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen)
     mode->userScreen = userScreen;
 
     if (num_modes)
-        newModes = realloc(modes, (num_modes + 1) * sizeof(RRModePtr));
+        newModes = reallocarray(modes, num_modes + 1, sizeof(RRModePtr));
     else
         newModes = malloc(sizeof(RRModePtr));
 
@@ -166,7 +166,7 @@ RRModesForScreen(ScreenPtr pScreen, int *num_ret)
     RRModePtr *screen_modes;
     int num_screen_modes = 0;
 
-    screen_modes = malloc((num_modes ? num_modes : 1) * sizeof(RRModePtr));
+    screen_modes = xallocarray((num_modes ? num_modes : 1), sizeof(RRModePtr));
     if (!screen_modes)
         return NULL;
 
diff --git a/randr/rrmonitor.c b/randr/rrmonitor.c
index fbdd352..c4bb617 100644
--- a/randr/rrmonitor.c
+++ b/randr/rrmonitor.c
@@ -494,8 +494,9 @@ RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor)
      * needs to not have any side-effects on failure
      */
     if (pScrPriv->numMonitors)
-        monitors = realloc(pScrPriv->monitors,
-                           (pScrPriv->numMonitors + 1) * sizeof (RRMonitorPtr));
+        monitors = reallocarray(pScrPriv->monitors,
+                                pScrPriv->numMonitors + 1,
+                                sizeof (RRMonitorPtr));
     else
         monitors = malloc(sizeof (RRMonitorPtr));
 
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 548e07d..10df4da 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -60,8 +60,8 @@ RROutputCreate(ScreenPtr pScreen,
     pScrPriv = rrGetScrPriv(pScreen);
 
     if (pScrPriv->numOutputs)
-        outputs = realloc(pScrPriv->outputs,
-                          (pScrPriv->numOutputs + 1) * sizeof(RROutputPtr));
+        outputs = reallocarray(pScrPriv->outputs,
+                               pScrPriv->numOutputs + 1, sizeof(RROutputPtr));
     else
         outputs = malloc(sizeof(RROutputPtr));
     if (!outputs)
@@ -124,7 +124,7 @@ RROutputSetClones(RROutputPtr output, RROutputPtr * clones, int numClones)
             return TRUE;
     }
     if (numClones) {
-        newClones = malloc(numClones * sizeof(RROutputPtr));
+        newClones = xallocarray(numClones, sizeof(RROutputPtr));
         if (!newClones)
             return FALSE;
     }
@@ -157,7 +157,7 @@ RROutputSetModes(RROutputPtr output,
     }
 
     if (numModes) {
-        newModes = malloc(numModes * sizeof(RRModePtr));
+        newModes = xallocarray(numModes, sizeof(RRModePtr));
         if (!newModes)
             return FALSE;
     }
@@ -200,8 +200,8 @@ RROutputAddUserMode(RROutputPtr output, RRModePtr mode)
             return BadMatch;
 
     if (output->userModes)
-        newModes = realloc(output->userModes,
-                           (output->numUserModes + 1) * sizeof(RRModePtr));
+        newModes = reallocarray(output->userModes,
+                                output->numUserModes + 1, sizeof(RRModePtr));
     else
         newModes = malloc(sizeof(RRModePtr));
     if (!newModes)
@@ -256,7 +256,7 @@ RROutputSetCrtcs(RROutputPtr output, RRCrtcPtr * crtcs, int numCrtcs)
             return TRUE;
     }
     if (numCrtcs) {
-        newCrtcs = malloc(numCrtcs * sizeof(RRCrtcPtr));
+        newCrtcs = xallocarray(numCrtcs, sizeof(RRCrtcPtr));
         if (!newCrtcs)
             return FALSE;
     }
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index e385e15..e56626c 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -140,7 +140,6 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
     RRPropertyPtr prop;
     rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
     int size_in_bytes;
-    int total_size;
     unsigned long total_len;
     RRPropertyValuePtr prop_value;
     RRPropertyValueRec new_value;
@@ -180,9 +179,8 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
     if (mode == PropModeReplace || len > 0) {
         void *new_data = NULL, *old_data = NULL;
 
-        total_size = total_len * size_in_bytes;
-        new_value.data = (void *) malloc(total_size);
-        if (!new_value.data && total_size) {
+        new_value.data = xallocarray(total_len, size_in_bytes);
+        if (!new_value.data && total_len && size_in_bytes) {
             if (add)
                 RRDestroyOutputProperty(prop);
             return BadAlloc;
@@ -350,7 +348,7 @@ RRConfigureOutputProperty(RROutputPtr output, Atom property,
         return BadMatch;
     }
 
-    new_values = malloc(num_values * sizeof(INT32));
+    new_values = xallocarray(num_values, sizeof(INT32));
     if (!new_values && num_values) {
         if (add)
             RRDestroyOutputProperty(prop);
@@ -400,7 +398,7 @@ ProcRRListOutputProperties(ClientPtr client)
     for (prop = output->properties; prop; prop = prop->next)
         numProps++;
     if (numProps)
-        if (!(pAtoms = (Atom *) malloc(numProps * sizeof(Atom))))
+        if (!(pAtoms = xallocarray(numProps, sizeof(Atom))))
             return BadAlloc;
 
     rep = (xRRListOutputPropertiesReply) {
@@ -447,7 +445,7 @@ ProcRRQueryOutputProperty(ClientPtr client)
         return BadName;
 
     if (prop->num_valid) {
-        extra = malloc(prop->num_valid * sizeof(INT32));
+        extra = xallocarray(prop->num_valid, sizeof(INT32));
         if (!extra)
             return BadAlloc;
     }
diff --git a/randr/rrproviderproperty.c b/randr/rrproviderproperty.c
index ff2c614..b79c17f 100644
--- a/randr/rrproviderproperty.c
+++ b/randr/rrproviderproperty.c
@@ -350,7 +350,7 @@ RRConfigureProviderProperty(RRProviderPtr provider, Atom property,
         return BadMatch;
     }
 
-    new_values = malloc(num_values * sizeof(INT32));
+    new_values = xallocarray(num_values, sizeof(INT32));
     if (!new_values && num_values) {
         if (add)
             RRDestroyProviderProperty(prop);
@@ -400,7 +400,7 @@ ProcRRListProviderProperties(ClientPtr client)
     for (prop = provider->properties; prop; prop = prop->next)
         numProps++;
     if (numProps)
-        if (!(pAtoms = (Atom *) malloc(numProps * sizeof(Atom))))
+        if (!(pAtoms = xallocarray(numProps, sizeof(Atom))))
             return BadAlloc;
 
     rep = (xRRListProviderPropertiesReply) {
@@ -445,7 +445,7 @@ ProcRRQueryProviderProperty(ClientPtr client)
         return BadName;
 
     if (prop->num_valid) {
-        extra = malloc(prop->num_valid * sizeof(INT32));
+        extra = xallocarray(prop->num_valid, sizeof(INT32));
         if (!extra)
             return BadAlloc;
     }
diff --git a/randr/rrtransform.c b/randr/rrtransform.c
index c8a2749..6137f85 100644
--- a/randr/rrtransform.c
+++ b/randr/rrtransform.c
@@ -70,7 +70,7 @@ RRTransformSetFilter(RRTransformPtr dst,
     xFixed *new_params;
 
     if (nparams) {
-        new_params = malloc(nparams * sizeof(xFixed));
+        new_params = xallocarray(nparams, sizeof(xFixed));
         if (!new_params)
             return FALSE;
         memcpy(new_params, params, nparams * sizeof(xFixed));
diff --git a/record/record.c b/record/record.c
index 0a466e2..1caf3f1 100644
--- a/record/record.c
+++ b/record/record.c
@@ -1074,19 +1074,19 @@ RecordAddClientToRCAP(RecordClientsAndProtocolPtr pRCAP, XID clientspec)
 {
     if (pRCAP->numClients == pRCAP->sizeClients) {
         if (pRCAP->clientIDsSeparatelyAllocated) {
-            XID *pNewIDs = (XID *) realloc(pRCAP->pClientIDs,
-                                           (pRCAP->sizeClients +
-                                            CLIENT_ARRAY_GROWTH_INCREMENT) *
-                                           sizeof(XID));
+            XID *pNewIDs =
+                reallocarray(pRCAP->pClientIDs,
+                             pRCAP->sizeClients + CLIENT_ARRAY_GROWTH_INCREMENT,
+                             sizeof(XID));
             if (!pNewIDs)
                 return;
             pRCAP->pClientIDs = pNewIDs;
             pRCAP->sizeClients += CLIENT_ARRAY_GROWTH_INCREMENT;
         }
         else {
-            XID *pNewIDs = (XID *) malloc((pRCAP->sizeClients +
-                                           CLIENT_ARRAY_GROWTH_INCREMENT) *
-                                          sizeof(XID));
+            XID *pNewIDs =
+                xallocarray(pRCAP->sizeClients + CLIENT_ARRAY_GROWTH_INCREMENT,
+                            sizeof(XID));
             if (!pNewIDs)
                 return;
             memcpy(pNewIDs, pRCAP->pClientIDs, pRCAP->numClients * sizeof(XID));
@@ -1217,7 +1217,7 @@ RecordCanonicalizeClientSpecifiers(XID *pClientspecs, int *pNumClientspecs,
     for (i = 0; i < numClients; i++) {
         if (pClientspecs[i] == XRecordAllClients || pClientspecs[i] == XRecordCurrentClients) { /* expand All/Current */
             int j, nc;
-            XID *pCanon = (XID *) malloc(sizeof(XID) * (currentMaxClients + 1));
+            XID *pCanon = xallocarray(currentMaxClients + 1, sizeof(XID));
 
             if (!pCanon)
                 return NULL;
@@ -1421,8 +1421,7 @@ static int
 RecordAllocIntervals(SetInfoPtr psi, int nIntervals)
 {
     assert(!psi->intervals);
-    psi->intervals = (RecordSetInterval *)
-        malloc(nIntervals * sizeof(RecordSetInterval));
+    psi->intervals = xallocarray(nIntervals, sizeof(RecordSetInterval));
     if (!psi->intervals)
         return BadAlloc;
     memset(psi->intervals, 0, nIntervals * sizeof(RecordSetInterval));
@@ -1584,7 +1583,7 @@ RecordRegisterClients(RecordContextPtr pContext, ClientPtr client,
      * range for extension replies.
      */
     maxSets = PREDEFSETS + 2 * stuff->nRanges;
-    si = (SetInfoPtr) malloc(sizeof(SetInfoRec) * maxSets);
+    si = xallocarray(maxSets, sizeof(SetInfoRec));
     if (!si) {
         err = BadAlloc;
         goto bailout;
@@ -1853,8 +1852,8 @@ ProcRecordCreateContext(ClientPtr client)
 
     /* make sure there is room in ppAllContexts to store the new context */
 
-    ppNewAllContexts = (RecordContextPtr *)
-        realloc(ppAllContexts, sizeof(RecordContextPtr) * (numContexts + 1));
+    ppNewAllContexts =
+        reallocarray(ppAllContexts, numContexts + 1, sizeof(RecordContextPtr));
     if (!ppNewAllContexts)
         goto bailout;
     ppAllContexts = ppNewAllContexts;
@@ -1971,8 +1970,7 @@ RecordAllocRanges(GetContextRangeInfoPtr pri, int nRanges)
 #define SZINCR 8
 
     newsize = max(pri->size + SZINCR, nRanges);
-    pNewRange = (xRecordRange *) realloc(pri->pRanges,
-                                         newsize * sizeof(xRecordRange));
+    pNewRange = reallocarray(pri->pRanges, newsize, sizeof(xRecordRange));
     if (!pNewRange)
         return BadAlloc;
 
@@ -2150,9 +2148,7 @@ ProcRecordGetContext(ClientPtr client)
 
     /* allocate and initialize space for record range info */
 
-    pRangeInfo =
-        (GetContextRangeInfoPtr) malloc(nRCAPs *
-                                        sizeof(GetContextRangeInfoRec));
+    pRangeInfo = xallocarray(nRCAPs, sizeof(GetContextRangeInfoRec));
     if (!pRangeInfo && nRCAPs > 0)
         return BadAlloc;
     for (i = 0; i < nRCAPs; i++) {
@@ -2733,7 +2729,8 @@ RecordAClientStateChange(CallbackListPtr *pcbl, void *nulldata,
 
         /* RecordDisableContext modifies contents of ppAllContexts. */
         numContextsCopy = numContexts;
-        ppAllContextsCopy = malloc(numContextsCopy * sizeof(RecordContextPtr));
+        ppAllContextsCopy = xallocarray(numContextsCopy,
+                                        sizeof(RecordContextPtr));
         assert(ppAllContextsCopy);
         memcpy(ppAllContextsCopy, ppAllContexts,
                numContextsCopy * sizeof(RecordContextPtr));
diff --git a/record/set.c b/record/set.c
index 34faa61..e0db385 100644
--- a/record/set.c
+++ b/record/set.c
@@ -303,9 +303,7 @@ IntervalListCreateSet(RecordSetInterval * pIntervals, int nIntervals,
     CARD16 first;
 
     if (nIntervals > 0) {
-        stackIntervals =
-            (RecordSetInterval *) malloc(sizeof(RecordSetInterval) *
-                                         nIntervals);
+        stackIntervals = xallocarray(nIntervals, sizeof(RecordSetInterval));
         if (!stackIntervals)
             return NULL;
 
diff --git a/render/filter.c b/render/filter.c
index 019ea7f..2741f40 100644
--- a/render/filter.c
+++ b/render/filter.c
@@ -67,7 +67,7 @@ PictureGetFilterId(const char *filter, int len, Bool makeit)
     memcpy(name, filter, len);
     name[len] = '\0';
     if (filterNames)
-        names = realloc(filterNames, (nfilterNames + 1) * sizeof(char *));
+        names = reallocarray(filterNames, nfilterNames + 1, sizeof(char *));
     else
         names = malloc(sizeof(char *));
     if (!names) {
@@ -145,7 +145,7 @@ PictureAddFilter(ScreenPtr pScreen,
             return -1;
     if (ps->filters)
         filters =
-            realloc(ps->filters, (ps->nfilters + 1) * sizeof(PictFilterRec));
+            reallocarray(ps->filters, ps->nfilters + 1, sizeof(PictFilterRec));
     else
         filters = malloc(sizeof(PictFilterRec));
     if (!filters)
@@ -177,9 +177,9 @@ PictureSetFilterAlias(ScreenPtr pScreen, const char *filter, const char *alias)
         PictFilterAliasPtr aliases;
 
         if (ps->filterAliases)
-            aliases = realloc(ps->filterAliases,
-                              (ps->nfilterAliases + 1) *
-                              sizeof(PictFilterAliasRec));
+            aliases = reallocarray(ps->filterAliases,
+                                   ps->nfilterAliases + 1,
+                                   sizeof(PictFilterAliasRec));
         else
             aliases = malloc(sizeof(PictFilterAliasRec));
         if (!aliases)
@@ -336,7 +336,7 @@ SetPicturePictFilter(PicturePtr pPicture, PictFilterPtr pFilter,
         return BadMatch;
 
     if (nparams != pPicture->filter_nparams) {
-        xFixed *new_params = malloc(nparams * sizeof(xFixed));
+        xFixed *new_params = xallocarray(nparams, sizeof(xFixed));
 
         if (!new_params && nparams)
             return BadAlloc;
diff --git a/render/miindex.c b/render/miindex.c
index 0375e8f..4119eef 100644
--- a/render/miindex.c
+++ b/render/miindex.c
@@ -254,7 +254,7 @@ miInitIndexed(ScreenPtr pScreen, PictFormatPtr pFormat)
         return FALSE;
 
     pFormat->index.nvalues = num;
-    pFormat->index.pValues = malloc(num * sizeof(xIndexValue));
+    pFormat->index.pValues = xallocarray(num, sizeof(xIndexValue));
     if (!pFormat->index.pValues) {
         free(pIndexed);
         return FALSE;
diff --git a/render/mipict.c b/render/mipict.c
index a725104..2571fda 100644
--- a/render/mipict.c
+++ b/render/mipict.c
@@ -510,7 +510,7 @@ miTriStrip(CARD8 op,
     int ntri;
 
     ntri = npoints - 2;
-    tris = malloc(ntri * sizeof(xTriangle));
+    tris = xallocarray(ntri, sizeof(xTriangle));
     if (!tris)
         return;
 
@@ -535,7 +535,7 @@ miTriFan(CARD8 op,
     int ntri;
 
     ntri = npoints - 2;
-    tris = malloc(ntri * sizeof(xTriangle));
+    tris = xallocarray(ntri, sizeof(xTriangle));
     if (!tris)
         return;
 
diff --git a/render/picture.c b/render/picture.c
index 6ff31ba..60517a4 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -837,7 +837,7 @@ initGradient(SourcePictPtr pGradient, int stopCount,
         dpos = stopPoints[i];
     }
 
-    pGradient->gradient.stops = malloc(stopCount * sizeof(PictGradientStop));
+    pGradient->gradient.stops = xallocarray(stopCount, sizeof(PictGradientStop));
     if (!pGradient->gradient.stops) {
         *error = BadAlloc;
         return;
diff --git a/render/render.c b/render/render.c
index 723f380..88d8a26 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1318,14 +1318,14 @@ ProcRenderCompositeGlyphs(ClientPtr client)
     if (nglyph <= NLOCALGLYPH)
         glyphsBase = glyphsLocal;
     else {
-        glyphsBase = (GlyphPtr *) malloc(nglyph * sizeof(GlyphPtr));
+        glyphsBase = xallocarray(nglyph, sizeof(GlyphPtr));
         if (!glyphsBase)
             return BadAlloc;
     }
     if (nlist <= NLOCALDELTA)
         listsBase = listsLocal;
     else {
-        listsBase = (GlyphListPtr) malloc(nlist * sizeof(GlyphListRec));
+        listsBase = xallocarray(nlist, sizeof(GlyphListRec));
         if (!listsBase) {
             rc = BadAlloc;
             goto bail;
@@ -1793,7 +1793,7 @@ ProcRenderCreateAnimCursor(ClientPtr client)
     ncursor =
         (client->req_len -
          (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1;
-    cursors = malloc(ncursor * (sizeof(CursorPtr) + sizeof(CARD32)));
+    cursors = xallocarray(ncursor, sizeof(CursorPtr) + sizeof(CARD32));
     if (!cursors)
         return BadAlloc;
     deltas = (CARD32 *) (cursors + ncursor);
diff --git a/xfixes/region.c b/xfixes/region.c
index 4492f12..dd74d7f 100644
--- a/xfixes/region.c
+++ b/xfixes/region.c
@@ -777,7 +777,7 @@ ProcXFixesExpandRegion(ClientPtr client)
     nBoxes = RegionNumRects(pSource);
     pSrc = RegionRects(pSource);
     if (nBoxes) {
-        pTmp = malloc(nBoxes * sizeof(BoxRec));
+        pTmp = xallocarray(nBoxes, sizeof(BoxRec));
         if (!pTmp)
             return BadAlloc;
         for (i = 0; i < nBoxes; i++) {
commit b9e665c8b2f048feb3064ce412e0b3e9eb6797b0
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 10:52:29 2015 -0700

    Convert dix/* to new *allocarray functions
    
    v2: remove now useless parentheses
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/dix/atom.c b/dix/atom.c
index 22cd0dc..7de7fb0 100644
--- a/dix/atom.c
+++ b/dix/atom.c
@@ -119,7 +119,7 @@ MakeAtom(const char *string, unsigned len, Bool makeit)
         if ((lastAtom + 1) >= tableLength) {
             NodePtr *table;
 
-            table = realloc(nodeTable, tableLength * (2 * sizeof(NodePtr)));
+            table = reallocarray(nodeTable, tableLength, 2 * sizeof(NodePtr));
             if (!table) {
                 if (nd->string != string) {
                     /* nd->string has been strdup'ed */
@@ -200,7 +200,7 @@ InitAtoms(void)
 {
     FreeAllAtoms();
     tableLength = InitialTableSize;
-    nodeTable = malloc(InitialTableSize * sizeof(NodePtr));
+    nodeTable = xallocarray(InitialTableSize, sizeof(NodePtr));
     if (!nodeTable)
         AtomError();
     nodeTable[None] = NULL;
diff --git a/dix/colormap.c b/dix/colormap.c
index 4d408d5..a3e5a2c 100644
--- a/dix/colormap.c
+++ b/dix/colormap.c
@@ -296,7 +296,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual,
         for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--)
             pent->refcnt = AllocPrivate;
         pmap->freeRed = 0;
-        ppix = malloc(size * sizeof(Pixel));
+        ppix = xallocarray(size, sizeof(Pixel));
         if (!ppix) {
             free(pmap);
             return BadAlloc;
@@ -337,7 +337,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual,
             for (pent = &pmap->green[size - 1]; pent >= pmap->green; pent--)
                 pent->refcnt = AllocPrivate;
             pmap->freeGreen = 0;
-            ppix = malloc(size * sizeof(Pixel));
+            ppix = xallocarray(size, sizeof(Pixel));
             if (!ppix) {
                 free(pmap->clientPixelsRed[client]);
                 free(pmap);
@@ -352,7 +352,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual,
             for (pent = &pmap->blue[size - 1]; pent >= pmap->blue; pent--)
                 pent->refcnt = AllocPrivate;
             pmap->freeBlue = 0;
-            ppix = malloc(size * sizeof(Pixel));
+            ppix = xallocarray(size, sizeof(Pixel));
             if (!ppix) {
                 free(pmap->clientPixelsGreen[client]);
                 free(pmap->clientPixelsRed[client]);
@@ -702,7 +702,7 @@ UpdateColors(ColormapPtr pmap)
 
     pVisual = pmap->pVisual;
     size = pVisual->ColormapEntries;
-    defs = malloc(size * sizeof(xColorItem));
+    defs = xallocarray(size, sizeof(xColorItem));
     if (!defs)
         return;
     n = 0;
@@ -792,8 +792,8 @@ AllocColor(ColormapPtr pmap,
         *pgreen = pmap->red[pixR].co.local.green;
         *pblue = pmap->red[pixR].co.local.blue;
         npix = pmap->numPixelsRed[client];
-        ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
-                                 (npix + 1) * sizeof(Pixel));
+        ppix = reallocarray(pmap->clientPixelsRed[client],
+                            npix + 1, sizeof(Pixel));
         if (!ppix)
             return BadAlloc;
         ppix[npix] = pixR;
@@ -814,22 +814,22 @@ AllocColor(ColormapPtr pmap,
         *pgreen = pmap->green[pixG].co.local.green;
         *pblue = pmap->blue[pixB].co.local.blue;
         npix = pmap->numPixelsRed[client];
-        ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
-                                 (npix + 1) * sizeof(Pixel));
+        ppix = reallocarray(pmap->clientPixelsRed[client],
+                            npix + 1, sizeof(Pixel));
         if (!ppix)
             return BadAlloc;
         ppix[npix] = pixR;
         pmap->clientPixelsRed[client] = ppix;
         npix = pmap->numPixelsGreen[client];
-        ppix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
-                                 (npix + 1) * sizeof(Pixel));
+        ppix = reallocarray(pmap->clientPixelsGreen[client],
+                            npix + 1, sizeof(Pixel));
         if (!ppix)
             return BadAlloc;
         ppix[npix] = pixG;
         pmap->clientPixelsGreen[client] = ppix;
         npix = pmap->numPixelsBlue[client];
-        ppix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
-                                 (npix + 1) * sizeof(Pixel));
+        ppix = reallocarray(pmap->clientPixelsBlue[client],
+                            npix + 1, sizeof(Pixel));
         if (!ppix)
             return BadAlloc;
         ppix[npix] = pixB;
@@ -1279,7 +1279,7 @@ FindColor(ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb * prgb,
         break;
     }
     npix = nump[client];
-    ppix = (Pixel *) realloc(pixp[client], (npix + 1) * sizeof(Pixel));
+    ppix = reallocarray(pixp[client], npix + 1, sizeof(Pixel));
     if (!ppix) {
         pent->refcnt--;
         if (!pent->fShared)
@@ -1647,9 +1647,9 @@ AllocDirect(int client, ColormapPtr pmap, int c, int r, int g, int b,
     for (p = pixels; p < pixels + c; p++)
         *p = 0;
 
-    ppixRed = malloc(npixR * sizeof(Pixel));
-    ppixGreen = malloc(npixG * sizeof(Pixel));
-    ppixBlue = malloc(npixB * sizeof(Pixel));
+    ppixRed = xallocarray(npixR, sizeof(Pixel));
+    ppixGreen = xallocarray(npixG, sizeof(Pixel));
+    ppixBlue = xallocarray(npixB, sizeof(Pixel));
     if (!ppixRed || !ppixGreen || !ppixBlue) {
         free(ppixBlue);
         free(ppixGreen);
@@ -1662,19 +1662,19 @@ AllocDirect(int client, ColormapPtr pmap, int c, int r, int g, int b,
     okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask);
 
     if (okR && okG && okB) {
-        rpix = (Pixel *) realloc(pmap->clientPixelsRed[client],
-                                 (pmap->numPixelsRed[client] + (c << r)) *
-                                 sizeof(Pixel));
+        rpix = reallocarray(pmap->clientPixelsRed[client],
+                            pmap->numPixelsRed[client] + (c << r),
+                            sizeof(Pixel));
         if (rpix)
             pmap->clientPixelsRed[client] = rpix;
-        gpix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
-                                 (pmap->numPixelsGreen[client] + (c << g)) *
-                                 sizeof(Pixel));
+        gpix = reallocarray(pmap->clientPixelsGreen[client],
+                            pmap->numPixelsGreen[client] + (c << g),
+                            sizeof(Pixel));
         if (gpix)
             pmap->clientPixelsGreen[client] = gpix;
-        bpix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
-                                 (pmap->numPixelsBlue[client] + (c << b)) *
-                                 sizeof(Pixel));
+        bpix = reallocarray(pmap->clientPixelsBlue[client],
+                            pmap->numPixelsBlue[client] + (c << b),
+                            sizeof(Pixel));
         if (bpix)
             pmap->clientPixelsBlue[client] = bpix;
     }
@@ -1747,7 +1747,7 @@ AllocPseudo(int client, ColormapPtr pmap, int c, int r, Bool contig,
     npix = c << r;
     if ((r >= 32) || (npix > pmap->freeRed) || (npix < c))
         return BadAlloc;
-    if (!(ppixTemp = malloc(npix * sizeof(Pixel))))
+    if (!(ppixTemp = xallocarray(npix, sizeof(Pixel))))
         return BadAlloc;
     ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask);
 
@@ -1755,9 +1755,8 @@ AllocPseudo(int client, ColormapPtr pmap, int c, int r, Bool contig,
 
         /* all the allocated pixels are added to the client pixel list,
          * but only the unique ones are returned to the client */
-        ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
-                                 (pmap->numPixelsRed[client] +
-                                  npix) * sizeof(Pixel));
+        ppix = reallocarray(pmap->clientPixelsRed[client],
+                            pmap->numPixelsRed[client] + npix, sizeof(Pixel));
         if (!ppix) {
             for (p = ppixTemp; p < ppixTemp + npix; p++)
                 pmap->red[*p].refcnt = 0;
@@ -1960,7 +1959,7 @@ AllocShared(ColormapPtr pmap, Pixel * ppix, int c, int r, int g, int b,
 
     npixClientNew = c << (r + g + b);
     npixShared = (c << r) + (c << g) + (c << b);
-    psharedList = malloc(npixShared * sizeof(SHAREDCOLOR *));
+    psharedList = xallocarray(npixShared, sizeof(SHAREDCOLOR *));
     if (!psharedList)
         return FALSE;
     ppshared = psharedList;
@@ -2204,7 +2203,7 @@ FreeCo(ColormapPtr pmap, int client, int color, int npixIn, Pixel * ppixIn,
                     npix++;
                 }
             }
-            pptr = (Pixel *) realloc(ppixClient, npixNew * sizeof(Pixel));
+            pptr = reallocarray(ppixClient, npixNew, sizeof(Pixel));
             if (pptr)
                 ppixClient = pptr;
             npixClient = npixNew;
@@ -2469,8 +2468,8 @@ IsMapInstalled(Colormap map, WindowPtr pWin)
     Colormap *pmaps;
     int imap, nummaps, found;
 
-    pmaps =
-        malloc(pWin->drawable.pScreen->maxInstalledCmaps * sizeof(Colormap));
+    pmaps = xallocarray(pWin->drawable.pScreen->maxInstalledCmaps,
+                        sizeof(Colormap));
     if (!pmaps)
         return FALSE;
     nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
@@ -2521,8 +2520,8 @@ ResizeVisualArray(ScreenPtr pScreen, int new_visual_count, DepthPtr depth)
     first_new_vid = depth->numVids;
     first_new_visual = pScreen->numVisuals;
 
-    vids =
-        realloc(depth->vids, (depth->numVids + new_visual_count) * sizeof(XID));
+    vids = reallocarray(depth->vids, depth->numVids + new_visual_count,
+                        sizeof(XID));
     if (!vids)
         return FALSE;
 
@@ -2530,7 +2529,7 @@ ResizeVisualArray(ScreenPtr pScreen, int new_visual_count, DepthPtr depth)
     depth->vids = vids;
 
     numVisuals = pScreen->numVisuals + new_visual_count;
-    visuals = realloc(pScreen->visuals, numVisuals * sizeof(VisualRec));
+    visuals = reallocarray(pScreen->visuals, numVisuals, sizeof(VisualRec));
     if (!visuals) {
         return FALSE;
     }
diff --git a/dix/devices.c b/dix/devices.c
index d8e7f9c..b2de6f1 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1469,8 +1469,8 @@ InitStringFeedbackClassDeviceStruct(DeviceIntPtr dev,
     feedc->ctrl.num_symbols_displayed = 0;
     feedc->ctrl.max_symbols = max_symbols;
     feedc->ctrl.symbols_supported =
-        malloc(sizeof(KeySym) * num_symbols_supported);
-    feedc->ctrl.symbols_displayed = malloc(sizeof(KeySym) * max_symbols);
+        xallocarray(num_symbols_supported, sizeof(KeySym));
+    feedc->ctrl.symbols_displayed = xallocarray(max_symbols, sizeof(KeySym));
     if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) {
         free(feedc->ctrl.symbols_supported);
         free(feedc->ctrl.symbols_displayed);
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 7dcdeab..9208582 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -344,7 +344,7 @@ Dispatch(void)
     nextFreeClientID = 1;
     nClients = 0;
 
-    clientReady = malloc(sizeof(int) * MaxClients);
+    clientReady = xallocarray(MaxClients, sizeof(int));
     if (!clientReady)
         return;
 
@@ -963,7 +963,7 @@ ProcQueryTree(ClientPtr client)
     if (numChildren) {
         int curChild = 0;
 
-        childIDs = malloc(numChildren * sizeof(Window));
+        childIDs = xallocarray(numChildren, sizeof(Window));
         if (!childIDs)
             return BadAlloc;
         for (pChild = pWin->lastChild; pChild != pHead;
diff --git a/dix/dixfonts.c b/dix/dixfonts.c
index bc2732f..be389e8 100644
--- a/dix/dixfonts.c
+++ b/dix/dixfonts.c
@@ -168,9 +168,8 @@ QueueFontWakeup(FontPathElementPtr fpe)
         }
     }
     if (num_slept_fpes == size_slept_fpes) {
-        new = (FontPathElementPtr *)
-            realloc(slept_fpes,
-                    sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+        new = reallocarray(slept_fpes, size_slept_fpes + 4,
+                           sizeof(FontPathElementPtr));
         if (!new)
             return;
         slept_fpes = new;
@@ -424,7 +423,7 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname,
      * copy the current FPE list, so that if it gets changed by another client
      * while we're blocking, the request still appears atomic
      */
-    c->fpe_list = malloc(sizeof(FontPathElementPtr) * num_fpes);
+    c->fpe_list = xallocarray(num_fpes, sizeof(FontPathElementPtr));
     if (!c->fpe_list) {
         free((void *) c->fontname);
         free(c);
@@ -821,7 +820,7 @@ ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
 
     if (!(c = malloc(sizeof *c)))
         return BadAlloc;
-    c->fpe_list = malloc(sizeof(FontPathElementPtr) * num_fpes);
+    c->fpe_list = xallocarray(num_fpes, sizeof(FontPathElementPtr));
     if (!c->fpe_list) {
         free(c);
         return BadAlloc;
@@ -1072,7 +1071,7 @@ StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
 
     if (!(c = malloc(sizeof *c)))
         goto badAlloc;
-    c->fpe_list = malloc(sizeof(FontPathElementPtr) * num_fpes);
+    c->fpe_list = xallocarray(num_fpes, sizeof(FontPathElementPtr));
     if (!c->fpe_list) {
         free(c);
         goto badAlloc;
@@ -1441,7 +1440,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
             *new_closure = *c;
             c = new_closure;
 
-            data = malloc(c->nChars * itemSize);
+            data = xallocarray(c->nChars, itemSize);
             if (!data) {
                 free(c);
                 c = old_closure;
@@ -1597,7 +1596,7 @@ SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
     unsigned char *cp = paths;
     FontPathElementPtr fpe = NULL, *fplist;
 
-    fplist = malloc(sizeof(FontPathElementPtr) * npaths);
+    fplist = xallocarray(npaths, sizeof(FontPathElementPtr));
     if (!fplist) {
         *bad = 0;
         return BadAlloc;
@@ -1894,8 +1893,7 @@ RegisterFPEFunctions(NameCheckFunc name_func,
     FPEFunctions *new;
 
     /* grow the list */
-    new = (FPEFunctions *) realloc(fpe_functions,
-                                   (num_fpe_types + 1) * sizeof(FPEFunctions));
+    new = reallocarray(fpe_functions, num_fpe_types + 1, sizeof(FPEFunctions));
     if (!new)
         return -1;
     fpe_functions = new;
diff --git a/dix/enterleave.c b/dix/enterleave.c
index 54f4b85..7f1f941 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -714,7 +714,7 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
         }
     }
 
-    sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent));
+    sev = ev = xallocarray(evcount, sizeof(xEvent));
     FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
 
     if (b != NULL) {
diff --git a/dix/events.c b/dix/events.c
index c232eba..7d2bb6b 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4785,8 +4785,8 @@ SetInputFocus(ClientPtr client,
             depth++;
         if (depth > focus->traceSize) {
             focus->traceSize = depth + 1;
-            focus->trace = realloc(focus->trace,
-                                   focus->traceSize * sizeof(WindowPtr));
+            focus->trace = reallocarray(focus->trace, focus->traceSize,
+                                        sizeof(WindowPtr));
         }
         focus->traceGood = depth;
         for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
diff --git a/dix/extension.c b/dix/extension.c
index 56e3abc..e81f673 100644
--- a/dix/extension.c
+++ b/dix/extension.c
@@ -103,8 +103,7 @@ AddExtension(const char *name, int NumEvents, int NumErrors,
         return ((ExtensionEntry *) NULL);
     }
     i = NumExtensions;
-    newexts = (ExtensionEntry **) realloc(extensions,
-                                          (i + 1) * sizeof(ExtensionEntry *));
+    newexts = reallocarray(extensions, i + 1, sizeof(ExtensionEntry *));
     if (!newexts) {
         free((void *) ext->name);
         dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION);
@@ -153,8 +152,7 @@ AddExtensionAlias(const char *alias, ExtensionEntry * ext)
 
     if (!ext)
         return FALSE;
-    aliases = realloc(ext->aliases,
-                      (ext->num_aliases + 1) * sizeof(char *));
+    aliases = reallocarray(ext->aliases, ext->num_aliases + 1, sizeof(char *));
     if (!aliases)
         return FALSE;
     ext->aliases = aliases;
diff --git a/dix/grabs.c b/dix/grabs.c
index b92f1e7..2a307a2 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -594,10 +594,10 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
         i++;
     if (!i)
         return TRUE;
-    deletes = malloc(i * sizeof(GrabPtr));
-    adds = malloc(i * sizeof(GrabPtr));
-    updates = malloc(i * sizeof(Mask **));
-    details = malloc(i * sizeof(Mask *));
+    deletes = xallocarray(i, sizeof(GrabPtr));
+    adds = xallocarray(i, sizeof(GrabPtr));
+    updates = xallocarray(i, sizeof(Mask **));
+    details = xallocarray(i, sizeof(Mask *));
     if (!deletes || !adds || !updates || !details) {
         free(details);
         free(updates);
diff --git a/dix/property.c b/dix/property.c
index ff7f31a..99608af 100644
--- a/dix/property.c
+++ b/dix/property.c
@@ -136,8 +136,8 @@ ProcRotateProperties(ClientPtr client)
         return rc;
 
     atoms = (Atom *) &stuff[1];
-    props = malloc(stuff->nAtoms * sizeof(PropertyPtr));
-    saved = malloc(stuff->nAtoms * sizeof(PropertyRec));
+    props = xallocarray(stuff->nAtoms, sizeof(PropertyPtr));
+    saved = xallocarray(stuff->nAtoms, sizeof(PropertyRec));
     if (!props || !saved) {
         rc = BadAlloc;
         goto out;
@@ -313,7 +313,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
             /* do nothing */
         }
         else if (mode == PropModeAppend) {
-            data = malloc((pProp->size + len) * sizeInBytes);
+            data = xallocarray(pProp->size + len, sizeInBytes);
             if (!data)
                 return BadAlloc;
             memcpy(data, pProp->data, pProp->size * sizeInBytes);
@@ -322,7 +322,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
             pProp->size += len;
         }
         else if (mode == PropModePrepend) {
-            data = malloc(sizeInBytes * (len + pProp->size));
+            data = xallocarray(len + pProp->size, sizeInBytes);
             if (!data)
                 return BadAlloc;
             memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes);
@@ -581,7 +581,7 @@ ProcListProperties(ClientPtr client)
     for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
         numProps++;
 
-    if (numProps && !(pAtoms = malloc(numProps * sizeof(Atom))))
+    if (numProps && !(pAtoms = xallocarray(numProps, sizeof(Atom))))
         return BadAlloc;
 
     numProps = 0;
diff --git a/dix/region.c b/dix/region.c
index 04e5901..fd73139 100644
--- a/dix/region.c
+++ b/dix/region.c
@@ -1247,7 +1247,7 @@ RegionValidate(RegionPtr badreg, Bool *pOverlap)
         if (sizeRI == numRI) {
             /* Oops, allocate space for new region information */
             sizeRI <<= 1;
-            rit = (RegionInfo *) realloc(ri, sizeRI * sizeof(RegionInfo));
+            rit = (RegionInfo *) reallocarray(ri, sizeRI, sizeof(RegionInfo));
             if (!rit)
                 goto bail;
             ri = rit;
diff --git a/dix/resource.c b/dix/resource.c
index 964f0b3..af8e162 100644
--- a/dix/resource.c
+++ b/dix/resource.c
@@ -510,7 +510,7 @@ CreateNewResourceType(DeleteType deleteFunc, const char *name)
 
     if (next & lastResourceClass)
         return 0;
-    types = realloc(resourceTypes, (next + 1) * sizeof(*resourceTypes));
+    types = reallocarray(resourceTypes, next + 1, sizeof(*resourceTypes));
     if (!types)
         return 0;
 
@@ -834,10 +834,10 @@ RebuildTable(int client)
      */
 
     j = 2 * clientTable[client].buckets;
-    tails = malloc(j * sizeof(ResourcePtr *));
+    tails =  xallocarray(j, sizeof(ResourcePtr *));
     if (!tails)
         return;
-    resources = malloc(j * sizeof(ResourcePtr));
+    resources =  xallocarray(j, sizeof(ResourcePtr));
     if (!resources) {
         free(tails);
         return;
diff --git a/dix/touch.c b/dix/touch.c
index 1eeed78..49d16ab 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -101,7 +101,7 @@ TouchResizeQueue(ClientPtr client, void *closure)
          * don't need to do it often */
         size = dev->last.num_touches + dev->last.num_touches / 2 + 1;
 
-        tmp = realloc(dev->last.touches, size * sizeof(*dev->last.touches));
+        tmp = reallocarray(dev->last.touches, size, sizeof(*dev->last.touches));
         if (tmp) {
             int j;
 
@@ -350,7 +350,7 @@ TouchBeginTouch(DeviceIntPtr dev, int sourceid, uint32_t touchid,
 
     /* If we get here, then we've run out of touches: enlarge dev->touch and
      * try again. */
-    tmp = realloc(t->touches, (t->num_touches + 1) * sizeof(*ti));
+    tmp = reallocarray(t->touches, t->num_touches + 1, sizeof(*ti));
     if (tmp) {
         t->touches = tmp;
         t->num_touches++;
@@ -547,8 +547,8 @@ TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite)
         return FALSE;
 
     if (srcsprite->spriteTraceGood > sprite->spriteTraceSize) {
-        trace = realloc(sprite->spriteTrace,
-                        srcsprite->spriteTraceSize * sizeof(*trace));
+        trace = reallocarray(sprite->spriteTrace,
+                             srcsprite->spriteTraceSize, sizeof(*trace));
         if (!trace) {
             sprite->spriteTraceGood = 0;
             return FALSE;
commit df4e41fdb47cdeab5155224557ed8ab4ec4dc659
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 10:08:25 2015 -0700

    Convert os/* to new *allocarray functions
    
    v2: remove now useless parentheses
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/os/connection.c b/os/connection.c
index 7ff44e1..c36b125 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -309,7 +309,7 @@ InitConnectionLimits(void)
 
 #if !defined(WIN32)
     if (!ConnectionTranslation)
-        ConnectionTranslation = (int *) xnfalloc(sizeof(int) * (lastfdesc + 1));
+        ConnectionTranslation = xnfallocarray(lastfdesc + 1, sizeof(int));
 #else
     InitConnectionTranslation();
 #endif
@@ -429,7 +429,9 @@ CreateWellKnownSockets(void)
         display = dynamic_display;
     }
 
-    ListenTransFds = malloc(ListenTransCount * sizeof (int));
+    ListenTransFds = xallocarray(ListenTransCount, sizeof (int));
+    if (ListenTransFds == NULL)
+        FatalError ("Failed to create listening socket array");
 
     for (i = 0; i < ListenTransCount; i++) {
         int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
@@ -1291,11 +1293,10 @@ ListenOnOpenFD(int fd, int noxauth)
 
     /* Allocate space to store it */
     ListenTransFds =
-        (int *) realloc(ListenTransFds, (ListenTransCount + 1) * sizeof(int));
+        xnfreallocarray(ListenTransFds, ListenTransCount + 1, sizeof(int));
     ListenTransConns =
-        (XtransConnInfo *) realloc(ListenTransConns,
-                                   (ListenTransCount +
-                                    1) * sizeof(XtransConnInfo));
+        xnfreallocarray(ListenTransConns, ListenTransCount + 1,
+                        sizeof(XtransConnInfo));
 
     /* Store it */
     ListenTransConns[ListenTransCount] = ciptr;
diff --git a/os/utils.c b/os/utils.c
index 23f4117..aef52c4 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -2001,7 +2001,7 @@ xstrtokenize(const char *str, const char *separators)
     if (!tmp)
         goto error;
     for (tok = strtok(tmp, separators); tok; tok = strtok(NULL, separators)) {
-        nlist = realloc(list, (num + 2) * sizeof(*list));
+        nlist = reallocarray(list, num + 2, sizeof(*list));
         if (!nlist)
             goto error;
         list = nlist;
commit ae75d50395fdd7a6bc382ba73e923c460764c702
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 09:28:07 2015 -0700

    Add no-fail equivalents of allocarray & reallocarray
    
    v2: Remove extra 's' from comment
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/include/os.h b/include/os.h
index 2633741..6638c84 100644
--- a/include/os.h
+++ b/include/os.h
@@ -76,6 +76,8 @@ typedef struct _NewClientRec *NewClientPtr;
 #define xnfstrdup(s) XNFstrdup(s)
 
 #define xallocarray(num, size) reallocarray(NULL, (num), (size))
+#define xnfallocarray(num, size) XNFreallocarray(NULL, (num), (size))
+#define xnfreallocarray(ptr, num, size) XNFreallocarray((ptr), (num), (size))
 #endif
 
 #include <stdio.h>
@@ -241,6 +243,13 @@ extern _X_EXPORT void *
 XNFrealloc(void * /*ptr */ , unsigned long /*amount */ );
 
 /*
+ * This function reallocarray(3)s passed buffer, terminating the server if
+ * there is not enough memory or the arguments overflow when multiplied.
+ */
+extern _X_EXPORT void *
+XNFreallocarray(void *ptr, size_t nmemb, size_t size);
+
+/*
  * This function strdup(3)s passed string. The only difference from the library
  * function that it is safe to pass NULL, as NULL will be returned.
  */
diff --git a/os/utils.c b/os/utils.c
index 24a8751..23f4117 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1158,6 +1158,16 @@ XNFrealloc(void *ptr, unsigned long amount)
     return ret;
 }
 
+void *
+XNFreallocarray(void *ptr, size_t nmemb, size_t size)
+{
+    void *ret = reallocarray(ptr, nmemb, size);
+
+    if (!ret)
+        FatalError("XNFreallocarray: Out of memory");
+    return ret;
+}
+
 char *
 Xstrdup(const char *s)
 {
commit c213b29d14aaf2f4523d638abc762eaaa873cf83
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 08:58:04 2015 -0700

    Add xallocarray() helper macro
    
    Uses reallocarray to perform integer overflow detection when allocating
    an array, using NULL as the previous pointer to force a new allocation.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/include/os.h b/include/os.h
index ffa5f39..2633741 100644
--- a/include/os.h
+++ b/include/os.h
@@ -74,6 +74,8 @@ typedef struct _NewClientRec *NewClientPtr;
 
 #define xstrdup(s) Xstrdup(s)
 #define xnfstrdup(s) XNFstrdup(s)
+
+#define xallocarray(num, size) reallocarray(NULL, (num), (size))
 #endif
 
 #include <stdio.h>
commit 0887c9463fc7d36d7874e7f978df4109542f7307
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 08:42:19 2015 -0700

    Import reallocarray() from OpenBSD
    
    Wrapper for realloc() that checks for overflow when multiplying
    arguments together, so we don't have to add overflow checks to
    every single call.  For documentation on usage, see:
    http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/calloc.3
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Acked-by: Matt Turner <mattst88 at gmail.com>

diff --git a/configure.ac b/configure.ac
index 606298b..a5bdbbf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -219,7 +219,7 @@ dnl Checks for library functions.
 AC_CHECK_FUNCS([backtrace ffs geteuid getuid issetugid getresuid \
 	getdtablesize getifaddrs getpeereid getpeerucred getprogname getzoneid \
 	mmap seteuid shmctl64 strncasecmp vasprintf vsnprintf walkcontext])
-AC_REPLACE_FUNCS([strcasecmp strcasestr strlcat strlcpy strndup])
+AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup])
 
 AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]])
 
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 1aa77a5..86cf6f2 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -149,6 +149,9 @@
 /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
 #undef HAVE_NDIR_H
 
+/* Define to 1 if you have the `reallocarray' function. */
+#undef HAVE_REALLOCARRAY
+
 /* Define to 1 if you have the <rpcsvc/dbm.h> header file. */
 #undef HAVE_RPCSVC_DBM_H
 
diff --git a/include/os.h b/include/os.h
index 9d8b859..ffa5f39 100644
--- a/include/os.h
+++ b/include/os.h
@@ -517,7 +517,14 @@ ddxGiveUp(enum ExitCode error);
 extern _X_EXPORT int
 TimeSinceLastInputEvent(void);
 
-/* strcasecmp.c */
+/* Function fallbacks provided by AC_REPLACE_FUNCS in configure.ac */
+
+#ifndef HAVE_REALLOCARRAY
+#define reallocarray xreallocarray
+extern _X_EXPORT void *
+reallocarray(void *optr, size_t nmemb, size_t size);
+#endif
+
 #ifndef HAVE_STRCASECMP
 #define strcasecmp xstrcasecmp
 extern _X_EXPORT int
diff --git a/include/xorg-server.h.in b/include/xorg-server.h.in
index 4cb9487..3152dbd 100644
--- a/include/xorg-server.h.in
+++ b/include/xorg-server.h.in
@@ -47,6 +47,9 @@
 /* Define to 1 if you have the `ffs' function. */
 #undef HAVE_FFS
 
+/* Define to 1 if you have the `reallocarray' function. */
+#undef HAVE_REALLOCARRAY
+
 /* Define to 1 if you have the `strcasecmp' function. */
 #undef HAVE_STRCASECMP
 
diff --git a/os/reallocarray.c b/os/reallocarray.c
new file mode 100644
index 0000000..c415e09
--- /dev/null
+++ b/os/reallocarray.c
@@ -0,0 +1,43 @@
+/*	$OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $	*/
+/*
+ * Copyright (c) 2008 Otto Moerbeek <otto at drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "os.h"
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW	((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+reallocarray(void *optr, size_t nmemb, size_t size)
+{
+	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+	    nmemb > 0 && SIZE_MAX / nmemb < size) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	return realloc(optr, size * nmemb);
+}
commit b96dc999968320ad6322b50c79d847efcfcd02b2
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 15:21:14 2015 -0700

    Add XNFcallocarray() to allow xnfcalloc() to check for overflow
    
    The xnfcalloc() macro took two arguments but simply multiplied them
    together without checking for overflow and defeating any overflow
    checking that calloc() might have done.  Let's not do that.
    
    The original XNFcalloc() function is left for now to preserve driver
    ABI, but is marked as deprecated so it can be removed in a future round
    of ABI break/cleanup.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/config/config.c b/config/config.c
index b5d634b..de45cc3 100644
--- a/config/config.c
+++ b/config/config.c
@@ -130,7 +130,8 @@ device_is_duplicate(const char *config_info)
 struct OdevAttributes *
 config_odev_allocate_attributes(void)
 {
-    struct OdevAttributes *attribs = XNFcalloc(sizeof (struct OdevAttributes));
+    struct OdevAttributes *attribs =
+        xnfcalloc(1, sizeof (struct OdevAttributes));
     attribs->fd = -1;
     return attribs;
 }
diff --git a/hw/xfree86/utils/cvt/cvt.c b/hw/xfree86/utils/cvt/cvt.c
index d5df17f..9413c20 100644
--- a/hw/xfree86/utils/cvt/cvt.c
+++ b/hw/xfree86/utils/cvt/cvt.c
@@ -54,11 +54,11 @@ XNFalloc(unsigned long n)
 
 /* xnfcalloc implementation used by the server code we built in */
 void *
-XNFcalloc(unsigned long n)
+XNFcallocarray(size_t nmemb, size_t size)
 {
     void *r;
 
-    r = calloc(1, n);
+    r = calloc(nmemb, size);
     if (!r) {
         perror("calloc failed");
         exit(1);
diff --git a/include/os.h b/include/os.h
index 3e68c49..9d8b859 100644
--- a/include/os.h
+++ b/include/os.h
@@ -69,7 +69,7 @@ typedef struct _NewClientRec *NewClientPtr;
 
 #ifndef xnfalloc
 #define xnfalloc(size) XNFalloc((unsigned long)(size))
-#define xnfcalloc(_num, _size) XNFcalloc((unsigned long)(_num)*(unsigned long)(_size))
+#define xnfcalloc(_num, _size) XNFcallocarray((_num), (_size))
 #define xnfrealloc(ptr, size) XNFrealloc((void *)(ptr), (unsigned long)(size))
 
 #define xstrdup(s) Xstrdup(s)
@@ -222,7 +222,14 @@ XNFalloc(unsigned long /*amount */ );
  * enough memory.
  */
 extern _X_EXPORT void *
-XNFcalloc(unsigned long /*amount */ );
+XNFcalloc(unsigned long /*amount */ ) _X_DEPRECATED;
+
+/*
+ * This function calloc(3)s buffer, terminating the server if there is not
+ * enough memory or the arguments overflow when multiplied
+ */
+extern _X_EXPORT void *
+XNFcallocarray(size_t nmemb, size_t size);
 
 /*
  * This function realloc(3)s passed buffer, terminating the server if there is
diff --git a/os/utils.c b/os/utils.c
index 75769f1..24a8751 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1128,10 +1128,20 @@ XNFalloc(unsigned long amount)
     return ptr;
 }
 
+/* The original XNFcalloc was used with the xnfcalloc macro which multiplied
+ * the arguments at the call site without allowing calloc to check for overflow.
+ * XNFcallocarray was added to fix that without breaking ABI.
+ */
 void *
 XNFcalloc(unsigned long amount)
 {
-    void *ret = calloc(1, amount);
+    return XNFcallocarray(1, amount);
+}
+
+void *
+XNFcallocarray(size_t nmemb, size_t size)
+{
+    void *ret = calloc(nmemb, size);
 
     if (!ret)
         FatalError("XNFcalloc: Out of memory");
commit f3ba909753cd216fc9eca4618a76cc283ccbf51e
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 11:07:24 2015 -0700

    Let calloc handle multiplication
    
    It's going to multiply anyway, so if we have non-constant values, might
    as well let it do the multiplication instead of adding another multiply,
    and good versions of calloc will check for & avoid overflow in the process.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c
index 413a66a..5291a4a 100644
--- a/Xext/panoramiXprocs.c
+++ b/Xext/panoramiXprocs.c
@@ -1106,7 +1106,7 @@ PanoramiXCopyArea(ClientPtr client)
         }
 
         pitch = PixmapBytePad(stuff->width, drawables[0]->depth);
-        if (!(data = calloc(1, stuff->height * pitch)))
+        if (!(data = calloc(stuff->height, pitch)))
             return BadAlloc;
 
         XineramaGetImageData(drawables, srcx, srcy,
diff --git a/Xi/xiquerypointer.c b/Xi/xiquerypointer.c
index 7ec0c85..b9e2958 100644
--- a/Xi/xiquerypointer.c
+++ b/Xi/xiquerypointer.c
@@ -152,10 +152,10 @@ ProcXIQueryPointer(ClientPtr client)
         rep.buttons_len =
             bytes_to_int32(bits_to_bytes(pDev->button->numButtons));
         rep.length += rep.buttons_len;
-        buttons_size = rep.buttons_len * 4;
-        buttons = calloc(1, buttons_size);
+        buttons = calloc(rep.buttons_len, 4);
         if (!buttons)
             return BadAlloc;
+        buttons_size = rep.buttons_len * 4;
 
         for (i = 1; i < pDev->button->numButtons; i++)
             if (BitIsOn(pDev->button->down, i))
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 17fa75e..7dcdeab 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -2786,7 +2786,7 @@ ProcQueryColors(ClientPtr client)
 
         count =
             bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq));
-        prgbs = calloc(1, count * sizeof(xrgb));
+        prgbs = calloc(count, sizeof(xrgb));
         if (!prgbs && count)
             return BadAlloc;
         if ((rc =
@@ -2908,10 +2908,10 @@ ProcCreateCursor(ClientPtr client)
     if (stuff->x > width || stuff->y > height)
         return BadMatch;
 
-    n = BitmapBytePad(width) * height;
-    srcbits = calloc(1, n);
+    srcbits = calloc(BitmapBytePad(width), height);
     if (!srcbits)
         return BadAlloc;
+    n = BitmapBytePad(width) * height;
     mskbits = malloc(n);
     if (!mskbits) {
         free(srcbits);
diff --git a/dix/glyphcurs.c b/dix/glyphcurs.c
index eca6a4c..3ff6ae8 100644
--- a/dix/glyphcurs.c
+++ b/dix/glyphcurs.c
@@ -78,7 +78,6 @@ ServerBitsFromGlyph(FontPtr pfont, unsigned ch, CursorMetricPtr cm,
     GCPtr pGC;
     xRectangle rect;
     PixmapPtr ppix;
-    long nby;
     char *pbits;
     ChangeGCVal gcval[3];
     unsigned char char2b[2];
@@ -88,8 +87,7 @@ ServerBitsFromGlyph(FontPtr pfont, unsigned ch, CursorMetricPtr cm,
     char2b[1] = (unsigned char) (ch & 0xff);
 
     pScreen = screenInfo.screens[0];
-    nby = BitmapBytePad(cm->width) * (long) cm->height;
-    pbits = calloc(1, nby);
+    pbits = calloc(BitmapBytePad(cm->width), cm->height);
     if (!pbits)
         return BadAlloc;
 
diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 889294f..02f7bf2 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -260,7 +260,7 @@ xf86AllocateEntity(void)
                               sizeof(EntityPtr) * xf86NumEntities);
     xf86Entities[xf86NumEntities - 1] = xnfcalloc(1, sizeof(EntityRec));
     xf86Entities[xf86NumEntities - 1]->entityPrivates =
-        xnfcalloc(sizeof(DevUnion) * xf86EntityPrivateCount, 1);
+        xnfcalloc(xf86EntityPrivateCount, sizeof(DevUnion));
     return xf86NumEntities - 1;
 }
 
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index d42572f..098d2dd 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1502,7 +1502,7 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
     if (!count)                 /* alloc enough storage even if no screen is specified */
         count = 1;
 
-    slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
+    slp = xnfcalloc((count + 1), sizeof(screenLayoutRec));
     slp[count].screen = NULL;
     /*
      * now that we have storage, loop over the list again and fill in our
diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c
index cc7ff1b..7ab378f 100644
--- a/hw/xfree86/common/xf86Configure.c
+++ b/hw/xfree86/common/xf86Configure.c
@@ -645,10 +645,10 @@ DoConfigure(void)
 
     xf86DoConfigurePass1 = FALSE;
 
-    dev2screen = xnfcalloc(1, xf86NumDrivers * sizeof(int));
+    dev2screen = xnfcalloc(xf86NumDrivers, sizeof(int));
 
     {
-        Bool *driverProbed = xnfcalloc(1, xf86NumDrivers * sizeof(Bool));
+        Bool *driverProbed = xnfcalloc(xf86NumDrivers, sizeof(Bool));
 
         for (screennum = 0; screennum < nDevToConfig; screennum++) {
             int k, l, n, oldNumScreens;
commit a28202a148508837911c5932a0d14af4b145bece
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 21 08:19:30 2015 -0700

    Remove remaining doc references to Xalloc, Xrealloc, and Xfree
    
    Functions were removed in commit cad9b053d52f62432
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/doc/Xserver-spec.xml b/doc/Xserver-spec.xml
index 4c34419..72a544b 100644
--- a/doc/Xserver-spec.xml
+++ b/doc/Xserver-spec.xml
@@ -1992,7 +1992,7 @@ regions, these blocks may need to be reallocated by your region
 software.  For instance, in the sample server, a RegionRec has some
 header information and a pointer to a dynamically allocated rectangle
 list.  Periodically, the rectangle list needs to be expanded with
-Xrealloc(), whereupon the new pointer is remembered in the RegionRec.</para>
+realloc(), whereupon the new pointer is remembered in the RegionRec.</para>
 <para>
 Most of the region operations come in two forms: a function pointer in
 the Screen structure, and a macro.  The server can be compiled so that
@@ -2598,7 +2598,7 @@ VisualRec data structure along with other display characteristics like the
 depth and other numbers.</para>
 <para>
 The allowable DepthRec's and VisualRec's are pointed to by fields in the ScreenRec.
-These are set up when InitOutput() is called; you should Xalloc() appropriate blocks
+These are set up when InitOutput() is called; you should malloc() appropriate blocks
 or use static variables initialized to the correct values.</para>
 </section>
 <section>
@@ -3897,7 +3897,7 @@ for CT_NONE, etc. are in Xserver/include/gc.h.)  This routine is
 responsible for incrementing any necessary reference counts (e.g. for
 a pixmap clip mask) for the new clipmask and freeing anything that
 used to be in the GC's clipMask field.  The lists of rectangles passed
-in can be freed with Xfree(), the regions can be destroyed with the
+in can be freed with free(), the regions can be destroyed with the
 RegionDestroy field in the screen, and pixmaps can be destroyed by
 calling the screen's DestroyPixmap function.  DIX and MI code expect
 what they pass in to this to be freed or otherwise inaccessible, and
@@ -5104,9 +5104,6 @@ mi and fb implementations.</para>
 <row><entry><function>WaitForSomething</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
 <row><entry><function>WindowExposures</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row>
 <row><entry><function>WriteToClient</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
-<row><entry><function>Xalloc</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
-<row><entry><function>Xfree</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
-<row><entry><function>Xrealloc</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
 	    </tbody>
 	  </tgroup>
 	</table>
commit 2a6d253b3f2ec4775412b4ae96a96b0b668ec827
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Feb 28 10:04:09 2015 -0800

    Remove apSolaris.shar (old "aperture" kernel driver for Solaris)
    
    Modern Solaris releases provide this functionality in the OS via the
    xsvc driver.   Since the move to libpciaccess, nothing in Xorg uses
    this aperture driver any more.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/hw/xfree86/os-support/solaris/Makefile.am b/hw/xfree86/os-support/solaris/Makefile.am
index 6cda4b3..e534bc8 100644
--- a/hw/xfree86/os-support/solaris/Makefile.am
+++ b/hw/xfree86/os-support/solaris/Makefile.am
@@ -33,5 +33,4 @@ AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(XORG_CFLAGS) $(DIX_CFLAGS)
 
 AM_CPPFLAGS = $(XORG_INCS) 
 
-EXTRA_DIST = solaris-amd64.S solaris-ia32.S solaris-sparcv8plus.S \
-	apSolaris.shar sun_inout.s
+EXTRA_DIST = solaris-amd64.S solaris-ia32.S solaris-sparcv8plus.S sun_inout.s
diff --git a/hw/xfree86/os-support/solaris/apSolaris.shar b/hw/xfree86/os-support/solaris/apSolaris.shar
deleted file mode 100644
index a3548f7..0000000
--- a/hw/xfree86/os-support/solaris/apSolaris.shar
+++ /dev/null
@@ -1,806 +0,0 @@
-#!/bin/sh
-#
-# This is a shell archive.  Save it in a file, remove anything before
-# this line, and then unpack it by entering "sh file".  Note, it may
-# create directories; files and directories will be owned by you and
-# have default permissions.
-# Made on Sun Jun 25 20:24:59 CEST 2006 by Martin Bochnig at martux.org
-#
-# This archive contains:
-#
-#	./aperture
-#	
-#	./aperture/Makefile
-#	./aperture/Makefile.amd64
-#	./aperture/Makefile.sparcv9
-#	./aperture/README
-#	./aperture/aperture.c
-#	./aperture/aperture.conf
-#	./aperture/devlink.tab
-#
-echo c - ./aperture
-mkdir -p ./aperture > /dev/null 2>&1
-#
-echo x - ./aperture/Makefile
-sed 's/^X//' >./aperture/Makefile << 'END-of-./aperture/Makefile'
-X#
-X#   File: makefile for aperture Framebuffer Driver
-X# Author: Doug Anson (danson at lgc.com)
-X#   Date: 2/15/94
-X# Modified: David Holland (davidh at use.com)
-X#   Date: 2/23/94
-X#   - Changed name, and debugging structure
-X# Modified: Marc Aurele La France (tsi at xfree86.org)
-X#   Date: 2001.06.08
-X#   - SPARC support, cleanup and turf aptest.
-X#
-X# >>NOTE<< Have a look at Makefile.sparcv9 for  specifics.
-X#
-X# Modified: Martin Bochnig (martin at martux.org)
-X#   Date: 2006.06.24
-X#   - Slightly modified to also build on Solaris 10 and 11.
-X#   - amd64 64 bit kernel support
-X#   - cosmetical changes to also support sun4v, not only sun4u
-X#
-X# >>NOTE<< Have a look at Makefile.amd64 for amd64 specifics.
-X#
-X# GNU gcc compiler
-XCC=gcc
-XCFLGS=-fno-builtin -Wall -O3
-X
-X#
-X# SUNWspro compiler
-X#CC=/opt/SUNWspro/bin/cc
-X#CFLGS=-Xa -xnolib -xO3
-X
-X#
-X# Debug error reporting
-X#DEBUG_FLG=
-X#DEBUG_FLG=-DAPERTURE_DEBUG
-X
-X#
-X# Files and object declarations
-XKERNEL_FLGS=-D_KERNEL -DSUNDDI
-XCFLAGS= $(CFLGS) $(KERNEL_FLGS) $(DEBUG_FLG)
-XCFILES= aperture.c
-XOBJS= aperture.o
-XDRIVER= aperture
-X
-X#
-X# Make rules
-Xall: $(DRIVER)
-X
-X$(DRIVER): $(OBJS)
-X	@if [ -f "Makefile.`isainfo -k`" ]; then \
-X		make -f Makefile.`isainfo -k` $(DRIVER); \
-X	else \
-X		rm -f $(DRIVER); \
-X		ld -r -o $(DRIVER) $(OBJS); \
-X	fi
-X
-Xinstall: $(DRIVER)
-X	@if [ -f "Makefile.`isainfo -k`" ]; then \
-X		make -f Makefile.`isainfo -k` install; \
-X	else \
-X		cp aperture.conf /kernel/drv; \
-X		cp $(DRIVER) /kernel/drv; \
-X	fi
-X
-Xadd_drv:
-X	@if [ -f "Makefile.`isainfo -k`" ]; then \
-X		make -f Makefile.`isainfo -k` add_drv; \
-X	else \
-X		add_drv aperture; \
-X	fi
-X
-Xclean:
-X	rm -f *% *.BAK $(OBJS) $(DRIVER) core
-X
-X.SUFFIXES: .i
-X
-X.c.i:
-X	$(CC) -E $(CFLAGS) $*.c > $@
-X
-X.c.o:
-X	@if [ -f "Makefile.`isainfo -k`" ]; then \
-X		make -f Makefile.`isainfo -k` $@; \
-X	else \
-X		rm -f $@; \
-X		$(CC) -c $(CFLAGS) $*.c -o $@; \
-X	fi
-END-of-./aperture/Makefile
-echo x - ./aperture/Makefile.amd64
-sed 's/^X//' >./aperture/Makefile.amd64 << 'END-of-./aperture/Makefile.amd64'
-X#
-X#   File: Makefile for aperture Framebuffer Driver
-X# Author: Doug Anson (danson at lgc.com)
-X#   Date: 2/15/94
-X# Modified: David Holland (davidh at use.com)
-X#   Date: 2/23/94
-X#   - Changed name, and debugging structure
-X# Modified: Marc Aurele La France (tsi at xfree86.org)
-X#   Date: 2001.06.08
-X#   - SPARC support, cleanup and turf aptest.
-X# Modified: Martin Bochnig (martin at martux.org)
-X#   - amd64 64 bit kernel support, cosmetics and also
-X#     supporting sun4v (and arbitrary sparcv9) platforms
-X#     as well as SunOS 5.10 or higher now
-X#   - Changed name
-X#
-X
-X#
-X# GNU gcc compiler, version 3.2 or later
-X#
-XCC=gcc
-XCFLGS=-fno-builtin -Wall -O3 -m64 -mcmodel=kernel
-X
-X#
-X# SUNWspro compiler (untested, might not properly work for amd64 here)
-X#CC=/opt/SUNWspro/bin/cc
-X#CFLGS=-Xa -xarch=v9 -xnolib -xO3
-X
-X#
-X# Debug error reporting
-X#DEBUG_FLG=
-X#DEBUG_FLG=-DAPERTURE_DEBUG
-X
-X#
-X# Files and object declarations
-XKERNEL_FLGS=-D_KERNEL -DSUNDDI
-XCFLAGS= $(CFLGS) $(KERNEL_FLGS) $(DEBUG_FLG)
-XCFILES= aperture.c
-XOBJS= aperture.o
-XDRIVER= aperture
-X
-X#
-X# Make rules
-Xall: $(DRIVER)
-X
-X$(DRIVER): $(OBJS)
-X	rm -f $(DRIVER)
-X	ld -r -o $(DRIVER) $(OBJS)
-X
-Xinstall: $(DRIVER)
-X	cp aperture.conf /kernel/drv
-X	cp $(DRIVER) /kernel/drv/amd64
-X
-Xadd_drv:
-X	add_drv aperture
-X
-Xclean:
-X	rm -f *% *.BAK $(OBJS) $(DRIVER) core
-X
-X.SUFFIXES: .i
-X
-X.c.i:
-X	$(CC) -E $(CFLAGS) $*.c > $@
-END-of-./aperture/Makefile.amd64
-echo x - ./aperture/Makefile.sparcv9
-sed 's/^X//' >./aperture/Makefile.sparcv9 << 'END-of-./aperture/Makefile.sparcv9'
-X#
-X#   File: makefile for aperture Framebuffer Driver
-X# Author: Doug Anson (danson at lgc.com)
-X#   Date: 2/15/94
-X# Modified: David Holland (davidh at use.com)
-X#   Date: 2/23/94
-X#   - Changed name, and debugging structure
-X# Modified: Marc Aurele La France (tsi at xfree86.org)
-X#   Date: 2001.06.08
-X#   - SPARC support, cleanup and turf aptest.
-X# Modified: Martin Bochnig (martin at martux.org)
-X#   Date: 2006.06.24
-X#   - Changed name for generic sparcv9 support
-X#   - updated to better work with Solaris 10 and 11
-X#
-X
-X#
-X# GNU gcc compiler, version 3.2 or later
-X#
-XCC=gcc
-XCFLGS=-fno-builtin -Wall -O3 -m64
-X
-X#
-X# SUNWspro compiler
-X#CC=/opt/SUNWspro/bin/cc
-X#CFLGS=-Xa -xarch=v9 -xnolib -xO3
-X
-X#
-X# Debug error reporting
-X#DEBUG_FLG=
-X#DEBUG_FLG=-DAPERTURE_DEBUG
-X
-X#
-X# Files and object declarations
-XKERNEL_FLGS=-D_KERNEL -DSUNDDI
-XCFLAGS= $(CFLGS) $(KERNEL_FLGS) $(DEBUG_FLG)
-XCFILES= aperture.c
-XOBJS= aperture.o
-XDRIVER= aperture
-X
-X#
-X# Make rules
-Xall: $(DRIVER)
-X
-X$(DRIVER): $(OBJS)
-X	rm -f $(DRIVER)
-X	ld -r -o $(DRIVER) $(OBJS)
-X
-Xinstall: $(DRIVER)
-X	cp aperture.conf /kernel/drv
-X	cp $(DRIVER) /kernel/drv/sparcv9
-X
-Xadd_drv:
-X	add_drv aperture
-X
-Xclean:
-X	rm -f *% *.BAK $(OBJS) $(DRIVER) core
-X
-X.SUFFIXES: .i
-X
-X.c.i:
-X	$(CC) -E $(CFLAGS) $*.c > $@
-END-of-./aperture/Makefile.sparcv9
-echo x - ./aperture/README
-sed 's/^X//' >./aperture/README << 'END-of-./aperture/README'
-XFramebuffer aperture driver.
-X
-XThis driver was written to provide a device that, unlike /dev/mem, allows
-Xmmap()'ing of ranges beyond installed memory.
-X
-XThe original x86-based version of this driver was the collaborative work of
-XDoug Anson (danson at lgc.com), and David Holland (davidh at use.com).  It has since
-Xbeen rewritten to also work on sparc machines and - later on - also on sparcv9 
-Xand recently amd64 64 bit kernels.
-XIt flawlessly compiles and installs on Solaris 10 and 11 now.
-X
-X
-XInstallation instructions:
-X
-X1) Check the Makefile, for appropriate CC, and CFLAGS definitions.  Compiling
-X   with APERTURE_DEBUG defined means the driver will generate reams of
-X   debugging output.  You'll probably want to leave this off...
-X
-X2) Type 'make' (or 'gmake').  Both the driver and test program should compile 
-X   without any problems. No warning messages should be generated.
-X
-X3) Become 'root'.
-X
-X4) Type 'make install' and 'make add_drv'.  The screen should look something
-X   like this:
-X
-X	# make install
-X	cp aperture aperture.conf /kernel/drv
-X	# make add_drv
-X	add_drv aperture
-X
-X   On a sparcv9 machine this will mention the /kernel/drv/sparcv9 directory
-X   instead of /kernel/drv. Similarily /kernel/drv/amd64 should be used on amd64.
-X
-X   This installs the driver to the system.
-X
-X5) While as root modify the file /etc/devlink.tab, adding these lines:
-X
-X# The following entry is for the framebuffer driver
-Xtype=ddi_pseudo;name=aperture	fbs/\M0
-X
-X   Add that line exactly as shown. You may also simply add the
-X   contents of the devlink.tab file supplied to /etc/devlink.tab.
-X   It contains the lines as well.  (Yes, that is a tab between
-X   aperture and fbs, not spaces - very important)
-X
-X6) Perform a reconfiguration boot of the system.
-X
-X	# touch /reconfigure
-X	# init 6
-X
-XBug reports, questions, suggestions, etc can be sent to xfree86 at xfree86.org.
-END-of-./aperture/README
-echo x - ./aperture/aperture.c
-sed 's/^X//' >./aperture/aperture.c << 'END-of-./aperture/aperture.c'
-X/*
-X * Copyright (C) 2001 The XFree86 Project, Inc.  All Rights Reserved.
-X *
-X * Permission is hereby granted, free of charge, to any person obtaining a copy
-X * of this software and associated documentation files (the "Software"), to
-X * deal in the Software without restriction, including without limitation the
-X * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-X * sell copies of the Software, and to permit persons to whom the Software is
-X * furnished to do so, subject to the following conditions:
-X *
-X * The above copyright notice and this permission notice shall be included in
-X * all copies or substantial portions of the Software.
-X *
-X * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-X * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-X * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-X * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-X * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-X * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-X *
-X * Except as contained in this notice, the name of the XFree86 Project shall
-X * not be used in advertising or otherwise to promote the sale, use or other
-X * dealings in this Software without prior written authorization from the
-X * XFree86 Project.
-X */
-X
-X/*
-X * Aperture driver for Solaris.
-X */
-X
-X/*
-X * Modified: Martin Bochnig (martin at martux.org)
-X * Log:      Commented out obsolete kernel interfaces DDI_IDENTIFIED and DDI_NOT_IDENTIFIED
-X *           not supported by SunOS 5.10 or higher anymore, 
-X *           see http://docs.sun.com/app/docs/doc/819-2255/6n4ibnffr?a=view
-X */
-X
-X#include <sys/conf.h>
-X#include <sys/ddi.h>
-X#include <sys/modctl.h>
-X#include <sys/open.h>
-X#include <sys/stat.h>
-X#include <sys/sunddi.h>
-X
-X#define DEV_IDENT  "aperture"
-X#define DEV_BANNER "XFree86 aperture driver"
-X
-X#ifndef D_64BIT
-X#define D_64BIT 0
-X#endif
-X
-X#ifndef NULL
-X#define NULL ((void *)0)
-X#endif
-X
-X/*
-X * open(9E)
-X */
-X/*ARGSUSED*/
-Xstatic int
-Xaperture_open
-X(
-X#ifdef __STDC__
-X	dev_t *devp,
-X	int flag,
-X	int typ,
-X	struct cred *cred
-X#endif
-X)
-X#ifndef __STDC__
-X	dev_t *devp;
-X	int flag;
-X	int typ;
-X	struct cred *cred;
-X#endif
-X{
-X	int error;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  entering open()\n");
-X
-X#endif
-X
-X	if ((typ != OTYP_CHR) || (getminor(*devp)))
-X		error = EINVAL;
-X	else
-X		error = 0;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  leaving open() = %d\n", error);
-X
-X#endif
-X
-X	return error;
-X}
-X
-X/*
-X * mmap(9E)
-X */
-X/*ARGSUSED*/
-Xstatic int
-Xaperture_mmap
-X(
-X#ifdef __STDC__
-X	dev_t dev,
-X	off_t off,
-X	int prot
-X#endif
-X)
-X#ifndef __STDC__
-X	dev_t dev;
-X	off_t off;
-X	int prot;
-X#endif
-X{
-X	pfn_t pf;
-X	int error;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  entering mmap(0x%016lx)\n", off);
-X
-X#endif
-X
-X	pf = btop((unsigned long)off);
-X
-X	/* Deal with mmap(9E) interface limits */
-X	error = (int)pf;
-X	if ((error < 0) || (pf != (pfn_t)error))
-X		error = -1;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  leaving mmap() = 0x%08lx", error);
-X
-X#endif
-X
-X	return error;
-X}
-X
-Xstatic struct cb_ops aperture_cb_ops =
-X{
-X	aperture_open,		/* open */
-X	nulldev,		/* close */
-X	nodev,			/* strategy */
-X	nodev,			/* print */
-X	nodev,			/* dump */
-X	nodev,			/* read */
-X	nodev,			/* write */
-X	nodev,			/* ioctl */
-X	nodev,			/* devmap */
-X	aperture_mmap,		/* mmap */
-X	ddi_segmap,		/* segmap */
-X	nochpoll,		/* poll */
-X	ddi_prop_op,		/* cb_prop_op */
-X	0,			/* streamtab  */
-X	D_NEW | D_MP | D_64BIT	/* Driver compatibility flag */
-X};
-X
-X
-Xstatic dev_info_t *aperture_dip;	/* private copy of devinfo pointer */
-X
-X/*
-X * getinfo(9E)
-X */
-X/*ARGSUSED*/
-Xstatic int
-Xaperture_getinfo
-X(
-X#ifdef __STDC__
-X	dev_info_t *dip,
-X	ddi_info_cmd_t infocmd,
-X	void *arg,
-X	void **result
-X#endif
-X)
-X#ifndef __STDC__
-X	dev_info_t *dip;
-X	ddi_info_cmd_t infocmd;
-X	void *arg;
-X	void **result;
-X#endif
-X{
-X	int error;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  entering getinfo()\n");
-X
-X#endif
-X
-X	switch (infocmd) {
-X	case DDI_INFO_DEVT2DEVINFO:
-X		*result = aperture_dip;
-X		error = DDI_SUCCESS;
-X		break;
-X	case DDI_INFO_DEVT2INSTANCE:
-X		*result = NULL;
-X		error = DDI_SUCCESS;
-X		break;
-X	default:
-X		error = DDI_FAILURE;
-X	}
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  leaving getinfo() = %d\n", error);
-X
-X#endif
-X
-X	return error;
-X}
-X
-X/*
-X * identify(9E)
-X */
-X/*ARGSUSED*/
-Xstatic int
-Xaperture_identify
-X(
-X#ifdef __STDC__
-X	dev_info_t *dip
-X#endif
-X)
-X#ifndef __STDC__
-X	dev_info_t *dip;
-X#endif
-X{
-X	int error;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  entering identify()\n");
-X
-X#endif
-X
-X	if (strcmp(ddi_get_name(dip), DEV_IDENT))
-X	  error = 1 /* DDI_NOT_IDENTIFIED obsolete since SunOS 5.10 */ ;
-X	else
-X	  error = 2 /* DDI_IDENTIFIED obsolete since SunOS 5.10 */ ;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  leaving identify() = %d\n", error);
-X
-X#endif
-X
-X	return error;
-X}
-X
-X/*
-X * attach(9E)
-X */
-X/*ARGSUSED*/
-Xstatic int
-Xaperture_attach
-X(
-X#ifdef __STDC__
-X	dev_info_t *dip,
-X	ddi_attach_cmd_t cmd
-X#endif
-X)
-X#ifndef __STDC__
-X	dev_info_t *dip;
-X	ddi_attach_cmd_t cmd;
-X#endif
-X{
-X	int error;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  entering attach()\n");
-X
-X#endif
-X
-X	if (cmd != DDI_ATTACH)
-X	{
-X
-X#ifdef APERTURE_DEBUG
-X
-X		cmn_err(CE_CONT, DEV_IDENT ":  not attach(, DDI_ATTACH)\n");
-X
-X#endif
-X
-X		error = DDI_FAILURE;
-X	}
-X	else
-X	{
-X		error = ddi_create_minor_node(dip, ddi_get_name(dip), S_IFCHR,
-X					      (minor_t)ddi_get_instance(dip),
-X					      NULL, 0 /* NODESPECIFIC_DEV obsolete since SunOS 5.10 */ );
-X
-X		if (error == DDI_SUCCESS)
-X		{
-X			aperture_dip = dip;
-X			ddi_report_dev(dip);
-X		}
-X	}
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  leaving attach() = %d\n", error);
-X
-X#endif
-X
-X	return error;
-X}
-X
-X/*
-X * detach(9E)
-X */
-Xstatic int
-Xaperture_detach
-X(
-X#ifdef __STDC__
-X	dev_info_t *dip,
-X	ddi_detach_cmd_t cmd
-X#endif
-X)
-X#ifndef __STDC__
-X	dev_info_t *dip;
-X	ddi_detach_cmd_t cmd;
-X#endif
-X{
-X	int error;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  entering detach()\n");
-X
-X#endif
-X
-X	if (cmd != DDI_DETACH)
-X	{
-X		error = DDI_FAILURE;
-X	}
-X	else
-X	{
-X		ddi_remove_minor_node(dip, NULL);
-X		aperture_dip = NULL;
-X		error = DDI_SUCCESS;
-X	}
-X
-X#if APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  leaving detach() = %d\n", error);
-X
-X#endif
-X
-X	return error;
-X}
-X
-X
-Xstatic struct dev_ops aperture_ops =
-X{
-X	DEVO_REV,		/* revision */
-X	0,			/* refcnt  */
-X	aperture_getinfo,	/* getinfo */
-X	aperture_identify,	/* identify */
-X	nulldev,		/* probe */
-X	aperture_attach,	/* attach */
-X	aperture_detach,	/* detach */
-X	nodev,			/* reset */
-X	&aperture_cb_ops,	/* driver operations */
-X	NULL			/* bus operations */
-X};
-X
-X
-Xstatic struct modldrv modldrv =
-X{
-X	&mod_driverops,		/* mod_ops structure pointer */
-X	DEV_BANNER,		/* driver banner string */
-X	&aperture_ops,		/* dev_ops structure pointer */
-X};
-X
-X
-Xstatic struct modlinkage modlinkage =
-X{
-X	MODREV_1,		/* module API revision */
-X	{
-X		&modldrv,	/* module driver structure pointer */
-X		NULL		/* list termination */
-X	}
-X};
-X
-X
-X/*
-X * _init(9E)
-X */
-Xint
-X_init
-X(
-X#ifdef __STDC__
-X	void
-X#endif
-X)
-X{
-X	int error;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  entering _init()\n");
-X
-X#endif
-X
-X	error = mod_install(&modlinkage);
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  leaving _init() = %d\n", error);
-X
-X#endif
-X
-X	return error;
-X}
-X
-X/*
-X * _info(9E)
-X */
-Xint
-X_info
-X(
-X#ifdef __STDC__
-X	struct modinfo *modinfop
-X#endif
-X)
-X#ifndef __STDC__
-X	struct modinfo *modinfop;
-X#endif
-X{
-X	int error;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  entering _info()\n");
-X
-X#endif
-X
-X	error = mod_info(&modlinkage, modinfop);
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  leaving _info() = %d\n", error);
-X
-X#endif
-X
-X	return error;
-X}
-X
-X/*
-X * _fini(9E)
-X */
-Xint
-X_fini
-X(
-X#ifdef __STDC__
-X	void
-X#endif
-X)
-X{
-X	int error;
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  entering _fini()\n");
-X
-X#endif
-X
-X	error = mod_remove(&modlinkage);
-X
-X#ifdef APERTURE_DEBUG
-X
-X	cmn_err(CE_CONT, DEV_IDENT ":  leaving _fini() = %d\n", error);
-X
-X#endif
-X
-X	return error;
-X}
-END-of-./aperture/aperture.c
-echo x - ./aperture/aperture.conf
-sed 's/^X//' >./aperture/aperture.conf << 'END-of-./aperture/aperture.conf'
-X#
-X# Copyright 1994 Doug Anson, danson at lgc.com & David Holland, davidh at use.com
-X#
-X# File:   aperture.conf
-X# Author: Doug Anson (danson at lgc.com)
-X# 
-X# Modified: David Holland (davidh at use.com)
-X# Log:	    Change comments		02/23/94
-X#	    Change defaults/comments	09/25/94
-X#
-X# Modified: Marc Aurele La France (tsi at xfree86.org)
-X# Log:      SPARC changes		2001.09
-X#
-X# Purpose:  This conf file is used by the aperture driver.
-X#
-Xname="aperture" parent="pseudo";
-END-of-./aperture/aperture.conf
-echo x - ./aperture/devlink.tab
-sed 's/^X//' >./aperture/devlink.tab << 'END-of-./aperture/devlink.tab'
-X# The following entry is for the aperture driver
-Xtype=ddi_pseudo;name=aperture	fbs/\M0
-END-of-./aperture/devlink.tab
-exit
-
commit b1029716e41e252f149b82124a149da180607c96
Author: Ray Strode <rstrode at redhat.com>
Date:   Thu Apr 16 11:28:16 2015 -0400

    systemd-logind: don't second guess D-Bus default timeout
    
    At the moment, the X server uses a non-default timeout for D-Bus
    messages to systemd-logind. The only timeouts normally used with
    D-Bus are:
    
    1) Infinite
    2) Default
    
    Anything else is just as arbitrary as Default, and so rarely makes
    sense to use instead of Default.
    
    Put another way, there's little reason to be fault tolerant against
    a local root running daemon (logind), that in some configurations, the
    X server already depends on for proper functionality.
    
    This commit changes systemd-logind to just use the default timeouts.
    
    Downstream-bug: https://bugzilla.redhat.com/show_bug.cgi?id=1209347
    Signed-off-by: Ray Strode <rstrode at redhat.com>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c
index 57c87c0..4ad41a3 100644
--- a/hw/xfree86/os-support/linux/systemd-logind.c
+++ b/hw/xfree86/os-support/linux/systemd-logind.c
@@ -40,8 +40,6 @@
 
 #include "systemd-logind.h"
 
-#define DBUS_TIMEOUT 500 /* Wait max 0.5 seconds */
-
 struct systemd_logind_info {
     DBusConnection *conn;
     char *session;
@@ -130,7 +128,7 @@ systemd_logind_take_fd(int _major, int _minor, const char *path,
     }
 
     reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
-                                                      DBUS_TIMEOUT, &error);
+                                                      DBUS_TIMEOUT_USE_DEFAULT, &error);
     if (!reply) {
         LogMessage(X_ERROR, "systemd-logind: failed to take device %s: %s\n",
                    path, error.message);
@@ -207,7 +205,7 @@ systemd_logind_release_fd(int _major, int _minor, int fd)
     }
 
     reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
-                                                      DBUS_TIMEOUT, &error);
+                                                      DBUS_TIMEOUT_USE_DEFAULT, &error);
     if (!reply)
         LogMessage(X_ERROR, "systemd-logind: failed to release device: %s\n",
                    error.message);
@@ -289,7 +287,7 @@ systemd_logind_ack_pause(struct systemd_logind_info *info,
     }
 
     reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
-                                                      DBUS_TIMEOUT, &error);
+                                                      DBUS_TIMEOUT_USE_DEFAULT, &error);
     if (!reply)
         LogMessage(X_ERROR, "systemd-logind: failed to ack pause: %s\n",
                    error.message);
@@ -457,7 +455,7 @@ connect_hook(DBusConnection *connection, void *data)
     }
 
     reply = dbus_connection_send_with_reply_and_block(connection, msg,
-                                                      DBUS_TIMEOUT, &error);
+                                                      DBUS_TIMEOUT_USE_DEFAULT, &error);
     if (!reply) {
         LogMessage(X_ERROR, "systemd-logind: failed to get session: %s\n",
                    error.message);
@@ -492,7 +490,7 @@ connect_hook(DBusConnection *connection, void *data)
     }
 
     reply = dbus_connection_send_with_reply_and_block(connection, msg,
-                                                      DBUS_TIMEOUT, &error);
+                                                      DBUS_TIMEOUT_USE_DEFAULT, &error);
     if (!reply) {
         LogMessage(X_ERROR, "systemd-logind: TakeControl failed: %s\n",
                    error.message);
@@ -564,7 +562,7 @@ systemd_logind_release_control(struct systemd_logind_info *info)
     }
 
     reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
-                                                      DBUS_TIMEOUT, &error);
+                                                      DBUS_TIMEOUT_USE_DEFAULT, &error);
     if (!reply) {
         LogMessage(X_ERROR, "systemd-logind: ReleaseControl failed: %s\n",
                    error.message);
commit 792e9251670ce94210df5c6d354059bbb97f4478
Author: Ray Strode <rstrode at redhat.com>
Date:   Thu Apr 16 11:28:15 2015 -0400

    systemd-logind: filter out non-signal messages from message filter
    
    It's possible to receive a message reply in the message filter if a
    previous message call timed out locally before the reply arrived.
    
    The message_filter function only handles signals, at the moment, and
    does not properly handle message replies.
    
    This commit changes the message_filter function to filter out all
    non-signal messages, including spurious message replies.
    
    Downstream-bug: https://bugzilla.redhat.com/show_bug.cgi?id=1209347
    Signed-off-by: Ray Strode <rstrode at redhat.com>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c
index 49758f4..57c87c0 100644
--- a/hw/xfree86/os-support/linux/systemd-logind.c
+++ b/hw/xfree86/os-support/linux/systemd-logind.c
@@ -313,6 +313,9 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
     dbus_int32_t major, minor;
     char *pause_str;
 
+    if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
     dbus_error_init(&error);
 
     if (dbus_message_is_signal(message,
commit 41932dfbc841a1adc6512d41085ea3f8ebecb42c
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Apr 8 07:45:28 2015 -0700

    mi: Partial pie-slice filled arcs may need more space for spans
    
    The mi filled arc code estimates that a filled arc will produce no
    more spans than the arc is tall. This is true for most arcs except
    for pie-slice arcs strictly between 180 and 360 degrees where the missing
    portion of the arc faces up or down such that we get two spans on some
    scanlines.
    
    For those, we need to reserve room for another height/2 spans. This
    patch just does it for all partial pie-sliced arcs to make the test
    easier to understand; it's just over-allocating a bit of memory, so
    that's safe.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/mi/mifillarc.c b/mi/mifillarc.c
index 246d70f..888519e 100644
--- a/mi/mifillarc.c
+++ b/mi/mifillarc.c
@@ -660,6 +660,11 @@ miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs_all, xArc * parcs)
             if (narcs && nspans + arc->height > MAX_SPANS_PER_LOOP)
                 break;
             nspans += arc->height;
+
+            /* A pie-slice arc may add another pile of spans */
+            if (pGC->arcMode == ArcPieSlice &&
+                (-FULLCIRCLE < arc->angle2 && arc->angle2 < FULLCIRCLE))
+                nspans += (arc->height + 1) >> 1;
         }
 
         pts = points = malloc (sizeof (DDXPointRec) * nspans +
commit 21e7d2bb5cd810688bb905b6ed092497ca8a2c59
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Wed Apr 8 14:07:52 2015 +0200

    Re-enable non serverfd input devices immediately on vtenter
    
    Non serverfd input devices will never get a systemd-logind dbus resume signal,
    causing them to never get re-enabled.
    
    This commit changes xf86VTEnter() to enable them immediately, fixing this.
    
    BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=89756
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index c06aaae..97a1f97 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -583,10 +583,11 @@ xf86VTEnter(void)
     /* Turn screen saver off when switching back */
     dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
 
-    /* If we use systemd-logind it will enable input devices for us */
-    if (!systemd_logind_controls_session())
-        for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
+    for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
+        /* Devices with server managed fds get enabled on logind resume */
+        if (!(pInfo->flags & XI86_SERVER_FD))
             xf86EnableInputDeviceForVTSwitch(pInfo);
+    }
 
     for (ih = InputHandlers; ih; ih = ih->next) {
         if (ih->is_input)
commit f1da6bf5d94911e78d2e27e6accf0c6e3aefb331
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Mar 31 17:07:43 2015 -0700

    Require randrproto version 1.5.0 or newer
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/configure.ac b/configure.ac
index 280c369..606298b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -782,7 +782,7 @@ LIBXSHMFENCE="xshmfence >= 1.1"
 
 dnl Required modules
 XPROTO="xproto >= 7.0.26"
-RANDRPROTO="randrproto >= 1.4.0"
+RANDRPROTO="randrproto >= 1.5.0"
 RENDERPROTO="renderproto >= 0.11"
 XEXTPROTO="xextproto >= 7.2.99.901"
 INPUTPROTO="inputproto >= 2.3"
commit e36236eade412dd3894f75f78a7b3d7c1037e6c3
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Tue Dec 30 09:13:16 2014 -0800

    xfree86: Add GPU screens even if there are no active GDevs
    
    xf86platformProbeDev creates GPU screens for any platform devices that were not
    matched by a GDev in the loop above, but only if there was at least one device.
    This means that it's impossible to configure a device as a GPU screen if there
    is only one platform device that matches that driver.
    
    Instead, create a GPU screen (if possible) for any platform device that was not
    claimed by the GDev loop.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Maarten Lankhorst <maarten.lankhorst at ubuntu.com>
    Acked-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 387b5f1..c1aaba4 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -428,6 +428,10 @@ xf86platformProbeDev(DriverPtr drvp)
 
     /* find the main device or any device specificed in xorg.conf */
     for (i = 0; i < numDevs; i++) {
+        /* skip inactive devices */
+        if (!devList[i]->active)
+            continue;
+
         for (j = 0; j < xf86_num_platform_devices; j++) {
             if (devList[i]->busID && *devList[i]->busID) {
                 if (xf86PlatformDeviceCheckBusID(&xf86_platform_devices[j], devList[i]->busID))
@@ -451,10 +455,14 @@ xf86platformProbeDev(DriverPtr drvp)
             continue;
     }
 
-    /* if autoaddgpu devices is enabled then go find a few more and add them as GPU screens */
-    if (xf86Info.autoAddGPU && numDevs) {
+    /* if autoaddgpu devices is enabled then go find any unclaimed platform
+     * devices and add them as GPU screens */
+    if (xf86Info.autoAddGPU) {
         for (j = 0; j < xf86_num_platform_devices; j++) {
-            probeSingleDevice(&xf86_platform_devices[j], drvp, devList[0], PLATFORM_PROBE_GPU_SCREEN);
+            if (probeSingleDevice(&xf86_platform_devices[j], drvp,
+                                  devList ?  devList[0] : NULL,
+                                  PLATFORM_PROBE_GPU_SCREEN))
+                foundScreen = TRUE;
         }
     }
 
commit 4ecda362594d771f401de467c2d58c0f552227a8
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Tue Dec 30 09:13:15 2014 -0800

    xfree86: Fix xf86_check_platform_slot's handling of PCI
    
    If a PCI entity is found, xf86_check_platform_slot performs a device ID check
    against the xf86_platform_device passed in.  However, it just returns
    immediately without checking the rest of the entities first.  This leads to this
    situation happening:
    
    1. The nvidia driver creates an entity 0 with bus.type == BUS_PCI
    2. The intel driver creates entity 1 for its platform device, opening
       /dev/dri/card0
    3. xf86platformProbeDev calls probeSingleDevice on the Intel platform device,
       which calls doPlatformProbe, which calls xf86_check_platform_slot.
    4. xf86_check_platform_slot compares the Intel platform device against the
       NVIDIA PCI entity.  Since they don't have the same device ID, it returns
       TRUE.
    5. doPlatformProbe calls xf86ClaimPlatformSlot, which creates a duplicate entity
       for the Intel one.
    
    Fix this by only returning FALSE if the PCI ID matches, and continuing the loop
    otherwise.  In the scenario above, this allows it to continue on to find the
    Intel platform device that matches the second entity.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Maarten Lankhorst <maarten.lankhorst at ubuntu.com>
    Acked-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 15988b8..387b5f1 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -153,8 +153,10 @@ xf86_check_platform_slot(const struct xf86_platform_device *pd)
     for (i = 0; i < xf86NumEntities; i++) {
         const EntityPtr u = xf86Entities[i];
 
-        if (pd->pdev && u->bus.type == BUS_PCI)
-            return !MATCH_PCI_DEVICES(pd->pdev, u->bus.id.pci);
+        if (pd->pdev && u->bus.type == BUS_PCI &&
+            MATCH_PCI_DEVICES(pd->pdev, u->bus.id.pci)) {
+            return FALSE;
+        }
         if ((u->bus.type == BUS_PLATFORM) && (pd == u->bus.id.plat)) {
             return FALSE;
         }
commit e608f3521eaaab972a3eea62aa04a65958351c1c
Merge: d3b9c47 5de1383
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Mar 31 09:06:08 2015 -0700

    Merge remote-tracking branch 'airlied/for-keithp'

commit d3b9c47c849d039493c5e0ca5c3af8affe738746
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Sun Mar 29 23:18:49 2015 +0100

    Fix XQuartz build
    
    Fix XQuartz build since commit e036cbfc "Make PseudoramiXExtensionInit()
    prototype more generally available"
    
    Add #include "nonsdk_extinit.h" to xprScreen.c
    
    Add #include "nonsdk_extinit.h" to miinitext.c under INXQUARTZ to provide
    declarations used under INXQUARTZ
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
    Tested-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c
index d0a525f..30f2218 100644
--- a/hw/xquartz/xpr/xprScreen.c
+++ b/hw/xquartz/xpr/xprScreen.c
@@ -54,6 +54,8 @@
 #include "damage.h"
 #endif
 
+#include "nonsdk_extinit.h"
+
 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
 // From NSApplication.h
 extern const double NSAppKitVersionNumber;
diff --git a/mi/miinitext.c b/mi/miinitext.c
index 5872bf5..086d2c3 100644
--- a/mi/miinitext.c
+++ b/mi/miinitext.c
@@ -108,6 +108,9 @@ SOFTWARE.
 #include "misc.h"
 #include "extension.h"
 #include "extinit.h"
+#ifdef INXQUARTZ
+#include "nonsdk_extinit.h"
+#endif
 #include "micmap.h"
 #include "globals.h"
 
commit 5de13830709a7f2d4d112d71e062f710ef466ab6
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Dec 16 09:56:50 2014 -0800

    randr: Use Monitor list for Xinerama
    
    This replaces the CRTC-based Xinerama implementation with one which
    uses Monitors instead, allowing clients to manipulate the Xinerama
    configuration through the RandR Monitor list.
    
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c
index 36632c7..b6e9586 100644
--- a/randr/rrxinerama.c
+++ b/randr/rrxinerama.c
@@ -149,35 +149,10 @@ ProcRRXineramaGetState(ClientPtr client)
     return Success;
 }
 
-static Bool
-RRXineramaCrtcActive(RRCrtcPtr crtc)
-{
-    return crtc->mode != NULL && crtc->numOutputs > 0;
-}
-
 static int
 RRXineramaScreenCount(ScreenPtr pScreen)
 {
-    int i, n;
-    ScreenPtr slave;
-
-    n = 0;
-    if (rrGetScrPriv(pScreen)) {
-        rrScrPriv(pScreen);
-        for (i = 0; i < pScrPriv->numCrtcs; i++)
-            if (RRXineramaCrtcActive(pScrPriv->crtcs[i]))
-                n++;
-    }
-
-    xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
-        rrScrPrivPtr pSlavePriv;
-        pSlavePriv = rrGetScrPriv(slave);
-        for (i = 0; i < pSlavePriv->numCrtcs; i++)
-            if (RRXineramaCrtcActive(pSlavePriv->crtcs[i]))
-                n++;
-    }
-
-    return n;
+    return RRMonitorCountList(pScreen);
 }
 
 static Bool
@@ -276,42 +251,16 @@ ProcRRXineramaIsActive(ClientPtr client)
 }
 
 static void
-RRXineramaWriteCrtc(ClientPtr client, RRCrtcPtr crtc)
+RRXineramaWriteMonitor(ClientPtr client, RRMonitorPtr monitor)
 {
     xXineramaScreenInfo scratch;
 
-    if (RRXineramaCrtcActive(crtc)) {
-        ScreenPtr pScreen = crtc->pScreen;
-        rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen);
-        BoxRec panned_area;
-
-        /* Check to see if crtc is panned and return the full area when applicable. */
-        if (pScrPriv && pScrPriv->rrGetPanning &&
-            pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL, NULL) &&
-            (panned_area.x2 > panned_area.x1) &&
-            (panned_area.y2 > panned_area.y1)) {
-            scratch.x_org = panned_area.x1;
-            scratch.y_org = panned_area.y1;
-            scratch.width = panned_area.x2 - panned_area.x1;
-            scratch.height = panned_area.y2 - panned_area.y1;
-        }
-        else {
-            int width, height;
-
-            RRCrtcGetScanoutSize(crtc, &width, &height);
-            scratch.x_org = crtc->x;
-            scratch.y_org = crtc->y;
-            scratch.width = width;
-            scratch.height = height;
-        }
-        if (client->swapped) {
-            swaps(&scratch.x_org);
-            swaps(&scratch.y_org);
-            swaps(&scratch.width);
-            swaps(&scratch.height);
-        }
-        WriteToClient(client, sz_XineramaScreenInfo, &scratch);
-    }
+    scratch.x_org = monitor->geometry.box.x1;
+    scratch.y_org = monitor->geometry.box.y1;
+    scratch.width = monitor->geometry.box.x2 - monitor->geometry.box.x1;
+    scratch.height = monitor->geometry.box.y2 - monitor->geometry.box.y1;
+
+    WriteToClient(client, sz_XineramaScreenInfo, &scratch);
 }
 
 int
@@ -319,21 +268,23 @@ ProcRRXineramaQueryScreens(ClientPtr client)
 {
     xXineramaQueryScreensReply rep;
     ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN];
-    int n = 0;
-    int i;
+    int m;
+    RRMonitorPtr monitors = NULL;
+    int nmonitors = 0;
 
     REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
 
     if (RRXineramaScreenActive(pScreen)) {
         RRGetInfo(pScreen, FALSE);
-        n = RRXineramaScreenCount(pScreen);
+        if (!RRMonitorMakeList(pScreen, TRUE, &monitors, &nmonitors))
+            return BadAlloc;
     }
 
     rep = (xXineramaQueryScreensReply) {
         .type = X_Reply,
         .sequenceNumber = client->sequence,
-        .length = bytes_to_int32(n * sz_XineramaScreenInfo),
-        .number = n
+        .length = bytes_to_int32(nmonitors * sz_XineramaScreenInfo),
+        .number = nmonitors
     };
     if (client->swapped) {
         swaps(&rep.sequenceNumber);
@@ -342,40 +293,11 @@ ProcRRXineramaQueryScreens(ClientPtr client)
     }
     WriteToClient(client, sizeof(xXineramaQueryScreensReply), &rep);
 
-    if (n) {
-        ScreenPtr slave;
-        rrScrPriv(pScreen);
-        int has_primary = 0;
-        RRCrtcPtr primary_crtc = NULL;
-
-        if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
-            has_primary = 1;
-            primary_crtc = pScrPriv->primaryOutput->crtc;
-            RRXineramaWriteCrtc(client, pScrPriv->primaryOutput->crtc);
-        }
-
-        for (i = 0; i < pScrPriv->numCrtcs; i++) {
-            if (has_primary &&
-                primary_crtc == pScrPriv->crtcs[i]) {
-                has_primary = 0;
-                continue;
-            }
-            RRXineramaWriteCrtc(client, pScrPriv->crtcs[i]);
-        }
-
-        xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
-            rrScrPrivPtr pSlavePriv;
-            pSlavePriv = rrGetScrPriv(slave);
-            for (i = 0; i < pSlavePriv->numCrtcs; i++) {
-                if (has_primary &&
-                    primary_crtc == pSlavePriv->crtcs[i]) {
-                    has_primary = 0;
-                    continue;
-                }
-                RRXineramaWriteCrtc(client, pSlavePriv->crtcs[i]);
-            }
-        }
-    }
+    for (m = 0; m < nmonitors; m++)
+        RRXineramaWriteMonitor(client, &monitors[m]);
+
+    if (monitors)
+        RRMonitorFreeList(monitors, nmonitors);
 
     return Success;
 }
commit 7e1f86d42b54fb7f6492875e47a718eaeca3069b
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Dec 16 01:59:03 2014 -0800

    randr: Add Monitor support (v1.1)
    
    Store the user-defined monitors in the RandR screen private.
    
    Generate a list of monitors from both the user-defined ones and from
    any outputs not mentioned in one of the user-defined monitors. This list
    covers both the outputs in the main screen as well as any slaves.
    
    v1.1: airlied: fix up primary skipping bug,
    fix wrong height initialiser
    add get_active flag from updated protocol.
    
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index fc428c8..be532ff 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -73,7 +73,7 @@
 
 /* RandR */
 #define SERVER_RANDR_MAJOR_VERSION		1
-#define SERVER_RANDR_MINOR_VERSION		4
+#define SERVER_RANDR_MINOR_VERSION		5
 
 /* Record */
 #define SERVER_RECORD_MAJOR_VERSION		1
diff --git a/randr/Makefile.am b/randr/Makefile.am
index ccaff3f..90dc9ec 100644
--- a/randr/Makefile.am
+++ b/randr/Makefile.am
@@ -15,6 +15,7 @@ librandr_la_SOURCES =	\
 	rrdispatch.c	\
 	rrinfo.c	\
 	rrmode.c	\
+	rrmonitor.c	\
 	rroutput.c	\
 	rrpointer.c	\
 	rrproperty.c	\
diff --git a/randr/randr.c b/randr/randr.c
index 6e3f14b..ad1dda2 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -98,6 +98,8 @@ RRCloseScreen(ScreenPtr pScreen)
     if (pScrPriv->provider)
         RRProviderDestroy(pScrPriv->provider);
 
+    RRMonitorClose(pScreen);
+
     free(pScrPriv->crtcs);
     free(pScrPriv->outputs);
     free(pScrPriv);
@@ -333,6 +335,8 @@ RRScreenInit(ScreenPtr pScreen)
     pScrPriv->numCrtcs = 0;
     pScrPriv->crtcs = NULL;
 
+    RRMonitorInit(pScreen);
+
     RRNScreens += 1;            /* keep count of screens that implement randr */
     return TRUE;
 }
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 13e6a85..438a52a 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -80,6 +80,7 @@ typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr;
 typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr;
 typedef struct _rrOutput RROutputRec, *RROutputPtr;
 typedef struct _rrProvider RRProviderRec, *RRProviderPtr;
+typedef struct _rrMonitor RRMonitorRec, *RRMonitorPtr;
 
 struct _rrMode {
     int refcnt;
@@ -169,6 +170,22 @@ struct _rrProvider {
     struct _rrProvider *output_source;
 };
 
+typedef struct _rrMonitorGeometry {
+    BoxRec box;
+    CARD32 mmWidth;
+    CARD32 mmHeight;
+} RRMonitorGeometryRec, *RRMonitorGeometryPtr;
+
+struct _rrMonitor {
+    Atom name;
+    ScreenPtr pScreen;
+    int numOutputs;
+    RROutput *outputs;
+    Bool primary;
+    Bool automatic;
+    RRMonitorGeometryRec geometry;
+};
+
 #if RANDR_12_INTERFACE
 typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen,
                                         CARD16 width,
@@ -338,6 +355,9 @@ typedef struct _rrScrPriv {
 
     RRProviderDestroyProcPtr rrProviderDestroy;
 
+    int numMonitors;
+    RRMonitorPtr *monitors;
+
 } rrScrPrivRec, *rrScrPrivPtr;
 
 extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
@@ -981,6 +1001,30 @@ extern _X_EXPORT void
  RRXineramaExtensionInit(void);
 #endif
 
+void
+RRMonitorInit(ScreenPtr screen);
+
+Bool
+RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr *monitors_ret, int *nmon_ret);
+
+int
+RRMonitorCountList(ScreenPtr screen);
+
+void
+RRMonitorFreeList(RRMonitorPtr monitors, int nmon);
+
+void
+RRMonitorClose(ScreenPtr screen);
+
+int
+ProcRRGetMonitors(ClientPtr client);
+
+int
+ProcRRSetMonitor(ClientPtr client);
+
+int
+ProcRRDeleteMonitor(ClientPtr client);
+
 #endif                          /* _RANDRSTR_H_ */
 
 /*
diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c
index b9346d3..13ac6b1 100644
--- a/randr/rrdispatch.c
+++ b/randr/rrdispatch.c
@@ -254,4 +254,7 @@ int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
         ProcRRChangeProviderProperty, /* 39 */
         ProcRRDeleteProviderProperty, /* 40 */
         ProcRRGetProviderProperty,    /* 41 */
+        ProcRRGetMonitors,            /* 42 */
+        ProcRRSetMonitor,             /* 43 */
+        ProcRRDeleteMonitor,          /* 44 */
 };
diff --git a/randr/rrmonitor.c b/randr/rrmonitor.c
new file mode 100644
index 0000000..fbdd352
--- /dev/null
+++ b/randr/rrmonitor.c
@@ -0,0 +1,748 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "randrstr.h"
+#include "swaprep.h"
+
+static Atom
+RRMonitorCrtcName(RRCrtcPtr crtc)
+{
+    char        name[20];
+
+    if (crtc->numOutputs) {
+        RROutputPtr     output = crtc->outputs[0];
+        return MakeAtom(output->name, output->nameLength, TRUE);
+    }
+    sprintf(name, "Monitor-%08x", crtc->id);
+    return MakeAtom(name, strlen(name), TRUE);
+}
+
+static Bool
+RRMonitorCrtcPrimary(RRCrtcPtr crtc)
+{
+    ScreenPtr screen = crtc->pScreen;
+    rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+    int o;
+
+    for (o = 0; o < crtc->numOutputs; o++)
+        if (crtc->outputs[o] == pScrPriv->primaryOutput)
+            return TRUE;
+    return FALSE;
+}
+
+#define DEFAULT_PIXELS_PER_MM   (96.0 / 25.4)
+
+static void
+RRMonitorGetCrtcGeometry(RRCrtcPtr crtc, RRMonitorGeometryPtr geometry)
+{
+    ScreenPtr screen = crtc->pScreen;
+    rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+    BoxRec      panned_area;
+
+    /* Check to see if crtc is panned and return the full area when applicable. */
+    if (pScrPriv && pScrPriv->rrGetPanning &&
+        pScrPriv->rrGetPanning(screen, crtc, &panned_area, NULL, NULL) &&
+        (panned_area.x2 > panned_area.x1) &&
+        (panned_area.y2 > panned_area.y1)) {
+        geometry->box = panned_area;
+    }
+    else {
+        int width, height;
+
+        RRCrtcGetScanoutSize(crtc, &width, &height);
+        geometry->box.x1 = crtc->x;
+        geometry->box.y1 = crtc->y;
+        geometry->box.x2 = geometry->box.x1 + width;
+        geometry->box.y2 = geometry->box.y1 + height;
+    }
+    if (crtc->numOutputs && crtc->outputs[0]->mmWidth && crtc->outputs[0]->mmHeight) {
+        RROutputPtr output = crtc->outputs[0];
+        geometry->mmWidth = output->mmWidth;
+        geometry->mmHeight = output->mmHeight;
+    } else {
+        geometry->mmWidth = floor ((geometry->box.x2 - geometry->box.x1) / DEFAULT_PIXELS_PER_MM + 0.5);
+        geometry->mmHeight = floor ((geometry->box.y2 - geometry->box.y1) / DEFAULT_PIXELS_PER_MM + 0.5);
+    }
+}
+
+static Bool
+RRMonitorSetFromServer(RRCrtcPtr crtc, RRMonitorPtr monitor)
+{
+    int o;
+
+    monitor->name = RRMonitorCrtcName(crtc);
+    monitor->pScreen = crtc->pScreen;
+    monitor->numOutputs = crtc->numOutputs;
+    monitor->outputs = calloc(crtc->numOutputs, sizeof(RRCrtc));
+    if (!monitor->outputs)
+        return FALSE;
+    for (o = 0; o < crtc->numOutputs; o++)
+        monitor->outputs[o] = crtc->outputs[o]->id;
+    monitor->primary = RRMonitorCrtcPrimary(crtc);
+    monitor->automatic = TRUE;
+    RRMonitorGetCrtcGeometry(crtc, &monitor->geometry);
+    return TRUE;
+}
+
+static Bool
+RRMonitorAutomaticGeometry(RRMonitorPtr monitor)
+{
+    return (monitor->geometry.box.x1 == 0 &&
+            monitor->geometry.box.y1 == 0 &&
+            monitor->geometry.box.x2 == 0 &&
+            monitor->geometry.box.y2 == 0);
+}
+
+static void
+RRMonitorGetGeometry(RRMonitorPtr monitor, RRMonitorGeometryPtr geometry)
+{
+    if (RRMonitorAutomaticGeometry(monitor) && monitor->numOutputs > 0) {
+        ScreenPtr               screen = monitor->pScreen;
+        rrScrPrivPtr            pScrPriv = rrGetScrPriv(screen);
+        RRMonitorGeometryRec    first = { .box = { 0, 0, 0, 0 }, .mmWidth = 0, .mmHeight = 0 };
+        RRMonitorGeometryRec    this;
+        int                     c, o, co;
+        int                     active_crtcs = 0;
+
+        *geometry = first;
+        for (o = 0; o < monitor->numOutputs; o++) {
+            RRCrtcPtr   crtc = NULL;
+            Bool        in_use = FALSE;
+
+            for (c = 0; !in_use && c < pScrPriv->numCrtcs; c++) {
+                crtc = pScrPriv->crtcs[c];
+                if (!crtc->mode)
+                    continue;
+                for (co = 0; !in_use && co < crtc->numOutputs; co++)
+                    if (monitor->outputs[o] == crtc->outputs[co]->id)
+                        in_use = TRUE;
+            }
+
+            if (!in_use)
+                continue;
+
+            RRMonitorGetCrtcGeometry(crtc, &this);
+
+            if (active_crtcs == 0) {
+                first = this;
+                *geometry = this;
+            } else {
+                geometry->box.x1 = min(this.box.x1, geometry->box.x1);
+                geometry->box.x2 = max(this.box.x2, geometry->box.x2);
+                geometry->box.y1 = min(this.box.y1, geometry->box.y1);
+                geometry->box.y2 = max(this.box.y2, geometry->box.y2);
+            }
+            active_crtcs++;
+        }
+
+        /* Adjust physical sizes to account for total area */
+        if (active_crtcs > 1 && first.box.x2 != first.box.x1 && first.box.y2 != first.box.y1) {
+            geometry->mmWidth = (this.box.x2 - this.box.x1) / (first.box.x2 - first.box.x1) * first.mmWidth;
+            geometry->mmHeight = (this.box.y2 - this.box.y1) / (first.box.y2 - first.box.y1) * first.mmHeight;
+        }
+    } else {
+        *geometry = monitor->geometry;
+    }
+}
+
+static Bool
+RRMonitorSetFromClient(RRMonitorPtr client_monitor, RRMonitorPtr monitor)
+{
+    monitor->name = client_monitor->name;
+    monitor->pScreen = client_monitor->pScreen;
+    monitor->numOutputs = client_monitor->numOutputs;
+    monitor->outputs = calloc(client_monitor->numOutputs, sizeof (RROutput));
+    if (!monitor->outputs && client_monitor->numOutputs)
+        return FALSE;
+    memcpy(monitor->outputs, client_monitor->outputs, client_monitor->numOutputs * sizeof (RROutput));
+    monitor->primary = client_monitor->primary;
+    monitor->automatic = client_monitor->automatic;
+    RRMonitorGetGeometry(client_monitor, &monitor->geometry);
+    return TRUE;
+}
+
+typedef struct _rrMonitorList {
+    int         num_client;
+    int         num_server;
+    RRCrtcPtr   *server_crtc;
+    int         num_crtcs;
+    int         client_primary;
+    int         server_primary;
+} RRMonitorListRec, *RRMonitorListPtr;
+
+static Bool
+RRMonitorInitList(ScreenPtr screen, RRMonitorListPtr mon_list, Bool get_active)
+{
+    rrScrPrivPtr        pScrPriv = rrGetScrPriv(screen);
+    int                 m, o, c, sc;
+    int                 numCrtcs;
+    ScreenPtr           slave;
+
+    if (!RRGetInfo(screen, FALSE))
+        return FALSE;
+
+    /* Count the number of crtcs in this and any slave screens */
+    numCrtcs = pScrPriv->numCrtcs;
+    xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+        rrScrPrivPtr pSlavePriv;
+        pSlavePriv = rrGetScrPriv(slave);
+        numCrtcs += pSlavePriv->numCrtcs;
+    }
+    mon_list->num_crtcs = numCrtcs;
+
+    mon_list->server_crtc = calloc(numCrtcs * 2, sizeof (RRCrtcPtr));
+    if (!mon_list->server_crtc)
+        return FALSE;
+
+    /* Collect pointers to all of the active crtcs */
+    c = 0;
+    for (sc = 0; sc < pScrPriv->numCrtcs; sc++, c++) {
+        if (pScrPriv->crtcs[sc]->mode != NULL)
+            mon_list->server_crtc[c] = pScrPriv->crtcs[sc];
+    }
+
+    xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+        rrScrPrivPtr pSlavePriv;
+        pSlavePriv = rrGetScrPriv(slave);
+        for (sc = 0; sc < pSlavePriv->numCrtcs; sc++, c++) {
+            if (pSlavePriv->crtcs[sc]->mode != NULL)
+                mon_list->server_crtc[c] = pSlavePriv->crtcs[sc];
+        }
+    }
+
+    /* Walk the list of client-defined monitors, clearing the covered
+     * CRTCs from the full list and finding whether one of the
+     * monitors is primary
+     */
+    mon_list->num_client = pScrPriv->numMonitors;
+    mon_list->client_primary = -1;
+
+    for (m = 0; m < pScrPriv->numMonitors; m++) {
+        RRMonitorPtr monitor = pScrPriv->monitors[m];
+        if (get_active) {
+            RRMonitorGeometryRec geom;
+
+            RRMonitorGetGeometry(monitor, &geom);
+            if (geom.box.x2 - geom.box.x1 == 0 ||
+                geom.box.y2 - geom.box.y1 == 0) {
+                mon_list->num_client--;
+                continue;
+            }
+        }
+        if (monitor->primary && mon_list->client_primary == -1)
+            mon_list->client_primary = m;
+        for (o = 0; o < monitor->numOutputs; o++) {
+            for (c = 0; c < numCrtcs; c++) {
+                RRCrtcPtr       crtc = mon_list->server_crtc[c];
+                if (crtc) {
+                    int             co;
+                    for (co = 0; co < crtc->numOutputs; co++)
+                        if (crtc->outputs[co]->id == monitor->outputs[o]) {
+                            mon_list->server_crtc[c] = NULL;
+                            break;
+                        }
+                }
+            }
+        }
+    }
+
+    /* Now look at the active CRTCs, and count
+     * those not covered by a client monitor, as well
+     * as finding whether one of them is marked primary
+     */
+    mon_list->num_server = 0;
+    mon_list->server_primary = -1;
+
+    for (c = 0; c < mon_list->num_crtcs; c++) {
+        RRCrtcPtr       crtc = mon_list->server_crtc[c];
+
+        if (!crtc)
+            continue;
+
+        mon_list->num_server++;
+
+        if (RRMonitorCrtcPrimary(crtc) && mon_list->server_primary == -1)
+            mon_list->server_primary = c;
+    }
+    return TRUE;
+}
+
+static void
+RRMonitorFiniList(RRMonitorListPtr list)
+{
+    free(list->server_crtc);
+}
+
+/* Construct a complete list of protocol-visible monitors, including
+ * the manually generated ones as well as those generated
+ * automatically from the remaining CRCTs
+ */
+
+Bool
+RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr *monitors_ret, int *nmon_ret)
+{
+    rrScrPrivPtr        pScrPriv = rrGetScrPriv(screen);
+    RRMonitorListRec    list;
+    int                 m, c;
+    RRMonitorPtr        mon, monitors;
+    Bool                has_primary = FALSE;
+
+    if (!pScrPriv)
+        return FALSE;
+
+    if (!RRMonitorInitList(screen, &list, get_active))
+        return FALSE;
+
+    monitors = calloc(list.num_client + list.num_server, sizeof (RRMonitorRec));
+    if (!monitors) {
+        RRMonitorFiniList(&list);
+        return FALSE;
+    }
+
+    mon = monitors;
+
+    /* Fill in the primary monitor data first
+     */
+    if (list.client_primary >= 0) {
+        RRMonitorSetFromClient(pScrPriv->monitors[list.client_primary], mon);
+        mon++;
+    } else if (list.server_primary >= 0) {
+        RRMonitorSetFromServer(pScrPriv->crtcs[list.server_primary], mon);
+        mon++;
+    }
+
+    /* Fill in the client-defined monitors next
+     */
+    for (m = 0; m < pScrPriv->numMonitors; m++) {
+        if (m == list.client_primary)
+            continue;
+        if (get_active) {
+            RRMonitorGeometryRec geom;
+
+            RRMonitorGetGeometry(pScrPriv->monitors[m], &geom);
+            if (geom.box.x2 - geom.box.x1 == 0 ||
+                geom.box.y2 - geom.box.y1 == 0) {
+                continue;
+            }
+        }
+        RRMonitorSetFromClient(pScrPriv->monitors[m], mon);
+        if (has_primary)
+            mon->primary = FALSE;
+        else if (mon->primary)
+            has_primary = TRUE;
+        mon++;
+    }
+
+    /* And finish with the list of crtc-inspired monitors
+     */
+    for (c = 0; c < pScrPriv->numCrtcs; c++) {
+        RRCrtcPtr crtc = pScrPriv->crtcs[c];
+        if (c == list.server_primary && list.client_primary < 0)
+            continue;
+
+        if (!list.server_crtc[c])
+            continue;
+
+        RRMonitorSetFromServer(crtc, mon);
+        if (has_primary)
+            mon->primary = FALSE;
+        else if (mon->primary)
+            has_primary = TRUE;
+        mon++;
+    }
+
+    RRMonitorFiniList(&list);
+    *nmon_ret = list.num_client + list.num_server;
+    *monitors_ret = monitors;
+    return TRUE;
+}
+
+int
+RRMonitorCountList(ScreenPtr screen)
+{
+    RRMonitorListRec    list;
+    int                 nmon;
+
+    if (!RRMonitorInitList(screen, &list, FALSE))
+        return -1;
+    nmon = list.num_client + list.num_server;
+    RRMonitorFiniList(&list);
+    return nmon;
+}
+
+static void
+RRMonitorFree(RRMonitorPtr monitor)
+{
+    free(monitor);
+}
+
+static RRMonitorPtr
+RRMonitorAlloc(int noutput)
+{
+    RRMonitorPtr        monitor;
+
+    monitor = calloc(1, sizeof (RRMonitorRec) + noutput * sizeof (RROutput));
+    if (!monitor)
+        return NULL;
+    monitor->numOutputs = noutput;
+    monitor->outputs = (RROutput *) (monitor + 1);
+    return monitor;
+}
+
+static int
+RRMonitorDelete(ClientPtr client, ScreenPtr screen, Atom name)
+{
+    rrScrPrivPtr        pScrPriv = rrGetScrPriv(screen);
+    int                 m;
+
+    if (!pScrPriv) {
+        client->errorValue = name;
+        return BadAtom;
+    }
+
+    for (m = 0; m < pScrPriv->numMonitors; m++) {
+        RRMonitorPtr    monitor = pScrPriv->monitors[m];
+        if (monitor->name == name) {
+            memmove(pScrPriv->monitors + m, pScrPriv->monitors + m + 1,
+                    (pScrPriv->numMonitors - (m + 1)) * sizeof (RRMonitorPtr));
+            --pScrPriv->numMonitors;
+            RRMonitorFree(monitor);
+            return Success;
+        }
+    }
+
+    client->errorValue = name;
+    return BadValue;
+}
+
+static Bool
+RRMonitorMatchesOutputName(ScreenPtr screen, Atom name)
+{
+    rrScrPrivPtr        pScrPriv = rrGetScrPriv(screen);
+    int                 o;
+    const char          *str = NameForAtom(name);
+    int                 len = strlen(str);
+
+    for (o = 0; o < pScrPriv->numOutputs; o++) {
+        RROutputPtr     output = pScrPriv->outputs[o];
+
+        if (output->nameLength == len && !memcmp(output->name, str, len))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+static int
+RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor)
+{
+    rrScrPrivPtr        pScrPriv = rrGetScrPriv(screen);
+    int                 m;
+    ScreenPtr           slave;
+    RRMonitorPtr        *monitors;
+
+    if (!pScrPriv)
+        return BadAlloc;
+
+    /* 	'name' must not match the name of any Output on the screen, or
+     *	a Value error results.
+     */
+
+    if (RRMonitorMatchesOutputName(screen, monitor->name)) {
+        client->errorValue = monitor->name;
+        return BadValue;
+    }
+
+    xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+        if (RRMonitorMatchesOutputName(slave, monitor->name)) {
+            client->errorValue = monitor->name;
+            return BadValue;
+        }
+    }
+
+    /* 'name' must not match the name of any Monitor on the screen, or
+     * a Value error results.
+     */
+
+    for (m = 0; m < pScrPriv->numMonitors; m++) {
+        if (pScrPriv->monitors[m]->name == monitor->name) {
+            client->errorValue = monitor->name;
+            return BadValue;
+        }
+    }
+
+    /* Allocate space for the new pointer. This is done before
+     * removing matching monitors as it may fail, and the request
+     * needs to not have any side-effects on failure
+     */
+    if (pScrPriv->numMonitors)
+        monitors = realloc(pScrPriv->monitors,
+                           (pScrPriv->numMonitors + 1) * sizeof (RRMonitorPtr));
+    else
+        monitors = malloc(sizeof (RRMonitorPtr));
+
+    if (!monitors)
+        return BadAlloc;
+
+    pScrPriv->monitors = monitors;
+
+    for (m = 0; m < pScrPriv->numMonitors; m++) {
+        RRMonitorPtr    existing = pScrPriv->monitors[m];
+        int             o, eo;
+
+	/* If 'name' matches an existing Monitor on the screen, the
+         * existing one will be deleted as if RRDeleteMonitor were called.
+         */
+        if (existing->name == monitor->name) {
+            (void) RRMonitorDelete(client, screen, existing->name);
+            continue;
+        }
+
+        /* For each output in 'info.outputs', each one is removed from all
+         * pre-existing Monitors. If removing the output causes the list
+         * of outputs for that Monitor to become empty, then that
+         * Monitor will be deleted as if RRDeleteMonitor were called.
+         */
+
+        for (eo = 0; eo < existing->numOutputs; eo++) {
+            for (o = 0; o < monitor->numOutputs; o++) {
+                if (monitor->outputs[o] == existing->outputs[eo]) {
+                    memmove(existing->outputs + eo, existing->outputs + eo + 1,
+                            (existing->numOutputs - (eo + 1)) * sizeof (RROutput));
+                    --existing->numOutputs;
+                    --eo;
+                    break;
+                }
+            }
+            if (existing->numOutputs == 0) {
+                (void) RRMonitorDelete(client, screen, existing->name);
+                break;
+            }
+        }
+        if (monitor->primary)
+            existing->primary = FALSE;
+    }
+
+    /* Add the new one to the list
+     */
+    pScrPriv->monitors[pScrPriv->numMonitors++] = monitor;
+
+    return Success;
+}
+
+void
+RRMonitorFreeList(RRMonitorPtr monitors, int nmon)
+{
+    int m;
+
+    for (m = 0; m < nmon; m++)
+        free(monitors[m].outputs);
+    free(monitors);
+}
+
+void
+RRMonitorInit(ScreenPtr screen)
+{
+    rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+
+    if (!pScrPriv)
+        return;
+
+    pScrPriv->numMonitors = 0;
+    pScrPriv->monitors = NULL;
+}
+
+void
+RRMonitorClose(ScreenPtr screen)
+{
+    rrScrPrivPtr        pScrPriv = rrGetScrPriv(screen);
+    int                 m;
+
+    if (!pScrPriv)
+        return;
+
+    for (m = 0; m < pScrPriv->numMonitors; m++)
+        RRMonitorFree(pScrPriv->monitors[m]);
+    free(pScrPriv->monitors);
+    pScrPriv->monitors = NULL;
+    pScrPriv->numMonitors = 0;
+}
+
+static CARD32
+RRMonitorTimestamp(ScreenPtr screen)
+{
+    rrScrPrivPtr        pScrPriv = rrGetScrPriv(screen);
+
+    /* XXX should take client monitor changes into account */
+    return pScrPriv->lastConfigTime.milliseconds;
+}
+
+int
+ProcRRGetMonitors(ClientPtr client)
+{
+    REQUEST(xRRGetMonitorsReq);
+    xRRGetMonitorsReply rep = {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence,
+        .length = 0,
+    };
+    WindowPtr           window;
+    ScreenPtr           screen;
+    int                 r;
+    RRMonitorPtr        monitors;
+    int                 nmonitors;
+    int                 noutputs;
+    int                 m;
+    Bool                get_active;
+    REQUEST_SIZE_MATCH(xRRGetMonitorsReq);
+    r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+    if (r != Success)
+        return r;
+    screen = window->drawable.pScreen;
+
+    get_active = stuff->get_active;
+    if (!RRMonitorMakeList(screen, get_active, &monitors, &nmonitors))
+        return BadAlloc;
+
+    rep.timestamp = RRMonitorTimestamp(screen);
+
+    noutputs = 0;
+    for (m = 0; m < nmonitors; m++) {
+        rep.length += SIZEOF(xRRMonitorInfo) >> 2;
+        rep.length += monitors[m].numOutputs;
+        noutputs += monitors[m].numOutputs;
+    }
+
+    rep.nmonitors = nmonitors;
+    rep.noutputs = noutputs;
+
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+        swapl(&rep.timestamp);
+        swapl(&rep.nmonitors);
+        swapl(&rep.noutputs);
+    }
+    WriteToClient(client, sizeof(xRRGetMonitorsReply), &rep);
+
+    client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
+
+    for (m = 0; m < nmonitors; m++) {
+        RRMonitorPtr    monitor = &monitors[m];
+        xRRMonitorInfo  info = {
+            .name = monitor->name,
+            .primary = monitor->primary,
+            .automatic = monitor->automatic,
+            .noutput = monitor->numOutputs,
+            .x = monitor->geometry.box.x1,
+            .y = monitor->geometry.box.y1,
+            .width = monitor->geometry.box.x2 - monitor->geometry.box.x1,
+            .height = monitor->geometry.box.y2 - monitor->geometry.box.y1,
+            .widthInMillimeters = monitor->geometry.mmWidth,
+            .heightInMillimeters = monitor->geometry.mmHeight,
+        };
+        if (client->swapped) {
+            swapl(&info.name);
+            swaps(&info.noutput);
+            swaps(&info.x);
+            swaps(&info.y);
+            swaps(&info.width);
+            swaps(&info.height);
+            swapl(&info.widthInMillimeters);
+            swapl(&info.heightInMillimeters);
+        }
+
+        WriteToClient(client, sizeof(xRRMonitorInfo), &info);
+        WriteSwappedDataToClient(client, monitor->numOutputs * sizeof (RROutput), monitor->outputs);
+    }
+
+    RRMonitorFreeList(monitors, nmonitors);
+
+    return Success;
+}
+
+int
+ProcRRSetMonitor(ClientPtr client)
+{
+    REQUEST(xRRSetMonitorReq);
+    WindowPtr           window;
+    ScreenPtr           screen;
+    RRMonitorPtr        monitor;
+    int                 r;
+
+    REQUEST_AT_LEAST_SIZE(xRRSetMonitorReq);
+
+    if (stuff->monitor.noutput != stuff->length - (SIZEOF(xRRSetMonitorReq) >> 2))
+        return BadLength;
+
+    r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+    if (r != Success)
+        return r;
+    screen = window->drawable.pScreen;
+
+    if (!ValidAtom(stuff->monitor.name))
+        return BadAtom;
+
+    /* Allocate the new monitor */
+    monitor = RRMonitorAlloc(stuff->monitor.noutput);
+    if (!monitor)
+        return BadAlloc;
+
+    /* Fill in the bits from the request */
+    monitor->pScreen = screen;
+    monitor->name = stuff->monitor.name;
+    monitor->primary = stuff->monitor.primary;
+    monitor->automatic = FALSE;
+    memcpy(monitor->outputs, stuff + 1, stuff->monitor.noutput * sizeof (RROutput));
+    monitor->geometry.box.x1 = stuff->monitor.x;
+    monitor->geometry.box.y1 = stuff->monitor.y;
+    monitor->geometry.box.x2 = stuff->monitor.x + stuff->monitor.width;
+    monitor->geometry.box.y2 = stuff->monitor.y + stuff->monitor.height;
+    monitor->geometry.mmWidth = stuff->monitor.widthInMillimeters;
+    monitor->geometry.mmHeight = stuff->monitor.heightInMillimeters;
+
+    r = RRMonitorAdd(client, screen, monitor);
+    if (r != Success)
+        RRMonitorFree(monitor);
+    return r;
+}
+
+int
+ProcRRDeleteMonitor(ClientPtr client)
+{
+    REQUEST(xRRDeleteMonitorReq);
+    WindowPtr           window;
+    ScreenPtr           screen;
+    int                 r;
+
+    REQUEST_SIZE_MATCH(xRRDeleteMonitorReq);
+    r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+    if (r != Success)
+        return r;
+    screen = window->drawable.pScreen;
+
+    if (!ValidAtom(stuff->name)) {
+        client->errorValue = stuff->name;
+        return BadAtom;
+    }
+
+    return RRMonitorDelete(client, screen, stuff->name);
+}
diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c
index 47558cf..cf2a3b0 100644
--- a/randr/rrsdispatch.c
+++ b/randr/rrsdispatch.c
@@ -565,6 +565,41 @@ static int SProcRRGetProviderProperty(ClientPtr client)
     return ProcRandrVector[stuff->randrReqType] (client);
 }
 
+static int SProcRRGetMonitors(ClientPtr client) {
+    REQUEST(xRRGetMonitorsReq);
+
+    REQUEST_SIZE_MATCH(xRRGetMonitorsReq);
+    swaps(&stuff->length);
+    swapl(&stuff->window);
+    return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int SProcRRSetMonitor(ClientPtr client) {
+    REQUEST(xRRSetMonitorReq);
+
+    REQUEST_AT_LEAST_SIZE(xRRGetMonitorsReq);
+    swaps(&stuff->length);
+    swapl(&stuff->window);
+    swapl(&stuff->monitor.name);
+    swaps(&stuff->monitor.noutput);
+    swaps(&stuff->monitor.x);
+    swaps(&stuff->monitor.y);
+    swaps(&stuff->monitor.width);
+    swaps(&stuff->monitor.height);
+    SwapRestL(stuff);
+    return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int SProcRRDeleteMonitor(ClientPtr client) {
+    REQUEST(xRRDeleteMonitorReq);
+
+    REQUEST_SIZE_MATCH(xRRDeleteMonitorReq);
+    swaps(&stuff->length);
+    swapl(&stuff->window);
+    swapl(&stuff->name);
+    return ProcRandrVector[stuff->randrReqType] (client);
+}
+
 int (*SProcRandrVector[RRNumberRequests]) (ClientPtr) = {
     SProcRRQueryVersion,        /* 0 */
 /* we skip 1 to make old clients fail pretty immediately */
@@ -614,4 +649,7 @@ int (*SProcRandrVector[RRNumberRequests]) (ClientPtr) = {
         SProcRRChangeProviderProperty,  /* 39 */
         SProcRRDeleteProviderProperty,  /* 40 */
         SProcRRGetProviderProperty,     /* 41 */
+        SProcRRGetMonitors,            /* 42 */
+        SProcRRSetMonitor,             /* 43 */
+        SProcRRDeleteMonitor,          /* 44 */
 };
commit 9c2b4f8e0e2b5d4b5e1102d6eea7bdb4211baa68
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Mar 31 11:18:44 2015 +1000

    xf86Crtc: add tile prop setting
    
    Add support for drivers to set the tiling
    property. This is used by clients to
    work out the monitor tiles for DisplayID
    monitors.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 9d592a7..a194724 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -3026,6 +3026,27 @@ xf86OutputSetEDIDProperty(xf86OutputPtr output, void *data, int data_len)
     }
 }
 
+#define TILE_ATOM_NAME		"TILE"
+/* changing this in the future could be tricky as people may hardcode 8 */
+#define TILE_PROP_NUM_ITEMS		8
+static void
+xf86OutputSetTileProperty(xf86OutputPtr output)
+{
+    Atom tile_atom = MakeAtom(TILE_ATOM_NAME, sizeof(TILE_ATOM_NAME) - 1, TRUE);
+
+    /* This may get called before the RandR resources have been created */
+    if (output->randr_output == NULL)
+        return;
+
+    if (output->tile_info.group_id != 0) {
+        RRChangeOutputProperty(output->randr_output, tile_atom, XA_INTEGER, 32,
+                               PropModeReplace, TILE_PROP_NUM_ITEMS, (uint32_t *)&output->tile_info, FALSE, TRUE);
+    }
+    else {
+        RRDeleteOutputProperty(output->randr_output, tile_atom);
+    }
+}
+
 #endif
 
 /* Pull out a phyiscal size from a detailed timing if available. */
@@ -3071,6 +3092,38 @@ handle_detailed_physical_size(struct detailed_monitor_section
     }
 }
 
+Bool
+xf86OutputParseKMSTile(const char *tile_data, int tile_length,
+                       struct xf86CrtcTileInfo *tile_info)
+{
+    int ret;
+
+    ret = sscanf(tile_data, "%d:%d:%d:%d:%d:%d:%d:%d",
+                 &tile_info->group_id,
+                 &tile_info->flags,
+                 &tile_info->num_h_tile,
+                 &tile_info->num_v_tile,
+                 &tile_info->tile_h_loc,
+                 &tile_info->tile_v_loc,
+                 &tile_info->tile_h_size,
+                 &tile_info->tile_v_size);
+    if (ret != 8)
+        return FALSE;
+    return TRUE;
+}
+
+void
+xf86OutputSetTile(xf86OutputPtr output, struct xf86CrtcTileInfo *tile_info)
+{
+    if (tile_info)
+        output->tile_info = *tile_info;
+    else
+        memset(&output->tile_info, 0, sizeof(output->tile_info));
+#ifdef RANDR_12_INTERFACE
+    xf86OutputSetTileProperty(output);
+#endif
+}
+
 /**
  * Set the EDID information for the specified output
  */
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 692bf40..3c5bbcf 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -70,6 +70,17 @@ typedef enum _xf86OutputStatus {
     XF86OutputStatusUnknown
 } xf86OutputStatus;
 
+struct xf86CrtcTileInfo {
+    uint32_t group_id;
+    uint32_t flags;
+    uint32_t num_h_tile;
+    uint32_t num_v_tile;
+    uint32_t tile_h_loc;
+    uint32_t tile_v_loc;
+    uint32_t tile_h_size;
+    uint32_t tile_v_size;
+};
+
 typedef struct _xf86CrtcFuncs {
    /**
     * Turns the crtc on/off, or sets intermediate power levels if available.
@@ -226,7 +237,7 @@ typedef struct _xf86CrtcFuncs {
 
 } xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
 
-#define XF86_CRTC_VERSION 5
+#define XF86_CRTC_VERSION 6
 
 struct _xf86Crtc {
     /**
@@ -500,7 +511,7 @@ typedef struct _xf86OutputFuncs {
      (*destroy) (xf86OutputPtr output);
 } xf86OutputFuncsRec, *xf86OutputFuncsPtr;
 
-#define XF86_OUTPUT_VERSION 2
+#define XF86_OUTPUT_VERSION 3
 
 struct _xf86Output {
     /**
@@ -615,6 +626,8 @@ struct _xf86Output {
     BoxRec initialTotalArea;
     BoxRec initialTrackingArea;
     INT16 initialBorder[4];
+
+    struct xf86CrtcTileInfo tile_info;
 };
 
 typedef struct _xf86ProviderFuncs {
@@ -881,6 +894,15 @@ extern _X_EXPORT void
  xf86OutputSetEDID(xf86OutputPtr output, xf86MonPtr edid_mon);
 
 /**
+ * Set the TILE information for the specified output
+ */
+extern _X_EXPORT void
+xf86OutputSetTile(xf86OutputPtr output, struct xf86CrtcTileInfo *tile_info);
+
+extern _X_EXPORT Bool
+xf86OutputParseKMSTile(const char *tile_data, int tile_length, struct xf86CrtcTileInfo *tile_info);
+
+/**
  * Return the list of modes supported by the EDID information
  * stored in 'output'
  */
commit 7088816fee0ca7d609c7bca41ef8c3fc938556f5
Merge: 95e83ff e977b40
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Mar 27 06:45:56 2015 -0700

    Merge remote-tracking branch 'anholt/glamor-next'

commit e977b404d7d1c6cd2be2168f4fdce0ae31cd1f9f
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Jan 17 07:44:27 2015 +1300

    glamor: * 1/size is faster than / size in VS
    
    Pass the inverse of the texture size to glamor vertex shaders so that
    we multiply by that instead of dividing by the size as multiplication
    is generally faster than division.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index e2d5204..75fe8a7 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -42,7 +42,7 @@ use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
     glBindTexture(GL_TEXTURE_2D, src->tex);
 
     glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
-    glUniform2f(prog->fill_size_uniform, src->width, src->height);
+    glUniform2f(prog->fill_size_inv_uniform, 1.0f/src->width, 1.0f/src->height);
 
     return TRUE;
 }
@@ -51,7 +51,7 @@ static const glamor_facet glamor_facet_copyarea = {
     "copy_area",
     .vs_vars = "attribute vec2 primitive;\n",
     .vs_exec = (GLAMOR_POS(gl_Position, primitive.xy)
-                "       fill_pos = (fill_offset + primitive.xy) / fill_size;\n"),
+                "       fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"),
     .fs_exec = "       gl_FragColor = texture2D(sampler, fill_pos);\n",
     .locations = glamor_program_location_fill,
     .use = use_copyarea,
@@ -71,7 +71,7 @@ use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
     glBindTexture(GL_TEXTURE_2D, src->tex);
 
     glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
-    glUniform2f(prog->fill_size_uniform, src->width, src->height);
+    glUniform2f(prog->fill_size_inv_uniform, 1.0f/src->width, 1.0f/src->height);
 
     glamor_set_color(dst, gc->fgPixel, prog->fg_uniform);
     glamor_set_color(dst, gc->bgPixel, prog->bg_uniform);
@@ -134,7 +134,7 @@ static const glamor_facet glamor_facet_copyplane = {
     .version = 130,
     .vs_vars = "attribute vec2 primitive;\n",
     .vs_exec = (GLAMOR_POS(gl_Position, (primitive.xy))
-                "       fill_pos = (fill_offset + primitive.xy) / fill_size;\n"),
+                "       fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"),
     .fs_exec = ("       uvec4 bits = uvec4(round(texture2D(sampler, fill_pos) * bitmul));\n"
                 "       if ((bits & bitplane) != uvec4(0,0,0,0))\n"
                 "               gl_FragColor = fg;\n"
diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index 3207aaf..8aab53f 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -40,12 +40,12 @@ const glamor_facet glamor_fill_solid = {
 static Bool
 use_tile(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
 {
-    return glamor_set_tiled(pixmap, gc, prog->fill_offset_uniform, prog->fill_size_uniform);
+    return glamor_set_tiled(pixmap, gc, prog->fill_offset_uniform, prog->fill_size_inv_uniform);
 }
 
 static const glamor_facet glamor_fill_tile = {
     .name = "tile",
-    .vs_exec =  "       fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+    .vs_exec =  "       fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
     .fs_exec =  "       gl_FragColor = texture2D(sampler, fill_pos);\n",
     .locations = glamor_program_location_fill,
     .use = use_tile,
@@ -56,12 +56,12 @@ use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
 {
     return glamor_set_stippled(pixmap, gc, prog->fg_uniform,
                                prog->fill_offset_uniform,
-                               prog->fill_size_uniform);
+                               prog->fill_size_inv_uniform);
 }
 
 static const glamor_facet glamor_fill_stipple = {
     .name = "stipple",
-    .vs_exec =  "       fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+    .vs_exec =  "       fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
     .fs_exec = ("       float a = texture2D(sampler, fill_pos).w;\n"
                 "       if (a == 0.0)\n"
                 "               discard;\n"
@@ -81,7 +81,7 @@ use_opaque_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
 
 static const glamor_facet glamor_fill_opaque_stipple = {
     .name = "opaque_stipple",
-    .vs_exec =  "       fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+    .vs_exec =  "       fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
     .fs_exec = ("       float a = texture2D(sampler, fill_pos).w;\n"
                 "       if (a == 0.0)\n"
                 "               gl_FragColor = bg;\n"
@@ -116,10 +116,10 @@ static glamor_location_var location_vars[] = {
     {
         .location = glamor_program_location_fill,
         .vs_vars = ("uniform vec2 fill_offset;\n"
-                    "uniform vec2 fill_size;\n"
+                    "uniform vec2 fill_size_inv;\n"
                     "varying vec2 fill_pos;\n"),
         .fs_vars = ("uniform sampler2D sampler;\n"
-                    "uniform vec2 fill_size;\n"
+                    "uniform vec2 fill_size_inv;\n"
                     "varying vec2 fill_pos;\n")
     },
     {
@@ -336,7 +336,7 @@ glamor_build_program(ScreenPtr          screen,
     prog->fg_uniform = glamor_get_uniform(prog, glamor_program_location_fg, "fg");
     prog->bg_uniform = glamor_get_uniform(prog, glamor_program_location_bg, "bg");
     prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_offset");
-    prog->fill_size_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size");
+    prog->fill_size_inv_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size_inv");
     prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font");
     prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane");
     prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul");
diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h
index 56ba03a..fa3877c 100644
--- a/glamor/glamor_program.h
+++ b/glamor/glamor_program.h
@@ -60,7 +60,7 @@ struct _glamor_program {
     GLint                       matrix_uniform;
     GLint                       fg_uniform;
     GLint                       bg_uniform;
-    GLint                       fill_size_uniform;
+    GLint                       fill_size_inv_uniform;
     GLint                       fill_offset_uniform;
     GLint                       font_uniform;
     GLint                       bitplane_uniform;
diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index df45b6f..6d29e9e 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -160,7 +160,7 @@ glamor_set_texture(PixmapPtr    pixmap,
                    int          off_x,
                    int          off_y,
                    GLint        offset_uniform,
-                   GLint        size_uniform)
+                   GLint        size_inv_uniform)
 {
     glamor_pixmap_private *texture_priv;
 
@@ -176,7 +176,7 @@ glamor_set_texture(PixmapPtr    pixmap,
     glBindTexture(GL_TEXTURE_2D, texture_priv->fbo->tex);
 
     glUniform2f(offset_uniform, off_x, off_y);
-    glUniform2f(size_uniform, texture->drawable.width, texture->drawable.height);
+    glUniform2f(size_inv_uniform, 1.0f/texture->drawable.width, 1.0f/texture->drawable.height);
     return TRUE;
 }
 
@@ -184,7 +184,7 @@ Bool
 glamor_set_tiled(PixmapPtr      pixmap,
                  GCPtr          gc,
                  GLint          offset_uniform,
-                 GLint          size_uniform)
+                 GLint          size_inv_uniform)
 {
     if (!glamor_set_alu(pixmap->drawable.pScreen, gc->alu))
         return FALSE;
@@ -197,7 +197,7 @@ glamor_set_tiled(PixmapPtr      pixmap,
                               -gc->patOrg.x,
                               -gc->patOrg.y,
                               offset_uniform,
-                              size_uniform);
+                              size_inv_uniform);
 }
 
 static PixmapPtr
commit 82634d2b69950e7e9a066c8c96bf2624ac26193a
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Feb 9 13:45:44 2015 +0000

    ephyr: Avoid a segfault with 'DISPLAY= Xephyr -glamor'
    
    ephyr_glamor_connect() returns NULL if we failed, but applying
    xcb_connection_has_error() to NULL is not permitted.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Daniel Martin <consume.noise at gmail.com>

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 506a852..c67ff60 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -443,7 +443,7 @@ hostx_init(void)
     else
 #endif
         HostX.conn = xcb_connect(NULL, &HostX.screen);
-    if (xcb_connection_has_error(HostX.conn)) {
+    if (!HostX.conn || xcb_connection_has_error(HostX.conn)) {
         fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n");
         exit(1);
     }
commit 391bcf77db96ff227e504c213aa5d5db09b6a050
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Feb 23 11:58:59 2015 -0500

    glamor: Fix up indentation
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index 9c7878f..391f376 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -923,10 +923,10 @@ glamor_get_transform_block_size(struct pixman_transform *transform,
     return TRUE;
 }
 
-#define VECTOR_FROM_POINT(p, x, y)	\
+#define VECTOR_FROM_POINT(p, x, y) do {\
 	p.v[0] = x;  \
 	p.v[1] = y;  \
-	p.v[2] = 1.0;
+	p.v[2] = 1.0; } while (0)
 void
 glamor_get_transform_extent_from_box(struct pixman_box32 *box,
                                      struct pixman_transform *transform)
@@ -936,12 +936,12 @@ glamor_get_transform_extent_from_box(struct pixman_box32 *box,
 
     struct pixman_f_transform ftransform;
 
-    VECTOR_FROM_POINT(p0, box->x1, box->y1)
-        VECTOR_FROM_POINT(p1, box->x2, box->y1)
-        VECTOR_FROM_POINT(p2, box->x2, box->y2)
-        VECTOR_FROM_POINT(p3, box->x1, box->y2)
+    VECTOR_FROM_POINT(p0, box->x1, box->y1);
+    VECTOR_FROM_POINT(p1, box->x2, box->y1);
+    VECTOR_FROM_POINT(p2, box->x2, box->y2);
+    VECTOR_FROM_POINT(p3, box->x1, box->y2);
 
-        pixman_f_transform_from_pixman_transform(&ftransform, transform);
+    pixman_f_transform_from_pixman_transform(&ftransform, transform);
     pixman_f_transform_point(&ftransform, &p0);
     pixman_f_transform_point(&ftransform, &p1);
     pixman_f_transform_point(&ftransform, &p2);
commit 0669babf2b5b50cbc185b0f714671b2c2b368778
Author: Matt Turner <mattst88 at gmail.com>
Date:   Wed Mar 4 13:42:48 2015 -0800

    glamor: Perform texture2D() separately from swizzle.
    
    The texture2D() happens in each branch, so we may as well do it as early
    as possible and hide some of its latency in the branching instructions.
    Moving it outside the (uniform) control flow reduces the number of
    instructions in the fs_source shader from 64 to 46 and in the
    set_alpha_source shader from 69 to 47 on Haswell.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index cbbe759..5517454 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -173,46 +173,48 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     const char *fs_source =
         "void main()\n"
         "{\n"
+        "   vec4 color = texture2D(sampler, source_texture);\n"
         "   if (revert == REVERT_NONE) \n"
         "    { \n"
         "     if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING))   \n"
-        "	  	gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
+        "		gl_FragColor = color.bgra;\n"
         "     else \n"
-        "	  	gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
+        "		gl_FragColor = color.rgba;\n"
         "    } \n"
         "   else \n"
         "    { \n"
         "     if (swap_rb == SWAP_DOWNLOADING)   \n"
-        "	  	gl_FragColor = texture2D(sampler, source_texture).argb;\n"
+        "		gl_FragColor = color.argb;\n"
         "     else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
-        "	  	gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+        "		gl_FragColor = color.abgr;\n"
         "     else if (swap_rb == SWAP_UPLOADING)\n"
-        "	  	gl_FragColor = texture2D(sampler, source_texture).gbar;\n"
+        "		gl_FragColor = color.gbar;\n"
         "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
-        "	  	gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+        "		gl_FragColor = color.abgr;\n"
         "    } \n"
         "}\n";
 
     const char *set_alpha_source =
         "void main()\n"
         "{\n"
+        "   vec4 color = texture2D(sampler, source_texture);\n"
         "   if (revert == REVERT_NONE) \n"
         "    { \n"
         "     if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING))   \n"
-        "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
+        "		gl_FragColor = vec4(color.bgr, 1);\n"
         "     else \n"
-        "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
+        "		gl_FragColor = vec4(color.rgb, 1);\n"
         "    } \n"
         "   else \n"
         "    { \n"
         "     if (swap_rb == SWAP_DOWNLOADING)   \n"
-        "	  	gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n"
+        "		gl_FragColor = vec4(1, color.rgb);\n"
         "     else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
-        "	  	gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
+        "		gl_FragColor = vec4(1, color.bgr);\n"
         "     else if (swap_rb == SWAP_UPLOADING)\n"
-        "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).gba, 1);\n"
+        "		gl_FragColor = vec4(color.gba, 1);\n"
         "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
-        "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).abg, 1);\n"
+        "		gl_FragColor = vec4(color.abg, 1);\n"
         "    } \n"
         "}\n";
     GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
commit 9e9fcf578063b4155aab4adab83f8d956bde5d1a
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Feb 4 14:38:15 2015 -0800

    glamor: Add a helper function for the common GL_QUADS fallback pattern.
    
    We should do better than this with an index buffer, but for now at
    least make it so that we don't have to copy the same code to new
    places.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index 2ea270c..e2d5204 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -387,13 +387,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
                       src_box->x2 - src_box->x1,
                       src_box->y2 - src_box->y1);
 
-            if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-                glDrawArrays(GL_QUADS, 0, nbox * 4);
-            else {
-                int i;
-                for (i = 0; i < nbox; i++)
-                    glDrawArrays(GL_TRIANGLE_FAN, i*4, 4);
-            }
+            glamor_glDrawArrays_GL_QUADS(glamor_priv, nbox);
         }
     }
     glDisable(GL_SCISSOR_TEST);
diff --git a/glamor/glamor_rects.c b/glamor/glamor_rects.c
index c8c92be..c378e4a 100644
--- a/glamor/glamor_rects.c
+++ b/glamor/glamor_rects.c
@@ -126,14 +126,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
             if (glamor_priv->glsl_version >= 130)
                 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nrect);
             else {
-                if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-                    glDrawArrays(GL_QUADS, 0, nrect * 4);
-                } else {
-                    int i;
-                    for (i = 0; i < nrect; i++) {
-                        glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
-                    }
-                }
+                glamor_glDrawArrays_GL_QUADS(glamor_priv, nrect);
             }
         }
     }
diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
index 7138db5..b358c60 100644
--- a/glamor/glamor_spans.c
+++ b/glamor/glamor_spans.c
@@ -134,14 +134,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
             if (glamor_priv->glsl_version >= 130)
                 glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, n);
             else {
-                if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-                    glDrawArrays(GL_QUADS, 0, 4 * n);
-                } else {
-                    int i;
-                    for (i = 0; i < n; i++) {
-                        glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
-                    }
-                }
+                glamor_glDrawArrays_GL_QUADS(glamor_priv, nbox);
             }
         }
     }
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 6a3bd29..0927ffb 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1393,4 +1393,21 @@ glamor_make_current(glamor_screen_private *glamor_priv)
     }
 }
 
+/**
+ * Helper function for implementing draws with GL_QUADS on GLES2,
+ * where we don't have them.
+ */
+static inline void
+glamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count)
+{
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+        glDrawArrays(GL_QUADS, 0, count * 4);
+    } else {
+        unsigned i;
+        for (i = 0; i < count; i++)
+            glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
+    }
+}
+
+
 #endif
commit 909a406aa239b8d231d6f63ce05a3e4a2bc3cb07
Author: Eric Anholt <eric at anholt.net>
Date:   Sun Dec 28 19:39:45 2014 -1000

    glamor: Don't optimize out scissor updates in CopyArea.
    
    This possibly is a minor hit for immediate mode renderers (no
    difference on copypixin100 on my hsw, n=12), but it gives important
    information about drawing bounds to a deferred renderer (3.1x
    improvement in copypixwin100 on vc4).
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index 1660ffd..2ea270c 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -315,7 +315,6 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
     struct copy_args args;
     glamor_program *prog;
     const glamor_facet *copy_facet;
-    Bool set_scissor;
     int n;
 
     glamor_make_current(glamor_priv);
@@ -367,9 +366,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
 
     glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y);
 
-    set_scissor = glamor_pixmap_priv_is_large(src_priv);
-    if (set_scissor)
-        glEnable(GL_SCISSOR_TEST);
+    glEnable(GL_SCISSOR_TEST);
 
     glamor_pixmap_loop(src_priv, src_box_x, src_box_y) {
         BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_x, src_box_y);
@@ -385,11 +382,10 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
             glamor_set_destination_drawable(dst, dst_box_x, dst_box_y, FALSE, FALSE,
                                             prog->matrix_uniform, &dst_off_x, &dst_off_y);
 
-            if (set_scissor)
-                glScissor(dst_off_x - args.dx,
-                          dst_off_y - args.dy,
-                          src_box->x2 - src_box->x1,
-                          src_box->y2 - src_box->y1);
+            glScissor(dst_off_x - args.dx,
+                      dst_off_y - args.dy,
+                      src_box->x2 - src_box->x1,
+                      src_box->y2 - src_box->y1);
 
             if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
                 glDrawArrays(GL_QUADS, 0, nbox * 4);
@@ -400,8 +396,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
             }
         }
     }
-    if (set_scissor)
-        glDisable(GL_SCISSOR_TEST);
+    glDisable(GL_SCISSOR_TEST);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     return TRUE;
commit 6ba6cc57e17aefb7db0201a1f3180ab55076eb48
Author: Eric Anholt <eric at anholt.net>
Date:   Sat Dec 27 09:00:58 2014 -1000

    glamor: Just set the logic op to what we want at the start of all rendering.
    
    By dropping the unconditional logic op disable at the end of
    rendering, this fixes GL errors being thrown in GLES2 contexts (which
    don't have logic ops).  On desktop, this also means a little less
    overhead per draw call from taking one less trip through the
    glEnable/glDisable switch statement of doom in Mesa.
    
    The exchange here is that we end up taking a trip through it in the
    XV, Render, and gradient-generation paths.  If the glEnable() is
    actually costly, we should probably cache our logic op state in our
    screen, since there's no way the GL could make that switch statement
    as cheap as the caller caching it would be.
    
    v2: Don't forget to set the logic op in Xephyr's drawing.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index 609fcb3..1660ffd 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -404,11 +404,9 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
         glDisable(GL_SCISSOR_TEST);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
-    glDisable(GL_COLOR_LOGIC_OP);
     return TRUE;
 
 bail_ctx:
-    glDisable(GL_COLOR_LOGIC_OP);
     return FALSE;
 }
 
@@ -452,7 +450,6 @@ glamor_copy_fbo_fbo_temp(DrawablePtr src,
 
     if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy))
         goto bail_ctx;
-    glDisable(GL_COLOR_LOGIC_OP);
 
     /* Find the size of the area to copy
      */
@@ -521,7 +518,6 @@ bail:
     return FALSE;
 
 bail_ctx:
-    glDisable(GL_COLOR_LOGIC_OP);
     return FALSE;
 }
 
diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c
index 49ad3b6..4281ff0 100644
--- a/glamor/glamor_dash.c
+++ b/glamor/glamor_dash.c
@@ -159,11 +159,11 @@ glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
                                        &glamor_priv->on_off_dash_line_progs,
                                        &glamor_facet_on_off_dash_lines);
         if (!prog)
-            goto bail_ctx;
+            goto bail;
         break;
     case LineDoubleDash:
         if (gc->fillStyle != FillSolid)
-            goto bail_ctx;
+            goto bail;
 
         prog = &glamor_priv->double_dash_line_prog;
 
@@ -171,18 +171,18 @@ glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
             if (!glamor_build_program(screen, prog,
                                       &glamor_facet_double_dash_lines,
                                       NULL))
-                goto bail_ctx;
+                goto bail;
         }
 
         if (!glamor_use_program(pixmap, gc, prog, NULL))
-            goto bail_ctx;
+            goto bail;
 
         glamor_set_color(pixmap, gc->fgPixel, prog->fg_uniform);
         glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform);
         break;
 
     default:
-        goto bail_ctx;
+        goto bail;
     }
 
 
@@ -195,8 +195,6 @@ glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
 
     return prog;
 
-bail_ctx:
-    glDisable(GL_COLOR_LOGIC_OP);
 bail:
     return NULL;
 }
@@ -230,7 +228,6 @@ glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog,
     }
 
     glDisable(GL_SCISSOR_TEST);
-    glDisable(GL_COLOR_LOGIC_OP);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 }
 
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 8c73f48..1791f6d 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -60,7 +60,7 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
                                    &glamor_priv->poly_glyph_blt_progs,
                                    &glamor_facet_poly_glyph_blt);
     if (!prog)
-        goto bail_ctx;
+        goto bail;
 
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
@@ -138,12 +138,9 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
         }
     }
 
-    glDisable(GL_COLOR_LOGIC_OP);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     return TRUE;
-bail_ctx:
-    glDisable(GL_COLOR_LOGIC_OP);
 bail:
     return FALSE;
 }
@@ -191,7 +188,7 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
                                    &glamor_priv->poly_glyph_blt_progs,
                                    &glamor_facet_poly_glyph_blt);
     if (!prog)
-        goto bail_ctx;
+        goto bail;
 
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
@@ -230,12 +227,9 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
         glDrawArrays(GL_POINTS, 0, num_points);
     }
 
-    glDisable(GL_COLOR_LOGIC_OP);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     return TRUE;
 
-bail_ctx:
-    glDisable(GL_COLOR_LOGIC_OP);
 bail:
     return FALSE;
 }
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 232b402..8ea645e 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -993,6 +993,8 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
          vertices, tex_vertices, 0))
         goto GRADIENT_FAIL;
 
+    glamor_set_alu(screen, GXcopy);
+
     /* Set all the stops and colors to shader. */
     if (stops_count > RADIAL_SMALL_STOPS) {
         stop_colors = malloc(4 * stops_count * sizeof(float));
@@ -1309,6 +1311,8 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
          vertices, tex_vertices, 1))
         goto GRADIENT_FAIL;
 
+    glamor_set_alu(screen, GXcopy);
+
     /* Normalize the PTs. */
     glamor_set_normalize_pt(xscale, yscale,
                             pixman_fixed_to_double(src_picture->pSourcePict->
diff --git a/glamor/glamor_lines.c b/glamor/glamor_lines.c
index 6c8bb88..2dd9c07 100644
--- a/glamor/glamor_lines.c
+++ b/glamor/glamor_lines.c
@@ -65,7 +65,7 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
                                    &glamor_facet_poly_lines);
 
     if (!prog)
-        goto bail_ctx;
+        goto bail;
 
     /* Set up the vertex buffers for the points */
 
@@ -117,12 +117,9 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
     }
 
     glDisable(GL_SCISSOR_TEST);
-    glDisable(GL_COLOR_LOGIC_OP);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     return TRUE;
-bail_ctx:
-    glDisable(GL_COLOR_LOGIC_OP);
 bail:
     return FALSE;
 }
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 0224b34..89b4c36 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -748,6 +748,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
                                       int swap_rb, int x, int y, int w, int h,
                                       int stride, void *bits, int pbo)
 {
+    ScreenPtr screen = pixmap->drawable.pScreen;
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(pixmap->drawable.pScreen);
@@ -833,6 +834,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
         glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
         glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
+        glamor_set_alu(screen, GXcopy);
         __glamor_upload_pixmap_to_texture(pixmap, &tex,
                                           format, type, 0, 0, w, h, bits, pbo);
         glActiveTexture(GL_TEXTURE0);
@@ -1131,6 +1133,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
     glamor_set_destination_pixmap_fbo(glamor_priv, temp_fbo, 0, 0, w, h);
+    glamor_set_alu(screen, GXcopy);
     glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
     glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
     glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c
index 01a1c7e..df7e5a2 100644
--- a/glamor/glamor_points.c
+++ b/glamor/glamor_points.c
@@ -55,17 +55,17 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
     glamor_make_current(glamor_priv);
 
     if (prog->failed)
-        goto bail_ctx;
+        goto bail;
 
     if (!prog->prog) {
         if (!glamor_build_program(screen, prog,
                                   &glamor_facet_point,
                                   &glamor_fill_solid))
-            goto bail_ctx;
+            goto bail;
     }
 
     if (!glamor_use_program(pixmap, gc, prog, NULL))
-        goto bail_ctx;
+        goto bail;
 
     vbo_ppt = glamor_get_vbo_space(screen, npt * (2 * sizeof (INT16)), &vbo_offset);
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -102,13 +102,10 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
     }
 
     glDisable(GL_SCISSOR_TEST);
-    glDisable(GL_COLOR_LOGIC_OP);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     return TRUE;
 
-bail_ctx:
-    glDisable(GL_COLOR_LOGIC_OP);
 bail:
     return FALSE;
 }
diff --git a/glamor/glamor_rects.c b/glamor/glamor_rects.c
index 7161921..c8c92be 100644
--- a/glamor/glamor_rects.c
+++ b/glamor/glamor_rects.c
@@ -65,7 +65,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
                                        &glamor_facet_polyfillrect_130);
 
         if (!prog)
-            goto bail_ctx;
+            goto bail;
 
         /* Set up the vertex buffers for the points */
 
@@ -87,7 +87,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
                                        &glamor_facet_polyfillrect_120);
 
         if (!prog)
-            goto bail_ctx;
+            goto bail;
 
         /* Set up the vertex buffers for the points */
 
@@ -139,14 +139,11 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
     }
 
     glDisable(GL_SCISSOR_TEST);
-    glDisable(GL_COLOR_LOGIC_OP);
     if (glamor_priv->glsl_version >= 130)
         glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     return TRUE;
-bail_ctx:
-    glDisable(GL_COLOR_LOGIC_OP);
 bail:
     return FALSE;
 }
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 6669f48..27c09fd 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1172,6 +1172,7 @@ glamor_composite_with_shader(CARD8 op,
 
     glamor_set_destination_pixmap_priv_nc(glamor_priv, dest_pixmap, dest_pixmap_priv);
     glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv, &key, shader, &op_info);
+    glamor_set_alu(screen, GXcopy);
 
     glamor_make_current(glamor_priv);
 
diff --git a/glamor/glamor_segs.c b/glamor/glamor_segs.c
index 6d469ce..e167325 100644
--- a/glamor/glamor_segs.c
+++ b/glamor/glamor_segs.c
@@ -109,12 +109,10 @@ glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc,
     }
 
     glDisable(GL_SCISSOR_TEST);
-    glDisable(GL_COLOR_LOGIC_OP);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     return TRUE;
 bail_ctx:
-    glDisable(GL_COLOR_LOGIC_OP);
 bail:
     return FALSE;
 }
diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
index fe8c7dc..7138db5 100644
--- a/glamor/glamor_spans.c
+++ b/glamor/glamor_spans.c
@@ -68,7 +68,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
                                        &glamor_facet_fillspans_130);
 
         if (!prog)
-            goto bail_ctx;
+            goto bail;
 
         /* Set up the vertex buffers for the points */
 
@@ -93,7 +93,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
                                        &glamor_facet_fillspans_120);
 
         if (!prog)
-            goto bail_ctx;
+            goto bail;
 
         /* Set up the vertex buffers for the points */
 
@@ -147,14 +147,11 @@ glamor_fill_spans_gl(DrawablePtr drawable,
     }
 
     glDisable(GL_SCISSOR_TEST);
-    glDisable(GL_COLOR_LOGIC_OP);
     if (glamor_priv->glsl_version >= 130)
         glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     return TRUE;
-bail_ctx:
-    glDisable(GL_COLOR_LOGIC_OP);
 bail:
     return FALSE;
 }
diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
index 68593a4..c7c1ab7 100644
--- a/glamor/glamor_text.c
+++ b/glamor/glamor_text.c
@@ -210,7 +210,6 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glDisable(GL_COLOR_LOGIC_OP);
 
     return x;
 }
@@ -286,18 +285,14 @@ glamor_poly_text(DrawablePtr drawable, GCPtr gc,
     prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_text_progs, &glamor_facet_poly_text);
 
     if (!prog)
-        goto bail_ctx;
+        goto bail;
 
     x = glamor_text(drawable, gc, glamor_font, prog,
                     x, y, count, chars, charinfo, sixteen);
 
-    glDisable(GL_COLOR_LOGIC_OP);
-
     *final_pos = x;
     return TRUE;
 
-bail_ctx:
-    glDisable(GL_COLOR_LOGIC_OP);
 bail:
     return FALSE;
 }
@@ -468,7 +463,6 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
     return TRUE;
 
 bail:
-    glDisable(GL_COLOR_LOGIC_OP);
     return FALSE;
 }
 
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 2d5b8e1..364104d 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -286,6 +286,7 @@ glamor_xv_render(glamor_port_private *port_priv)
     glamor_get_drawable_deltas(port_priv->pDraw, port_priv->pPixmap, &dst_x_off,
                                &dst_y_off);
     glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
+    glamor_set_alu(screen, GXcopy);
 
     for (i = 0; i < 3; i++) {
         if (port_priv->src_pix[i]) {
diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c
index 8fe7516..582e3af 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -214,6 +214,8 @@ ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
     glUseProgram(glamor->texture_shader);
     glViewport(0, 0, glamor->width, glamor->height);
+    if (!ephyr_glamor_gles2)
+        glDisable(GL_COLOR_LOGIC_OP);
 
     glVertexAttribPointer(glamor->texture_shader_position_loc,
                           2, GL_FLOAT, FALSE, 0, position);
commit 8102927282d5134493e5009a876a6b01a68d1f97
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Feb 5 12:52:02 2015 +0000

    glamor: Fix build when configured --enable-glamor --disable-xshmfence
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_sync.c b/glamor/glamor_sync.c
index 5e158c3..fbc47d4 100644
--- a/glamor/glamor_sync.c
+++ b/glamor/glamor_sync.c
@@ -94,8 +94,10 @@ glamor_sync_init(ScreenPtr screen)
 			return FALSE;
 	}
 
+#ifdef HAVE_XSHMFENCE
 	if (!miSyncShmScreenInit(screen))
 		return FALSE;
+#endif
 
 	screen_funcs = miSyncGetScreenFuncs(screen);
 	glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
commit 4218a1e066cf39bb980ebbc9f69536c85232da5c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Feb 5 11:59:22 2015 +0100

    glamor: check max native ALU instructions
    
    When using glamor (either in Xephyr or Xwayland) on hardware with too
    low instructions limit, glamor fallbacks to sw due to large shaders.
    
    This makes glamor unbearably slow on such hardware.
    
    Check reported value for GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
    and fail in glamor_init() if the limit is lower than 128.
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=88316
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index a6d97ea..6f4f309 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -301,6 +301,35 @@ glamor_create_screen_resources(ScreenPtr screen)
     return ret;
 }
 
+static Bool
+glamor_check_instruction_count(int gl_version)
+{
+    GLint max_native_alu_instructions;
+
+    /* Avoid using glamor if the reported instructions limit is too low,
+     * as this would cause glamor to fallback on sw due to large shaders
+     * which ends up being unbearably slow.
+     */
+    if (gl_version < 30) {
+        if (!epoxy_has_gl_extension("GL_ARB_fragment_program")) {
+            ErrorF("GL_ARB_fragment_program required\n");
+            return FALSE;
+        }
+
+        glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB,
+                          GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB,
+                          &max_native_alu_instructions);
+        if (max_native_alu_instructions < GLAMOR_MIN_ALU_INSTRUCTIONS) {
+            LogMessage(X_WARNING,
+                       "glamor requires at least %d instructions (%d reported)\n",
+                       GLAMOR_MIN_ALU_INSTRUCTIONS, max_native_alu_instructions);
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
 /** Set up glamor for an already-configured GL context. */
 Bool
 glamor_init(ScreenPtr screen, unsigned int flags)
@@ -378,6 +407,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
             ErrorF("Require OpenGL version 2.1 or later.\n");
             goto fail;
         }
+
+        if (!glamor_check_instruction_count(gl_version))
+            goto fail;
     } else {
         if (gl_version < 20) {
             ErrorF("Require Open GLES2.0 or later.\n");
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index cd91924..898a934 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -1082,4 +1082,6 @@ void glamor_xv_render(glamor_port_private *port_priv);
 
 #include "glamor_font.h"
 
+#define GLAMOR_MIN_ALU_INSTRUCTIONS 128 /* Minimum required number of native ALU instructions */
+
 #endif                          /* GLAMOR_PRIV_H */
commit e0788a03144186522fd0ef0e9c954e2744b40275
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 23:47:23 2014 -0700

    glamor: Eliminate GLAMOR_TEXTURE_LARGE pixmap type
    
    Initialize full pixmap private for all pixmaps, including block
    dimensions and counts so that no checks are needed when walking the
    fbos.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index f9ea8e0..a6d97ea 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -60,6 +60,21 @@ glamor_get_drawable_pixmap(DrawablePtr drawable)
         return (PixmapPtr) drawable;
 }
 
+static void
+glamor_init_pixmap_private_small(PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv)
+{
+    pixmap_priv->box.x1 = 0;
+    pixmap_priv->box.x2 = pixmap->drawable.width;
+    pixmap_priv->box.y1 = 0;
+    pixmap_priv->box.y2 = pixmap->drawable.height;
+    pixmap_priv->block_w = pixmap->drawable.width;
+    pixmap_priv->block_h = pixmap->drawable.height;
+    pixmap_priv->block_hcnt = 1;
+    pixmap_priv->block_wcnt = 1;
+    pixmap_priv->box_array = &pixmap_priv->box;
+    pixmap_priv->fbo_array = &pixmap_priv->fbo;
+}
+
 _X_EXPORT void
 glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
 {
@@ -72,10 +87,7 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
         glamor_set_pixmap_private(pixmap, pixmap_priv);
     }
     pixmap_priv->type = type;
-    pixmap_priv->box.x1 = 0;
-    pixmap_priv->box.x2 = pixmap->drawable.width;
-    pixmap_priv->box.y1 = 0;
-    pixmap_priv->box.y2 = pixmap->drawable.height;
+    glamor_init_pixmap_private_small(pixmap, pixmap_priv);
 }
 
 _X_EXPORT void
@@ -138,7 +150,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
                      unsigned int usage)
 {
     PixmapPtr pixmap;
-    glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
     glamor_pixmap_private *pixmap_priv;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     glamor_pixmap_fbo *fbo = NULL;
@@ -171,27 +182,21 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
     screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
 
+    pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
+
     if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) {
-        pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
-        pixmap_priv->box.x1 = 0;
-        pixmap_priv->box.y1 = 0;
-        pixmap_priv->box.x2 = w;
-        pixmap_priv->box.y2 = h;
+        glamor_init_pixmap_private_small(pixmap, pixmap_priv);
         return pixmap;
     }
     else if (usage == GLAMOR_CREATE_NO_LARGE ||
         glamor_check_fbo_size(glamor_priv, w, h))
     {
-        pixmap_priv->type = type;
-        pixmap_priv->box.x1 = 0;
-        pixmap_priv->box.y1 = 0;
-        pixmap_priv->box.x2 = w;
-        pixmap_priv->box.y2 = h;
+        glamor_init_pixmap_private_small(pixmap, pixmap_priv);
         fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
     } else {
         int tile_size = glamor_priv->max_fbo_size;
-        DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n", pixmap, w, h, tile_size);
-        pixmap_priv->type = GLAMOR_TEXTURE_LARGE;
+        DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n",
+               pixmap, w, h, tile_size);
         fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
                                       tile_size, tile_size, pixmap_priv);
     }
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 1e51d74..d07182d 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -56,7 +56,6 @@ typedef enum glamor_pixmap_type {
     GLAMOR_TEXTURE_DRM,
     GLAMOR_DRM_ONLY,
     GLAMOR_TEXTURE_ONLY,
-    GLAMOR_TEXTURE_LARGE
 } glamor_pixmap_type_t;
 
 #define GLAMOR_EGL_EXTERNAL_BUFFER 3
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 6789b4b..ea0e801 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -473,7 +473,6 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
     pixmap_priv->fbo = fbo;
 
     switch (pixmap_priv->type) {
-    case GLAMOR_TEXTURE_LARGE:
     case GLAMOR_TEXTURE_ONLY:
     case GLAMOR_TEXTURE_DRM:
         pixmap_priv->gl_fbo = GLAMOR_FBO_NORMAL;
@@ -484,7 +483,6 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
             pixmap_priv->gl_tex = 0;
         }
         pixmap->devPrivate.ptr = NULL;
-        break;
     default:
         break;
     }
@@ -498,11 +496,10 @@ glamor_pixmap_destroy_fbo(glamor_screen_private *glamor_priv,
 
     if (glamor_pixmap_priv_is_large(priv)) {
         int i;
-        glamor_pixmap_private *large = priv;
 
-        for (i = 0; i < large->block_wcnt * large->block_hcnt; i++)
-            glamor_destroy_fbo(glamor_priv, large->fbo_array[i]);
-        free(large->fbo_array);
+        for (i = 0; i < priv->block_wcnt * priv->block_hcnt; i++)
+            glamor_destroy_fbo(glamor_priv, priv->fbo_array[i]);
+        free(priv->fbo_array);
     }
     else {
         fbo = glamor_pixmap_detach_fbo(priv);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 33b2c5f..cd91924 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -466,7 +466,6 @@ typedef struct glamor_pixmap_private {
     int block_h;
     int block_wcnt;
     int block_hcnt;
-    int nbox;
     BoxPtr box_array;
     glamor_pixmap_fbo **fbo_array;
 } glamor_pixmap_private;
@@ -520,13 +519,13 @@ glamor_pixmap_is_memory(PixmapPtr pixmap)
 static inline Bool
 glamor_pixmap_priv_is_large(glamor_pixmap_private *priv)
 {
-    return priv && priv->type == GLAMOR_TEXTURE_LARGE;
+    return priv && (priv->block_wcnt > 1 || priv->block_hcnt > 1);
 }
 
 static inline Bool
 glamor_pixmap_priv_is_small(glamor_pixmap_private *priv)
 {
-    return priv && priv->type != GLAMOR_TEXTURE_LARGE;
+    return priv && priv->block_wcnt <= 1 && priv->block_hcnt <= 1;
 }
 
 static inline Bool
@@ -559,43 +558,29 @@ glamor_set_pixmap_fbo_current(glamor_pixmap_private *priv, int idx)
 static inline glamor_pixmap_fbo *
 glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int x, int y)
 {
-    if (glamor_pixmap_priv_is_large(priv)) {
-        assert(x < priv->block_wcnt);
-        assert(y < priv->block_hcnt);
-        return priv->fbo_array[y * priv->block_wcnt + x];
-    }
-    assert (x == 0);
-    assert (y == 0);
-    return priv->fbo;
+    assert(x < priv->block_wcnt);
+    assert(y < priv->block_hcnt);
+    return priv->fbo_array[y * priv->block_wcnt + x];
 }
 
 static inline BoxPtr
 glamor_pixmap_box_at(glamor_pixmap_private *priv, int x, int y)
 {
-    if (glamor_pixmap_priv_is_large(priv)) {
-        assert(x < priv->block_wcnt);
-        assert(y < priv->block_hcnt);
-        return &priv->box_array[y * priv->block_wcnt + x];
-    }
-    assert (x == 0);
-    assert (y == 0);
-    return &priv->box;
+    assert(x < priv->block_wcnt);
+    assert(y < priv->block_hcnt);
+    return &priv->box_array[y * priv->block_wcnt + x];
 }
 
 static inline int
 glamor_pixmap_wcnt(glamor_pixmap_private *priv)
 {
-    if (glamor_pixmap_priv_is_large(priv))
-        return priv->block_wcnt;
-    return 1;
+    return priv->block_wcnt;
 }
 
 static inline int
 glamor_pixmap_hcnt(glamor_pixmap_private *priv)
 {
-    if (glamor_pixmap_priv_is_large(priv))
-        return priv->block_hcnt;
-    return 1;
+    return priv->block_hcnt;
 }
 
 #define glamor_pixmap_loop(priv, x, y)                  \
commit cc731ce0ca4d6c5c8d9c1130864e652a814644b4
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 23:20:11 2014 -0700

    glamor: Create inline tests for small/large pixmaps
    
    This will let us eliminate the pixmap types shortly
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
index 4459fce..e188d8a 100644
--- a/glamor/glamor_compositerects.c
+++ b/glamor/glamor_compositerects.c
@@ -246,7 +246,7 @@ glamor_composite_rectangles(CARD8 op,
         goto done;
     }
     else {
-        if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) {
+        if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) {
             int error;
 
             source = CreateSolidPicture(0, color, &error);
diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index 18fcdf9..609fcb3 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -367,7 +367,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
 
     glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y);
 
-    set_scissor = src_priv->type == GLAMOR_TEXTURE_LARGE;
+    set_scissor = glamor_pixmap_priv_is_large(src_priv);
     if (set_scissor)
         glEnable(GL_SCISSOR_TEST);
 
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 63c66cd..6789b4b 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -496,7 +496,7 @@ glamor_pixmap_destroy_fbo(glamor_screen_private *glamor_priv,
 {
     glamor_pixmap_fbo *fbo;
 
-    if (priv->type == GLAMOR_TEXTURE_LARGE) {
+    if (glamor_pixmap_priv_is_large(priv)) {
         int i;
         glamor_pixmap_private *large = priv;
 
diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index 6eda4e9..9c7878f 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -4,7 +4,7 @@
 
 static inline glamor_pixmap_private *
 __glamor_large(glamor_pixmap_private *pixmap_priv) {
-    assert(pixmap_priv->type == GLAMOR_TEXTURE_LARGE);
+    assert(glamor_pixmap_priv_is_large(pixmap_priv));
     return pixmap_priv;
 }
 
@@ -167,7 +167,7 @@ glamor_compute_clipped_regions_ext(PixmapPtr pixmap,
 
     DEBUGF("ext called \n");
 
-    if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+    if (glamor_pixmap_priv_is_small(pixmap_priv)) {
         clipped_regions = calloc(1, sizeof(*clipped_regions));
         if (clipped_regions == NULL) {
             *n_region = 0;
@@ -355,7 +355,7 @@ _glamor_compute_clipped_regions(PixmapPtr pixmap,
     glamor_pixmap_private *priv;
 
     DEBUGRegionPrint(region);
-    if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+    if (glamor_pixmap_priv_is_small(pixmap_priv)) {
         clipped_regions = calloc(1, sizeof(*clipped_regions));
         clipped_regions[0].region = RegionCreate(NULL, 1);
         clipped_regions[0].block_idx = 0;
@@ -798,7 +798,7 @@ glamor_merge_clipped_regions(PixmapPtr pixmap,
     }
 
     temp_priv = glamor_get_pixmap_private(temp_pixmap);
-    assert(temp_priv->type != GLAMOR_TEXTURE_LARGE);
+    assert(glamor_pixmap_priv_is_small(temp_priv));
 
     priv->box = temp_box;
     if (temp_extent->x1 >= 0 && temp_extent->x2 <= pixmap_width
@@ -1065,7 +1065,7 @@ glamor_composite_largepixmap_region(CARD8 op,
     else
         mask_repeat_type = RepeatNone;
 
-    if (dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+    if (glamor_pixmap_priv_is_large(dest_pixmap_priv)) {
         dest_block_width = __glamor_large(dest_pixmap_priv)->block_w;
         dest_block_height = __glamor_large(dest_pixmap_priv)->block_h;
     } else {
@@ -1096,7 +1096,7 @@ glamor_composite_largepixmap_region(CARD8 op,
      */
     if (source_pixmap_priv
         && source->transform
-        && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        && glamor_pixmap_priv_is_large(source_pixmap_priv)) {
         int source_transformed_block_width, source_transformed_block_height;
 
         if (!glamor_get_transform_block_size(source->transform,
@@ -1118,7 +1118,7 @@ glamor_composite_largepixmap_region(CARD8 op,
     }
 
     if (mask_pixmap_priv
-        && mask->transform && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        && mask->transform && glamor_pixmap_priv_is_large(mask_pixmap_priv)) {
         int mask_transformed_block_width, mask_transformed_block_height;
 
         if (!glamor_get_transform_block_size(mask->transform,
@@ -1156,7 +1156,7 @@ glamor_composite_largepixmap_region(CARD8 op,
     if (source_pixmap_priv
         && (source_pixmap_priv == dest_pixmap_priv ||
             source_pixmap_priv == mask_pixmap_priv)
-        && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        && glamor_pixmap_priv_is_large(source_pixmap_priv)) {
         /* XXX self-copy... */
         need_free_source_pixmap_priv = source_pixmap_priv;
         source_pixmap_priv = malloc(sizeof(*source_pixmap_priv));
@@ -1172,7 +1172,7 @@ glamor_composite_largepixmap_region(CARD8 op,
         glamor_set_pixmap_fbo_current(dest_pixmap_priv,
                                clipped_dest_regions[i].block_idx);
         if (source_pixmap_priv &&
-            source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+            glamor_pixmap_priv_is_large(source_pixmap_priv)) {
             if (!source->transform && source_repeat_type != RepeatPad) {
                 RegionTranslate(clipped_dest_regions[i].region,
                                 x_source - x_dest, y_source - y_dest);
@@ -1213,7 +1213,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                                            clipped_source_regions[j].block_idx);
 
                 if (mask_pixmap_priv &&
-                    mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+                    glamor_pixmap_priv_is_large(mask_pixmap_priv)) {
                     if (is_normal_mask_fbo && is_normal_source_fbo) {
                         /* both mask and source are normal fbo box without transform or repeatpad.
                          * The region is clipped against source and then we clip it against mask here.*/
@@ -1371,7 +1371,7 @@ glamor_composite_largepixmap_region(CARD8 op,
         }
         else {
             if (mask_pixmap_priv &&
-                mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+                glamor_pixmap_priv_is_large(mask_pixmap_priv)) {
                 if (!mask->transform && mask_repeat_type != RepeatPad) {
                     RegionTranslate(clipped_dest_regions[i].region,
                                     x_mask - x_dest, y_mask - y_dest);
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index d1551a4..0224b34 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -799,7 +799,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
     if (no_alpha == 0
         && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING
 #ifdef WALKAROUND_LARGE_TEXTURE_MAP
-        && pixmap_priv->type != GLAMOR_TEXTURE_LARGE
+        && glamor_pixmap_priv_is_small(pixmap_priv)
 #endif
         ) {
         int fbo_x_off, fbo_y_off;
@@ -956,7 +956,7 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
     force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
         && !glamor_check_fbo_size(glamor_priv, w, h);
 
-    if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
+    if (glamor_pixmap_priv_is_large(pixmap_priv) || force_clip) {
         RegionRec region;
         BoxRec box;
         int n_region;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 6cbebd2..33b2c5f 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -471,15 +471,86 @@ typedef struct glamor_pixmap_private {
     glamor_pixmap_fbo **fbo_array;
 } glamor_pixmap_private;
 
+extern DevPrivateKeyRec glamor_pixmap_private_key;
+
+static inline glamor_pixmap_private *
+glamor_get_pixmap_private(PixmapPtr pixmap)
+{
+    glamor_pixmap_private *priv;
+
+    if (pixmap == NULL)
+        return NULL;
+
+    priv = dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
+    if (!priv) {
+        glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
+        priv = dixLookupPrivate(&pixmap->devPrivates,
+                                &glamor_pixmap_private_key);
+    }
+    return priv;
+}
+
+void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
+
 /*
- * @base.fbo: current fbo.
- *
- **/
+ * Returns TRUE if pixmap has no image object
+ */
+static inline Bool
+glamor_pixmap_drm_only(PixmapPtr pixmap)
+{
+    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+    return priv && priv->type == GLAMOR_DRM_ONLY;
+}
+
+/*
+ * Returns TRUE if pixmap is plain memory (not a GL object at all)
+ */
+static inline Bool
+glamor_pixmap_is_memory(PixmapPtr pixmap)
+{
+    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+    return !priv || priv->type == GLAMOR_MEMORY;
+}
+
+/*
+ * Returns TRUE if pixmap requires multiple textures to hold it
+ */
+static inline Bool
+glamor_pixmap_priv_is_large(glamor_pixmap_private *priv)
+{
+    return priv && priv->type == GLAMOR_TEXTURE_LARGE;
+}
+
+static inline Bool
+glamor_pixmap_priv_is_small(glamor_pixmap_private *priv)
+{
+    return priv && priv->type != GLAMOR_TEXTURE_LARGE;
+}
+
+static inline Bool
+glamor_pixmap_is_large(PixmapPtr pixmap)
+{
+    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+    return priv && glamor_pixmap_priv_is_large(priv);
+}
+/*
+ * Returns TRUE if pixmap has an FBO
+ */
+static inline Bool
+glamor_pixmap_has_fbo(PixmapPtr pixmap)
+{
+    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+    return priv && priv->gl_fbo == GLAMOR_FBO_NORMAL;
+}
 
 static inline void
 glamor_set_pixmap_fbo_current(glamor_pixmap_private *priv, int idx)
 {
-    if (priv->type == GLAMOR_TEXTURE_LARGE) {
+    if (glamor_pixmap_priv_is_large(priv)) {
         priv->fbo = priv->fbo_array[idx];
         priv->box = priv->box_array[idx];
     }
@@ -488,7 +559,7 @@ glamor_set_pixmap_fbo_current(glamor_pixmap_private *priv, int idx)
 static inline glamor_pixmap_fbo *
 glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int x, int y)
 {
-    if (priv->type == GLAMOR_TEXTURE_LARGE) {
+    if (glamor_pixmap_priv_is_large(priv)) {
         assert(x < priv->block_wcnt);
         assert(y < priv->block_hcnt);
         return priv->fbo_array[y * priv->block_wcnt + x];
@@ -501,7 +572,7 @@ glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int x, int y)
 static inline BoxPtr
 glamor_pixmap_box_at(glamor_pixmap_private *priv, int x, int y)
 {
-    if (priv->type == GLAMOR_TEXTURE_LARGE) {
+    if (glamor_pixmap_priv_is_large(priv)) {
         assert(x < priv->block_wcnt);
         assert(y < priv->block_hcnt);
         return &priv->box_array[y * priv->block_wcnt + x];
@@ -514,7 +585,7 @@ glamor_pixmap_box_at(glamor_pixmap_private *priv, int x, int y)
 static inline int
 glamor_pixmap_wcnt(glamor_pixmap_private *priv)
 {
-    if (priv->type == GLAMOR_TEXTURE_LARGE)
+    if (glamor_pixmap_priv_is_large(priv))
         return priv->block_wcnt;
     return 1;
 }
@@ -522,7 +593,7 @@ glamor_pixmap_wcnt(glamor_pixmap_private *priv)
 static inline int
 glamor_pixmap_hcnt(glamor_pixmap_private *priv)
 {
-    if (priv->type == GLAMOR_TEXTURE_LARGE)
+    if (glamor_pixmap_priv_is_large(priv))
         return priv->block_hcnt;
     return 1;
 }
@@ -557,7 +628,6 @@ typedef struct {
 
 extern DevPrivateKeyRec glamor_gc_private_key;
 extern DevPrivateKeyRec glamor_screen_private_key;
-extern DevPrivateKeyRec glamor_pixmap_private_key;
 
 static inline glamor_screen_private *
 glamor_get_screen_private(ScreenPtr screen)
@@ -572,69 +642,6 @@ glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
     dixSetPrivate(&screen->devPrivates, &glamor_screen_private_key, priv);
 }
 
-static inline glamor_pixmap_private *
-glamor_get_pixmap_private(PixmapPtr pixmap)
-{
-    glamor_pixmap_private *priv;
-
-    if (pixmap == NULL)
-        return NULL;
-
-    priv = dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
-    if (!priv) {
-        glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
-        priv = dixLookupPrivate(&pixmap->devPrivates,
-                                &glamor_pixmap_private_key);
-    }
-    return priv;
-}
-
-/*
- * Returns TRUE if pixmap has no image object
- */
-static inline Bool
-glamor_pixmap_drm_only(PixmapPtr pixmap)
-{
-    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
-
-    return priv && priv->type == GLAMOR_DRM_ONLY;
-}
-
-/*
- * Returns TRUE if pixmap is plain memory (not a GL object at all)
- */
-static inline Bool
-glamor_pixmap_is_memory(PixmapPtr pixmap)
-{
-    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
-
-    return !priv || priv->type == GLAMOR_TEXTURE_LARGE;
-}
-
-/*
- * Returns TRUE if pixmap requires multiple textures to hold it
- */
-static inline Bool
-glamor_pixmap_is_large(PixmapPtr pixmap)
-{
-    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
-
-    return priv && priv->type == GLAMOR_TEXTURE_LARGE;
-}
-
-/*
- * Returns TRUE if pixmap has an FBO
- */
-static inline Bool
-glamor_pixmap_has_fbo(PixmapPtr pixmap)
-{
-    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
-
-    return priv && priv->gl_fbo == GLAMOR_FBO_NORMAL;
-}
-
-void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
-
 static inline glamor_gc_private *
 glamor_get_gc_private(GCPtr gc)
 {
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index b961f45..6669f48 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -542,7 +542,7 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
     if (repeat_type != RepeatNone)
         repeat_type += RepeatFix;
     else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-             || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+             || glamor_pixmap_priv_is_large(pixmap_priv)) {
         if (picture->transform)
             repeat_type += RepeatFix;
     }
diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index 7d1e685..df45b6f 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -169,7 +169,7 @@ glamor_set_texture(PixmapPtr    pixmap,
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(texture_priv))
         return FALSE;
 
-    if (texture_priv->type == GLAMOR_TEXTURE_LARGE)
+    if (glamor_pixmap_priv_is_large(texture_priv))
         return FALSE;
 
     glActiveTexture(GL_TEXTURE0);
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index b922771..6a3bd29 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -57,7 +57,7 @@
 
 #define PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, w, h)          \
   do {								\
-	if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) {	\
+	if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) {	\
 		w = priv->box.x2 - priv->box.x1;	\
 		h = priv->box.y2 - priv->box.y1;	\
 	} else {						\
@@ -78,7 +78,7 @@
 
 #define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_)		\
    do {								\
-	if (_X_UNLIKELY(_priv_ && (_priv_)->type == GLAMOR_TEXTURE_LARGE)) {  \
+        if (_X_UNLIKELY(_priv_ && glamor_pixmap_priv_is_large(_priv_))) { \
 		*(_xoff_) = - (_priv_)->box.x1;	\
 		*(_yoff_) = - (_priv_)->box.y1;	\
 	} else {						\
@@ -410,7 +410,7 @@
 							 texcoords,	\
 							 stride)	\
   do {									\
-    if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) {		\
+    if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) {		\
 	glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,	\
 						 yscale, _x1_, _y1_,	\
 						 _x2_, _y2_,	\
@@ -493,7 +493,7 @@
 				     x1, y1, x2, y2,			\
                                      vertices, stride)	\
   do {									\
-     if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) {		\
+     if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) {		\
 	float tx1, tx2, ty1, ty2;					\
 	int fbo_x_off, fbo_y_off;					\
 	pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
@@ -523,7 +523,7 @@
 					    _x1_, _y1_, _x2_, _y2_,	\
 	                                    vertices, stride)		\
   do {									\
-     if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) {		\
+     if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) {		\
 	float tx1, tx2, ty1, ty2;					\
 	if (repeat_type == RepeatPad) {					\
 		tx1 = _x1_ - priv->box.x1;			        \
@@ -943,7 +943,7 @@ glamor_is_large_pixmap(PixmapPtr pixmap)
     glamor_pixmap_private *priv;
 
     priv = glamor_get_pixmap_private(pixmap);
-    return (priv->type == GLAMOR_TEXTURE_LARGE);
+    return (glamor_pixmap_priv_is_large(priv));
 }
 
 inline static Bool
commit 020fcc582837b80b20843a09c1e28fa96096fe6b
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 23:08:57 2014 -0700

    glamor: Eliminate separate 'large' pixmap private structure
    
    Just embed the large elements in the regular pixmap private and
    collapse the union to a single struct.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 555f650..f9ea8e0 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -72,10 +72,10 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
         glamor_set_pixmap_private(pixmap, pixmap_priv);
     }
     pixmap_priv->type = type;
-    pixmap_priv->base.box.x1 = 0;
-    pixmap_priv->base.box.x2 = pixmap->drawable.width;
-    pixmap_priv->base.box.y1 = 0;
-    pixmap_priv->base.box.y2 = pixmap->drawable.height;
+    pixmap_priv->box.x1 = 0;
+    pixmap_priv->box.x2 = pixmap->drawable.width;
+    pixmap_priv->box.y1 = 0;
+    pixmap_priv->box.y2 = pixmap->drawable.height;
 }
 
 _X_EXPORT void
@@ -90,7 +90,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
     glamor_priv = glamor_get_screen_private(screen);
     pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-    if (pixmap_priv->base.fbo) {
+    if (pixmap_priv->fbo) {
         fbo = glamor_pixmap_detach_fbo(pixmap_priv);
         glamor_destroy_fbo(glamor_priv, fbo);
     }
@@ -116,10 +116,10 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
 
     glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen);
     pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
-    glamor_priv->screen_fbo = pixmap_priv->base.fbo->fb;
+    glamor_priv->screen_fbo = pixmap_priv->fbo->fb;
 
-    pixmap_priv->base.fbo->width = screen_pixmap->drawable.width;
-    pixmap_priv->base.fbo->height = screen_pixmap->drawable.height;
+    pixmap_priv->fbo->width = screen_pixmap->drawable.width;
+    pixmap_priv->fbo->height = screen_pixmap->drawable.height;
 }
 
 uint32_t
@@ -130,7 +130,7 @@ glamor_get_pixmap_texture(PixmapPtr pixmap)
     if (pixmap_priv->type != GLAMOR_TEXTURE_ONLY)
         return 0;
 
-    return pixmap_priv->base.fbo->tex;
+    return pixmap_priv->fbo->tex;
 }
 
 PixmapPtr
@@ -173,20 +173,20 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 
     if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) {
         pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
-        pixmap_priv->base.box.x1 = 0;
-        pixmap_priv->base.box.y1 = 0;
-        pixmap_priv->base.box.x2 = w;
-        pixmap_priv->base.box.y2 = h;
+        pixmap_priv->box.x1 = 0;
+        pixmap_priv->box.y1 = 0;
+        pixmap_priv->box.x2 = w;
+        pixmap_priv->box.y2 = h;
         return pixmap;
     }
     else if (usage == GLAMOR_CREATE_NO_LARGE ||
         glamor_check_fbo_size(glamor_priv, w, h))
     {
         pixmap_priv->type = type;
-        pixmap_priv->base.box.x1 = 0;
-        pixmap_priv->base.box.y1 = 0;
-        pixmap_priv->base.box.x2 = w;
-        pixmap_priv->base.box.y2 = h;
+        pixmap_priv->box.x1 = 0;
+        pixmap_priv->box.y1 = 0;
+        pixmap_priv->box.x2 = w;
+        pixmap_priv->box.y2 = h;
         fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
     } else {
         int tile_size = glamor_priv->max_fbo_size;
@@ -639,7 +639,7 @@ glamor_fd_from_pixmap(ScreenPtr screen,
             return -1;
         return glamor_egl_dri3_fd_name_from_tex(screen,
                                                 pixmap,
-                                                pixmap_priv->base.fbo->tex,
+                                                pixmap_priv->fbo->tex,
                                                 FALSE, stride, size);
     default:
         break;
@@ -664,7 +664,7 @@ glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
             return -1;
         return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen,
                                                 pixmap,
-                                                pixmap_priv->base.fbo->tex,
+                                                pixmap_priv->fbo->tex,
                                                 TRUE, stride, size);
     default:
         break;
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 737b274..cbbe759 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -43,9 +43,9 @@ glamor_get_drawable_location(const DrawablePtr drawable)
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(drawable->pScreen);
     if (pixmap_priv == NULL ||
-        pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED)
+        pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED)
         return 'm';
-    if (pixmap_priv->base.fbo->fb == glamor_priv->screen_fbo)
+    if (pixmap_priv->fbo->fb == glamor_priv->screen_fbo)
         return 's';
     else
         return 'f';
diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c
index e8f60fa..49ad3b6 100644
--- a/glamor/glamor_dash.c
+++ b/glamor/glamor_dash.c
@@ -189,7 +189,7 @@ glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
     /* Set the dash pattern as texture 1 */
 
     glActiveTexture(GL_TEXTURE1);
-    glBindTexture(GL_TEXTURE_2D, dash_priv->base.fbo->tex);
+    glBindTexture(GL_TEXTURE_2D, dash_priv->fbo->tex);
     glUniform1i(prog->dash_uniform, 1);
     glUniform1f(prog->dash_length_uniform, dash_pixmap->drawable.width);
 
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 113450c..6033780 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -239,7 +239,6 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
                    "Failed to create textured screen.");
         return FALSE;
     }
-
     glamor_set_screen_pixmap(screen_pixmap, NULL);
     return TRUE;
 }
@@ -272,7 +271,7 @@ glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image)
         glamor_get_pixmap_private(pixmap);
     EGLImageKHR old;
 
-    old = pixmap_priv->base.image;
+    old = pixmap_priv->image;
     if (old) {
         ScreenPtr                               screen = pixmap->drawable.pScreen;
         ScrnInfoPtr                             scrn = xf86ScreenToScrn(screen);
@@ -280,7 +279,7 @@ glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image)
 
         eglDestroyImageKHR(glamor_egl->display, old);
     }
-    pixmap_priv->base.image = image;
+    pixmap_priv->image = image;
 }
 
 Bool
@@ -420,7 +419,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
 
     glamor_make_current(glamor_priv);
 
-    image = pixmap_priv->base.image;
+    image = pixmap_priv->image;
     if (!image) {
         image = eglCreateImageKHR(glamor_egl->display,
                                   glamor_egl->context,
@@ -536,7 +535,7 @@ glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
     struct glamor_pixmap_private *pixmap_priv =
         glamor_get_pixmap_private(pixmap);
 
-    if (pixmap_priv && pixmap_priv->base.image) {
+    if (pixmap_priv && pixmap_priv->image) {
         ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
         struct glamor_egl_screen_private *glamor_egl =
             glamor_egl_get_screen_private(scrn);
@@ -545,8 +544,8 @@ glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
          * a texture. we must call glFlush to make sure the
          * operation on that texture has been done.*/
         glamor_block_handler(pixmap->drawable.pScreen);
-        eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
-        pixmap_priv->base.image = NULL;
+        eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
+        pixmap_priv->image = NULL;
     }
 }
 
@@ -561,13 +560,12 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 
     glamor_pixmap_exchange_fbos(front, back);
 
-    temp = back_priv->base.image;
-    back_priv->base.image = front_priv->base.image;
-    front_priv->base.image = temp;
+    temp = back_priv->image;
+    back_priv->image = front_priv->image;
+    front_priv->image = temp;
 
     glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
     glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
-
 }
 
 void
@@ -589,8 +587,8 @@ glamor_egl_close_screen(ScreenPtr screen)
     screen_pixmap = screen->GetScreenPixmap(screen);
     pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
 
-    eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
-    pixmap_priv->base.image = NULL;
+    eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
+    pixmap_priv->image = NULL;
 
     screen->CloseScreen = glamor_egl->saved_close_screen;
 
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index cf5216d..63c66cd 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -368,9 +368,9 @@ _glamor_create_fbo_array(glamor_screen_private *glamor_priv,
     glamor_pixmap_fbo **fbo_array;
     BoxPtr box_array;
     int i, j;
-    glamor_pixmap_private_large_t *priv;
+    glamor_pixmap_private *priv;
 
-    priv = &pixmap_priv->large;
+    priv = pixmap_priv;
 
     block_wcnt = (w + block_w - 1) / block_w;
     block_hcnt = (h + block_h - 1) / block_h;
@@ -407,7 +407,7 @@ _glamor_create_fbo_array(glamor_screen_private *glamor_priv,
                                                                   format,
                                                                   GLAMOR_CREATE_PIXMAP_FIXUP);
             else
-                fbo_array[i * block_wcnt + j] = priv->base.fbo;
+                fbo_array[i * block_wcnt + j] = priv->fbo;
             if (fbo_array[i * block_wcnt + j] == NULL)
                 goto cleanup;
         }
@@ -437,8 +437,8 @@ glamor_create_fbo_array(glamor_screen_private *glamor_priv,
                         int block_w, int block_h,
                         glamor_pixmap_private *pixmap_priv)
 {
-    pixmap_priv->large.block_w = block_w;
-    pixmap_priv->large.block_h = block_h;
+    pixmap_priv->block_w = block_w;
+    pixmap_priv->block_h = block_h;
     return _glamor_create_fbo_array(glamor_priv, w, h, format, flag,
                                     block_w, block_h, pixmap_priv, 0);
 }
@@ -451,11 +451,11 @@ glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
     if (pixmap_priv == NULL)
         return NULL;
 
-    fbo = pixmap_priv->base.fbo;
+    fbo = pixmap_priv->fbo;
     if (fbo == NULL)
         return NULL;
 
-    pixmap_priv->base.fbo = NULL;
+    pixmap_priv->fbo = NULL;
     return fbo;
 }
 
@@ -467,21 +467,21 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-    if (pixmap_priv->base.fbo)
+    if (pixmap_priv->fbo)
         return;
 
-    pixmap_priv->base.fbo = fbo;
+    pixmap_priv->fbo = fbo;
 
     switch (pixmap_priv->type) {
     case GLAMOR_TEXTURE_LARGE:
     case GLAMOR_TEXTURE_ONLY:
     case GLAMOR_TEXTURE_DRM:
-        pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL;
+        pixmap_priv->gl_fbo = GLAMOR_FBO_NORMAL;
         if (fbo->tex != 0)
-            pixmap_priv->base.gl_tex = 1;
+            pixmap_priv->gl_tex = 1;
         else {
             /* XXX For the Xephyr only, may be broken now. */
-            pixmap_priv->base.gl_tex = 0;
+            pixmap_priv->gl_tex = 0;
         }
         pixmap->devPrivate.ptr = NULL;
         break;
@@ -498,7 +498,7 @@ glamor_pixmap_destroy_fbo(glamor_screen_private *glamor_priv,
 
     if (priv->type == GLAMOR_TEXTURE_LARGE) {
         int i;
-        glamor_pixmap_private_large_t *large = &priv->large;
+        glamor_pixmap_private *large = priv;
 
         for (i = 0; i < large->block_wcnt * large->block_hcnt; i++)
             glamor_destroy_fbo(glamor_priv, large->fbo_array[i]);
@@ -520,7 +520,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
 
     glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
     pixmap_priv = glamor_get_pixmap_private(pixmap);
-    if (pixmap_priv->base.fbo == NULL) {
+    if (pixmap_priv->fbo == NULL) {
 
         fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
                                 pixmap->drawable.height, format, flag);
@@ -531,13 +531,13 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
     }
     else {
         /* We do have a fbo, but it may lack of fb or tex. */
-        if (!pixmap_priv->base.fbo->tex)
-            pixmap_priv->base.fbo->tex =
+        if (!pixmap_priv->fbo->tex)
+            pixmap_priv->fbo->tex =
                 _glamor_create_tex(glamor_priv, pixmap->drawable.width,
                                    pixmap->drawable.height, format);
 
-        if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->base.fbo->fb == 0)
-            if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->base.fbo) != 0)
+        if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0)
+            if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->fbo) != 0)
                 return FALSE;
     }
 
@@ -552,7 +552,7 @@ glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back)
 
     front_priv = glamor_get_pixmap_private(front);
     back_priv = glamor_get_pixmap_private(back);
-    temp_fbo = front_priv->base.fbo;
-    front_priv->base.fbo = back_priv->base.fbo;
-    back_priv->base.fbo = temp_fbo;
+    temp_fbo = front_priv->fbo;
+    front_priv->fbo = back_priv->fbo;
+    back_priv->fbo = temp_fbo;
 }
diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index 2c91c27..6eda4e9 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -2,10 +2,10 @@
 
 #include "glamor_priv.h"
 
-static inline glamor_pixmap_private_large_t *
+static inline glamor_pixmap_private *
 __glamor_large(glamor_pixmap_private *pixmap_priv) {
     assert(pixmap_priv->type == GLAMOR_TEXTURE_LARGE);
-    return &pixmap_priv->large;
+    return pixmap_priv;
 }
 
 /**
@@ -185,7 +185,7 @@ glamor_compute_clipped_regions_ext(PixmapPtr pixmap,
         small_box.y2 = block_h;
     }
     else {
-        glamor_pixmap_private_large_t *priv = __glamor_large(pixmap_priv);
+        glamor_pixmap_private *priv = __glamor_large(pixmap_priv);
 
         clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
                                                            priv->block_h,
@@ -352,7 +352,7 @@ _glamor_compute_clipped_regions(PixmapPtr pixmap,
     int right_shift = 0;
     int down_shift = 0;
     int x_center_shift = 0, y_center_shift = 0;
-    glamor_pixmap_private_large_t *priv;
+    glamor_pixmap_private *priv;
 
     DEBUGRegionPrint(region);
     if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
@@ -763,7 +763,7 @@ glamor_merge_clipped_regions(PixmapPtr pixmap,
     int overlap;
     int i;
     int pixmap_width, pixmap_height;
-    glamor_pixmap_private_large_t *priv;
+    glamor_pixmap_private *priv;
 
     priv = __glamor_large(pixmap_priv);
     pixmap_width = pixmap->drawable.width;
@@ -858,7 +858,7 @@ glamor_merge_clipped_regions(PixmapPtr pixmap,
         RegionDestroy(clipped_regions[i].region);
     RegionDestroy(temp_region);
     priv->box = temp_box;
-    priv->base.fbo = glamor_pixmap_detach_fbo(temp_priv);
+    priv->fbo = glamor_pixmap_detach_fbo(temp_priv);
     DEBUGF("priv box x1 %d y1 %d x2 %d y2 %d \n",
            priv->box.x1, priv->box.y1, priv->box.x2, priv->box.y2);
     glamor_destroy_pixmap(temp_pixmap);
@@ -1335,8 +1335,8 @@ glamor_composite_largepixmap_region(CARD8 op,
                         null_mask = 0;
                     if (need_clean_mask_fbo) {
                         assert(is_normal_mask_fbo == 0);
-                        glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->base.fbo);
-                        mask_pixmap_priv->base.fbo = NULL;
+                        glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->fbo);
+                        mask_pixmap_priv->fbo = NULL;
                         need_clean_mask_fbo = 0;
                     }
                 }
@@ -1364,8 +1364,8 @@ glamor_composite_largepixmap_region(CARD8 op,
                 null_source = 0;
             if (need_clean_source_fbo) {
                 assert(is_normal_source_fbo == 0);
-                glamor_destroy_fbo(glamor_priv, source_pixmap_priv->base.fbo);
-                source_pixmap_priv->base.fbo = NULL;
+                glamor_destroy_fbo(glamor_priv, source_pixmap_priv->fbo);
+                source_pixmap_priv->fbo = NULL;
                 need_clean_source_fbo = 0;
             }
         }
@@ -1426,8 +1426,8 @@ glamor_composite_largepixmap_region(CARD8 op,
                 if (null_mask)
                     null_mask = 0;
                 if (need_clean_mask_fbo) {
-                    glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->base.fbo);
-                    mask_pixmap_priv->base.fbo = NULL;
+                    glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->fbo);
+                    mask_pixmap_priv->fbo = NULL;
                     need_clean_mask_fbo = 0;
                 }
             }
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 008d183..53b032c 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -70,8 +70,8 @@ glamor_create_picture(PicturePtr picture)
         pixmap_priv = glamor_get_pixmap_private(pixmap);
     }
 
-    pixmap_priv->base.is_picture = 1;
-    pixmap_priv->base.picture = picture;
+    pixmap_priv->is_picture = 1;
+    pixmap_priv->picture = picture;
 
     return miCreatePicture(picture);
 }
@@ -89,8 +89,8 @@ glamor_destroy_picture(PicturePtr picture)
     pixmap_priv = glamor_get_pixmap_private(pixmap);
 
     if (pixmap_priv) {
-        pixmap_priv->base.is_picture = 0;
-        pixmap_priv->base.picture = NULL;
+        pixmap_priv->is_picture = 0;
+        pixmap_priv->picture = NULL;
     }
     miDestroyPicture(picture);
 }
@@ -99,5 +99,5 @@ void
 glamor_picture_format_fixup(PicturePtr picture,
                             glamor_pixmap_private *pixmap_priv)
 {
-    pixmap_priv->base.picture = picture;
+    pixmap_priv->picture = picture;
 }
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 7935bf2..d1551a4 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -81,7 +81,7 @@ glamor_set_destination_pixmap_priv_nc(glamor_screen_private *glamor_priv,
     int w, h;
 
     PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, pixmap_priv, w, h);
-    glamor_set_destination_pixmap_fbo(glamor_priv, pixmap_priv->base.fbo, 0, 0, w, h);
+    glamor_set_destination_pixmap_fbo(glamor_priv, pixmap_priv->fbo, 0, 0, w, h);
 }
 
 int
@@ -478,7 +478,7 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
     if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
-        pict_format = pixmap_priv->base.picture->format;
+        pict_format = pixmap_priv->picture->format;
     else
         pict_format = format_for_depth(pixmap->drawable.depth);
 
@@ -804,13 +804,13 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
         ) {
         int fbo_x_off, fbo_y_off;
 
-        assert(pixmap_priv->base.fbo->tex);
+        assert(pixmap_priv->fbo->tex);
         pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
 
         assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
-        assert(x + fbo_x_off + w <= pixmap_priv->base.fbo->width);
-        assert(y + fbo_y_off + h <= pixmap_priv->base.fbo->height);
-        __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
+        assert(x + fbo_x_off + w <= pixmap_priv->fbo->width);
+        assert(y + fbo_y_off + h <= pixmap_priv->fbo->height);
+        __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
                                           format, type,
                                           x + fbo_x_off, y + fbo_y_off, w, h,
                                           bits, pbo);
@@ -874,17 +874,17 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
     pixmap_priv = glamor_get_pixmap_private(pixmap);
     glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 
-    if (pixmap_priv->base.gl_fbo != GLAMOR_FBO_UNATTACHED)
+    if (pixmap_priv->gl_fbo != GLAMOR_FBO_UNATTACHED)
         return 0;
 
-    if (pixmap_priv->base.fbo
-        && (pixmap_priv->base.fbo->width < pixmap->drawable.width
-            || pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
+    if (pixmap_priv->fbo
+        && (pixmap_priv->fbo->width < pixmap->drawable.width
+            || pixmap_priv->fbo->height < pixmap->drawable.height)) {
         fbo = glamor_pixmap_detach_fbo(pixmap_priv);
         glamor_destroy_fbo(glamor_priv, fbo);
     }
 
-    if (pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb)
+    if (pixmap_priv->fbo && pixmap_priv->fbo->fb)
         return 0;
 
     if (!(no_alpha || (revert == REVERT_NORMAL)
@@ -895,8 +895,8 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
     }
 
     if ((flag == GLAMOR_CREATE_FBO_NO_FBO
-         && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
-        || (flag == 0 && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
+         && pixmap_priv->fbo && pixmap_priv->fbo->tex)
+        || (flag == 0 && pixmap_priv->fbo && pixmap_priv->fbo->fb))
         return 0;
 
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
@@ -980,8 +980,8 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
             clipped_regions =
                 glamor_compute_clipped_regions_ext(pixmap, &region,
                                                    &n_region,
-                                                   pixmap_priv->large.block_w,
-                                                   pixmap_priv->large.block_h,
+                                                   pixmap_priv->block_w,
+                                                   pixmap_priv->block_h,
                                                    0,
                                                    0);
         DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
@@ -1052,10 +1052,10 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-    if ((pixmap_priv->base.fbo)
-        && (pixmap_priv->base.fbo->pbo_valid)) {
+    if ((pixmap_priv->fbo)
+        && (pixmap_priv->fbo->pbo_valid)) {
         data = NULL;
-        pbo = pixmap_priv->base.fbo->pbo;
+        pbo = pixmap_priv->fbo->pbo;
     }
     else {
         data = pixmap->devPrivate.ptr;
@@ -1126,7 +1126,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
     glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
+    glBindTexture(GL_TEXTURE_2D, source_priv->fbo->tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
diff --git a/glamor/glamor_prepare.c b/glamor/glamor_prepare.c
index fb85d90..83ba7f1 100644
--- a/glamor/glamor_prepare.c
+++ b/glamor/glamor_prepare.c
@@ -54,7 +54,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
          * we'll assume that it's directly mapped
          * by a lower level driver
          */
-        if (!priv->base.prepared)
+        if (!priv->prepared)
             return TRUE;
 
         /* In X, multiple Drawables can be stored in the same Pixmap (such as
@@ -65,28 +65,28 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
          * As a result, when doing a series of mappings for a fallback, we may
          * need to add more boxes to the set of data we've downloaded, as we go.
          */
-        RegionSubtract(&region, &region, &priv->base.prepare_region);
+        RegionSubtract(&region, &region, &priv->prepare_region);
         if (!RegionNotEmpty(&region))
             return TRUE;
 
         if (access == GLAMOR_ACCESS_RW)
             FatalError("attempt to remap buffer as writable");
 
-        if (priv->base.pbo) {
-            glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo);
+        if (priv->pbo) {
+            glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->pbo);
             glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
             pixmap->devPrivate.ptr = NULL;
         }
     } else {
-        RegionInit(&priv->base.prepare_region, box, 1);
+        RegionInit(&priv->prepare_region, box, 1);
 
         if (glamor_priv->has_rw_pbo) {
-            if (priv->base.pbo == 0)
-                glGenBuffers(1, &priv->base.pbo);
+            if (priv->pbo == 0)
+                glGenBuffers(1, &priv->pbo);
 
             gl_usage = GL_STREAM_READ;
 
-            glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo);
+            glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->pbo);
             glBufferData(GL_PIXEL_PACK_BUFFER,
                          pixmap->devKind * pixmap->drawable.height, NULL,
                          gl_usage);
@@ -96,7 +96,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
             if (!pixmap->devPrivate.ptr)
                 return FALSE;
         }
-        priv->base.map_access = access;
+        priv->map_access = access;
     }
 
     glamor_download_boxes(pixmap, RegionRects(&region), RegionNumRects(&region),
@@ -105,7 +105,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
     RegionUninit(&region);
 
     if (glamor_priv->has_rw_pbo) {
-        if (priv->base.map_access == GLAMOR_ACCESS_RW)
+        if (priv->map_access == GLAMOR_ACCESS_RW)
             gl_access = GL_READ_WRITE;
         else
             gl_access = GL_READ_ONLY;
@@ -114,7 +114,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
         glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
     }
 
-    priv->base.prepared = TRUE;
+    priv->prepared = TRUE;
     return TRUE;
 }
 
@@ -133,34 +133,34 @@ glamor_fini_pixmap(PixmapPtr pixmap)
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
         return;
 
-    if (!priv->base.prepared)
+    if (!priv->prepared)
         return;
 
     if (glamor_priv->has_rw_pbo) {
-        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->base.pbo);
+        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->pbo);
         glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
         pixmap->devPrivate.ptr = NULL;
     }
 
-    if (priv->base.map_access == GLAMOR_ACCESS_RW) {
+    if (priv->map_access == GLAMOR_ACCESS_RW) {
         glamor_upload_boxes(pixmap,
-                            RegionRects(&priv->base.prepare_region),
-                            RegionNumRects(&priv->base.prepare_region),
+                            RegionRects(&priv->prepare_region),
+                            RegionNumRects(&priv->prepare_region),
                             0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind);
     }
 
-    RegionUninit(&priv->base.prepare_region);
+    RegionUninit(&priv->prepare_region);
 
     if (glamor_priv->has_rw_pbo) {
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-        glDeleteBuffers(1, &priv->base.pbo);
-        priv->base.pbo = 0;
+        glDeleteBuffers(1, &priv->pbo);
+        priv->pbo = 0;
     } else {
         free(pixmap->devPrivate.ptr);
         pixmap->devPrivate.ptr = NULL;
     }
 
-    priv->base.prepared = FALSE;
+    priv->prepared = FALSE;
 }
 
 Bool
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index e9b05bb..6cbebd2 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -377,6 +377,14 @@ typedef struct glamor_pixmap_fbo {
  * @is_picture: The drawable is attached to a picture.
  * @pict_format: the corresponding picture's format.
  * @pixmap: The corresponding pixmap's pointer.
+ * @box: current fbo's coords in the whole pixmap.
+ * @block_w: block width of this large pixmap.
+ * @block_h: block height of this large pixmap.
+ * @block_wcnt: block count in one block row.
+ * @block_hcnt: block count in one block column.
+ * @nbox: total block count.
+ * @box_array: contains each block's corresponding box.
+ * @fbo_array: contains each block's fbo pointer.
  *
  * For GLAMOR_TEXTURE_LARGE, nbox should larger than 1.
  * And the box and fbo will both have nbox elements.
@@ -426,9 +434,6 @@ typedef struct glamor_pixmap_fbo {
  * to the box and fbo elements. Thus the inner routines
  * can handle it as normal, only the coords calculation need
  * to aware of it's large pixmap.
- *
- * Currently, we haven't implemented the atlas pixmap.
- *
  **/
 
 typedef struct glamor_pixmap_clipped_regions {
@@ -436,7 +441,7 @@ typedef struct glamor_pixmap_clipped_regions {
     RegionPtr region;
 } glamor_pixmap_clipped_regions;
 
-typedef struct glamor_pixmap_private_base {
+typedef struct glamor_pixmap_private {
     glamor_pixmap_type_t type;
     enum glamor_fbo_state gl_fbo;
     /**
@@ -457,26 +462,6 @@ typedef struct glamor_pixmap_private_base {
 #if GLAMOR_HAS_GBM
     EGLImageKHR image;
 #endif
-} glamor_pixmap_private_base_t;
-
-/*
- * @base.fbo: current fbo.
- * @box: current fbo's coords in the whole pixmap.
- * @block_w: block width of this large pixmap.
- * @block_h: block height of this large pixmap.
- * @block_wcnt: block count in one block row.
- * @block_hcnt: block count in one block column.
- * @nbox: total block count.
- * @box_array: contains each block's corresponding box.
- * @fbo_array: contains each block's fbo pointer.
- *
- **/
-typedef struct glamor_pixmap_private_large {
-    union {
-        glamor_pixmap_type_t type;
-        glamor_pixmap_private_base_t base;
-    };
-    BoxRec box;
     int block_w;
     int block_h;
     int block_wcnt;
@@ -484,22 +469,19 @@ typedef struct glamor_pixmap_private_large {
     int nbox;
     BoxPtr box_array;
     glamor_pixmap_fbo **fbo_array;
-} glamor_pixmap_private_large_t;
-
-typedef struct glamor_pixmap_private {
-    union {
-        glamor_pixmap_type_t type;
-        glamor_pixmap_private_base_t base;
-        glamor_pixmap_private_large_t large;
-    };
 } glamor_pixmap_private;
 
+/*
+ * @base.fbo: current fbo.
+ *
+ **/
+
 static inline void
 glamor_set_pixmap_fbo_current(glamor_pixmap_private *priv, int idx)
 {
     if (priv->type == GLAMOR_TEXTURE_LARGE) {
-        priv->large.base.fbo = priv->large.fbo_array[idx];
-        priv->large.box = priv->large.box_array[idx];
+        priv->fbo = priv->fbo_array[idx];
+        priv->box = priv->box_array[idx];
     }
 }
 
@@ -507,33 +489,33 @@ static inline glamor_pixmap_fbo *
 glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int x, int y)
 {
     if (priv->type == GLAMOR_TEXTURE_LARGE) {
-        assert(x < priv->large.block_wcnt);
-        assert(y < priv->large.block_hcnt);
-        return priv->large.fbo_array[y * priv->large.block_wcnt + x];
+        assert(x < priv->block_wcnt);
+        assert(y < priv->block_hcnt);
+        return priv->fbo_array[y * priv->block_wcnt + x];
     }
     assert (x == 0);
     assert (y == 0);
-    return priv->base.fbo;
+    return priv->fbo;
 }
 
 static inline BoxPtr
 glamor_pixmap_box_at(glamor_pixmap_private *priv, int x, int y)
 {
     if (priv->type == GLAMOR_TEXTURE_LARGE) {
-        assert(x < priv->large.block_wcnt);
-        assert(y < priv->large.block_hcnt);
-        return &priv->large.box_array[y * priv->large.block_wcnt + x];
+        assert(x < priv->block_wcnt);
+        assert(y < priv->block_hcnt);
+        return &priv->box_array[y * priv->block_wcnt + x];
     }
     assert (x == 0);
     assert (y == 0);
-    return &priv->base.box;
+    return &priv->box;
 }
 
 static inline int
 glamor_pixmap_wcnt(glamor_pixmap_private *priv)
 {
     if (priv->type == GLAMOR_TEXTURE_LARGE)
-        return priv->large.block_wcnt;
+        return priv->block_wcnt;
     return 1;
 }
 
@@ -541,7 +523,7 @@ static inline int
 glamor_pixmap_hcnt(glamor_pixmap_private *priv)
 {
     if (priv->type == GLAMOR_TEXTURE_LARGE)
-        return priv->large.block_hcnt;
+        return priv->block_hcnt;
     return 1;
 }
 
@@ -615,7 +597,7 @@ glamor_pixmap_drm_only(PixmapPtr pixmap)
 {
     glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
 
-    return priv && priv->base.type == GLAMOR_DRM_ONLY;
+    return priv && priv->type == GLAMOR_DRM_ONLY;
 }
 
 /*
@@ -626,7 +608,7 @@ glamor_pixmap_is_memory(PixmapPtr pixmap)
 {
     glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
 
-    return !priv || priv->base.type == GLAMOR_TEXTURE_LARGE;
+    return !priv || priv->type == GLAMOR_TEXTURE_LARGE;
 }
 
 /*
@@ -637,7 +619,7 @@ glamor_pixmap_is_large(PixmapPtr pixmap)
 {
     glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
 
-    return priv && priv->base.type == GLAMOR_TEXTURE_LARGE;
+    return priv && priv->type == GLAMOR_TEXTURE_LARGE;
 }
 
 /*
@@ -648,7 +630,7 @@ glamor_pixmap_has_fbo(PixmapPtr pixmap)
 {
     glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
 
-    return priv && priv->base.gl_fbo == GLAMOR_FBO_NORMAL;
+    return priv && priv->gl_fbo == GLAMOR_FBO_NORMAL;
 }
 
 void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 3ef9a15..b961f45 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -491,7 +491,7 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
 
     glamor_make_current(glamor_priv);
     glActiveTexture(GL_TEXTURE0 + unit);
-    glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex);
+    glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
     repeat_type = picture->repeatType;
     switch (picture->repeatType) {
     case RepeatNone:
@@ -933,7 +933,7 @@ glamor_composite_choose_shader(CARD8 op,
              * Does it need special handle? */
             glamor_fallback("source == dest\n");
         }
-        if (source_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
+        if (source_pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED) {
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
             source_status = GLAMOR_UPLOAD_PENDING;
 #else
@@ -949,7 +949,7 @@ glamor_composite_choose_shader(CARD8 op,
             glamor_fallback("mask == dest\n");
             goto fail;
         }
-        if (mask_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
+        if (mask_pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED) {
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
             mask_status = GLAMOR_UPLOAD_PENDING;
 #else
diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index eddc468..7d1e685 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -173,7 +173,7 @@ glamor_set_texture(PixmapPtr    pixmap,
         return FALSE;
 
     glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, texture_priv->base.fbo->tex);
+    glBindTexture(GL_TEXTURE_2D, texture_priv->fbo->tex);
 
     glUniform2f(offset_uniform, off_x, off_y);
     glUniform2f(size_uniform, texture->drawable.width, texture->drawable.height);
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 688350d..b922771 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -51,15 +51,15 @@
 
 #define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
    do {									\
-    *(_pxscale_) = 1.0 / (_pixmap_priv_)->base.fbo->width;			\
-    *(_pyscale_) = 1.0 / (_pixmap_priv_)->base.fbo->height;			\
+    *(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width;			\
+    *(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height;			\
   } while(0)
 
 #define PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, w, h)          \
   do {								\
 	if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) {	\
-		w = priv->large.box.x2 - priv->large.box.x1;	\
-		h = priv->large.box.y2 - priv->large.box.y1;	\
+		w = priv->box.x2 - priv->box.x1;	\
+		h = priv->box.y2 - priv->box.y1;	\
 	} else {						\
 		w = (pixmap)->drawable.width;		\
 		h = (pixmap)->drawable.height;		\
@@ -70,17 +70,17 @@
   do {								\
 	int actual_w, actual_h;					\
 	PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, actual_w, actual_h);	\
-	wh[0] = (float)priv->base.fbo->width / actual_w;	\
-	wh[1] = (float)priv->base.fbo->height / actual_h;	\
-	wh[2] = 1.0 / priv->base.fbo->width;			\
-	wh[3] = 1.0 / priv->base.fbo->height;			\
+	wh[0] = (float)priv->fbo->width / actual_w;	\
+	wh[1] = (float)priv->fbo->height / actual_h;	\
+	wh[2] = 1.0 / priv->fbo->width;			\
+	wh[3] = 1.0 / priv->fbo->height;			\
   } while(0)
 
 #define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_)		\
    do {								\
 	if (_X_UNLIKELY(_priv_ && (_priv_)->type == GLAMOR_TEXTURE_LARGE)) {  \
-		*(_xoff_) = - (_priv_)->large.box.x1;	\
-		*(_yoff_) = - (_priv_)->large.box.y1;	\
+		*(_xoff_) = - (_priv_)->box.x1;	\
+		*(_yoff_) = - (_priv_)->box.y1;	\
 	} else {						\
 		*(_xoff_) = 0;					\
 		*(_yoff_) = 0;					\
@@ -204,9 +204,9 @@
 	DEBUGF("c %f d %f oddx %d oddy %d \n",			\
 		c, d, odd_x, odd_y);				\
 	DEBUGF("x2 %d x1 %d fbo->width %d \n", priv->box.x2,	\
-		priv->box.x1, priv->base.fbo->width);		\
+		priv->box.x1, priv->fbo->width);		\
 	DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, 	\
-		priv->box.y1, priv->base.fbo->height);		\
+		priv->box.y1, priv->fbo->height);		\
 	_glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x,	\
 		(pixmap)->drawable.width,		\
 		priv->box.x1, priv->box.x2);			\
@@ -425,16 +425,16 @@
     glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_);		\
     DEBUGF("transformed %f %f %f %f %f %f %f %f\n",			\
 	   tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4);			\
-    glamor_get_repeat_transform_coords(pixmap, (&priv->large), repeat_type, \
+    glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
 				       ttx1, tty1, 			\
 				       tx1, ty1);			\
-    glamor_get_repeat_transform_coords(pixmap, (&priv->large), repeat_type, 	\
+    glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, 	\
 				       ttx2, tty2, 			\
 				       tx2, ty2);			\
-    glamor_get_repeat_transform_coords(pixmap, (&priv->large), repeat_type, 	\
+    glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, 	\
 				       ttx3, tty3, 			\
 				       tx3, ty3);			\
-    glamor_get_repeat_transform_coords(pixmap, (&priv->large), repeat_type, 	\
+    glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, 	\
 				       ttx4, tty4, 			\
 				       tx4, ty4);			\
     DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, 	\
@@ -526,12 +526,12 @@
      if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) {		\
 	float tx1, tx2, ty1, ty2;					\
 	if (repeat_type == RepeatPad) {					\
-		tx1 = _x1_ - priv->large.box.x1;			\
-		ty1 = _y1_ - priv->large.box.y1;			\
+		tx1 = _x1_ - priv->box.x1;			        \
+		ty1 = _y1_ - priv->box.y1;			        \
 		tx2 = tx1 + ((_x2_) - (_x1_));				\
 		ty2 = ty1 + ((_y2_) - (_y1_));				\
 	} else {							\
-            glamor_get_repeat_coords(pixmap, (&priv->large), repeat_type, \
+            glamor_get_repeat_coords(pixmap, priv, repeat_type,         \
 				 tx1, ty1, tx2, ty2,			\
 				 _x1_, _y1_, _x2_, _y2_);		\
 	}								\
@@ -756,9 +756,9 @@ glamor_translate_boxes(BoxPtr boxes, int nbox, int dx, int dy)
 						|| _depth_ == 30	\
 						|| _depth_ == 32)
 
-#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->base.is_picture == 1)
-#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv && pixmap_priv->base.gl_fbo == GLAMOR_FBO_NORMAL)
-#define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv)    (pixmap_priv && (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED))
+#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->is_picture == 1)
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv && pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv)    (pixmap_priv && (pixmap_priv->gl_fbo == GLAMOR_FBO_DOWNLOADED))
 
 /**
  * Borrow from uxa.
@@ -811,7 +811,7 @@ format_for_pixmap(PixmapPtr pixmap)
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
     if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
-        pict_format = pixmap_priv->base.picture->format;
+        pict_format = pixmap_priv->picture->format;
     else
         pict_format = format_for_depth((pixmap)->drawable.depth);
 
diff --git a/glamor/glamor_window.c b/glamor/glamor_window.c
index 60647bf..a39e723 100644
--- a/glamor/glamor_window.c
+++ b/glamor/glamor_window.c
@@ -79,16 +79,16 @@ glamor_set_window_pixmap(WindowPtr win, PixmapPtr pPixmap)
 
         pixmap_priv = glamor_get_pixmap_private(old);
         if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) &&
-            pixmap_priv->base.picture->pDrawable == (DrawablePtr) win) {
-            pic = pixmap_priv->base.picture;
-            pixmap_priv->base.is_picture = 0;
-            pixmap_priv->base.picture = NULL;
+            pixmap_priv->picture->pDrawable == (DrawablePtr) win) {
+            pic = pixmap_priv->picture;
+            pixmap_priv->is_picture = 0;
+            pixmap_priv->picture = NULL;
         }
 
         pixmap_priv = glamor_get_pixmap_private(pPixmap);
         if (pixmap_priv) {
-            pixmap_priv->base.is_picture = ! !pic;
-            pixmap_priv->base.picture = pic;
+            pixmap_priv->is_picture = ! !pic;
+            pixmap_priv->picture = pic;
         }
     }
 
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 74654f5..2d5b8e1 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -306,21 +306,21 @@ glamor_xv_render(glamor_port_private *port_priv)
     glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
 
     glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->base.fbo->tex);
+    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
     glActiveTexture(GL_TEXTURE1);
-    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->base.fbo->tex);
+    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
     glActiveTexture(GL_TEXTURE2);
-    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->base.fbo->tex);
+    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->fbo->tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
commit 9ef5cbf8ab8a51941d469bfcaca6cbfb7838d1ef
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 22:54:27 2014 -0700

    glamor: Remove unused glamor_pixmap_private_atlas_t
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index c5c6bb3..e9b05bb 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -486,23 +486,11 @@ typedef struct glamor_pixmap_private_large {
     glamor_pixmap_fbo **fbo_array;
 } glamor_pixmap_private_large_t;
 
-/*
- * @box: the relative coords in the corresponding fbo.
- */
-typedef struct glamor_pixmap_private_atlas {
-    union {
-        glamor_pixmap_type_t type;
-        glamor_pixmap_private_base_t base;
-    };
-    BoxRec box;
-} glamor_pixmap_private_atlas_t;
-
 typedef struct glamor_pixmap_private {
     union {
         glamor_pixmap_type_t type;
         glamor_pixmap_private_base_t base;
         glamor_pixmap_private_large_t large;
-        glamor_pixmap_private_atlas_t atlas;
     };
 } glamor_pixmap_private;
 
commit af687396f1875de0a45683aad4fd5a9a2e00f10d
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 22:50:53 2014 -0700

    glamor: Remove screen private and pixmap ptrs from pixmap private and fbo
    
    There's no reason to waste memory storing redundant copies of the same
    pointer all over the system; just pass in pointers as necessary to
    each function.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 6ee006f..555f650 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -64,16 +64,12 @@ _X_EXPORT void
 glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
 {
     glamor_pixmap_private *pixmap_priv;
-    glamor_screen_private *glamor_priv =
-        glamor_get_screen_private(pixmap->drawable.pScreen);
 
     pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
                                    &glamor_pixmap_private_key);
     if (pixmap_priv == NULL) {
         pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
         glamor_set_pixmap_private(pixmap, pixmap_priv);
-        pixmap_priv->base.pixmap = pixmap;
-        pixmap_priv->base.glamor_priv = glamor_priv;
     }
     pixmap_priv->type = type;
     pixmap_priv->base.box.x1 = 0;
@@ -96,7 +92,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
 
     if (pixmap_priv->base.fbo) {
         fbo = glamor_pixmap_detach_fbo(pixmap_priv);
-        glamor_destroy_fbo(fbo);
+        glamor_destroy_fbo(glamor_priv, fbo);
     }
 
     format = gl_iformat_for_pixmap(pixmap);
@@ -170,9 +166,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     }
     glamor_set_pixmap_private(pixmap, pixmap_priv);
 
-    pixmap_priv->base.pixmap = pixmap;
-    pixmap_priv->base.glamor_priv = glamor_priv;
-
     format = gl_iformat_for_pixmap(pixmap);
 
     pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
@@ -557,8 +550,8 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
     else {
         if (old_priv == NULL)
             return;
-
-        glamor_pixmap_destroy_fbo(old_priv);
+        glamor_pixmap_destroy_fbo(glamor_get_screen_private(pixmap->drawable.pScreen),
+                                  old_priv);
         free(old_priv);
     }
 
diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
index 3b6b2ed..4459fce 100644
--- a/glamor/glamor_compositerects.c
+++ b/glamor/glamor_compositerects.c
@@ -254,7 +254,7 @@ glamor_composite_rectangles(CARD8 op,
                 goto done;
             if (glamor_composite_clipped_region(op, source,
                                                 NULL, dst,
-                                                NULL, NULL, priv,
+                                                NULL, NULL, pixmap,
                                                 &region, 0, 0, 0, 0, 0, 0))
                 goto done;
         }
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 941eaee..cf5216d 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -112,9 +112,10 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 }
 
 static void
-glamor_purge_fbo(glamor_pixmap_fbo *fbo)
+glamor_purge_fbo(glamor_screen_private *glamor_priv,
+                 glamor_pixmap_fbo *fbo)
 {
-    glamor_make_current(fbo->glamor_priv);
+    glamor_make_current(glamor_priv);
 
     if (fbo->fb)
         glDeleteFramebuffers(1, &fbo->fb);
@@ -127,7 +128,8 @@ glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 }
 
 static void
-glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
+glamor_pixmap_fbo_cache_put(glamor_screen_private *glamor_priv,
+                            glamor_pixmap_fbo *fbo)
 {
     struct xorg_list *cache;
     int n_format;
@@ -139,32 +141,33 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
     n_format = cache_format(fbo->format);
 
     if (fbo->fb == 0 || fbo->external || n_format == -1
-        || fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
-        fbo->glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX;
-        glamor_fbo_expire(fbo->glamor_priv);
-        glamor_purge_fbo(fbo);
+        || glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
+        glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX;
+        glamor_fbo_expire(glamor_priv);
+        glamor_purge_fbo(glamor_priv, fbo);
         return;
     }
 
-    cache = &fbo->glamor_priv->fbo_cache[n_format]
+    cache = &glamor_priv->fbo_cache[n_format]
         [cache_wbucket(fbo->width)]
         [cache_hbucket(fbo->height)];
     DEBUGF
         ("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n",
          fbo, cache, fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
 
-    fbo->glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
+    glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
     xorg_list_add(&fbo->list, cache);
-    fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
+    fbo->expire = glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
 #endif
 }
 
 static int
-glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
+glamor_pixmap_ensure_fb(glamor_screen_private *glamor_priv,
+                        glamor_pixmap_fbo *fbo)
 {
     int status, err = 0;
 
-    glamor_make_current(fbo->glamor_priv);
+    glamor_make_current(glamor_priv);
 
     if (fbo->fb == 0)
         glGenFramebuffers(1, &fbo->fb);
@@ -224,11 +227,10 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
     fbo->height = h;
     fbo->external = FALSE;
     fbo->format = format;
-    fbo->glamor_priv = glamor_priv;
 
     if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
-        if (glamor_pixmap_ensure_fb(fbo) != 0) {
-            glamor_purge_fbo(fbo);
+        if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) {
+            glamor_purge_fbo(glamor_priv, fbo);
             fbo = NULL;
         }
     }
@@ -258,7 +260,7 @@ glamor_fbo_expire(glamor_screen_private *glamor_priv)
                     xorg_list_del(&fbo_entry->list);
                     DEBUGF("cache %p fbo %p expired %d current %d \n", cache,
                            fbo_entry, fbo_entry->expire, glamor_priv->tick);
-                    glamor_purge_fbo(fbo_entry);
+                    glamor_purge_fbo(glamor_priv, fbo_entry);
                 }
             }
 
@@ -295,16 +297,17 @@ glamor_fini_pixmap_fbo(ScreenPtr screen)
                 xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache,
                                                       list) {
                     xorg_list_del(&fbo_entry->list);
-                    glamor_purge_fbo(fbo_entry);
+                    glamor_purge_fbo(glamor_priv, fbo_entry);
                 }
             }
 }
 
 void
-glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
+glamor_destroy_fbo(glamor_screen_private *glamor_priv,
+                   glamor_pixmap_fbo *fbo)
 {
     xorg_list_del(&fbo->list);
-    glamor_pixmap_fbo_cache_put(fbo);
+    glamor_pixmap_fbo_cache_put(glamor_priv, fbo);
 
 }
 
@@ -420,7 +423,7 @@ _glamor_create_fbo_array(glamor_screen_private *glamor_priv,
  cleanup:
     for (i = 0; i < block_wcnt * block_hcnt; i++)
         if ((fbo_array)[i])
-            glamor_destroy_fbo((fbo_array)[i]);
+            glamor_destroy_fbo(glamor_priv, (fbo_array)[i]);
     free(box_array);
     free(fbo_array);
     return NULL;
@@ -488,7 +491,8 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
 }
 
 void
-glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv)
+glamor_pixmap_destroy_fbo(glamor_screen_private *glamor_priv,
+                          glamor_pixmap_private *priv)
 {
     glamor_pixmap_fbo *fbo;
 
@@ -497,13 +501,13 @@ glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv)
         glamor_pixmap_private_large_t *large = &priv->large;
 
         for (i = 0; i < large->block_wcnt * large->block_hcnt; i++)
-            glamor_destroy_fbo(large->fbo_array[i]);
+            glamor_destroy_fbo(glamor_priv, large->fbo_array[i]);
         free(large->fbo_array);
     }
     else {
         fbo = glamor_pixmap_detach_fbo(priv);
         if (fbo)
-            glamor_destroy_fbo(fbo);
+            glamor_destroy_fbo(glamor_priv, fbo);
     }
 }
 
@@ -533,7 +537,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
                                    pixmap->drawable.height, format);
 
         if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->base.fbo->fb == 0)
-            if (glamor_pixmap_ensure_fb(pixmap_priv->base.fbo) != 0)
+            if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->base.fbo) != 0)
                 return FALSE;
     }
 
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 2b9f7f3..232b402 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -682,9 +682,9 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
         return 0;
     }
 
-    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+    glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
 
-    pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale);
+    pixmap_priv_get_dest_scale(pixmap, pixmap_priv, xscale, yscale);
 
     DEBUGF("xscale = %f, yscale = %f,"
            " x_source = %d, y_source = %d, width = %d, height = %d\n",
diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index 9b24584..2c91c27 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -150,12 +150,13 @@ __glamor_compute_clipped_regions(int block_w,
  */
 
 glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
+glamor_compute_clipped_regions_ext(PixmapPtr pixmap,
                                    RegionPtr region,
                                    int *n_region,
                                    int inner_block_w, int inner_block_h,
                                    int reverse, int upsidedown)
 {
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     glamor_pixmap_clipped_regions *clipped_regions, *inner_regions,
         *result_regions;
     int i, j, x, y, k, inner_n_regions;
@@ -176,8 +177,8 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
         clipped_regions[0].block_idx = 0;
         RegionCopy(clipped_regions[0].region, region);
         *n_region = 1;
-        block_w = pixmap_priv->base.pixmap->drawable.width;
-        block_h = pixmap_priv->base.pixmap->drawable.height;
+        block_w = pixmap->drawable.width;
+        block_h = pixmap->drawable.height;
         box_array = &small_box;
         small_box.x1 = small_box.y1 = 0;
         small_box.x2 = block_w;
@@ -190,10 +191,8 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
                                                            priv->block_h,
                                                            priv->block_wcnt,
                                                            0, 0,
-                                                           priv->base.pixmap->
-                                                           drawable.width,
-                                                           priv->base.pixmap->
-                                                           drawable.height,
+                                                           pixmap->drawable.width,
+                                                           pixmap->drawable.height,
                                                            region, n_region,
                                                            reverse, upsidedown);
 
@@ -336,7 +335,8 @@ _glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh)
  *
  */
 static glamor_pixmap_clipped_regions *
-_glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
+_glamor_compute_clipped_regions(PixmapPtr pixmap,
+                                glamor_pixmap_private *pixmap_priv,
                                 RegionPtr region, int *n_region,
                                 int repeat_type, int is_transform,
                                 int reverse, int upsidedown)
@@ -366,8 +366,8 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 
     priv = __glamor_large(pixmap_priv);
 
-    pixmap_width = priv->base.pixmap->drawable.width;
-    pixmap_height = priv->base.pixmap->drawable.height;
+    pixmap_width = pixmap->drawable.width;
+    pixmap_height = pixmap->drawable.height;
     if (repeat_type == 0 || repeat_type == RepeatPad) {
         RegionPtr saved_region = NULL;
 
@@ -385,10 +385,8 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
                                                            priv->block_h,
                                                            priv->block_wcnt,
                                                            0, 0,
-                                                           priv->base.pixmap->
-                                                           drawable.width,
-                                                           priv->base.pixmap->
-                                                           drawable.height,
+                                                           pixmap->drawable.width,
+                                                           pixmap->drawable.height,
                                                            region, n_region,
                                                            reverse, upsidedown);
         if (saved_region)
@@ -670,11 +668,13 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 }
 
 glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region,
+glamor_compute_clipped_regions(PixmapPtr pixmap,
+                               RegionPtr region,
                                int *n_region, int repeat_type,
                                int reverse, int upsidedown)
 {
-    return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type,
+    glamor_pixmap_private       *priv = glamor_get_pixmap_private(pixmap);
+    return _glamor_compute_clipped_regions(pixmap, priv, region, n_region, repeat_type,
                                            0, reverse, upsidedown);
 }
 
@@ -682,12 +682,13 @@ glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region,
  * by default. Or just use region32 for repeat cases?
  **/
 glamor_pixmap_clipped_regions *
-glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
+glamor_compute_transform_clipped_regions(PixmapPtr pixmap,
                                          struct pixman_transform *transform,
                                          RegionPtr region, int *n_region,
                                          int dx, int dy, int repeat_type,
                                          int reverse, int upsidedown)
 {
+    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
     BoxPtr temp_extent;
     struct pixman_box32 temp_box;
     struct pixman_box16 short_box;
@@ -714,8 +715,8 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
             temp_box.x1 = 0;
         if (temp_box.y1 < 0)
             temp_box.y1 = 0;
-        temp_box.x2 = MIN(temp_box.x2, priv->base.pixmap->drawable.width);
-        temp_box.y2 = MIN(temp_box.y2, priv->base.pixmap->drawable.height);
+        temp_box.x2 = MIN(temp_box.x2, pixmap->drawable.width);
+        temp_box.y2 = MIN(temp_box.y2, pixmap->drawable.height);
     }
     /* Now copy back the box32 to a box16 box. */
     short_box.x1 = temp_box.x1;
@@ -725,7 +726,8 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
     RegionInitBoxes(temp_region, &short_box, 1);
     DEBUGF("copy to temp source region \n");
     DEBUGRegionPrint(temp_region);
-    ret = _glamor_compute_clipped_regions(priv,
+    ret = _glamor_compute_clipped_regions(pixmap,
+                                          priv,
                                           temp_region,
                                           n_region,
                                           repeat_type, 1, reverse, upsidedown);
@@ -747,7 +749,8 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
  * if the clipped result cross the region boundary.
  */
 static void
-glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
+glamor_merge_clipped_regions(PixmapPtr pixmap,
+                             glamor_pixmap_private *pixmap_priv,
                              int repeat_type,
                              glamor_pixmap_clipped_regions *clipped_regions,
                              int *n_regions, int *need_clean_fbo)
@@ -763,8 +766,8 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
     glamor_pixmap_private_large_t *priv;
 
     priv = __glamor_large(pixmap_priv);
-    pixmap_width = priv->base.pixmap->drawable.width;
-    pixmap_height = priv->base.pixmap->drawable.height;
+    pixmap_width = pixmap->drawable.width;
+    pixmap_height =pixmap->drawable.height;
 
     temp_region = RegionCreate(NULL, 4);
     for (i = 0; i < *n_regions; i++) {
@@ -784,10 +787,10 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
     DEBUGF("%d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2,
            temp_box.y2);
     temp_pixmap =
-        glamor_create_pixmap(priv->base.pixmap->drawable.pScreen,
+        glamor_create_pixmap(pixmap->drawable.pScreen,
                              temp_box.x2 - temp_box.x1,
                              temp_box.y2 - temp_box.y1,
-                             priv->base.pixmap->drawable.depth,
+                             pixmap->drawable.depth,
                              GLAMOR_CREATE_PIXMAP_FIXUP);
     if (temp_pixmap == NULL) {
         assert(0);
@@ -808,7 +811,7 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
         copy_box.y2 = temp_extent->y2 - temp_extent->y1;
         dx = temp_extent->x1;
         dy = temp_extent->y1;
-        glamor_copy(&priv->base.pixmap->drawable,
+        glamor_copy(&pixmap->drawable,
                     &temp_pixmap->drawable,
                     NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
 //              glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
@@ -840,7 +843,7 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
                        copy_box.x1, copy_box.y1, copy_box.x2,
                        copy_box.y2, dx, dy);
 
-                glamor_copy(&priv->base.pixmap->drawable,
+                glamor_copy(&pixmap->drawable,
                             &temp_pixmap->drawable,
                             NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
 
@@ -966,7 +969,8 @@ glamor_get_transform_extent_from_box(struct pixman_box32 *box,
 }
 
 static void
-_glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
+_glamor_process_transformed_clipped_region(PixmapPtr pixmap,
+                                           glamor_pixmap_private *priv,
                                            int repeat_type,
                                            glamor_pixmap_clipped_regions *
                                            clipped_regions, int *n_regions,
@@ -976,7 +980,7 @@ _glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
 
     if (*n_regions != 1) {
         /* Merge all source regions into one region. */
-        glamor_merge_clipped_regions(priv, repeat_type,
+        glamor_merge_clipped_regions(pixmap, priv, repeat_type,
                                      clipped_regions, n_regions,
                                      need_clean_fbo);
     }
@@ -990,22 +994,22 @@ _glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
             int rem;
 
             temp_box = RegionExtents(clipped_regions[0].region);
-            modulus(temp_box->x1, priv->base.pixmap->drawable.width, rem);
-            shift_x = (temp_box->x1 - rem) / priv->base.pixmap->drawable.width;
-            modulus(temp_box->y1, priv->base.pixmap->drawable.height, rem);
-            shift_y = (temp_box->y1 - rem) / priv->base.pixmap->drawable.height;
+            modulus(temp_box->x1, pixmap->drawable.width, rem);
+            shift_x = (temp_box->x1 - rem) / pixmap->drawable.width;
+            modulus(temp_box->y1, pixmap->drawable.height, rem);
+            shift_y = (temp_box->y1 - rem) / pixmap->drawable.height;
 
             if (shift_x != 0) {
                 __glamor_large(priv)->box.x1 +=
-                    shift_x * priv->base.pixmap->drawable.width;
+                    shift_x * pixmap->drawable.width;
                 __glamor_large(priv)->box.x2 +=
-                    shift_x * priv->base.pixmap->drawable.width;
+                    shift_x * pixmap->drawable.width;
             }
             if (shift_y != 0) {
                 __glamor_large(priv)->box.y1 +=
-                    shift_y * priv->base.pixmap->drawable.height;
+                    shift_y * pixmap->drawable.height;
                 __glamor_large(priv)->box.y2 +=
-                    shift_y * priv->base.pixmap->drawable.height;
+                    shift_y * pixmap->drawable.height;
             }
         }
     }
@@ -1016,9 +1020,9 @@ glamor_composite_largepixmap_region(CARD8 op,
                                     PicturePtr source,
                                     PicturePtr mask,
                                     PicturePtr dest,
-                                    glamor_pixmap_private *source_pixmap_priv,
-                                    glamor_pixmap_private *mask_pixmap_priv,
-                                    glamor_pixmap_private *dest_pixmap_priv,
+                                    PixmapPtr source_pixmap,
+                                    PixmapPtr mask_pixmap,
+                                    PixmapPtr dest_pixmap,
                                     RegionPtr region, Bool force_clip,
                                     INT16 x_source,
                                     INT16 y_source,
@@ -1027,6 +1031,11 @@ glamor_composite_largepixmap_region(CARD8 op,
                                     INT16 x_dest, INT16 y_dest,
                                     CARD16 width, CARD16 height)
 {
+    ScreenPtr screen = dest_pixmap->drawable.pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_pixmap_private *source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+    glamor_pixmap_private *mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+    glamor_pixmap_private *dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
     glamor_pixmap_clipped_regions *clipped_dest_regions;
     glamor_pixmap_clipped_regions *clipped_source_regions;
     glamor_pixmap_clipped_regions *clipped_mask_regions;
@@ -1060,8 +1069,8 @@ glamor_composite_largepixmap_region(CARD8 op,
         dest_block_width = __glamor_large(dest_pixmap_priv)->block_w;
         dest_block_height = __glamor_large(dest_pixmap_priv)->block_h;
     } else {
-        dest_block_width = dest_pixmap_priv->base.pixmap->drawable.width;
-        dest_block_height = dest_pixmap_priv->base.pixmap->drawable.height;
+        dest_block_width = dest_pixmap->drawable.width;
+        dest_block_height = dest_pixmap->drawable.height;
     }
     fixed_block_width = dest_block_width;
     fixed_block_height = dest_block_height;
@@ -1134,12 +1143,12 @@ glamor_composite_largepixmap_region(CARD8 op,
     if (force_clip || fixed_block_width < dest_block_width
         || fixed_block_height < dest_block_height)
         clipped_dest_regions =
-            glamor_compute_clipped_regions_ext(dest_pixmap_priv, region,
+            glamor_compute_clipped_regions_ext(dest_pixmap, region,
                                                &n_dest_regions,
                                                fixed_block_width,
                                                fixed_block_height, 0, 0);
     else
-        clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap_priv,
+        clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap,
                                                               region,
                                                               &n_dest_regions,
                                                               0, 0, 0);
@@ -1168,7 +1177,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                 RegionTranslate(clipped_dest_regions[i].region,
                                 x_source - x_dest, y_source - y_dest);
                 clipped_source_regions =
-                    glamor_compute_clipped_regions(source_pixmap_priv,
+                    glamor_compute_clipped_regions(source_pixmap,
                                                    clipped_dest_regions[i].
                                                    region, &n_source_regions,
                                                    source_repeat_type, 0, 0);
@@ -1176,7 +1185,7 @@ glamor_composite_largepixmap_region(CARD8 op,
             }
             else {
                 clipped_source_regions =
-                    glamor_compute_transform_clipped_regions(source_pixmap_priv,
+                    glamor_compute_transform_clipped_regions(source_pixmap,
                                                              source->transform,
                                                              clipped_dest_regions
                                                              [i].region,
@@ -1193,7 +1202,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                 }
                 else
                     _glamor_process_transformed_clipped_region
-                        (source_pixmap_priv, source_repeat_type,
+                        (source_pixmap, source_pixmap_priv, source_repeat_type,
                          clipped_source_regions, &n_source_regions,
                          &need_clean_source_fbo);
             }
@@ -1214,7 +1223,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                         RegionTranslate(clipped_source_regions[j].region,
                                         -x_source + x_mask, -y_source + y_mask);
                         clipped_mask_regions =
-                            glamor_compute_clipped_regions(mask_pixmap_priv,
+                            glamor_compute_clipped_regions(mask_pixmap,
                                                            clipped_source_regions
                                                            [j].region,
                                                            &n_mask_regions,
@@ -1230,7 +1239,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                         RegionTranslate(clipped_dest_regions[i].region,
                                         -x_dest + x_mask, -y_dest + y_mask);
                         clipped_mask_regions =
-                            glamor_compute_clipped_regions(mask_pixmap_priv,
+                            glamor_compute_clipped_regions(mask_pixmap,
                                                            clipped_dest_regions
                                                            [i].region,
                                                            &n_mask_regions,
@@ -1244,14 +1253,14 @@ glamor_composite_largepixmap_region(CARD8 op,
                         if (!is_normal_source_fbo)
                             clipped_mask_regions =
                                 glamor_compute_transform_clipped_regions
-                                (mask_pixmap_priv, mask->transform,
+                                (mask_pixmap, mask->transform,
                                  clipped_dest_regions[i].region,
                                  &n_mask_regions, x_mask - x_dest,
                                  y_mask - y_dest, mask_repeat_type, 0, 0);
                         else
                             clipped_mask_regions =
                                 glamor_compute_transform_clipped_regions
-                                (mask_pixmap_priv, mask->transform,
+                                (mask_pixmap, mask->transform,
                                  clipped_source_regions[j].region,
                                  &n_mask_regions, x_mask - x_source,
                                  y_mask - y_source, mask_repeat_type, 0, 0);
@@ -1263,7 +1272,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                         }
                         else
                             _glamor_process_transformed_clipped_region
-                                (mask_pixmap_priv, mask_repeat_type,
+                                (mask_pixmap, mask_pixmap_priv, mask_repeat_type,
                                  clipped_mask_regions, &n_mask_regions,
                                  &need_clean_mask_fbo);
                     }
@@ -1273,9 +1282,9 @@ glamor_composite_largepixmap_region(CARD8 op,
 	if (!glamor_composite_clipped_region(op,		\
 			 null_source ? NULL : source,		\
 			 null_mask ? NULL : mask, dest,		\
-			 null_source ? NULL : source_pixmap_priv, \
-			 null_mask ? NULL : mask_pixmap_priv, 	\
-			 dest_pixmap_priv, region,		\
+			 null_source ? NULL : source_pixmap,    \
+			 null_mask ? NULL : mask_pixmap, 	\
+			 dest_pixmap, region,		        \
 			 x_source, y_source, x_mask, y_mask,	\
 			 x_dest, y_dest)) {			\
 		assert(0);					\
@@ -1326,7 +1335,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                         null_mask = 0;
                     if (need_clean_mask_fbo) {
                         assert(is_normal_mask_fbo == 0);
-                        glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
+                        glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->base.fbo);
                         mask_pixmap_priv->base.fbo = NULL;
                         need_clean_mask_fbo = 0;
                     }
@@ -1355,7 +1364,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                 null_source = 0;
             if (need_clean_source_fbo) {
                 assert(is_normal_source_fbo == 0);
-                glamor_destroy_fbo(source_pixmap_priv->base.fbo);
+                glamor_destroy_fbo(glamor_priv, source_pixmap_priv->base.fbo);
                 source_pixmap_priv->base.fbo = NULL;
                 need_clean_source_fbo = 0;
             }
@@ -1367,7 +1376,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                     RegionTranslate(clipped_dest_regions[i].region,
                                     x_mask - x_dest, y_mask - y_dest);
                     clipped_mask_regions =
-                        glamor_compute_clipped_regions(mask_pixmap_priv,
+                        glamor_compute_clipped_regions(mask_pixmap,
                                                        clipped_dest_regions[i].
                                                        region, &n_mask_regions,
                                                        mask_repeat_type, 0, 0);
@@ -1376,7 +1385,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                 else {
                     clipped_mask_regions =
                         glamor_compute_transform_clipped_regions
-                        (mask_pixmap_priv, mask->transform,
+                        (mask_pixmap, mask->transform,
                          clipped_dest_regions[i].region, &n_mask_regions,
                          x_mask - x_dest, y_mask - y_dest, mask_repeat_type, 0,
                          0);
@@ -1388,7 +1397,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                     }
                     else
                         _glamor_process_transformed_clipped_region
-                            (mask_pixmap_priv, mask_repeat_type,
+                            (mask_pixmap, mask_pixmap_priv, mask_repeat_type,
                              clipped_mask_regions, &n_mask_regions,
                              &need_clean_mask_fbo);
                 }
@@ -1417,7 +1426,7 @@ glamor_composite_largepixmap_region(CARD8 op,
                 if (null_mask)
                     null_mask = 0;
                 if (need_clean_mask_fbo) {
-                    glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
+                    glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->base.fbo);
                     mask_pixmap_priv->base.fbo = NULL;
                     need_clean_mask_fbo = 0;
                 }
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index f5021b2..7935bf2 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -63,31 +63,36 @@ glamor_pixmap_fini(ScreenPtr screen)
 }
 
 void
-glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *fbo, int x0, int y0,
+glamor_set_destination_pixmap_fbo(glamor_screen_private *glamor_priv,
+                                  glamor_pixmap_fbo *fbo, int x0, int y0,
                                   int width, int height)
 {
-    glamor_make_current(fbo->glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
     glViewport(x0, y0, width, height);
 }
 
 void
-glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
+glamor_set_destination_pixmap_priv_nc(glamor_screen_private *glamor_priv,
+                                      PixmapPtr pixmap,
+                                      glamor_pixmap_private *pixmap_priv)
 {
     int w, h;
 
-    PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h);
-    glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0, w, h);
+    PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, pixmap_priv, w, h);
+    glamor_set_destination_pixmap_fbo(glamor_priv, pixmap_priv->base.fbo, 0, 0, w, h);
 }
 
 int
-glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv)
+glamor_set_destination_pixmap_priv(glamor_screen_private *glamor_priv,
+                                   PixmapPtr pixmap,
+                                   glamor_pixmap_private *pixmap_priv)
 {
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
         return -1;
 
-    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+    glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
     return 0;
 }
 
@@ -96,8 +101,10 @@ glamor_set_destination_pixmap(PixmapPtr pixmap)
 {
     int err;
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    err = glamor_set_destination_pixmap_priv(pixmap_priv);
+    err = glamor_set_destination_pixmap_priv(glamor_priv, pixmap, pixmap_priv);
     return err;
 }
 
@@ -810,7 +817,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
     } else {
         ptexcoords = texcoords_inv;
 
-        pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
+        pixmap_priv_get_dest_scale(pixmap, pixmap_priv, &dst_xscale, &dst_yscale);
         glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
                                      dst_yscale,
                                      x, y,
@@ -825,7 +832,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
                               GL_FALSE, 2 * sizeof(float), ptexcoords);
         glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-        glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+        glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
         __glamor_upload_pixmap_to_texture(pixmap, &tex,
                                           format, type, 0, 0, w, h, bits, pbo);
         glActiveTexture(GL_TEXTURE0);
@@ -874,7 +881,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
         && (pixmap_priv->base.fbo->width < pixmap->drawable.width
             || pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
         fbo = glamor_pixmap_detach_fbo(pixmap_priv);
-        glamor_destroy_fbo(fbo);
+        glamor_destroy_fbo(glamor_priv, fbo);
     }
 
     if (pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb)
@@ -927,6 +934,8 @@ Bool
 glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
                                     int h, int stride, void *bits, int pbo)
 {
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     GLenum format, type;
     int no_alpha, revert, swap_rb;
     glamor_pixmap_private *pixmap_priv;
@@ -944,8 +953,8 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
         return FALSE;
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
-    force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
-        && !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
+    force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
+        && !glamor_check_fbo_size(glamor_priv, w, h);
 
     if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
         RegionRec region;
@@ -965,11 +974,11 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
         RegionInitBoxes(&region, &box, 1);
         if (!force_clip)
             clipped_regions =
-                glamor_compute_clipped_regions(pixmap_priv, &region, &n_region,
+                glamor_compute_clipped_regions(pixmap, &region, &n_region,
                                                0, 0, 0);
         else
             clipped_regions =
-                glamor_compute_clipped_regions_ext(pixmap_priv, &region,
+                glamor_compute_clipped_regions_ext(pixmap, &region,
                                                    &n_region,
                                                    pixmap_priv->large.block_w,
                                                    pixmap_priv->large.block_h,
@@ -1121,7 +1130,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
-    glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
+    glamor_set_destination_pixmap_fbo(glamor_priv, temp_fbo, 0, 0, w, h);
     glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
     glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
     glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 1df96d6..c5c6bb3 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -72,7 +72,7 @@ typedef struct glamor_composite_shader {
     union {
         float source_solid_color[4];
         struct {
-            struct glamor_pixmap_private *source_priv;
+            PixmapPtr source_pixmap;
             PicturePtr source;
         };
     };
@@ -80,7 +80,7 @@ typedef struct glamor_composite_shader {
     union {
         float mask_solid_color[4];
         struct {
-            struct glamor_pixmap_private *mask_priv;
+            PixmapPtr mask_pixmap;
             PicturePtr mask;
         };
     };
@@ -369,7 +369,6 @@ typedef struct glamor_pixmap_fbo {
     Bool external;
     GLenum format;
     GLenum type;
-    glamor_screen_private *glamor_priv;
 } glamor_pixmap_fbo;
 
 /*
@@ -449,10 +448,8 @@ typedef struct glamor_pixmap_private_base {
     unsigned char is_picture:1;
     unsigned char gl_tex:1;
     glamor_pixmap_fbo *fbo;
-    PixmapPtr pixmap;
     BoxRec box;
     int drm_stride;
-    glamor_screen_private *glamor_priv;
     PicturePtr picture;
     GLuint pbo;
     RegionRec prepare_region;
@@ -610,6 +607,9 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
 {
     glamor_pixmap_private *priv;
 
+    if (pixmap == NULL)
+        return NULL;
+
     priv = dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
     if (!priv) {
         glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
@@ -619,6 +619,50 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
     return priv;
 }
 
+/*
+ * Returns TRUE if pixmap has no image object
+ */
+static inline Bool
+glamor_pixmap_drm_only(PixmapPtr pixmap)
+{
+    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+    return priv && priv->base.type == GLAMOR_DRM_ONLY;
+}
+
+/*
+ * Returns TRUE if pixmap is plain memory (not a GL object at all)
+ */
+static inline Bool
+glamor_pixmap_is_memory(PixmapPtr pixmap)
+{
+    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+    return !priv || priv->base.type == GLAMOR_TEXTURE_LARGE;
+}
+
+/*
+ * Returns TRUE if pixmap requires multiple textures to hold it
+ */
+static inline Bool
+glamor_pixmap_is_large(PixmapPtr pixmap)
+{
+    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+    return priv && priv->base.type == GLAMOR_TEXTURE_LARGE;
+}
+
+/*
+ * Returns TRUE if pixmap has an FBO
+ */
+static inline Bool
+glamor_pixmap_has_fbo(PixmapPtr pixmap)
+{
+    glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+    return priv && priv->base.gl_fbo == GLAMOR_FBO_NORMAL;
+}
+
 void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
 
 static inline glamor_gc_private *
@@ -652,9 +696,10 @@ glamor_pixmap_fbo *glamor_create_fbo_from_tex(glamor_screen_private *
                                               int flag);
 glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private *glamor_priv, int w,
                                      int h, GLenum format, int flag);
-void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
-void glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv);
-
+void glamor_destroy_fbo(glamor_screen_private *glamor_priv,
+                        glamor_pixmap_fbo *fbo);
+void glamor_pixmap_destroy_fbo(glamor_screen_private *glamor_priv,
+                               glamor_pixmap_private *priv);
 void glamor_init_pixmap_fbo(ScreenPtr screen);
 void glamor_fini_pixmap_fbo(ScreenPtr screen);
 Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
@@ -679,13 +724,13 @@ void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
                                     unsigned long fg_pixel, GLfloat *color);
 
 int glamor_set_destination_pixmap(PixmapPtr pixmap);
-int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv);
-void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int);
+int glamor_set_destination_pixmap_priv(glamor_screen_private *glamor_priv, PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv);
+void glamor_set_destination_pixmap_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *, int, int, int, int);
 
 /* nc means no check. caller must ensure this pixmap has valid fbo.
  * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly.
  * */
-void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv);
+void glamor_set_destination_pixmap_priv_nc(glamor_screen_private *glamor_priv, PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv);
 
 glamor_pixmap_fbo *glamor_es2_pixmap_read_prepare(PixmapPtr source, int x,
                                                   int y, int w, int h,
@@ -716,9 +761,9 @@ Bool glamor_composite_clipped_region(CARD8 op,
                                      PicturePtr source,
                                      PicturePtr mask,
                                      PicturePtr dest,
-                                     glamor_pixmap_private *soruce_pixmap_priv,
-                                     glamor_pixmap_private *mask_pixmap_priv,
-                                     glamor_pixmap_private *dest_pixmap_priv,
+                                     PixmapPtr source_pixmap,
+                                     PixmapPtr mask_pixmap,
+                                     PixmapPtr dest_pixmap,
                                      RegionPtr region,
                                      int x_source,
                                      int y_source,
@@ -749,23 +794,6 @@ PicturePtr glamor_convert_gradient_picture(ScreenPtr screen,
                                            int x_source,
                                            int y_source, int width, int height);
 
-Bool glamor_composite_choose_shader(CARD8 op,
-                                    PicturePtr source,
-                                    PicturePtr mask,
-                                    PicturePtr dest,
-                                    glamor_pixmap_private *source_pixmap_priv,
-                                    glamor_pixmap_private *mask_pixmap_priv,
-                                    glamor_pixmap_private *dest_pixmap_priv,
-                                    struct shader_key *s_key,
-                                    glamor_composite_shader ** shader,
-                                    struct blendinfo *op_info,
-                                    PictFormatShort *psaved_source_format);
-
-void glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
-                                       struct shader_key *key,
-                                       glamor_composite_shader *shader,
-                                       struct blendinfo *op_info);
-
 void *glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
 
 /* glamor_trapezoid.c */
@@ -832,19 +860,19 @@ Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
                                          int pbo);
 
 glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions(glamor_pixmap_private *priv,
+glamor_compute_clipped_regions(PixmapPtr pixmap,
                                RegionPtr region, int *clipped_nbox,
                                int repeat_type, int reverse,
                                int upsidedown);
 
 glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
+glamor_compute_clipped_regions_ext(PixmapPtr pixmap,
                                    RegionPtr region, int *n_region,
                                    int inner_block_w, int inner_block_h,
                                    int reverse, int upsidedown);
 
 glamor_pixmap_clipped_regions *
-glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
+glamor_compute_transform_clipped_regions(PixmapPtr pixmap,
                                          struct pixman_transform *transform,
                                          RegionPtr region,
                                          int *n_region, int dx, int dy,
@@ -855,9 +883,9 @@ Bool glamor_composite_largepixmap_region(CARD8 op,
                                          PicturePtr source,
                                          PicturePtr mask,
                                          PicturePtr dest,
-                                         glamor_pixmap_private *source_pixmap_priv,
-                                         glamor_pixmap_private *mask_pixmap_priv,
-                                         glamor_pixmap_private *dest_pixmap_priv,
+                                         PixmapPtr source_pixmap,
+                                         PixmapPtr mask_pixmap,
+                                         PixmapPtr dest_pixmap,
                                          RegionPtr region, Bool force_clip,
                                          INT16 x_source,
                                          INT16 y_source,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 1d60622..3ef9a15 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -482,9 +482,10 @@ glamor_set_composite_op(ScreenPtr screen,
 static void
 glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
                              PicturePtr picture,
-                             glamor_pixmap_private *pixmap_priv,
+                             PixmapPtr pixmap,
                              GLuint wh_location, GLuint repeat_location)
 {
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     float wh[4];
     int repeat_type;
 
@@ -546,7 +547,7 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
             repeat_type += RepeatFix;
     }
     if (repeat_type >= RepeatFix) {
-        glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
+        glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, pixmap_priv);
         if ((wh[0] != 1.0 || wh[1] != 1.0)
             || (glamor_priv->gl_flavor == GLAMOR_GL_ES2
                 && repeat_type == RepeatFix))
@@ -786,7 +787,8 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
 }
 
 static void
-glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
+glamor_set_normalize_tcoords_generic(PixmapPtr pixmap,
+                                     glamor_pixmap_private *priv,
                                      int repeat_type,
                                      float *matrix,
                                      float xscale, float yscale,
@@ -804,24 +806,27 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
                                                      x2, y2,
                                                      texcoords, stride);
     else if (!matrix && repeat_type != RepeatNone)
-        glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,
+        glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type,
                                                 xscale, yscale,
                                                 x1, y1,
                                                 x2, y2,
                                                 texcoords, stride);
     else if (matrix && repeat_type != RepeatNone)
-        glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type,
+        glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, repeat_type,
                                                             matrix, xscale,
                                                             yscale, x1, y1, x2,
                                                             y2,
                                                             texcoords, stride);
 }
 
-Bool
+static Bool
 glamor_composite_choose_shader(CARD8 op,
                                PicturePtr source,
                                PicturePtr mask,
                                PicturePtr dest,
+                               PixmapPtr source_pixmap,
+                               PixmapPtr mask_pixmap,
+                               PixmapPtr dest_pixmap,
                                glamor_pixmap_private *source_pixmap_priv,
                                glamor_pixmap_private *mask_pixmap_priv,
                                glamor_pixmap_private *dest_pixmap_priv,
@@ -831,9 +836,6 @@ glamor_composite_choose_shader(CARD8 op,
                                PictFormatShort *psaved_source_format)
 {
     ScreenPtr screen = dest->pDrawable->pScreen;
-    PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
-    PixmapPtr source_pixmap = NULL;
-    PixmapPtr mask_pixmap = NULL;
     enum glamor_pixmap_status source_status = GLAMOR_NONE;
     enum glamor_pixmap_status mask_status = GLAMOR_NONE;
     PictFormatShort saved_source_format = 0;
@@ -926,7 +928,6 @@ glamor_composite_choose_shader(CARD8 op,
 
     if (key.source == SHADER_SOURCE_TEXTURE ||
         key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
-        source_pixmap = source_pixmap_priv->base.pixmap;
         if (source_pixmap == dest_pixmap) {
             /* XXX source and the dest share the same texture.
              * Does it need special handle? */
@@ -944,7 +945,6 @@ glamor_composite_choose_shader(CARD8 op,
 
     if (key.mask == SHADER_MASK_TEXTURE ||
         key.mask == SHADER_MASK_TEXTURE_ALPHA) {
-        mask_pixmap = mask_pixmap_priv->base.pixmap;
         if (mask_pixmap == dest_pixmap) {
             glamor_fallback("mask == dest\n");
             goto fail;
@@ -1052,7 +1052,7 @@ glamor_composite_choose_shader(CARD8 op,
         memcpy(&(*shader)->source_solid_color[0],
                source_solid_color, 4 * sizeof(float));
     else {
-        (*shader)->source_priv = source_pixmap_priv;
+        (*shader)->source_pixmap = source_pixmap;
         (*shader)->source = source;
     }
 
@@ -1060,7 +1060,7 @@ glamor_composite_choose_shader(CARD8 op,
         memcpy(&(*shader)->mask_solid_color[0],
                mask_solid_color, 4 * sizeof(float));
     else {
-        (*shader)->mask_priv = mask_pixmap_priv;
+        (*shader)->mask_pixmap = mask_pixmap;
         (*shader)->mask = mask;
     }
 
@@ -1076,16 +1076,13 @@ glamor_composite_choose_shader(CARD8 op,
     return ret;
 }
 
-void
-glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
+static void
+glamor_composite_set_shader_blend(glamor_screen_private *glamor_priv,
+                                  glamor_pixmap_private *dest_priv,
                                   struct shader_key *key,
                                   glamor_composite_shader *shader,
                                   struct blendinfo *op_info)
 {
-    glamor_screen_private *glamor_priv;
-
-    glamor_priv = dest_priv->base.glamor_priv;
-
     glamor_make_current(glamor_priv);
     glUseProgram(shader->prog);
 
@@ -1096,7 +1093,7 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
     else {
         glamor_set_composite_texture(glamor_priv, 0,
                                      shader->source,
-                                     shader->source_priv, shader->source_wh,
+                                     shader->source_pixmap, shader->source_wh,
                                      shader->source_repeat_mode);
     }
 
@@ -1108,7 +1105,7 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
         else {
             glamor_set_composite_texture(glamor_priv, 1,
                                          shader->mask,
-                                         shader->mask_priv, shader->mask_wh,
+                                         shader->mask_pixmap, shader->mask_wh,
                                          shader->mask_repeat_mode);
         }
     }
@@ -1127,6 +1124,9 @@ glamor_composite_with_shader(CARD8 op,
                              PicturePtr source,
                              PicturePtr mask,
                              PicturePtr dest,
+                             PixmapPtr source_pixmap,
+                             PixmapPtr mask_pixmap,
+                             PixmapPtr dest_pixmap,
                              glamor_pixmap_private *source_pixmap_priv,
                              glamor_pixmap_private *mask_pixmap_priv,
                              glamor_pixmap_private *dest_pixmap_priv,
@@ -1134,10 +1134,7 @@ glamor_composite_with_shader(CARD8 op,
                              Bool two_pass_ca)
 {
     ScreenPtr screen = dest->pDrawable->pScreen;
-    glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
-    PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
-    PixmapPtr source_pixmap = NULL;
-    PixmapPtr mask_pixmap = NULL;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     GLfloat dst_xscale, dst_yscale;
     GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
     struct shader_key key, key_ca;
@@ -1153,6 +1150,7 @@ glamor_composite_with_shader(CARD8 op,
     struct blendinfo op_info, op_info_ca;
 
     if (!glamor_composite_choose_shader(op, source, mask, dest,
+                                        source_pixmap, mask_pixmap, dest_pixmap,
                                         source_pixmap_priv, mask_pixmap_priv,
                                         dest_pixmap_priv,
                                         &key, &shader, &op_info,
@@ -1162,6 +1160,7 @@ glamor_composite_with_shader(CARD8 op,
     }
     if (two_pass_ca) {
         if (!glamor_composite_choose_shader(PictOpAdd, source, mask, dest,
+                                            source_pixmap, mask_pixmap, dest_pixmap,
                                             source_pixmap_priv,
                                             mask_pixmap_priv, dest_pixmap_priv,
                                             &key_ca, &shader_ca, &op_info_ca,
@@ -1171,8 +1170,8 @@ glamor_composite_with_shader(CARD8 op,
         }
     }
 
-    glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
-    glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
+    glamor_set_destination_pixmap_priv_nc(glamor_priv, dest_pixmap, dest_pixmap_priv);
+    glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv, &key, shader, &op_info);
 
     glamor_make_current(glamor_priv);
 
@@ -1184,10 +1183,9 @@ glamor_composite_with_shader(CARD8 op,
     dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
     glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
                                &dest_x_off, &dest_y_off);
-    pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
+    pixmap_priv_get_dest_scale(dest_pixmap, dest_pixmap_priv, &dst_xscale, &dst_yscale);
 
     if (glamor_priv->has_source_coords) {
-        source_pixmap = source_pixmap_priv->base.pixmap;
         glamor_get_drawable_deltas(source->pDrawable,
                                    source_pixmap, &source_x_off, &source_y_off);
         pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale);
@@ -1198,7 +1196,6 @@ glamor_composite_with_shader(CARD8 op,
     }
 
     if (glamor_priv->has_mask_coords) {
-        mask_pixmap = mask_pixmap_priv->base.pixmap;
         glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
                                    &mask_x_off, &mask_y_off);
         pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale);
@@ -1250,7 +1247,8 @@ glamor_composite_with_shader(CARD8 op,
                                              vb_stride);
             vertices += 2;
             if (key.source != SHADER_SOURCE_SOLID) {
-                glamor_set_normalize_tcoords_generic(source_pixmap_priv,
+                glamor_set_normalize_tcoords_generic(source_pixmap,
+                                                     source_pixmap_priv,
                                                      source->repeatType,
                                                      psrc_matrix, src_xscale,
                                                      src_yscale, x_source,
@@ -1261,7 +1259,8 @@ glamor_composite_with_shader(CARD8 op,
             }
 
             if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
-                glamor_set_normalize_tcoords_generic(mask_pixmap_priv,
+                glamor_set_normalize_tcoords_generic(mask_pixmap,
+                                                     mask_pixmap_priv,
                                                      mask->repeatType,
                                                      pmask_matrix, mask_xscale,
                                                      mask_yscale, x_mask,
@@ -1280,11 +1279,11 @@ glamor_composite_with_shader(CARD8 op,
         glamor_flush_composite_rects(screen);
         nrect -= rect_processed;
         if (two_pass_ca) {
-            glamor_composite_set_shader_blend(dest_pixmap_priv,
+            glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv,
                                               &key_ca, shader_ca, &op_info_ca);
             glamor_flush_composite_rects(screen);
             if (nrect)
-                glamor_composite_set_shader_blend(dest_pixmap_priv,
+                glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv,
                                                   &key, shader, &op_info);
         }
     }
@@ -1371,17 +1370,21 @@ glamor_composite_clipped_region(CARD8 op,
                                 PicturePtr source,
                                 PicturePtr mask,
                                 PicturePtr dest,
-                                glamor_pixmap_private *source_pixmap_priv,
-                                glamor_pixmap_private *mask_pixmap_priv,
-                                glamor_pixmap_private *dest_pixmap_priv,
+                                PixmapPtr source_pixmap,
+                                PixmapPtr mask_pixmap,
+                                PixmapPtr dest_pixmap,
                                 RegionPtr region,
                                 int x_source,
                                 int y_source,
                                 int x_mask, int y_mask, int x_dest, int y_dest)
 {
+    glamor_pixmap_private *source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+    glamor_pixmap_private *mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+    glamor_pixmap_private *dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
     ScreenPtr screen = dest->pDrawable->pScreen;
-    PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
     PicturePtr temp_src = source, temp_mask = mask;
+    PixmapPtr temp_src_pixmap = source_pixmap;
+    PixmapPtr temp_mask_pixmap = mask_pixmap;
     glamor_pixmap_private *temp_src_priv = source_pixmap_priv;
     glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv;
     int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
@@ -1411,12 +1414,6 @@ glamor_composite_clipped_region(CARD8 op,
     DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n",
            x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
 
-    if (source_pixmap_priv)
-        source_pixmap = source_pixmap_priv->base.pixmap;
-
-    if (mask_pixmap_priv)
-        mask_pixmap = mask_pixmap_priv->base.pixmap;
-
     /* XXX is it possible source mask have non-zero drawable.x/y? */
     if (source
         && ((!source->pDrawable
@@ -1434,8 +1431,8 @@ glamor_composite_clipped_region(CARD8 op,
             temp_src = source;
             goto out;
         }
-        temp_src_priv =
-            glamor_get_pixmap_private((PixmapPtr) (temp_src->pDrawable));
+        temp_src_pixmap = (PixmapPtr) (temp_src->pDrawable);
+        temp_src_priv = glamor_get_pixmap_private(temp_src_pixmap);
         x_temp_src = -extent->x1 + x_dest + dest->pDrawable->x;
         y_temp_src = -extent->y1 + y_dest + dest->pDrawable->y;
     }
@@ -1458,8 +1455,8 @@ glamor_composite_clipped_region(CARD8 op,
             temp_mask = mask;
             goto out;
         }
-        temp_mask_priv =
-            glamor_get_pixmap_private((PixmapPtr) (temp_mask->pDrawable));
+        temp_mask_pixmap = (PixmapPtr) (temp_mask->pDrawable);
+        temp_mask_priv = glamor_get_pixmap_private(temp_mask_pixmap);
         x_temp_mask = -extent->x1 + x_dest + dest->pDrawable->x;
         y_temp_mask = -extent->y1 + y_dest + dest->pDrawable->y;
     }
@@ -1521,6 +1518,7 @@ glamor_composite_clipped_region(CARD8 op,
             DEBUGF("dest %d %d \n", prect[i].x_dst, prect[i].y_dst);
         }
         ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest,
+                                          temp_src_pixmap, temp_mask_pixmap, dest_pixmap,
                                           temp_src_priv, temp_mask_priv,
                                           dest_pixmap_priv,
                                           box_cnt, prect, two_pass_ca);
@@ -1553,8 +1551,6 @@ glamor_composite(CARD8 op,
                  INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
 {
     ScreenPtr screen = dest->pDrawable->pScreen;
-    glamor_pixmap_private *dest_pixmap_priv;
-    glamor_pixmap_private *source_pixmap_priv = NULL, *mask_pixmap_priv = NULL;
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
     PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
@@ -1563,19 +1559,15 @@ glamor_composite(CARD8 op,
     int nbox, ok = FALSE;
     int force_clip = 0;
 
-    dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
-
     if (source->pDrawable) {
         source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
-        source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-        if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY)
+        if (glamor_pixmap_drm_only(source_pixmap))
             goto fail;
     }
 
     if (mask && mask->pDrawable) {
         mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
-        mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-        if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
+        if (glamor_pixmap_drm_only(mask_pixmap))
             goto fail;
     }
 
@@ -1584,9 +1576,8 @@ glamor_composite(CARD8 op,
          source_pixmap, x_source, y_source, x_mask, y_mask, x_dest, y_dest,
          width, height);
 
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+    if (!glamor_pixmap_has_fbo(dest_pixmap))
         goto fail;
-    }
 
     if (op >= ARRAY_SIZE(composite_op_info))
         goto fail;
@@ -1636,28 +1627,28 @@ glamor_composite(CARD8 op,
      * pixmap. */
     if (!glamor_check_fbo_size(glamor_priv,
                                extent->x2 - extent->x1, extent->y2 - extent->y1)
-        && (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE)
-        && ((source_pixmap_priv
-             && (source_pixmap_priv->type == GLAMOR_MEMORY ||
+        && glamor_pixmap_is_large(dest_pixmap)
+        && ((source_pixmap
+             && (glamor_pixmap_is_memory(source_pixmap) ||
                  source->repeatType == RepeatPad))
-            || (mask_pixmap_priv &&
-                (mask_pixmap_priv->type == GLAMOR_MEMORY ||
+            || (mask_pixmap &&
+                (glamor_pixmap_is_memory(mask_pixmap) ||
                  mask->repeatType == RepeatPad))
-            || (!source_pixmap_priv &&
+            || (!source_pixmap &&
                 (source->pSourcePict->type != SourcePictTypeSolidFill))
-            || (!mask_pixmap_priv && mask &&
+            || (!mask_pixmap && mask &&
                 mask->pSourcePict->type != SourcePictTypeSolidFill)))
         force_clip = 1;
 
-    if (force_clip || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
-        || (source_pixmap_priv
-            && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
-        || (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE))
+    if (force_clip || glamor_pixmap_is_large(dest_pixmap)
+        || (source_pixmap
+            && glamor_pixmap_is_large(source_pixmap))
+        || (mask_pixmap && glamor_pixmap_is_large(mask_pixmap)))
         ok = glamor_composite_largepixmap_region(op,
                                                  source, mask, dest,
-                                                 source_pixmap_priv,
-                                                 mask_pixmap_priv,
-                                                 dest_pixmap_priv,
+                                                 source_pixmap,
+                                                 mask_pixmap,
+                                                 dest_pixmap,
                                                  &region, force_clip,
                                                  x_source, y_source,
                                                  x_mask, y_mask,
@@ -1665,9 +1656,9 @@ glamor_composite(CARD8 op,
     else
         ok = glamor_composite_clipped_region(op, source,
                                              mask, dest,
-                                             source_pixmap_priv,
-                                             mask_pixmap_priv,
-                                             dest_pixmap_priv,
+                                             source_pixmap,
+                                             mask_pixmap,
+                                             dest_pixmap,
                                              &region,
                                              x_source, y_source,
                                              x_mask, y_mask, x_dest, y_dest);
@@ -1758,21 +1749,27 @@ glamor_composite_glyph_rects(CARD8 op,
     if (!(glamor_is_large_picture(src)
           || (mask && glamor_is_large_picture(mask))
           || glamor_is_large_picture(dst))) {
+        PixmapPtr src_pixmap = NULL;
+        PixmapPtr mask_pixmap = NULL;
+        PixmapPtr dst_pixmap = NULL;
+        PixmapPtr temp_src_pixmap = NULL;
         glamor_pixmap_private *src_pixmap_priv = NULL;
         glamor_pixmap_private *mask_pixmap_priv = NULL;
         glamor_pixmap_private *dst_pixmap_priv;
         glamor_pixmap_private *temp_src_priv = NULL;
         BoxRec src_extent;
 
-        dst_pixmap_priv = glamor_get_pixmap_private
-            (glamor_get_drawable_pixmap(dst->pDrawable));
+        dst_pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
+        dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
 
-        if (mask && mask->pDrawable)
-            mask_pixmap_priv = glamor_get_pixmap_private
-                (glamor_get_drawable_pixmap(mask->pDrawable));
-        if (src->pDrawable)
-            src_pixmap_priv = glamor_get_pixmap_private
-                (glamor_get_drawable_pixmap(src->pDrawable));
+        if (mask && mask->pDrawable) {
+            mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
+            mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+        }
+        if (src->pDrawable) {
+            src_pixmap = glamor_get_drawable_pixmap(src->pDrawable);
+            src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+        }
 
         if (!src->pDrawable
             && (src->pSourcePict->type != SourcePictTypeSolidFill)) {
@@ -1788,13 +1785,14 @@ glamor_composite_glyph_rects(CARD8 op,
             if (!temp_src)
                 goto fallback;
 
-            temp_src_priv = glamor_get_pixmap_private
-                ((PixmapPtr) (temp_src->pDrawable));
+            temp_src_pixmap = (PixmapPtr) (temp_src->pDrawable);
+            temp_src_priv = glamor_get_pixmap_private(temp_src_pixmap);
             glamor_composite_src_rect_translate(nrect, rects,
                                                 -src_extent.x1, -src_extent.y1);
         }
         else {
             temp_src = src;
+            temp_src_pixmap = src_pixmap;
             temp_src_priv = src_pixmap_priv;
         }
 
@@ -1802,6 +1800,7 @@ glamor_composite_glyph_rects(CARD8 op,
             if (op == PictOpOver) {
                 if (glamor_composite_with_shader(PictOpOutReverse,
                                                  temp_src, mask, dst,
+                                                 temp_src_pixmap, mask_pixmap, dst_pixmap,
                                                  temp_src_priv,
                                                  mask_pixmap_priv,
                                                  dst_pixmap_priv, nrect, rects,
@@ -1811,7 +1810,9 @@ glamor_composite_glyph_rects(CARD8 op,
         }
         else {
             if (glamor_composite_with_shader
-                (op, temp_src, mask, dst, temp_src_priv, mask_pixmap_priv,
+                (op, temp_src, mask, dst,
+                 temp_src_pixmap, mask_pixmap, dst_pixmap,
+                 temp_src_priv, mask_pixmap_priv,
                  dst_pixmap_priv, nrect, rects, FALSE))
                 goto done;
         }
diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index c1df560..eddc468 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -43,6 +43,8 @@ glamor_set_destination_drawable(DrawablePtr     drawable,
                                 int             *p_off_x,
                                 int             *p_off_y)
 {
+    ScreenPtr screen = drawable->pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     int off_x, off_y;
@@ -95,7 +97,7 @@ glamor_set_destination_drawable(DrawablePtr     drawable,
                 scale_x, (off_x + center_adjust) * scale_x - 1.0f,
                 scale_y, (off_y + center_adjust) * scale_y - 1.0f);
 
-    glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y),
+    glamor_set_destination_pixmap_fbo(glamor_priv, glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y),
                                       0, 0, w, h);
 }
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 31e92d8..688350d 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -41,10 +41,10 @@
 #define t_from_x_coord_y(_yscale_, _y_)          (1.0 - (_y_) * (_yscale_))
 #define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
 
-#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_)  \
+#define pixmap_priv_get_dest_scale(pixmap, _pixmap_priv_, _pxscale_, _pyscale_) \
   do {                                                                   \
     int _w_,_h_;                                                         \
-    PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, _w_, _h_);                \
+    PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, _pixmap_priv_, _w_, _h_);        \
     *(_pxscale_) = 1.0 / _w_;                                            \
     *(_pyscale_) = 1.0 / _h_;                                            \
    } while(0)
@@ -55,21 +55,21 @@
     *(_pyscale_) = 1.0 / (_pixmap_priv_)->base.fbo->height;			\
   } while(0)
 
-#define PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, w, h)			\
+#define PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, w, h)          \
   do {								\
 	if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) {	\
 		w = priv->large.box.x2 - priv->large.box.x1;	\
 		h = priv->large.box.y2 - priv->large.box.y1;	\
 	} else {						\
-		w = priv->base.pixmap->drawable.width;		\
-		h = priv->base.pixmap->drawable.height;		\
+		w = (pixmap)->drawable.width;		\
+		h = (pixmap)->drawable.height;		\
 	}							\
   } while(0)
 
-#define glamor_pixmap_fbo_fix_wh_ratio(wh, priv)  		\
+#define glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, priv)         \
   do {								\
 	int actual_w, actual_h;					\
-	PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, actual_w, actual_h);	\
+	PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, actual_w, actual_h);	\
 	wh[0] = (float)priv->base.fbo->width / actual_w;	\
 	wh[1] = (float)priv->base.fbo->height / actual_h;	\
 	wh[2] = 1.0 / priv->base.fbo->width;			\
@@ -189,17 +189,17 @@
 		txy = xy - bxy1;			\
   } while(0)
 
-#define _glamor_get_reflect_transform_coords(priv, repeat_type,	\
+#define _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type,	\
 					    tx1, ty1, 		\
 				            _x1_, _y1_)		\
   do {								\
 	int odd_x, odd_y;					\
 	float c, d;						\
 	fodd_repeat_mod(_x1_,priv->box.x2,			\
-		    priv->base.pixmap->drawable.width,		\
+		    (pixmap)->drawable.width,		\
 		    odd_x, c);					\
 	fodd_repeat_mod(_y1_,	priv->box.y2,			\
-		    priv->base.pixmap->drawable.height,		\
+		    (pixmap)->drawable.height,		\
 		    odd_y, d);					\
 	DEBUGF("c %f d %f oddx %d oddy %d \n",			\
 		c, d, odd_x, odd_y);				\
@@ -208,14 +208,14 @@
 	DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, 	\
 		priv->box.y1, priv->base.fbo->height);		\
 	_glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x,	\
-		priv->base.pixmap->drawable.width,		\
+		(pixmap)->drawable.width,		\
 		priv->box.x1, priv->box.x2);			\
 	_glamor_repeat_reflect_fixup(ty1, _y1_, d, odd_y,	\
-		priv->base.pixmap->drawable.height,		\
+		(pixmap)->drawable.height,		\
 		priv->box.y1, priv->box.y2);			\
    } while(0)
 
-#define _glamor_get_repeat_coords(priv, repeat_type, tx1,	\
+#define _glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1,	\
 				  ty1, tx2, ty2,		\
 				  _x1_, _y1_, _x2_,		\
 				  _y2_, c, d, odd_x, odd_y)	\
@@ -224,10 +224,10 @@
 		DEBUGF("x1 y1 %d %d\n",				\
 			_x1_, _y1_ );				\
 		DEBUGF("width %d box.x1 %d \n",			\
-		       (priv)->base.pixmap->drawable.width,	\
+		       (pixmap)->drawable.width,	\
 		       priv->box.x1);				\
 		if (odd_x) {					\
-			c = (priv)->base.pixmap->drawable.width	\
+			c = (pixmap)->drawable.width	\
 				- c;				\
 			tx1 = c - priv->box.x1;			\
 			tx2 = tx1 - ((_x2_) - (_x1_));		\
@@ -236,7 +236,7 @@
 			tx2 = tx1 + ((_x2_) - (_x1_));		\
 		}						\
 		if (odd_y){					\
-			d = (priv)->base.pixmap->drawable.height\
+			d = (pixmap)->drawable.height\
 			    - d;				\
 			ty1 = d - priv->box.y1;			\
 			ty2 = ty1 - ((_y2_) - (_y1_));		\
@@ -253,11 +253,11 @@
    } while(0)
 
 /* _x1_ ... _y2_ may has fractional. */
-#define glamor_get_repeat_transform_coords(priv, repeat_type, tx1,	\
+#define glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, tx1, \
 					   ty1, _x1_, _y1_)		\
   do {									\
 	DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n",		\
-		(priv)->base.pixmap->drawable.width,			\
+		(pixmap)->drawable.width,			\
 		priv->box.x1, priv->box.x2, priv->box.y1,		\
 		priv->box.y2);						\
 	DEBUGF("x1 %f y1 %f \n", _x1_, _y1_);				\
@@ -265,33 +265,33 @@
 		tx1 = _x1_ - priv->box.x1;				\
 		ty1 = _y1_ - priv->box.y1;				\
 	} else			\
-		_glamor_get_reflect_transform_coords(priv, repeat_type, \
+                _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type, \
 				  tx1, ty1, 				\
 				  _x1_, _y1_);				\
 	DEBUGF("tx1 %f ty1 %f \n", tx1, ty1);				\
    } while(0)
 
 /* _x1_ ... _y2_ must be integer. */
-#define glamor_get_repeat_coords(priv, repeat_type, tx1,		\
+#define glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1,		\
 				 ty1, tx2, ty2, _x1_, _y1_, _x2_,	\
 				 _y2_) 					\
   do {									\
 	int c, d;							\
 	int odd_x = 0, odd_y = 0;					\
 	DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n",		\
-		(priv)->base.pixmap->drawable.width,			\
+		(pixmap)->drawable.width,			\
 		priv->box.x1, priv->box.x2,				\
 		priv->box.y1, priv->box.y2);				\
-	modulus((_x1_), (priv)->base.pixmap->drawable.width, c); 	\
-	modulus((_y1_), (priv)->base.pixmap->drawable.height, d);	\
+	modulus((_x1_), (pixmap)->drawable.width, c); 	\
+	modulus((_y1_), (pixmap)->drawable.height, d);	\
 	DEBUGF("c %d d %d \n", c, d);					\
 	if (repeat_type == RepeatReflect) {				\
 		odd_x = abs((_x1_ - c)					\
-			/ (priv->base.pixmap->drawable.width)) & 1;	\
+                            / ((pixmap)->drawable.width)) & 1;            \
 		odd_y = abs((_y1_ - d)					\
-			/ (priv->base.pixmap->drawable.height)) & 1;	\
+                            / ((pixmap)->drawable.height)) & 1;           \
 	}								\
-	_glamor_get_repeat_coords(priv, repeat_type, tx1, ty1, tx2, ty2,\
+	_glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, ty1, tx2, ty2, \
 				  _x1_, _y1_, _x2_, _y2_, c, d,		\
 				  odd_x, odd_y);			\
    } while(0)
@@ -317,7 +317,7 @@
 		(texcoord)[1]);						\
   } while(0)
 
-#define glamor_set_transformed_point(priv, matrix, xscale,		\
+#define glamor_set_transformed_point(priv, matrix, xscale,              \
 				     yscale, texcoord,			\
                                      x, y)				\
   do {									\
@@ -400,7 +400,7 @@
 				texcoords+4);			\
     } while (0)
 
-#define glamor_set_repeat_transformed_normalize_tcoords_ext( priv,	\
+#define glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, \
 							 repeat_type,	\
 							 matrix,	\
 							 xscale,	\
@@ -425,16 +425,16 @@
     glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_);		\
     DEBUGF("transformed %f %f %f %f %f %f %f %f\n",			\
 	   tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4);			\
-    glamor_get_repeat_transform_coords((&priv->large), repeat_type, 	\
+    glamor_get_repeat_transform_coords(pixmap, (&priv->large), repeat_type, \
 				       ttx1, tty1, 			\
 				       tx1, ty1);			\
-    glamor_get_repeat_transform_coords((&priv->large), repeat_type, 	\
+    glamor_get_repeat_transform_coords(pixmap, (&priv->large), repeat_type, 	\
 				       ttx2, tty2, 			\
 				       tx2, ty2);			\
-    glamor_get_repeat_transform_coords((&priv->large), repeat_type, 	\
+    glamor_get_repeat_transform_coords(pixmap, (&priv->large), repeat_type, 	\
 				       ttx3, tty3, 			\
 				       tx3, ty3);			\
-    glamor_get_repeat_transform_coords((&priv->large), repeat_type, 	\
+    glamor_get_repeat_transform_coords(pixmap, (&priv->large), repeat_type, 	\
 				       ttx4, tty4, 			\
 				       tx4, ty4);			\
     DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, 	\
@@ -450,7 +450,8 @@
    }									\
   } while (0)
 
-#define glamor_set_repeat_transformed_normalize_tcoords( priv,		\
+#define glamor_set_repeat_transformed_normalize_tcoords( pixmap,        \
+                                                         priv,          \
 							 repeat_type,	\
 							 matrix,	\
 							 xscale,	\
@@ -459,7 +460,8 @@
 							 _x2_, _y2_,   	\
 							 texcoords)	\
   do {									\
-	glamor_set_repeat_transformed_normalize_tcoords_ext( priv,	\
+      glamor_set_repeat_transformed_normalize_tcoords_ext( pixmap,      \
+                                                           priv,	\
 							 repeat_type,	\
 							 matrix,	\
 							 xscale,	\
@@ -516,7 +518,7 @@
                                      vertices, 2);			\
  } while(0)
 
-#define glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,	\
+#define glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type, \
 					    xscale, yscale,		\
 					    _x1_, _y1_, _x2_, _y2_,	\
 	                                    vertices, stride)		\
@@ -529,7 +531,7 @@
 		tx2 = tx1 + ((_x2_) - (_x1_));				\
 		ty2 = ty1 + ((_y2_) - (_y1_));				\
 	} else {							\
-	glamor_get_repeat_coords((&priv->large), repeat_type,		\
+            glamor_get_repeat_coords(pixmap, (&priv->large), repeat_type, \
 				 tx1, ty1, tx2, ty2,			\
 				 _x1_, _y1_, _x2_, _y2_);		\
 	}								\
@@ -791,10 +793,10 @@ static inline GLenum
 gl_iformat_for_pixmap(PixmapPtr pixmap)
 {
     glamor_screen_private *glamor_priv =
-        glamor_get_screen_private(pixmap->drawable.pScreen);
+        glamor_get_screen_private((pixmap)->drawable.pScreen);
 
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
-        (pixmap->drawable.depth == 1 || pixmap->drawable.depth == 8)) {
+        ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) {
         return GL_ALPHA;
     } else {
         return GL_RGBA;
@@ -811,7 +813,7 @@ format_for_pixmap(PixmapPtr pixmap)
     if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
         pict_format = pixmap_priv->base.picture->format;
     else
-        pict_format = format_for_depth(pixmap->drawable.depth);
+        pict_format = format_for_depth((pixmap)->drawable.depth);
 
     return pict_format;
 }
@@ -967,8 +969,8 @@ static inline void
 _glamor_dump_pixmap_bits(PixmapPtr pixmap, int x, int y, int w, int h)
 {
     int i, j;
-    unsigned char *p = pixmap->devPrivate.ptr;
-    int stride = pixmap->devKind;
+    unsigned char *p = (pixmap)->devPrivate.ptr;
+    int stride = (pixmap)->devKind;
 
     p = p + y * stride + x;
 
@@ -985,8 +987,8 @@ static inline void
 _glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h)
 {
     int i, j;
-    unsigned char *p = pixmap->devPrivate.ptr;
-    int stride = pixmap->devKind;
+    unsigned char *p = (pixmap)->devPrivate.ptr;
+    int stride = (pixmap)->devKind;
 
     p = p + y * stride + x;
 
@@ -1003,8 +1005,8 @@ static inline void
 _glamor_dump_pixmap_sword(PixmapPtr pixmap, int x, int y, int w, int h)
 {
     int i, j;
-    unsigned short *p = pixmap->devPrivate.ptr;
-    int stride = pixmap->devKind / 2;
+    unsigned short *p = (pixmap)->devPrivate.ptr;
+    int stride = (pixmap)->devKind / 2;
 
     p = p + y * stride + x;
 
@@ -1021,8 +1023,8 @@ static inline void
 _glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h)
 {
     int i, j;
-    unsigned int *p = pixmap->devPrivate.ptr;
-    int stride = pixmap->devKind / 4;
+    unsigned int *p = (pixmap)->devPrivate.ptr;
+    int stride = (pixmap)->devKind / 4;
 
     p = p + y * stride + x;
 
@@ -1038,11 +1040,11 @@ _glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h)
 static inline void
 glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
 {
-    w = ((x + w) > pixmap->drawable.width) ? (pixmap->drawable.width - x) : w;
-    h = ((y + h) > pixmap->drawable.height) ? (pixmap->drawable.height - y) : h;
+    w = ((x + w) > (pixmap)->drawable.width) ? ((pixmap)->drawable.width - x) : w;
+    h = ((y + h) > (pixmap)->drawable.height) ? ((pixmap)->drawable.height - y) : h;
 
-    glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
-    switch (pixmap->drawable.depth) {
+    glamor_prepare_access(&(pixmap)->drawable, GLAMOR_ACCESS_RO);
+    switch ((pixmap)->drawable.depth) {
     case 8:
         _glamor_dump_pixmap_byte(pixmap, x, y, w, h);
         break;
@@ -1059,9 +1061,9 @@ glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
         _glamor_dump_pixmap_bits(pixmap, x, y, w, h);
         break;
     default:
-        ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth);
+        ErrorF("dump depth %d, not implemented.\n", (pixmap)->drawable.depth);
     }
-    glamor_finish_access(&pixmap->drawable);
+    glamor_finish_access(&(pixmap)->drawable);
 }
 
 static inline void
@@ -1259,7 +1261,7 @@ glamor_compare_pictures(ScreenPtr screen,
                                       GLAMOR_CREATE_PIXMAP_CPU);
 
         pixman_pic = CreatePicture(0,
-                                   &pixmap->drawable,
+                                   &(pixmap)->drawable,
                                    PictureMatchFormat(screen,
                                                       PIXMAN_FORMAT_DEPTH
                                                       (format), format), 0, 0,
@@ -1287,7 +1289,7 @@ glamor_compare_pictures(ScreenPtr screen,
                                       GLAMOR_CREATE_PIXMAP_CPU);
 
         pixman_pic = CreatePicture(0,
-                                   &pixmap->drawable,
+                                   &(pixmap)->drawable,
                                    PictureMatchFormat(screen,
                                                       PIXMAN_FORMAT_DEPTH
                                                       (format), format), 0, 0,
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 83e24ad..74654f5 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -241,8 +241,8 @@ glamor_xv_render(glamor_port_private *port_priv)
 {
     ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_pixmap_private *pixmap_priv =
-        glamor_get_pixmap_private(port_priv->pPixmap);
+    PixmapPtr pixmap = port_priv->pPixmap;
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     glamor_pixmap_private *src_pixmap_priv[3];
     float vertices[32], texcoords[8];
     BoxPtr box = REGION_RECTS(&port_priv->clip);
@@ -282,10 +282,10 @@ glamor_xv_render(glamor_port_private *port_priv)
     off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright;
     gamma = 1.0;
 
-    pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
+    pixmap_priv_get_dest_scale(pixmap, pixmap_priv, &dst_xscale, &dst_yscale);
     glamor_get_drawable_deltas(port_priv->pDraw, port_priv->pPixmap, &dst_x_off,
                                &dst_y_off);
-    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+    glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
 
     for (i = 0; i < 3; i++) {
         if (port_priv->src_pix[i]) {
commit 1eb954c3830d46c27bf2a61f825b59f12092728c
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 21:31:32 2014 -0700

    glamor: Remove remaining support for FBOs not matching pixmap size
    
    The core rendering code already requires that FBOs be allocated at
    exactly the pixmap size so that tiling and stippling work
    correctly. Remove the allocation support for that, along with the
    render code.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index ff6ed25..941eaee 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -72,7 +72,7 @@ cache_hbucket(int size)
 
 static glamor_pixmap_fbo *
 glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
-                            int w, int h, GLenum format, int flag)
+                            int w, int h, GLenum format)
 {
     struct xorg_list *cache;
     glamor_pixmap_fbo *fbo_entry, *ret_fbo = NULL;
@@ -87,33 +87,18 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
     cache = &glamor_priv->fbo_cache[n_format]
         [cache_wbucket(w)]
         [cache_hbucket(h)];
-    if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) {
-        xorg_list_for_each_entry(fbo_entry, cache, list) {
-            if (fbo_entry->width >= w && fbo_entry->height >= h) {
-
-                DEBUGF("Request w %d h %d format %x \n", w, h, format);
-                DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
-                       fbo_entry, fbo_entry->width, fbo_entry->height,
-                       fbo_entry->fb, fbo_entry->tex);
-                xorg_list_del(&fbo_entry->list);
-                ret_fbo = fbo_entry;
-                break;
-            }
-        }
-    }
-    else {
-        xorg_list_for_each_entry(fbo_entry, cache, list) {
-            if (fbo_entry->width == w && fbo_entry->height == h) {
-
-                DEBUGF("Request w %d h %d format %x \n", w, h, format);
-                DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
-                       fbo_entry, fbo_entry->width, fbo_entry->height,
-                       fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
-                assert(format == fbo_entry->format);
-                xorg_list_del(&fbo_entry->list);
-                ret_fbo = fbo_entry;
-                break;
-            }
+
+    xorg_list_for_each_entry(fbo_entry, cache, list) {
+        if (fbo_entry->width == w && fbo_entry->height == h) {
+
+            DEBUGF("Request w %d h %d format %x \n", w, h, format);
+            DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
+                   fbo_entry, fbo_entry->width, fbo_entry->height,
+                   fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
+            assert(format == fbo_entry->format);
+            xorg_list_del(&fbo_entry->list);
+            ret_fbo = fbo_entry;
+            break;
         }
     }
 
@@ -355,18 +340,11 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 {
     glamor_pixmap_fbo *fbo;
     GLint tex = 0;
-    int cache_flag;
 
     if (flag == GLAMOR_CREATE_FBO_NO_FBO)
         goto new_fbo;
 
-    /* Tiling from textures requires exact pixmap sizes. As we don't
-     * know which pixmaps will be used as tiles, just allocate
-     * everything at the requested size
-     */
-    cache_flag = GLAMOR_CACHE_EXACT_SIZE;
-
-    fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h, format, cache_flag);
+    fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h, format);
     if (fbo)
         return fbo;
  new_fbo:
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 0d92710..f5021b2 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -1132,62 +1132,3 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     return temp_fbo;
 }
-
-/* fixup a fbo to the exact size as the pixmap. */
-/* XXX LARGE pixmap? */
-Bool
-glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
-{
-    glamor_pixmap_fbo *old_fbo;
-    glamor_pixmap_fbo *new_fbo = NULL;
-    PixmapPtr scratch = NULL;
-    glamor_pixmap_private *scratch_priv;
-    DrawablePtr drawable;
-    GCPtr gc = NULL;
-    int ret = FALSE;
-
-    drawable = &pixmap_priv->base.pixmap->drawable;
-
-    if (!GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(pixmap_priv))
-        return TRUE;
-
-    old_fbo = pixmap_priv->base.fbo;
-
-    if (!old_fbo)
-        return FALSE;
-
-    gc = GetScratchGC(drawable->depth, screen);
-    if (!gc)
-        goto fail;
-
-    scratch = glamor_create_pixmap(screen, drawable->width, drawable->height,
-                                   drawable->depth, GLAMOR_CREATE_PIXMAP_FIXUP);
-
-    scratch_priv = glamor_get_pixmap_private(scratch);
-
-    if (!scratch_priv->base.fbo)
-        goto fail;
-
-    ValidateGC(&scratch->drawable, gc);
-    glamor_copy_area(drawable,
-                     &scratch->drawable,
-                     gc, 0, 0, drawable->width, drawable->height, 0, 0);
-    old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
-    new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
-    glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo);
-    glamor_pixmap_attach_fbo(scratch, old_fbo);
-
-    DEBUGF("old %dx%d type %d\n",
-           drawable->width, drawable->height, pixmap_priv->type);
-    DEBUGF("copy tex %d  %dx%d to tex %d %dx%d \n",
-           old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex,
-           new_fbo->width, new_fbo->height);
-    ret = TRUE;
- fail:
-    if (gc)
-        FreeScratchGC(gc);
-    if (scratch)
-        glamor_destroy_pixmap(scratch);
-
-    return ret;
-}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 1fde919..1df96d6 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -895,10 +895,6 @@ void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap);
 
 void glamor_destroy_picture(PicturePtr picture);
 
-/* fixup a fbo to the exact size as the pixmap. */
-Bool glamor_fixup_pixmap_priv(ScreenPtr screen,
-                              glamor_pixmap_private *pixmap_priv);
-
 void glamor_picture_format_fixup(PicturePtr picture,
                                  glamor_pixmap_private *pixmap_priv);
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 298e1a0..1d60622 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -542,8 +542,7 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
         repeat_type += RepeatFix;
     else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
              || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-        if (picture->transform
-            || (GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(pixmap_priv)))
+        if (picture->transform)
             repeat_type += RepeatFix;
     }
     if (repeat_type >= RepeatFix) {
@@ -1040,23 +1039,6 @@ glamor_composite_choose_shader(CARD8 op,
         goto fail;
     }
 
-    /*Before enter the rendering stage, we need to fixup
-     * transformed source and mask, if the transform is not int translate. */
-    if (key.source != SHADER_SOURCE_SOLID
-        && source->transform
-        && !pixman_transform_is_int_translate(source->transform)
-        && source_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
-        if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv))
-            goto fail;
-    }
-    if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID
-        && mask->transform
-        && !pixman_transform_is_int_translate(mask->transform)
-        && mask_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
-        if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv))
-            goto fail;
-    }
-
     if (!glamor_set_composite_op(screen, op, op_info, dest, mask))
         goto fail;
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 7954257..31e92d8 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -55,10 +55,6 @@
     *(_pyscale_) = 1.0 / (_pixmap_priv_)->base.fbo->height;			\
   } while(0)
 
-#define GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(priv)			\
-   (priv->base.fbo->width != priv->base.pixmap->drawable.width 	\
-      || priv->base.fbo->height != priv->base.pixmap->drawable.height)	\
-
 #define PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, w, h)			\
   do {								\
 	if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) {	\
commit adb847faeb51c567933fab97b97e79ee3d184dc8
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 20:49:49 2014 -0700

    glamor: Eliminate GLAMOR_TEXTURE_PACK pixmap type
    
    This is not used anywhere
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index 1a9efc5..1e51d74 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -56,8 +56,7 @@ typedef enum glamor_pixmap_type {
     GLAMOR_TEXTURE_DRM,
     GLAMOR_DRM_ONLY,
     GLAMOR_TEXTURE_ONLY,
-    GLAMOR_TEXTURE_LARGE,
-    GLAMOR_TEXTURE_PACK
+    GLAMOR_TEXTURE_LARGE
 } glamor_pixmap_type_t;
 
 #define GLAMOR_EGL_EXTERNAL_BUFFER 3
commit 2f80c7791bb0b11f261cb1e3e0d89163dcdd0342
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 20:48:40 2014 -0700

    glamor: Eliminate GLAMOR_SEPARATE_TEXTURE pixmap type
    
    This was only used to signal when we couldn't ask the DDX to draw to a
    pixmap; now that we have no DDX-based fallbacks, we don't need to have
    this type.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index d8419c1..1a9efc5 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -54,7 +54,6 @@ struct glamor_context;
 typedef enum glamor_pixmap_type {
     GLAMOR_MEMORY,
     GLAMOR_TEXTURE_DRM,
-    GLAMOR_SEPARATE_TEXTURE,
     GLAMOR_DRM_ONLY,
     GLAMOR_TEXTURE_ONLY,
     GLAMOR_TEXTURE_LARGE,
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index bc658f8..008d183 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -69,16 +69,6 @@ glamor_create_picture(PicturePtr picture)
         glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
         pixmap_priv = glamor_get_pixmap_private(pixmap);
     }
-    else {
-        if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-            /* If the picture format is not compatible with glamor fbo format,
-             * we have to mark this pixmap as a separated texture, and don't
-             * fallback to DDX layer. */
-            if (pixmap_priv->type == GLAMOR_TEXTURE_DRM
-                && !glamor_pict_format_is_compatible(picture))
-                glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE);
-        }
-    }
 
     pixmap_priv->base.is_picture = 1;
     pixmap_priv->base.picture = picture;
commit c6ab13566798c7adff23a609575a7ac2d1ce2df6
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 20:44:31 2014 -0700

    glamor: Remove ddx fallback check functions
    
    With no DDX-based fallback support, we can remove these functions as
    they are no longer called.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index c15d17c..7954257 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -939,40 +939,6 @@ glamor_pict_format_is_compatible(PicturePtr picture)
     }
 }
 
-/* return TRUE if we can access this pixmap at DDX driver. */
-inline static Bool
-glamor_ddx_fallback_check_pixmap(DrawablePtr drawable)
-{
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-    return (!pixmap_priv
-            || (pixmap_priv->type == GLAMOR_TEXTURE_DRM
-                || pixmap_priv->type == GLAMOR_MEMORY
-                || pixmap_priv->type == GLAMOR_DRM_ONLY));
-}
-
-inline static Bool
-glamor_ddx_fallback_check_gc(GCPtr gc)
-{
-    PixmapPtr pixmap;
-
-    if (!gc)
-        return TRUE;
-    switch (gc->fillStyle) {
-    case FillStippled:
-    case FillOpaqueStippled:
-        pixmap = gc->stipple;
-        break;
-    case FillTiled:
-        pixmap = gc->tile.pixmap;
-        break;
-    default:
-        pixmap = NULL;
-    }
-    return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable));
-}
-
 inline static Bool
 glamor_is_large_pixmap(PixmapPtr pixmap)
 {
commit 90d326fcc687e6d6d4b308f6272ededcf8145a17
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 20:40:21 2014 -0700

    glamor: Remove _nf rendering functions
    
    These were used by the non-standard glamor implementation in the intel
    driver.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 7de2dba..6ee006f 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -34,6 +34,7 @@
 #include <stdlib.h>
 
 #include "glamor_priv.h"
+#include "mipict.h"
 
 DevPrivateKeyRec glamor_screen_private_key;
 DevPrivateKeyRec glamor_pixmap_private_key;
@@ -486,7 +487,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     ps->AddTraps = glamor_add_traps;
 
     glamor_priv->saved_procs.composite_rects = ps->CompositeRects;
-    ps->CompositeRects = glamor_composite_rectangles;
+    ps->CompositeRects = miCompositeRects;
 
     glamor_priv->saved_procs.glyphs = ps->Glyphs;
     ps->Glyphs = glamor_glyphs;
diff --git a/glamor/glamor.h b/glamor/glamor.h
index b7a41e5..d8419c1 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -308,146 +308,6 @@ extern _X_EXPORT void glamor_destroy_gc(GCPtr gc);
 extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region);
 
-/* Glamor rendering/drawing functions with XXX_nf.
- * nf means no fallback within glamor internal if possible. If glamor
- * fail to accelerate the operation, glamor will return a false, and the
- * caller need to implement fallback method. Return a true means the
- * rendering request get done successfully. */
-extern _X_EXPORT Bool glamor_fill_spans_nf(DrawablePtr drawable,
-                                           GCPtr gc,
-                                           int n, DDXPointPtr points,
-                                           int *widths, int sorted);
-
-extern _X_EXPORT Bool glamor_poly_fill_rect_nf(DrawablePtr drawable,
-                                               GCPtr gc,
-                                               int nrect, xRectangle *prect);
-
-extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable,
-                                          GCPtr gc, int depth, int x, int y,
-                                          int w, int h, int left_pad,
-                                          int image_format, char *bits);
-
-extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src,
-                                            DrawablePtr dst,
-                                            GCPtr gc,
-                                            BoxPtr box,
-                                            int nbox,
-                                            int dx,
-                                            int dy,
-                                            Bool reverse,
-                                            Bool upsidedown, Pixel bitplane,
-                                            void *closure);
-
-extern _X_EXPORT Bool glamor_copy_nf(DrawablePtr src,
-                                     DrawablePtr dst,
-                                     GCPtr gc,
-                                     BoxPtr box,
-                                     int nbox,
-                                     int dx,
-                                     int dy,
-                                     Bool reverse,
-                                     Bool upsidedown, Pixel bitplane,
-                                     void *closure);
-
-extern _X_EXPORT Bool glamor_composite_nf(CARD8 op,
-                                          PicturePtr source,
-                                          PicturePtr mask,
-                                          PicturePtr dest,
-                                          INT16 x_source,
-                                          INT16 y_source,
-                                          INT16 x_mask,
-                                          INT16 y_mask,
-                                          INT16 x_dest, INT16 y_dest,
-                                          CARD16 width, CARD16 height);
-
-extern _X_EXPORT Bool glamor_trapezoids_nf(CARD8 op,
-                                           PicturePtr src, PicturePtr dst,
-                                           PictFormatPtr mask_format,
-                                           INT16 x_src, INT16 y_src,
-                                           int ntrap, xTrapezoid *traps);
-
-extern _X_EXPORT Bool glamor_glyphs_nf(CARD8 op,
-                                       PicturePtr src,
-                                       PicturePtr dst,
-                                       PictFormatPtr mask_format,
-                                       INT16 x_src,
-                                       INT16 y_src, int nlist,
-                                       GlyphListPtr list, GlyphPtr *glyphs);
-
-extern _X_EXPORT Bool glamor_triangles_nf(CARD8 op,
-                                          PicturePtr pSrc,
-                                          PicturePtr pDst,
-                                          PictFormatPtr maskFormat,
-                                          INT16 xSrc, INT16 ySrc,
-                                          int ntris, xTriangle *tris);
-
-extern _X_EXPORT void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
-
-extern _X_EXPORT Bool glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc,
-                                          char *src, DDXPointPtr points,
-                                          int *widths, int n, int sorted);
-
-extern _X_EXPORT Bool glamor_get_spans_nf(DrawablePtr drawable, int wmax,
-                                          DDXPointPtr points, int *widths,
-                                          int count, char *dst);
-
-extern _X_EXPORT Bool glamor_composite_rects_nf(CARD8 op,
-                                                PicturePtr pDst,
-                                                xRenderColor *color,
-                                                int nRect, xRectangle *rects);
-
-extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y,
-                                          int w, int h, unsigned int format,
-                                          unsigned long planeMask, char *d);
-
-extern _X_EXPORT Bool glamor_add_traps_nf(PicturePtr pPicture,
-                                          INT16 x_off,
-                                          INT16 y_off, int ntrap,
-                                          xTrap *traps);
-
-extern _X_EXPORT Bool glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst,
-                                           GCPtr pGC, int srcx, int srcy, int w,
-                                           int h, int dstx, int dsty,
-                                           unsigned long bitPlane,
-                                           RegionPtr *pRegion);
-
-extern _X_EXPORT Bool glamor_image_glyph_blt_nf(DrawablePtr pDrawable,
-                                                GCPtr pGC, int x, int y,
-                                                unsigned int nglyph,
-                                                CharInfoPtr *ppci,
-                                                void *pglyphBase);
-
-extern _X_EXPORT Bool glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
-                                               int x, int y,
-                                               unsigned int nglyph,
-                                               CharInfoPtr *ppci,
-                                               void *pglyphBase);
-
-extern _X_EXPORT Bool glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
-                                            DrawablePtr pDrawable, int w, int h,
-                                            int x, int y);
-
-extern _X_EXPORT Bool glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC,
-                                           int mode, int npt, DDXPointPtr ppt);
-
-extern _X_EXPORT Bool glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC,
-                                             int nseg, xSegment *pSeg);
-
-extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc,
-                                           int mode, int n, DDXPointPtr points);
-
-extern _X_EXPORT Bool glamor_poly_text8_nf(DrawablePtr drawable, GCPtr gc,
-                                           int x, int y, int count, char *chars, int *final_pos);
-
-extern _X_EXPORT Bool glamor_poly_text16_nf(DrawablePtr drawable, GCPtr gc,
-                                            int x, int y, int count, unsigned short *chars, int *final_pos);
-
-extern _X_EXPORT Bool glamor_image_text8_nf(DrawablePtr drawable, GCPtr gc,
-                                            int x, int y, int count, char *chars);
-
-extern _X_EXPORT Bool glamor_image_text16_nf(DrawablePtr drawable, GCPtr gc,
-                                             int x, int y, int count, unsigned short *chars);
-
 #define HAS_GLAMOR_TEXT 1
 
 #ifdef GLAMOR_FOR_XORG
diff --git a/glamor/glamor_addtraps.c b/glamor/glamor_addtraps.c
index fdc0f42..7ad9f30 100644
--- a/glamor/glamor_addtraps.c
+++ b/glamor/glamor_addtraps.c
@@ -28,34 +28,13 @@
 
 #include "glamor_priv.h"
 
-static Bool
-_glamor_add_traps(PicturePtr pPicture,
-                  INT16 x_off,
-                  INT16 y_off, int ntrap, xTrap *traps, Bool fallback)
+void
+glamor_add_traps(PicturePtr pPicture,
+                 INT16 x_off,
+                 INT16 y_off, int ntrap, xTrap *traps)
 {
-    if (!fallback
-        && (!pPicture->pDrawable
-            || glamor_ddx_fallback_check_pixmap(pPicture->pDrawable)))
-        return FALSE;
-
     if (glamor_prepare_access_picture(pPicture, GLAMOR_ACCESS_RW)) {
         fbAddTraps(pPicture, x_off, y_off, ntrap, traps);
     }
     glamor_finish_access_picture(pPicture);
-
-    return TRUE;
-}
-
-void
-glamor_add_traps(PicturePtr pPicture,
-                 INT16 x_off, INT16 y_off, int ntrap, xTrap *traps)
-{
-    _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, TRUE);
-}
-
-Bool
-glamor_add_traps_nf(PicturePtr pPicture,
-                    INT16 x_off, INT16 y_off, int ntrap, xTrap *traps)
-{
-    return _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, FALSE);
 }
diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index 3320935..18fcdf9 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -709,39 +709,3 @@ glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_regio
 
     RegionUninit(&dst_region);
 }
-
-Bool
-glamor_copy_n_to_n_nf(DrawablePtr src,
-                      DrawablePtr dst,
-                      GCPtr gc,
-                      BoxPtr box,
-                      int nbox,
-                      int dx,
-                      int dy,
-                      Bool reverse,
-                      Bool upsidedown, Pixel bitplane,
-                      void *closure)
-{
-    if (glamor_copy_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure))
-        return TRUE;
-    if (glamor_ddx_fallback_check_pixmap(src) && glamor_ddx_fallback_check_pixmap(dst))
-        return FALSE;
-    glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
-    return TRUE;
-}
-
-Bool
-glamor_copy_plane_nf(DrawablePtr src, DrawablePtr dst, GCPtr gc,
-                     int srcx, int srcy, int w, int h, int dstx, int dsty,
-                     unsigned long bitplane, RegionPtr *region)
-{
-    if (glamor_ddx_fallback_check_pixmap(src) &&
-        glamor_ddx_fallback_check_pixmap(dst) &&
-        glamor_ddx_fallback_check_gc(gc))
-        return FALSE;
-
-    *region = glamor_copy_plane(src, dst, gc,
-                                srcx, srcy, w, h, dstx, dsty,
-                                bitplane);
-    return TRUE;
-}
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 73b1df5..8c73f48 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -160,32 +160,6 @@ glamor_poly_glyph_blt(DrawablePtr drawable, GCPtr gc,
                    ppci, pglyph_base);
 }
 
-Bool
-glamor_poly_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
-                         int start_x, int y, unsigned int nglyph,
-                         CharInfoPtr *ppci, void *pglyph_base)
-{
-    if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci,
-                                 pglyph_base))
-        return TRUE;
-    if (glamor_ddx_fallback_check_pixmap(drawable) &&
-        glamor_ddx_fallback_check_gc(gc)) {
-        return FALSE;
-    }
-    miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
-                   ppci, pglyph_base);
-    return TRUE;
-}
-
-Bool
-glamor_image_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
-                          int start_x, int y, unsigned int nglyph,
-                          CharInfoPtr *ppci, void *pglyph_base)
-{
-    miImageGlyphBlt(drawable, gc, start_x, y, nglyph, ppci, pglyph_base);
-    return TRUE;
-}
-
 static Bool
 glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
                       DrawablePtr drawable, int w, int h, int x, int y)
@@ -275,21 +249,3 @@ glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
 
     miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
 }
-
-Bool
-glamor_push_pixels_nf(GCPtr gc, PixmapPtr bitmap,
-                      DrawablePtr drawable, int w, int h, int x, int y)
-{
-    if (glamor_push_pixels_gl(gc, bitmap, drawable, w, h, x, y))
-        return TRUE;
-
-    if (glamor_ddx_fallback_check_pixmap(drawable) &&
-        glamor_ddx_fallback_check_pixmap(&bitmap->drawable) &&
-        glamor_ddx_fallback_check_gc(gc))
-    {
-        return FALSE;
-    }
-
-    miPushPixels(gc, bitmap, drawable, w, h, x, y);
-    return TRUE;
-}
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 1f13624..2cf0c7d 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -1166,11 +1166,9 @@ static void
 glamor_glyphs_flush_mask(struct glyphs_flush_mask_arg *arg)
 {
     if (arg->buffer->count > 0) {
-#ifdef RENDER
         glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source,
                                      NULL, arg->mask,
                                      arg->buffer->count, arg->buffer->rects);
-#endif
     }
     arg->buffer->count = 0;
     arg->buffer->source = NULL;
@@ -1769,15 +1767,3 @@ glamor_glyphs(CARD8 op,
     _glamor_glyphs(op, src, dst, mask_format, x_src,
                    y_src, nlist, list, glyphs, TRUE);
 }
-
-Bool
-glamor_glyphs_nf(CARD8 op,
-                 PicturePtr src,
-                 PicturePtr dst,
-                 PictFormatPtr mask_format,
-                 INT16 x_src,
-                 INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr *glyphs)
-{
-    return _glamor_glyphs(op, src, dst, mask_format, x_src,
-                          y_src, nlist, list, glyphs, FALSE);
-}
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 4ded89d..2b9f7f3 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -32,8 +32,6 @@
 
 #include "glamor_priv.h"
 
-#ifdef RENDER
-
 #define LINEAR_SMALL_STOPS (6 + 2)
 #define LINEAR_LARGE_STOPS (16 + 2)
 
@@ -1473,5 +1471,3 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
 }
 
 #endif                          /* End of GLAMOR_GRADIENT_SHADER */
-
-#endif                          /* End of RENDER */
diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c
index b38b412..5633da6 100644
--- a/glamor/glamor_image.c
+++ b/glamor/glamor_image.c
@@ -102,19 +102,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
 }
 
-Bool
-glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-                    int w, int h, int leftPad, int format, char *bits)
-{
-    if (glamor_put_image_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits))
-        return TRUE;
-    if (glamor_ddx_fallback_check_pixmap(drawable) &&
-        glamor_ddx_fallback_check_gc(gc))
-        return FALSE;
-    glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
-    return TRUE;
-}
-
 static Bool
 glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h,
                     unsigned int format, unsigned long plane_mask, char *d)
@@ -163,17 +150,3 @@ glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
         return;
     glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d);
 }
-
-Bool
-glamor_get_image_nf(DrawablePtr drawable, int x, int y, int w, int h,
-                    unsigned int format, unsigned long plane_mask, char *d)
-{
-    if (glamor_get_image_gl(drawable, x, y, w, h, format, plane_mask, d))
-        return TRUE;
-
-    if (glamor_ddx_fallback_check_pixmap(drawable))
-        return FALSE;
-
-    glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d);
-    return TRUE;
-}
diff --git a/glamor/glamor_lines.c b/glamor/glamor_lines.c
index e9a6195..6c8bb88 100644
--- a/glamor/glamor_lines.c
+++ b/glamor/glamor_lines.c
@@ -167,21 +167,3 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc,
         return;
     glamor_poly_lines_bail(drawable, gc, mode, n, points);
 }
-
-Bool
-glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc,
-                     int mode, int n, DDXPointPtr points)
-{
-    if (glamor_poly_lines_gl(drawable, gc, mode, n, points))
-        return TRUE;
-
-    if (glamor_ddx_fallback_check_pixmap(drawable) &&
-        glamor_ddx_fallback_check_gc(gc))
-    {
-        return FALSE;
-    }
-
-    glamor_poly_lines_bail(drawable, gc, mode, n, points);
-    return TRUE;
-}
-
diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c
index 84383d2..01a1c7e 100644
--- a/glamor/glamor_points.c
+++ b/glamor/glamor_points.c
@@ -121,18 +121,3 @@ glamor_poly_point(DrawablePtr drawable, GCPtr gc, int mode, int npt,
         return;
     miPolyPoint(drawable, gc, mode, npt, ppt);
 }
-
-Bool
-glamor_poly_point_nf(DrawablePtr drawable, GCPtr gc, int mode, int npt,
-                     DDXPointPtr ppt)
-{
-    if (glamor_poly_point_gl(drawable, gc, mode, npt, ppt))
-        return TRUE;
-
-    if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
-        return FALSE;
-
-    miPolyPoint(drawable, gc, mode, npt, ppt);
-    return TRUE;
-}
-
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 60070e9..1fde919 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -48,9 +48,7 @@
     "precision mediump float;\n"  \
     "#endif\n"
 
-#ifdef RENDER
 #include "glyphstr.h"
-#endif
 
 #include "glamor_debug.h"
 #include "glamor_context.h"
@@ -704,6 +702,7 @@ glamor_track_stipple(GCPtr gc);
 
 /* glamor_glyphs.c */
 Bool glamor_realize_glyph_caches(ScreenPtr screen);
+void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
 void glamor_glyphs_fini(ScreenPtr screen);
 void glamor_glyphs(CARD8 op,
                    PicturePtr pSrc,
diff --git a/glamor/glamor_rects.c b/glamor/glamor_rects.c
index 3a5c3f3..7161921 100644
--- a/glamor/glamor_rects.c
+++ b/glamor/glamor_rects.c
@@ -173,15 +173,3 @@ glamor_poly_fill_rect(DrawablePtr drawable,
         return;
     glamor_poly_fill_rect_bail(drawable, gc, nrect, prect);
 }
-
-Bool
-glamor_poly_fill_rect_nf(DrawablePtr drawable,
-                         GCPtr gc, int nrect, xRectangle *prect)
-{
-    if (glamor_poly_fill_rect_gl(drawable, gc, nrect, prect))
-        return TRUE;
-    if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
-        return FALSE;
-    glamor_poly_fill_rect_bail(drawable, gc, nrect, prect);
-    return TRUE;
-}
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 2386f2e..298e1a0 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -34,7 +34,6 @@
 
 #include "glamor_priv.h"
 
-#ifdef RENDER
 #include "mipict.h"
 #include "fbpict.h"
 #if 0
@@ -1560,17 +1559,16 @@ glamor_composite_clipped_region(CARD8 op,
     return ok;
 }
 
-static Bool
-_glamor_composite(CARD8 op,
-                  PicturePtr source,
-                  PicturePtr mask,
-                  PicturePtr dest,
-                  INT16 x_source,
-                  INT16 y_source,
-                  INT16 x_mask,
-                  INT16 y_mask,
-                  INT16 x_dest, INT16 y_dest,
-                  CARD16 width, CARD16 height, Bool fallback)
+void
+glamor_composite(CARD8 op,
+                 PicturePtr source,
+                 PicturePtr mask,
+                 PicturePtr dest,
+                 INT16 x_source,
+                 INT16 y_source,
+                 INT16 x_mask,
+                 INT16 y_mask,
+                 INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
 {
     ScreenPtr screen = dest->pDrawable->pScreen;
     glamor_pixmap_private *dest_pixmap_priv;
@@ -1578,7 +1576,6 @@ _glamor_composite(CARD8 op,
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
     PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    Bool ret = TRUE;
     RegionRec region;
     BoxPtr extent;
     int nbox, ok = FALSE;
@@ -1639,18 +1636,16 @@ _glamor_composite(CARD8 op,
                                   (mask_pixmap ? mask->pDrawable->y : 0),
                                   x_dest + dest->pDrawable->x,
                                   y_dest + dest->pDrawable->y, width, height)) {
-        ret = TRUE;
-        goto done;
+        return;
     }
 
     nbox = REGION_NUM_RECTS(&region);
     DEBUGF("first clipped when compositing.\n");
     DEBUGRegionPrint(&region);
     extent = RegionExtents(&region);
-    if (nbox == 0) {
-        ret = TRUE;
-        goto done;
-    }
+    if (nbox == 0)
+        return;
+
     /* If destination is not a large pixmap, but the region is larger
      * than texture size limitation, and source or mask is memory pixmap,
      * then there may be need to load a large memory pixmap to a
@@ -1698,17 +1693,9 @@ _glamor_composite(CARD8 op,
     REGION_UNINIT(dest->pDrawable->pScreen, &region);
 
     if (ok)
-        goto done;
- fail:
+        return;
 
-    if (!fallback && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable)
-        && (!source_pixmap
-            || glamor_ddx_fallback_check_pixmap(&source_pixmap->drawable))
-        && (!mask_pixmap
-            || glamor_ddx_fallback_check_pixmap(&mask_pixmap->drawable))) {
-        ret = FALSE;
-        goto done;
-    }
+ fail:
 
     glamor_fallback
         ("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c)  to pict %p:%p %dx%d (%c)\n",
@@ -1739,40 +1726,6 @@ _glamor_composite(CARD8 op,
     glamor_finish_access_picture(mask);
     glamor_finish_access_picture(source);
     glamor_finish_access_picture(dest);
-
- done:
-    return ret;
-}
-
-void
-glamor_composite(CARD8 op,
-                 PicturePtr source,
-                 PicturePtr mask,
-                 PicturePtr dest,
-                 INT16 x_source,
-                 INT16 y_source,
-                 INT16 x_mask,
-                 INT16 y_mask,
-                 INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
-{
-    _glamor_composite(op, source, mask, dest, x_source, y_source,
-                      x_mask, y_mask, x_dest, y_dest, width, height, TRUE);
-}
-
-Bool
-glamor_composite_nf(CARD8 op,
-                    PicturePtr source,
-                    PicturePtr mask,
-                    PicturePtr dest,
-                    INT16 x_source,
-                    INT16 y_source,
-                    INT16 x_mask,
-                    INT16 y_mask,
-                    INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
-{
-    return _glamor_composite(op, source, mask, dest, x_source, y_source,
-                             x_mask, y_mask, x_dest, y_dest, width, height,
-                             FALSE);
 }
 
 static void
@@ -1900,31 +1853,3 @@ glamor_composite_glyph_rects(CARD8 op,
     if (temp_src && temp_src != src)
         FreePicture(temp_src, 0);
 }
-
-static Bool
-_glamor_composite_rects(CARD8 op,
-                        PicturePtr pDst,
-                        xRenderColor *color,
-                        int nRect, xRectangle *rects, Bool fallback)
-{
-    miCompositeRects(op, pDst, color, nRect, rects);
-    return TRUE;
-}
-
-void
-glamor_composite_rects(CARD8 op,
-                       PicturePtr pDst,
-                       xRenderColor *color, int nRect, xRectangle *rects)
-{
-    _glamor_composite_rects(op, pDst, color, nRect, rects, TRUE);
-}
-
-Bool
-glamor_composite_rects_nf(CARD8 op,
-                          PicturePtr pDst,
-                          xRenderColor *color, int nRect, xRectangle *rects)
-{
-    return _glamor_composite_rects(op, pDst, color, nRect, rects, FALSE);
-}
-
-#endif                          /* RENDER */
diff --git a/glamor/glamor_segs.c b/glamor/glamor_segs.c
index ff0daef..6d469ce 100644
--- a/glamor/glamor_segs.c
+++ b/glamor/glamor_segs.c
@@ -168,21 +168,3 @@ glamor_poly_segment(DrawablePtr drawable, GCPtr gc,
 
     glamor_poly_segment_bail(drawable, gc, nseg, segs);
 }
-
-Bool
-glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc,
-                       int nseg, xSegment *segs)
-{
-    if (glamor_poly_segment_gl(drawable, gc, nseg, segs))
-        return TRUE;
-
-    if (glamor_ddx_fallback_check_pixmap(drawable) &&
-        glamor_ddx_fallback_check_gc(gc))
-    {
-        return FALSE;
-    }
-
-    glamor_poly_segment_bail(drawable, gc, nseg, segs);
-    return TRUE;
-}
-
diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
index 6ebb12e..fe8c7dc 100644
--- a/glamor/glamor_spans.c
+++ b/glamor/glamor_spans.c
@@ -182,21 +182,6 @@ glamor_fill_spans(DrawablePtr drawable,
     glamor_fill_spans_bail(drawable, gc, n, points, widths, sorted);
 }
 
-Bool
-glamor_fill_spans_nf(DrawablePtr drawable,
-                     GCPtr gc,
-                     int n, DDXPointPtr points, int *widths, int sorted)
-{
-    if (glamor_fill_spans_gl(drawable, gc, n, points, widths, sorted))
-        return TRUE;
-
-    if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
-        return FALSE;
-
-    glamor_fill_spans_bail(drawable, gc, n, points, widths, sorted);
-    return TRUE;
-}
-
 static Bool
 glamor_get_spans_gl(DrawablePtr drawable, int wmax,
                     DDXPointPtr points, int *widths, int count, char *dst)
@@ -282,20 +267,6 @@ glamor_get_spans(DrawablePtr drawable, int wmax,
     glamor_get_spans_bail(drawable, wmax, points, widths, count, dst);
 }
 
-Bool
-glamor_get_spans_nf(DrawablePtr drawable, int wmax,
-                    DDXPointPtr points, int *widths, int count, char *dst)
-{
-    if (glamor_get_spans_gl(drawable, wmax, points, widths, count, dst))
-        return TRUE;
-
-    if (glamor_ddx_fallback_check_pixmap(drawable))
-        return FALSE;
-
-    glamor_get_spans_bail(drawable, wmax, points, widths, count, dst);
-    return TRUE;
-}
-
 static Bool
 glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
                     DDXPointPtr points, int *widths, int numPoints, int sorted)
@@ -415,17 +386,3 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
         return;
     glamor_set_spans_bail(drawable, gc, src, points, widths, numPoints, sorted);
 }
-
-Bool
-glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, char *src,
-                    DDXPointPtr points, int *widths, int numPoints, int sorted)
-{
-    if (glamor_set_spans_gl(drawable, gc, src, points, widths, numPoints, sorted))
-        return TRUE;
-
-    if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
-        return FALSE;
-
-    glamor_set_spans_bail(drawable, gc, src, points, widths, numPoints, sorted);
-    return TRUE;
-}
diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
index 59cd0fd..68593a4 100644
--- a/glamor/glamor_text.c
+++ b/glamor/glamor_text.c
@@ -302,18 +302,6 @@ bail:
     return FALSE;
 }
 
-Bool
-glamor_poly_text8_nf(DrawablePtr drawable, GCPtr gc,
-                     int x, int y, int count, char *chars, int *final_pos)
-{
-    if (glamor_poly_text(drawable, gc, x, y, count, chars, FALSE, final_pos))
-        return TRUE;
-    if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
-        return FALSE;
-    *final_pos = miPolyText8(drawable, gc, x, y, count, chars);
-    return TRUE;
-}
-
 int
 glamor_poly_text8(DrawablePtr drawable, GCPtr gc,
                    int x, int y, int count, char *chars)
@@ -325,19 +313,6 @@ glamor_poly_text8(DrawablePtr drawable, GCPtr gc,
     return miPolyText8(drawable, gc, x, y, count, chars);
 }
 
-Bool
-glamor_poly_text16_nf(DrawablePtr drawable, GCPtr gc,
-                      int x, int y, int count, unsigned short *chars, int *final_pos)
-{
-    if (glamor_poly_text(drawable, gc, x, y, count, (char *) chars, TRUE, final_pos))
-        return TRUE;
-
-    if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
-        return FALSE;
-    *final_pos = miPolyText16(drawable, gc, x, y, count, chars);
-    return TRUE;
-}
-
 int
 glamor_poly_text16(DrawablePtr drawable, GCPtr gc,
                     int x, int y, int count, unsigned short *chars)
@@ -497,13 +472,6 @@ bail:
     return FALSE;
 }
 
-Bool
-glamor_image_text8_nf(DrawablePtr drawable, GCPtr gc,
-                   int x, int y, int count, char *chars)
-{
-    return glamor_image_text(drawable, gc, x, y, count, chars, FALSE);
-}
-
 void
 glamor_image_text8(DrawablePtr drawable, GCPtr gc,
                    int x, int y, int count, char *chars)
@@ -512,13 +480,6 @@ glamor_image_text8(DrawablePtr drawable, GCPtr gc,
         miImageText8(drawable, gc, x, y, count, chars);
 }
 
-Bool
-glamor_image_text16_nf(DrawablePtr drawable, GCPtr gc,
-                       int x, int y, int count, unsigned short *chars)
-{
-    return glamor_image_text(drawable, gc, x, y, count, (char *) chars, TRUE);
-}
-
 void
 glamor_image_text16(DrawablePtr drawable, GCPtr gc,
                     int x, int y, int count, unsigned short *chars)
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index f8bf6c9..a448a6b 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -32,7 +32,6 @@
 
 #include "glamor_priv.h"
 
-#ifdef RENDER
 #include "mipict.h"
 #include "fbpict.h"
 
@@ -155,18 +154,3 @@ glamor_trapezoids(CARD8 op,
 
     FreePicture(picture, 0);
 }
-
-Bool
-glamor_trapezoids_nf(CARD8 op,
-                     PicturePtr src, PicturePtr dst,
-                     PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-                     int ntrap, xTrapezoid *traps)
-{
-    DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap);
-
-    glamor_trapezoids(op, src, dst, mask_format, x_src,
-                      y_src, ntrap, traps);
-    return TRUE;
-}
-
-#endif                          /* RENDER */
diff --git a/glamor/glamor_triangles.c b/glamor/glamor_triangles.c
index b89cb2d..88a46c1 100644
--- a/glamor/glamor_triangles.c
+++ b/glamor/glamor_triangles.c
@@ -28,29 +28,6 @@
 
 #include "glamor_priv.h"
 
-static Bool
-_glamor_triangles(CARD8 op,
-                  PicturePtr pSrc,
-                  PicturePtr pDst,
-                  PictFormatPtr maskFormat,
-                  INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris,
-                  Bool fallback)
-{
-    if (!fallback && glamor_ddx_fallback_check_pixmap(pDst->pDrawable)
-        && (!pSrc->pDrawable
-            || glamor_ddx_fallback_check_pixmap(pSrc->pDrawable)))
-        return FALSE;
-
-    if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW) &&
-        glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) {
-        fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris);
-    }
-    glamor_finish_access_picture(pSrc);
-    glamor_finish_access_picture(pDst);
-
-    return TRUE;
-}
-
 void
 glamor_triangles(CARD8 op,
                  PicturePtr pSrc,
@@ -58,17 +35,10 @@ glamor_triangles(CARD8 op,
                  PictFormatPtr maskFormat,
                  INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
 {
-    _glamor_triangles(op, pSrc, pDst, maskFormat,
-                      xSrc, ySrc, ntris, tris, TRUE);
-}
-
-Bool
-glamor_triangles_nf(CARD8 op,
-                    PicturePtr pSrc,
-                    PicturePtr pDst,
-                    PictFormatPtr maskFormat,
-                    INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
-{
-    return _glamor_triangles(op, pSrc, pDst, maskFormat,
-                             xSrc, ySrc, ntris, tris, FALSE);
+    if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW) &&
+        glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) {
+        fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris);
+    }
+    glamor_finish_access_picture(pSrc);
+    glamor_finish_access_picture(pDst);
 }
commit 697f8581e04a93862a6049cc982d01d25f9a0410
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 20:30:12 2014 -0700

    glamor: Eliminate GLAMOR_USE_SCREEN and GLAMOR_USE_PICTURE_SCREEN
    
    Remove these defines as we start to remove support for non-standard
    glamor layering as used by the intel driver.
    
    v2: Rebase on the blockhandler change and the Xephyr init failure
        change (by anholt), fix stray NO_DRI3 addition to xwayland.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index d9ea496..7de2dba 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -309,10 +309,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_screen_private *glamor_priv;
     int gl_version;
     int max_viewport_size[2];
-
-#ifdef RENDER
     PictureScreenPtr ps = GetPictureScreenIfSet(screen);
-#endif
+
     if (flags & ~GLAMOR_VALID_FLAGS) {
         ErrorF("glamor_init: Invalid flags %x\n", flags);
         return FALSE;
@@ -447,51 +445,45 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     if (!glamor_font_init(screen))
         goto fail;
 
-    if (flags & GLAMOR_USE_SCREEN) {
+    glamor_priv->saved_procs.block_handler = screen->BlockHandler;
+    screen->BlockHandler = _glamor_block_handler;
 
-        glamor_priv->saved_procs.block_handler = screen->BlockHandler;
-        screen->BlockHandler = _glamor_block_handler;
+    glamor_priv->saved_procs.create_gc = screen->CreateGC;
+    screen->CreateGC = glamor_create_gc;
 
-        glamor_priv->saved_procs.create_gc = screen->CreateGC;
-        screen->CreateGC = glamor_create_gc;
+    glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
+    screen->CreatePixmap = glamor_create_pixmap;
 
-        glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
-        screen->CreatePixmap = glamor_create_pixmap;
+    glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
+    screen->DestroyPixmap = glamor_destroy_pixmap;
 
-        glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
-        screen->DestroyPixmap = glamor_destroy_pixmap;
+    glamor_priv->saved_procs.get_spans = screen->GetSpans;
+    screen->GetSpans = glamor_get_spans;
 
-        glamor_priv->saved_procs.get_spans = screen->GetSpans;
-        screen->GetSpans = glamor_get_spans;
+    glamor_priv->saved_procs.get_image = screen->GetImage;
+    screen->GetImage = glamor_get_image;
 
-        glamor_priv->saved_procs.get_image = screen->GetImage;
-        screen->GetImage = glamor_get_image;
+    glamor_priv->saved_procs.change_window_attributes =
+        screen->ChangeWindowAttributes;
+    screen->ChangeWindowAttributes = glamor_change_window_attributes;
 
-        glamor_priv->saved_procs.change_window_attributes =
-            screen->ChangeWindowAttributes;
-        screen->ChangeWindowAttributes = glamor_change_window_attributes;
+    glamor_priv->saved_procs.copy_window = screen->CopyWindow;
+    screen->CopyWindow = glamor_copy_window;
 
-        glamor_priv->saved_procs.copy_window = screen->CopyWindow;
-        screen->CopyWindow = glamor_copy_window;
+    glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion;
+    screen->BitmapToRegion = glamor_bitmap_to_region;
 
-        glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion;
-        screen->BitmapToRegion = glamor_bitmap_to_region;
-    }
-#ifdef RENDER
-    if (flags & GLAMOR_USE_PICTURE_SCREEN) {
-        glamor_priv->saved_procs.composite = ps->Composite;
-        ps->Composite = glamor_composite;
+    glamor_priv->saved_procs.composite = ps->Composite;
+    ps->Composite = glamor_composite;
 
-        glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
-        ps->Trapezoids = glamor_trapezoids;
+    glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
+    ps->Trapezoids = glamor_trapezoids;
 
-        glamor_priv->saved_procs.triangles = ps->Triangles;
-        ps->Triangles = glamor_triangles;
+    glamor_priv->saved_procs.triangles = ps->Triangles;
+    ps->Triangles = glamor_triangles;
 
-        glamor_priv->saved_procs.addtraps = ps->AddTraps;
-        ps->AddTraps = glamor_add_traps;
-
-    }
+    glamor_priv->saved_procs.addtraps = ps->AddTraps;
+    ps->AddTraps = glamor_add_traps;
 
     glamor_priv->saved_procs.composite_rects = ps->CompositeRects;
     ps->CompositeRects = glamor_composite_rectangles;
@@ -508,13 +500,14 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture;
     ps->DestroyPicture = glamor_destroy_picture;
     glamor_init_composite_shaders(screen);
-#endif
+
     glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
     screen->SetWindowPixmap = glamor_set_window_pixmap;
 
     glamor_init_vbo(screen);
     glamor_init_pixmap_fbo(screen);
     glamor_init_finish_access_shaders(screen);
+
 #ifdef GLAMOR_GRADIENT_SHADER
     glamor_init_gradient_shader(screen);
 #endif
@@ -537,9 +530,7 @@ glamor_release_screen_priv(ScreenPtr screen)
     glamor_screen_private *glamor_priv;
 
     glamor_priv = glamor_get_screen_private(screen);
-#ifdef RENDER
     glamor_fini_composite_shaders(screen);
-#endif
     glamor_fini_vbo(screen);
     glamor_fini_pixmap_fbo(screen);
     glamor_fini_finish_access_shaders(screen);
@@ -578,43 +569,34 @@ glamor_close_screen(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
     PixmapPtr screen_pixmap;
-    int flags;
-
-#ifdef RENDER
     PictureScreenPtr ps = GetPictureScreenIfSet(screen);
-#endif
+
     glamor_priv = glamor_get_screen_private(screen);
-    flags = glamor_priv->flags;
     glamor_sync_close(screen);
     glamor_glyphs_fini(screen);
     screen->CloseScreen = glamor_priv->saved_procs.close_screen;
     screen->CreateScreenResources =
         glamor_priv->saved_procs.create_screen_resources;
-    if (flags & GLAMOR_USE_SCREEN) {
-
-        screen->CreateGC = glamor_priv->saved_procs.create_gc;
-        screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
-        screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
-        screen->GetSpans = glamor_priv->saved_procs.get_spans;
-        screen->ChangeWindowAttributes =
-            glamor_priv->saved_procs.change_window_attributes;
-        screen->CopyWindow = glamor_priv->saved_procs.copy_window;
-        screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
-        screen->BlockHandler = glamor_priv->saved_procs.block_handler;
-    }
-#ifdef RENDER
-    if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) {
 
-        ps->Composite = glamor_priv->saved_procs.composite;
-        ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
-        ps->Triangles = glamor_priv->saved_procs.triangles;
-        ps->CreatePicture = glamor_priv->saved_procs.create_picture;
-    }
+    screen->CreateGC = glamor_priv->saved_procs.create_gc;
+    screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
+    screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
+    screen->GetSpans = glamor_priv->saved_procs.get_spans;
+    screen->ChangeWindowAttributes =
+        glamor_priv->saved_procs.change_window_attributes;
+    screen->CopyWindow = glamor_priv->saved_procs.copy_window;
+    screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
+    screen->BlockHandler = glamor_priv->saved_procs.block_handler;
+
+    ps->Composite = glamor_priv->saved_procs.composite;
+    ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
+    ps->Triangles = glamor_priv->saved_procs.triangles;
+    ps->CreatePicture = glamor_priv->saved_procs.create_picture;
     ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
     ps->Glyphs = glamor_priv->saved_procs.glyphs;
     ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph;
     screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
-#endif
+
     screen_pixmap = screen->GetScreenPixmap(screen);
     glamor_set_pixmap_private(screen_pixmap, NULL);
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index dc8e694..b7a41e5 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -62,15 +62,9 @@ typedef enum glamor_pixmap_type {
 } glamor_pixmap_type_t;
 
 #define GLAMOR_EGL_EXTERNAL_BUFFER 3
-#define GLAMOR_INVERTED_Y_AXIS         1 /* compat stub */
-#define GLAMOR_USE_SCREEN		(1 << 1)
-#define GLAMOR_USE_PICTURE_SCREEN 	(1 << 2)
-#define GLAMOR_USE_EGL_SCREEN		(1 << 3)
-#define GLAMOR_NO_DRI3			(1 << 4)
-#define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS  		\
-				 | GLAMOR_USE_SCREEN 			\
-                                 | GLAMOR_USE_PICTURE_SCREEN		\
-				 | GLAMOR_USE_EGL_SCREEN                \
+#define GLAMOR_USE_EGL_SCREEN		(1 << 0)
+#define GLAMOR_NO_DRI3			(1 << 1)
+#define GLAMOR_VALID_FLAGS      (GLAMOR_USE_EGL_SCREEN                \
                                  | GLAMOR_NO_DRI3)
 
 /* @glamor_init: Initialize glamor internal data structure.
@@ -78,23 +72,13 @@ typedef enum glamor_pixmap_type {
  * @screen: Current screen pointer.
  * @flags:  Please refer the flags description above.
  *
- * 	@GLAMOR_USE_SCREEN:
- *	If running in an pre-existing X environment, and the
- * 	gl context is GLX, then you should set this bit and
- * 	let the glamor to handle all the screen related
- * 	functions such as GC ops and CreatePixmap/DestroyPixmap.
- *
- * 	@GLAMOR_USE_PICTURE_SCREEN:
- * 	If don't use any other underlying DDX driver to handle
- * 	the picture related rendering functions, please set this
- * 	bit on. Otherwise, clear this bit. And then it is the DDX
- * 	driver's responsibility to determine how/when to jump to
- * 	glamor's picture compositing path.
- *
  * 	@GLAMOR_USE_EGL_SCREEN:
  * 	If you are using EGL layer, then please set this bit
  * 	on, otherwise, clear it.
  *
+ *      @GLAMOR_NO_DRI3
+ *      Disable the built-in DRI3 support
+ *
  * This function initializes necessary internal data structure
  * for glamor. And before calling into this function, the OpenGL
  * environment should be ready. Should be called before any real
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 8e14877..506a852 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -1407,9 +1407,7 @@ ephyr_glamor_init(ScreenPtr screen)
     ephyr_glamor_set_window_size(scrpriv->glamor,
                                  scrpriv->win_width, scrpriv->win_height);
 
-    if (!glamor_init(screen,
-                     GLAMOR_USE_SCREEN |
-                     GLAMOR_USE_PICTURE_SCREEN)) {
+    if (!glamor_init(screen, 0)) {
         FatalError("Failed to initialize glamor\n");
         return FALSE;
     }
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index d52517d..e2f3846 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1049,10 +1049,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
 
 #ifdef GLAMOR
     if (ms->drmmode.glamor) {
-        if (!glamor_init(pScreen,
-                         GLAMOR_USE_EGL_SCREEN |
-                         GLAMOR_USE_SCREEN |
-                         GLAMOR_USE_PICTURE_SCREEN)) {
+        if (!glamor_init(pScreen, GLAMOR_USE_EGL_SCREEN)) {
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                        "Failed to initialize glamor at ScreenInit() time.\n");
             return FALSE;
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index dd85518..d06006c 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -549,11 +549,7 @@ xwl_glamor_init(struct xwl_screen *xwl_screen)
         return FALSE;
     }
 
-    if (!glamor_init(xwl_screen->screen,
-                     GLAMOR_INVERTED_Y_AXIS |
-                     GLAMOR_USE_EGL_SCREEN |
-                     GLAMOR_USE_SCREEN |
-                     GLAMOR_USE_PICTURE_SCREEN)) {
+    if (!glamor_init(xwl_screen->screen, GLAMOR_USE_EGL_SCREEN)) {
         ErrorF("Failed to initialize glamor\n");
         return FALSE;
     }
commit 28ff815c4b32c88bd9007fd79f2acf3682a4b4db
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 29 20:20:29 2014 -0700

    glamor: Eliminate GLAMOR_CREATE_PIXMAP_MAP and GLAMOR_MEMORY_MAP
    
    GLAMOR_MEMORY_MAP was only used with GLAMOR_CREATE_PIXMAP_MAP, and
    GLAMOR_CREATE_PIXMAP_MAP doesn't appear to be used anywhere, so just
    remove both of them.
    
    v2: Fix a stray whitespace bug that was introduced (change by anholt).
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 6a3b336..d9ea496 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -169,9 +169,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     }
     glamor_set_pixmap_private(pixmap, pixmap_priv);
 
-    if (usage == GLAMOR_CREATE_PIXMAP_MAP)
-        type = GLAMOR_MEMORY_MAP;
-
     pixmap_priv->base.pixmap = pixmap;
     pixmap_priv->base.glamor_priv = glamor_priv;
 
@@ -188,7 +185,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
         pixmap_priv->base.box.y2 = h;
         return pixmap;
     }
-    else if (type == GLAMOR_MEMORY_MAP || usage == GLAMOR_CREATE_NO_LARGE ||
+    else if (usage == GLAMOR_CREATE_NO_LARGE ||
         glamor_check_fbo_size(glamor_priv, w, h))
     {
         pixmap_priv->type = type;
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 206158c..dc8e694 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -53,7 +53,6 @@ struct glamor_context;
  */
 typedef enum glamor_pixmap_type {
     GLAMOR_MEMORY,
-    GLAMOR_MEMORY_MAP,
     GLAMOR_TEXTURE_DRM,
     GLAMOR_SEPARATE_TEXTURE,
     GLAMOR_DRM_ONLY,
@@ -142,7 +141,6 @@ extern _X_EXPORT Bool glamor_destroy_pixmap(PixmapPtr pixmap);
 #define GLAMOR_CREATE_PIXMAP_CPU        0x100
 #define GLAMOR_CREATE_PIXMAP_FIXUP      0x101
 #define GLAMOR_CREATE_FBO_NO_FBO        0x103
-#define GLAMOR_CREATE_PIXMAP_MAP        0x104
 #define GLAMOR_CREATE_NO_LARGE          0x105
 #define GLAMOR_CREATE_PIXMAP_NO_TEXTURE 0x106
 
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index ad4dfe6..ff6ed25 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -241,12 +241,6 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
     fbo->format = format;
     fbo->glamor_priv = glamor_priv;
 
-    if (flag == GLAMOR_CREATE_PIXMAP_MAP) {
-        glamor_make_current(glamor_priv);
-        glGenBuffers(1, &fbo->pbo);
-        goto done;
-    }
-
     if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
         if (glamor_pixmap_ensure_fb(fbo) != 0) {
             glamor_purge_fbo(fbo);
@@ -254,7 +248,6 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
         }
     }
 
- done:
     return fbo;
 }
 
@@ -367,9 +360,6 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
     if (flag == GLAMOR_CREATE_FBO_NO_FBO)
         goto new_fbo;
 
-    if (flag == GLAMOR_CREATE_PIXMAP_MAP)
-        goto no_tex;
-
     /* Tiling from textures requires exact pixmap sizes. As we don't
      * know which pixmaps will be used as tiles, just allocate
      * everything at the requested size
@@ -381,7 +371,6 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
         return fbo;
  new_fbo:
     tex = _glamor_create_tex(glamor_priv, w, h, format);
- no_tex:
     fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
 
     return fbo;
@@ -513,7 +502,6 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
             /* XXX For the Xephyr only, may be broken now. */
             pixmap_priv->base.gl_tex = 0;
         }
-    case GLAMOR_MEMORY_MAP:
         pixmap->devPrivate.ptr = NULL;
         break;
     default:
commit 0e1372e1bd8f79fa295738bc1e983cb3648ba4be
Author: Maarten Lankhorst <maarten.lankhorst at ubuntu.com>
Date:   Mon Jan 19 12:37:55 2015 +0100

    glamor: GL_TEXTURE_MAX_LEVEL is not available on GLES2
    
    Remove the calls to GL_TEXTURE_MAX_LEVEL. Setting the filtering is
    a sufficient hint to the driver about texture mipmap allocation.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at ubuntu.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 8d73e47..ad4dfe6 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -348,7 +348,6 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
         glamor_make_current(glamor_priv);
         glGenTextures(1, &tex);
         glBindTexture(GL_TEXTURE_2D, tex);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
diff --git a/glamor/glamor_font.c b/glamor/glamor_font.c
index 0ca91fa..cc0fecf 100644
--- a/glamor/glamor_font.c
+++ b/glamor/glamor_font.c
@@ -97,7 +97,6 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, glamor_font->texture_id);
 
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 947113e..0d92710 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -717,7 +717,6 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
     }
 
     glBindTexture(GL_TEXTURE_2D, *tex);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
commit c1f35c3d862f77cbd2fb871be5613fb0ca7e508b
Author: Maarten Lankhorst <maarten.lankhorst at ubuntu.com>
Date:   Mon Jan 12 15:29:34 2015 +0100

    glamor: Use GL_FRAMEBUFFER instead of GL_READ_FRAMEBUFFER
    
    The latter might not be available on GLES2.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at ubuntu.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
index 582d11d..6ebb12e 100644
--- a/glamor/glamor_spans.c
+++ b/glamor/glamor_spans.c
@@ -226,7 +226,7 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
         BoxPtr                  box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
         glamor_pixmap_fbo       *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y);
 
-        glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->fb);
+        glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
         glPixelStorei(GL_PACK_ALIGNMENT, 4);
 
         d = dst;
diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
index c920435..aa5e861 100644
--- a/glamor/glamor_transfer.c
+++ b/glamor/glamor_transfer.c
@@ -186,7 +186,7 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
         BoxPtr                  boxes = in_boxes;
         int                     nbox = in_nbox;
 
-        glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->fb);
+        glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
 
         while (nbox--) {
 
commit b66501b4fd9c392e0f971ea356b27eb71c9c9e79
Author: Maarten Lankhorst <maarten.lankhorst at ubuntu.com>
Date:   Mon Jan 19 12:36:52 2015 +0100

    glamor: do not check for gl errors in glamor_build_program
    
    According to Eric Anholt the check for glGetError is not needed here.
    Because a opengl error might be set before this function is called
    keeping the check could result in glamor_build_program returning
    failure when building the shader succeeded.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at ubuntu.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index 1d0328f..3207aaf 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -343,9 +343,6 @@ glamor_build_program(ScreenPtr          screen,
     prog->dash_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash");
     prog->dash_length_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash_length");
 
-    if (glGetError() != GL_NO_ERROR)
-        goto fail;
-
     free(version_string);
     free(fs_vars);
     free(vs_vars);
commit 7c6f483670770e4e534cafd4e70d0b1490f4cca6
Author: Maarten Lankhorst <maarten.lankhorst at ubuntu.com>
Date:   Mon Jan 19 12:32:54 2015 +0100

    glamor: only use (un)pack_subimage when available
    
    Check for GL_EXT_unpack_subimage and GL_NV_pack_subimage to
    check if GL_(UN)PACK_ROW_LENGTH is available. Set the offsets
    manually to prevent calls to GL_(UN)PACK_SKIP_*.
    
    v2: Check support for GL_NV_pack_subimage as suggested by Matt Turner.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at ubuntu.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 017266a..6a3b336 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -411,6 +411,14 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         epoxy_has_gl_extension("GL_ARB_buffer_storage");
     glamor_priv->has_nv_texture_barrier =
         epoxy_has_gl_extension("GL_NV_texture_barrier");
+    glamor_priv->has_unpack_subimage =
+        glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP ||
+        epoxy_gl_version() >= 30 ||
+        epoxy_has_gl_extension("GL_EXT_unpack_subimage");
+    glamor_priv->has_pack_subimage =
+        glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP ||
+        epoxy_gl_version() >= 30 ||
+        epoxy_has_gl_extension("GL_NV_pack_subimage");
 
     glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);
     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index ed6e2d1..60070e9 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -236,6 +236,8 @@ typedef struct glamor_screen_private {
     int has_buffer_storage;
     int has_khr_debug;
     int has_nv_texture_barrier;
+    int has_pack_subimage;
+    int has_unpack_subimage;
     int max_fbo_size;
     int has_rw_pbo;
 
diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
index 8914155..c920435 100644
--- a/glamor/glamor_transfer.c
+++ b/glamor/glamor_transfer.c
@@ -73,7 +73,9 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
     glamor_make_current(glamor_priv);
 
     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
+
+    if (glamor_priv->has_unpack_subimage)
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
 
     glamor_pixmap_loop(priv, box_x, box_y) {
         BoxPtr                  box = glamor_pixmap_box_at(priv, box_x, box_y);
@@ -92,25 +94,34 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
             int y1 = MAX(boxes->y1 + dy_dst, box->y1);
             int y2 = MIN(boxes->y2 + dy_dst, box->y2);
 
+            size_t ofs = (y1 - dy_dst + dy_src) * byte_stride;
+            ofs += (x1 - dx_dst + dx_src) * bytes_per_pixel;
+
             boxes++;
 
             if (x2 <= x1 || y2 <= y1)
                 continue;
 
-            glPixelStorei(GL_UNPACK_SKIP_ROWS, y1 - dy_dst + dy_src);
-            glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1 - dx_dst + dx_src);
-
-            glTexSubImage2D(GL_TEXTURE_2D, 0,
-                            x1 - box->x1, y1 - box->y1,
-                            x2 - x1, y2 - y1,
-                            format, type,
-                            bits);
+            if (glamor_priv->has_unpack_subimage ||
+                x2 - x1 == byte_stride / bytes_per_pixel) {
+                glTexSubImage2D(GL_TEXTURE_2D, 0,
+                                x1 - box->x1, y1 - box->y1,
+                                x2 - x1, y2 - y1,
+                                format, type,
+                                bits + ofs);
+            } else {
+                for (; y1 < y2; y1++, ofs += byte_stride)
+                    glTexSubImage2D(GL_TEXTURE_2D, 0,
+                                    x1 - box->x1, y1 - box->y1,
+                                    x2 - x1, 1,
+                                    format, type,
+                                    bits + ofs);
+            }
         }
     }
 
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
-    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+    if (glamor_priv->has_unpack_subimage)
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 }
 
 /*
@@ -166,7 +177,8 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
     glamor_make_current(glamor_priv);
 
     glPixelStorei(GL_PACK_ALIGNMENT, 4);
-    glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
+    if (glamor_priv->has_pack_subimage)
+        glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
 
     glamor_pixmap_loop(priv, box_x, box_y) {
         BoxPtr                  box = glamor_pixmap_box_at(priv, box_x, box_y);
@@ -183,20 +195,25 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
             int                     x2 = MIN(boxes->x2 + dx_src, box->x2);
             int                     y1 = MAX(boxes->y1 + dy_src, box->y1);
             int                     y2 = MIN(boxes->y2 + dy_src, box->y2);
+            size_t ofs = (y1 - dy_src + dy_dst) * byte_stride;
+            ofs += (x1 - dx_src + dx_dst) * bytes_per_pixel;
 
             boxes++;
 
             if (x2 <= x1 || y2 <= y1)
                 continue;
 
-            glPixelStorei(GL_PACK_SKIP_PIXELS, x1 - dx_src + dx_dst);
-            glPixelStorei(GL_PACK_SKIP_ROWS, y1 - dy_src + dy_dst);
-            glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits);
+            if (glamor_priv->has_pack_subimage ||
+                x2 - x1 == byte_stride / bytes_per_pixel) {
+                glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits + ofs);
+            } else {
+                for (; y1 < y2; y1++, ofs += byte_stride)
+                    glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, 1, format, type, bits + ofs);
+            }
         }
     }
-    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
-    glPixelStorei(GL_PACK_SKIP_ROWS, 0);
-    glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+    if (glamor_priv->has_pack_subimage)
+        glPixelStorei(GL_PACK_ROW_LENGTH, 0);
 }
 
 /*
commit 4f534c26c64cc1edd33b04d30e4df818b7ae55d9
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Jan 28 16:08:26 2015 +0100

    xwayland: Add dependency on glamor libs
    
    So that Xwayland gets re-linked each time glamor is modified.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am
index 9945540..ab1bbb6 100644
--- a/hw/xwayland/Makefile.am
+++ b/hw/xwayland/Makefile.am
@@ -43,6 +43,7 @@ xwayland-glamor.c : $(nodist_Xwayland_SOURCES)
 glamor_lib = $(top_builddir)/glamor/libglamor.la
 
 Xwayland_LDADD += $(GLAMOR_LIBS) $(GBM_LIBS) -lEGL -lGL
+Xwayland_DEPENDENCIES = $(glamor_lib)
 endif
 
 EXTRA_DIST = drm.xml
commit 251a067993658fd02f158fef36476f898c238e3c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Mon Feb 2 10:41:06 2015 +0100

    ephyr: Fail if glamor is requested but not usable
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index f64861b..8e14877 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -1407,9 +1407,12 @@ ephyr_glamor_init(ScreenPtr screen)
     ephyr_glamor_set_window_size(scrpriv->glamor,
                                  scrpriv->win_width, scrpriv->win_height);
 
-    glamor_init(screen,
-                GLAMOR_USE_SCREEN |
-                GLAMOR_USE_PICTURE_SCREEN);
+    if (!glamor_init(screen,
+                     GLAMOR_USE_SCREEN |
+                     GLAMOR_USE_PICTURE_SCREEN)) {
+        FatalError("Failed to initialize glamor\n");
+        return FALSE;
+    }
 
     return TRUE;
 }
commit 23702dd2689e2e1e65be5767ac0303a985bb04a0
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Thu Mar 19 12:26:29 2015 +0000

    randr: coding style fixes
    
    In most of xserver code-base we define new functions at column 0, with
    their return type provided on the previous line. Two functions did not
    follow this rule so update them, and get them wrapped up to 80 as an
    added bonus.
    
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 0df96a4..e235c5f 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -1575,7 +1575,8 @@ ProcRRGetCrtcTransform(ClientPtr client)
     return Success;
 }
 
-static Bool check_all_screen_crtcs(ScreenPtr pScreen, int *x, int *y)
+static Bool
+check_all_screen_crtcs(ScreenPtr pScreen, int *x, int *y)
 {
     rrScrPriv(pScreen);
     int i;
@@ -1595,7 +1596,8 @@ static Bool check_all_screen_crtcs(ScreenPtr pScreen, int *x, int *y)
     return FALSE;
 }
 
-static Bool constrain_all_screen_crtcs(DeviceIntPtr pDev, ScreenPtr pScreen, int *x, int *y)
+static Bool
+constrain_all_screen_crtcs(DeviceIntPtr pDev, ScreenPtr pScreen, int *x, int *y)
 {
     rrScrPriv(pScreen);
     int i;
commit 739e8fac0e9d8d4c1653e53a8f3ce2d38b3de320
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Thu Mar 19 12:22:18 2015 +0000

    randr: wrap long line
    
    Also make use of total_name_len variable for consistency.
    
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index c2a7798..d0ca91e 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -413,8 +413,9 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
         .nbytesNames = total_name_len
     };
 
-    rep.length = (total_crtcs + total_outputs + total_modes * bytes_to_int32(SIZEOF(xRRModeInfo)) +
-                  bytes_to_int32(rep.nbytesNames));
+    rep.length = (total_crtcs + total_outputs +
+                  total_modes * bytes_to_int32(SIZEOF(xRRModeInfo)) +
+                  bytes_to_int32(total_name_len));
 
     extraLen = rep.length << 2;
     if (extraLen) {
commit 363cd0e0b499ea8c32b2aa5cf7ea0f0a56b4c3ef
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Thu Mar 19 12:19:23 2015 +0000

    randr: use local variables where possible
    
    This will allow us to make the code more readable, and the lines will
    fit within 80 columns.
    
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index dca0691..0df96a4 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -394,7 +394,7 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, int width, int height,
     Bool ret;
     int depth;
     PixmapPtr mscreenpix;
-    PixmapPtr protopix = crtc->pScreen->current_master->GetScreenPixmap(crtc->pScreen->current_master);
+    PixmapPtr protopix = master->GetScreenPixmap(master);
     rrScrPriv(crtc->pScreen);
 
     /* create a pixmap on the master screen,
@@ -457,18 +457,20 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
     /* have to iterate all the crtcs of the attached gpu masters
        and all their output slaves */
     for (c = 0; c < pScrPriv->numCrtcs; c++) {
-        if (pScrPriv->crtcs[c] == rr_crtc) {
+        RRCrtcPtr crtc = pScrPriv->crtcs[c];
+
+        if (crtc == rr_crtc) {
             newbox.x1 = x;
             newbox.x2 = x + w;
             newbox.y1 = y;
             newbox.y2 = y + h;
         } else {
-            if (!pScrPriv->crtcs[c]->mode)
+            if (!crtc->mode)
                 continue;
-            newbox.x1 = pScrPriv->crtcs[c]->x;
-            newbox.x2 = pScrPriv->crtcs[c]->x + pScrPriv->crtcs[c]->mode->mode.width;
-            newbox.y1 = pScrPriv->crtcs[c]->y;
-            newbox.y2 = pScrPriv->crtcs[c]->y + pScrPriv->crtcs[c]->mode->mode.height;
+            newbox.x1 = crtc->x;
+            newbox.x2 = crtc->x + crtc->mode->mode.width;
+            newbox.y1 = crtc->y;
+            newbox.y2 = crtc->y + crtc->mode->mode.height;
         }
         RegionInit(&new_crtc_region, &newbox, 1);
         RegionUnion(&total_region, &total_region, &new_crtc_region);
@@ -477,19 +479,21 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
     xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
         rrScrPrivPtr    slave_priv = rrGetScrPriv(slave);
         for (c = 0; c < slave_priv->numCrtcs; c++) {
-            if (slave_priv->crtcs[c] == rr_crtc) {
+            RRCrtcPtr slave_crtc = slave_priv->crtcs[c];
+
+            if (slave_crtc == rr_crtc) {
                 newbox.x1 = x;
                 newbox.x2 = x + w;
                 newbox.y1 = y;
                 newbox.y2 = y + h;
             }
             else {
-                if (!slave_priv->crtcs[c]->mode)
+                if (!slave_crtc->mode)
                     continue;
-                newbox.x1 = slave_priv->crtcs[c]->x;
-                newbox.x2 = slave_priv->crtcs[c]->x + slave_priv->crtcs[c]->mode->mode.width;
-                newbox.y1 = slave_priv->crtcs[c]->y;
-                newbox.y2 = slave_priv->crtcs[c]->y + slave_priv->crtcs[c]->mode->mode.height;
+                newbox.x1 = slave_crtc->x;
+                newbox.x2 = slave_crtc->x + slave_crtc->mode->mode.width;
+                newbox.y1 = slave_crtc->y;
+                newbox.y2 = slave_crtc->y + slave_crtc->mode->mode.height;
             }
             RegionInit(&new_crtc_region, &newbox, 1);
             RegionUnion(&total_region, &total_region, &new_crtc_region);
commit 93ef0e580e9cdbe739046a0873971d402525ef00
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Thu Mar 19 12:40:06 2015 +0000

    randr: use randr: prefix in ErrorF()
    
    To provide some information about the origin of the message.
    
    Cc: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 6d297aa..dca0691 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -428,7 +428,7 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, int width, int height,
 
     ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix);
     if (ret == FALSE) {
-        ErrorF("failed to set shadow slave pixmap\n");
+        ErrorF("randr: failed to set shadow slave pixmap\n");
         return FALSE;
     }
 
commit a08ee773983c44ebb893f10a1dcfa443f2734277
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Thu Mar 19 12:36:50 2015 +0000

    randr: remove chatty error messages
    
    All of these seem like left over from developments stage. Remove them as
    they can cause excessive flood in the logs.
    
    Cc: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 69b3ecf..6d297aa 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -502,7 +502,6 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
 
     if (new_width == screen_pixmap->drawable.width &&
         new_height == screen_pixmap->drawable.height) {
-        ErrorF("adjust shatters %d %d\n", newsize->x1, newsize->x2);
     } else {
         pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0);
     }
@@ -557,7 +556,6 @@ RRCrtcSet(RRCrtcPtr crtc,
                 width = mode->mode.width;
                 height = mode->mode.height;
             }
-            ErrorF("have a master to look out for\n");
             ret = rrCheckPixmapBounding(master, crtc,
                                         x, y, width, height);
             if (!ret)
@@ -565,8 +563,6 @@ RRCrtcSet(RRCrtcPtr crtc,
 
             if (pScreen->current_master) {
                 ret = rrCreateSharedPixmap(crtc, width, height, x, y);
-                ErrorF("need to create shared pixmap %d", ret);
-
             }
         }
 #if RANDR_12_INTERFACE
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index e7ea49d..c2a7798 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -400,8 +400,6 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
         update_totals(iter, pScrPriv);
     }
 
-    ErrorF("reporting %d %d %d %d\n", total_crtcs, total_outputs, total_modes, total_name_len);
-
     pScrPriv = rrGetScrPriv(pScreen);
     rep = (xRRGetScreenResourcesReply) {
         .type = X_Reply,
commit a34d29c2edd786f0baa0e7c334f4174eeecb71d2
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Sun Mar 8 17:56:58 2015 +0000

    configure.ac: remove remaining TLS references
    
    No longer used with the removal of the GL dispatch (glapi) from libglx a
    few releases ago.
    
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/configure.ac b/configure.ac
index 280c369..7fa5030 100644
--- a/configure.ac
+++ b/configure.ac
@@ -560,17 +560,7 @@ dnl GLX build options
 AC_ARG_ENABLE(aiglx,          AS_HELP_STRING([--enable-aiglx], [Build accelerated indirect GLX (default: enabled)]),
                                 [AIGLX=$enableval],
                                 [AIGLX=yes])
-XORG_TLS
-AC_ARG_ENABLE(glx-tls,        AS_HELP_STRING([--enable-glx-tls], [Build GLX with TLS support (default: auto)]),
-                                [GLX_USE_TLS=$enableval
-                                 if test "x$GLX_USE_TLS" = "xyes" && test "${ac_cv_tls}" = "none" ; then
-                                   AC_MSG_ERROR([GLX with TLS support requested, but the compiler does not support it.])
-                                 fi],
-                                [GLX_USE_TLS=no
-                                 if test "${ac_cv_tls}" != "none" ; then
-                                   GLX_USE_TLS=yes
-                                 fi])
-AC_SUBST(GLX_TLS, ${GLX_USE_TLS})
+
 AC_ARG_WITH(khronos-spec-dir, AS_HELP_STRING([--with-khronos-spec-dir=PATH], [Path to Khronos OpenGL registry database files (default: auto)]),
 				[KHRONOS_SPEC_DIR="${withval}"],
 				[KHRONOS_SPEC_DIR=auto])
@@ -1324,10 +1314,6 @@ if test "x$AIGLX" = xyes -a \( "x$DRI2" = xyes \); then
 fi
 AM_CONDITIONAL(AIGLX_DRI_LOADER, { test "x$DRI2" = xyes; } && test "x$AIGLX" = xyes)
 
-if test "x$GLX_USE_TLS" = xyes ; then
-	GLX_DEFINES="-DGLX_USE_TLS -DPTHREADS"
-	GLX_SYS_LIBS="$GLX_SYS_LIBS -lpthread"
-fi
 AC_SUBST([GLX_DEFINES])
 AC_SUBST([GLX_SYS_LIBS])
 
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 1aa77a5..bd479cf 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -454,9 +454,6 @@
 /* Define to __typeof__ if your compiler spells it that way. */
 #undef typeof
 
-/* The compiler supported TLS storage class, prefering initial-exec if tls_model is supported */
-#undef TLS
-
 /* Correctly set _XSERVER64 for OSX fat binaries */
 #ifdef __APPLE__
 #include "dix-config-apple-verbatim.h"
diff --git a/m4/xorg-tls.m4 b/m4/xorg-tls.m4
deleted file mode 100644
index 5768775..0000000
--- a/m4/xorg-tls.m4
+++ /dev/null
@@ -1,55 +0,0 @@
-dnl Copyright © 2011 Apple Inc.
-dnl
-dnl Permission is hereby granted, free of charge, to any person obtaining a
-dnl copy of this software and associated documentation files (the "Software"),
-dnl to deal in the Software without restriction, including without limitation
-dnl the rights to use, copy, modify, merge, publish, distribute, sublicense,
-dnl and/or sell copies of the Software, and to permit persons to whom the
-dnl Software is furnished to do so, subject to the following conditions:
-dnl
-dnl The above copyright notice and this permission notice (including the next
-dnl paragraph) shall be included in all copies or substantial portions of the
-dnl Software.
-dnl
-dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-dnl IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-dnl THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-dnl FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-dnl DEALINGS IN THE SOFTWARE.
-dnl
-dnl Authors: Jeremy Huddleston <jeremyhu at apple.com>
-
-AC_DEFUN([XORG_TLS], [
-    AC_REQUIRE([XORG_STRICT_OPTION])
-    AC_MSG_CHECKING(for thread local storage (TLS) support)
-    AC_CACHE_VAL(ac_cv_tls, [
-        ac_cv_tls=none
-        keywords="__thread __declspec(thread)"
-        for kw in $keywords ; do
-            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int $kw test;]], [])], ac_cv_tls=$kw ; break ;)
-        done
-    ])
-    AC_MSG_RESULT($ac_cv_tls)
-
-    if test "$ac_cv_tls" != "none"; then
-        AC_MSG_CHECKING(for tls_model attribute support)
-        AC_CACHE_VAL(ac_cv_tls_model, [
-            save_CFLAGS="$CFLAGS"
-            CFLAGS="$CFLAGS $STRICT_CFLAGS"
-            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int $ac_cv_tls __attribute__((tls_model("initial-exec"))) test;]], [])],
-                           ac_cv_tls_model=yes, ac_cv_tls_model=no)
-            CFLAGS="$save_CFLAGS"
-        ])
-        AC_MSG_RESULT($ac_cv_tls_model)
-
-        if test "x$ac_cv_tls_model" = "xyes" ; then
-            xorg_tls=$ac_cv_tls' __attribute__((tls_model("initial-exec")))'
-        else
-            xorg_tls=$ac_cv_tls
-        fi
-
-        AC_DEFINE_UNQUOTED([TLS], $xorg_tls, [The compiler supported TLS storage class, prefering initial-exec if tls_model is supported])
-    fi
-])
commit 95e83ff87ab0149ab01c9299524dfbe37d9b21a2
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Jul 12 02:00:43 2012 +0100

    Don't allow both RandR XINERAMA and pseudoramiX XINERAMA extensions to register
    
    Prevent RRXinerama from activating if PseudoramiX is, so we don't get XINERAMA
    listed twice in the list of extensions.  I think this is otherwise benign, as
    the PseudoramiX XINERAMA gets registered first and thus handles all requests.
    
    Perhaps AddExtension() ought to warn us if the extension name is already
    registered?
    
    This appears to be a long-standing bug seen in XQuartz, and now in XWin as well.
    
    Future work: Perhaps since RRXinerama isn't actually doing anything useful but
    faking it when we have one screen, it seems that the PseudoramiX code could be
    also used in that case.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/pseudoramiX/pseudoramiX.c b/pseudoramiX/pseudoramiX.c
index d0e2603..e59ca13 100644
--- a/pseudoramiX/pseudoramiX.c
+++ b/pseudoramiX/pseudoramiX.c
@@ -49,6 +49,7 @@
 #define DEBUG_LOG PseudoramiXDebug
 
 Bool noPseudoramiXExtension = FALSE;
+extern Bool noRRXineramaExtension;
 
 extern int
 ProcPanoramiXQueryVersion(ClientPtr client);
@@ -190,6 +191,9 @@ PseudoramiXExtensionInit(void)
         }
     }
 
+    /* Do not allow RRXinerama to initialize if we did */
+    noRRXineramaExtension = success;
+
     if (!success) {
         ErrorF("%s Extension (PseudoramiX) failed to initialize\n",
                PANORAMIX_PROTOCOL_NAME);
diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c
index b336bd7..36632c7 100644
--- a/randr/rrxinerama.c
+++ b/randr/rrxinerama.c
@@ -84,6 +84,8 @@ static int ProcRRXineramaIsActive(ClientPtr client);
 static int ProcRRXineramaQueryScreens(ClientPtr client);
 static int SProcRRXineramaDispatch(ClientPtr client);
 
+Bool noRRXineramaExtension = FALSE;
+
 /* Proc */
 
 int
@@ -488,6 +490,9 @@ RRXineramaExtensionInit(void)
         return;
 #endif
 
+    if (noRRXineramaExtension)
+      return;
+
     /*
      * Xinerama isn't capable enough to have multiple protocol screens each
      * with their own output geometry.  So if there's more than one protocol
commit 234fe391802b114e96d60a6630f717f8e4fb726c
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Fri Nov 7 13:38:20 2014 +0000

    hw/xwin: Report OS version in log
    
    Report OS version in log
    Report if WoW64 is in use
    Manifest for compatbility with Windows versions, so we don't get lied to by GetVersionEx()
    Also, make the description in the manifest a bit more generic
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am
index 9afde7e..4da3d12 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -71,6 +71,7 @@ SRCS =	InitInput.c \
 	winmsgwindow.c \
 	winmultiwindowclass.c \
 	winmultiwindowicons.c \
+	winos.c \
 	winprefs.c \
 	winprefsyacc.y \
 	winprefslex.l \
diff --git a/hw/xwin/XWin.exe.manifest b/hw/xwin/XWin.exe.manifest
index 477334f..bd44b10 100755
--- a/hw/xwin/XWin.exe.manifest
+++ b/hw/xwin/XWin.exe.manifest
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
-	<description>The XWin X Windows server for Cygwin.</description>
+	<description>The XWin X Windows server</description>
 	<dependency>
 	   <dependentAssembly>
 	     <assemblyIdentity
@@ -18,4 +18,18 @@
 	     <dpiAware>true</dpiAware>
 	   </asmv3:windowsSettings>
 	</asmv3:application>
+    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+        <application>
+            <!-- Windows Vista -->
+            <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+            <!-- Windows 7 -->
+            <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+            <!-- Windows 8 -->
+            <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+            <!-- Windows 8.1 -->
+            <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+            <!-- Windows 10 -->
+            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+        </application>
+    </compatibility>
 </assembly>
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index d41d001..5710ea8 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -1196,6 +1196,12 @@ Bool
 winCreateMsgWindowThread(void);
 
 /*
+ * winos.c
+ */
+void
+winOS(void);
+
+/*
  * END DDX and DIX Function Prototypes
  */
 
diff --git a/hw/xwin/winos.c b/hw/xwin/winos.c
new file mode 100644
index 0000000..0d825bb
--- /dev/null
+++ b/hw/xwin/winos.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010-2014 Colin Harrison All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ *
+ * Author: Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
+
+static const char*
+IsWow64(void)
+{
+#ifdef __x86_64__
+    return " (64-bit)";
+#else
+    WINBOOL bIsWow64;
+    LPFN_ISWOW64PROCESS fnIsWow64Process =
+        (LPFN_ISWOW64PROCESS) GetProcAddress(GetModuleHandle(TEXT("kernel32")),
+                                             "IsWow64Process");
+    if (NULL != fnIsWow64Process) {
+        if (fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
+            return bIsWow64 ? " (WoW64)" : " (32-bit)";
+    }
+
+    /* OS doesn't support IsWow64Process() */
+    return "";
+#endif
+}
+
+/*
+ * Report the OS version
+ */
+
+void
+winOS(void)
+{
+    OSVERSIONINFOEX osvi = {0};
+
+    /* Get operating system version information */
+    osvi.dwOSVersionInfoSize = sizeof(osvi);
+    GetVersionEx((LPOSVERSIONINFO)&osvi);
+
+    ErrorF("OS: Windows NT %d.%d build %d%s\n",
+           (int)osvi.dwMajorVersion, (int)osvi.dwMinorVersion,
+           (int)osvi.dwBuildNumber, IsWow64());
+}
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 65bba81..73aa027 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -1200,6 +1200,7 @@ winLogVersionInfo(void)
         }
     }
 #endif
+    winOS();
     if (strlen(BUILDERSTRING))
         ErrorF("%s\n", BUILDERSTRING);
     ErrorF("Contact: %s\n", BUILDERADDR);
commit 7a22912edbda826778463f8fefa9c8e689858bbe
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Nov 6 15:22:58 2014 +0000

    hw/xwin: Remove Shadow DirectDraw engine
    
    Maybe a long time ago this made some kind of sense, but now there's no good
    reason to ever use this, rather than the Shadow DirectDraw NonLocking engine.
    
    Also remove screen private data members used by other removed engines.
    
    Also remove no longer needed OS version check in winDetectSupportedEngines()
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 3b1ef3f..b6f2583 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -738,7 +738,6 @@ winUseMsg(void)
     ErrorF("-engine engine_type_id\n"
            "\tOverride the server's automatically selected engine type:\n"
            "\t\t1 - Shadow GDI\n"
-           "\t\t2 - Shadow DirectDraw\n"
            "\t\t4 - Shadow DirectDraw4 Non-Locking\n"
         );
 
diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am
index 0ea8ba7..9afde7e 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -76,7 +76,6 @@ SRCS =	InitInput.c \
 	winprefslex.l \
 	winprocarg.c \
 	winscrinit.c \
-	winshaddd.c \
 	winshadddnl.c \
 	winshadgdi.c \
 	wintaskbar.c \
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index 41019d1..d68ee2a 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -248,9 +248,6 @@ functionality does not provide a benefit at any number of boxes; we
 can only determine the usefulness of this feature through testing.
 This option probably has limited effect on current \fIWindows\fP versions
 as they already perform GDI batching.
-This parameter works in conjunction with engines 1, 2, and 4 (Shadow
-GDI, Shadow DirectDraw, and Shadow DirectDraw Non-Locking,
-respectively).
 .TP 8
 .B "\-engine \fIengine_type_id\fP"
 This option, which is intended for Cygwin/X developers,
@@ -265,8 +262,6 @@ The engine type ids are:
 .RS
 .IP 1 4
 Shadow GDI
-.IP 2 4
-Shadow DirectDraw
 .IP 4 4
 Shadow DirectDraw Non-Locking
 .RE
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index b7d20ca..d41d001 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -101,7 +101,6 @@
 
 #define WIN_SERVER_NONE		0x0L    /* 0 */
 #define WIN_SERVER_SHADOW_GDI	0x1L    /* 1 */
-#define WIN_SERVER_SHADOW_DD	0x2L    /* 2 */
 #define WIN_SERVER_SHADOW_DDNL	0x4L    /* 4 */
 
 #define AltMapIndex		Mod1MapIndex
@@ -468,35 +467,20 @@ typedef struct _winPrivScreenRec {
     int iE3BCachedPress;
     Bool fE3BFakeButton2Sent;
 
-    /* Privates used by shadow fb GDI server */
+    /* Privates used by shadow fb GDI engine */
     HBITMAP hbmpShadow;
     HDC hdcScreen;
     HDC hdcShadow;
     HWND hwndScreen;
     BITMAPINFOHEADER *pbmih;
 
-    /* Privates used by shadow fb and primary fb DirectDraw servers */
+    /* Privates used by shadow fb DirectDraw Nonlocking engine */
     LPDIRECTDRAW pdd;
-    LPDIRECTDRAWSURFACE2 pddsPrimary;
-    LPDIRECTDRAW2 pdd2;
-
-    /* Privates used by shadow fb DirectDraw server */
-    LPDIRECTDRAWSURFACE2 pddsShadow;
-    LPDDSURFACEDESC pddsdShadow;
-
-    /* Privates used by primary fb DirectDraw server */
-    LPDIRECTDRAWSURFACE2 pddsOffscreen;
-    LPDDSURFACEDESC pddsdOffscreen;
-    LPDDSURFACEDESC pddsdPrimary;
-
-    /* Privates used by shadow fb DirectDraw Nonlocking server */
     LPDIRECTDRAW4 pdd4;
     LPDIRECTDRAWSURFACE4 pddsShadow4;
     LPDIRECTDRAWSURFACE4 pddsPrimary4;
-    BOOL fRetryCreateSurface;
-
-    /* Privates used by both shadow fb DirectDraw servers */
     LPDIRECTDRAWCLIPPER pddcPrimary;
+    BOOL fRetryCreateSurface;
 
 #ifdef XWIN_MULTIWINDOWEXTWM
     /* Privates used by multi-window external window manager */
@@ -921,13 +905,6 @@ Bool
  winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv);
 
 /*
- * winshaddd.c
- */
-
-Bool
- winSetEngineFunctionsShadowDD(ScreenPtr pScreen);
-
-/*
  * winshadddnl.c
  */
 
diff --git a/hw/xwin/winengine.c b/hw/xwin/winengine.c
index b473b3a..b8f8da0 100644
--- a/hw/xwin/winengine.c
+++ b/hw/xwin/winengine.c
@@ -54,16 +54,9 @@ static HMODULE g_hmodDirectDraw = NULL;
 void
 winDetectSupportedEngines(void)
 {
-    OSVERSIONINFO osvi;
-
     /* Initialize the engine support flags */
     g_dwEnginesSupported = WIN_SERVER_SHADOW_GDI;
 
-    /* Get operating system version information */
-    ZeroMemory(&osvi, sizeof(osvi));
-    osvi.dwOSVersionInfoSize = sizeof(osvi);
-    GetVersionEx(&osvi);
-
     /* Do we have DirectDraw? */
     if (g_hmodDirectDraw != NULL) {
         LPDIRECTDRAW lpdd = NULL;
@@ -85,12 +78,6 @@ winDetectSupportedEngines(void)
                           "winDetectSupportedEngines - DirectDraw not installed\n");
             return;
         }
-        else {
-            /* We have DirectDraw */
-            winErrorFVerb(2,
-                          "winDetectSupportedEngines - DirectDraw installed, allowing ShadowDD\n");
-            g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD;
-        }
 
         /* Try to query for DirectDraw4 interface */
         ddrval = IDirectDraw_QueryInterface(lpdd,
@@ -187,9 +174,6 @@ winSetEngine(ScreenPtr pScreen)
         case WIN_SERVER_SHADOW_GDI:
             winSetEngineFunctionsShadowGDI(pScreen);
             break;
-        case WIN_SERVER_SHADOW_DD:
-            winSetEngineFunctionsShadowDD(pScreen);
-            break;
         case WIN_SERVER_SHADOW_DDNL:
             winSetEngineFunctionsShadowDDNL(pScreen);
             break;
@@ -209,16 +193,6 @@ winSetEngine(ScreenPtr pScreen)
         return TRUE;
     }
 
-    /* ShadowDD is next in line */
-    if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DD) {
-        winErrorFVerb(2, "winSetEngine - Using Shadow DirectDraw\n");
-        pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DD;
-
-        /* Set engine function pointers */
-        winSetEngineFunctionsShadowDD(pScreen);
-        return TRUE;
-    }
-
     /* ShadowGDI is next in line */
     if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) {
         winErrorFVerb(2, "winSetEngine - Using Shadow GDI DIB\n");
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index 31d5fdd..e68ee12 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -313,8 +313,6 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
     if (pScreenInfo->dwDepth == 8
         && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
             || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
-                && pScreenInfo->fFullScreen)
-            || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
                 && pScreenInfo->fFullScreen))) {
         winSetColormapFunctions(pScreen);
 
@@ -388,7 +386,6 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
 
     /* Initialize the shadow framebuffer layer */
     if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
-         || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
          || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)
 #ifdef XWIN_MULTIWINDOWEXTWM
         && !pScreenInfo->fMWExtWM
diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c
deleted file mode 100644
index 4904eb4..0000000
--- a/hw/xwin/winshaddd.c
+++ /dev/null
@@ -1,1221 +0,0 @@
-/*
- *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- *
- *Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- *"Software"), to deal in the Software without restriction, including
- *without limitation the rights to use, copy, modify, merge, publish,
- *distribute, sublicense, and/or sell copies of the Software, and to
- *permit persons to whom the Software is furnished to do so, subject to
- *the following conditions:
- *
- *The above copyright notice and this permission notice shall be
- *included in all copies or substantial portions of the Software.
- *
- *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
- *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- *Except as contained in this notice, the name of the XFree86 Project
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from the XFree86 Project.
- *
- * Authors:	Dakshinamurthy Karra
- *		Suhaib M Siddiqi
- *		Peter Busch
- *		Harold L Hunt II
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-
-/*
- * Local prototypes
- */
-
-static Bool
- winAllocateFBShadowDD(ScreenPtr pScreen);
-
-static void
- winShadowUpdateDD(ScreenPtr pScreen, shadowBufPtr pBuf);
-
-static Bool
- winCloseScreenShadowDD(ScreenPtr pScreen);
-
-static Bool
- winInitVisualsShadowDD(ScreenPtr pScreen);
-
-static Bool
- winAdjustVideoModeShadowDD(ScreenPtr pScreen);
-
-static Bool
- winBltExposedRegionsShadowDD(ScreenPtr pScreen);
-
-static Bool
- winActivateAppShadowDD(ScreenPtr pScreen);
-
-static Bool
- winRedrawScreenShadowDD(ScreenPtr pScreen);
-
-static Bool
- winRealizeInstalledPaletteShadowDD(ScreenPtr pScreen);
-
-static Bool
- winInstallColormapShadowDD(ColormapPtr pColormap);
-
-static Bool
- winStoreColorsShadowDD(ColormapPtr pmap, int ndef, xColorItem * pdefs);
-
-static Bool
- winCreateColormapShadowDD(ColormapPtr pColormap);
-
-static Bool
- winDestroyColormapShadowDD(ColormapPtr pColormap);
-
-static Bool
- winCreatePrimarySurfaceShadowDD(ScreenPtr pScreen);
-
-static Bool
- winReleasePrimarySurfaceShadowDD(ScreenPtr pScreen);
-
-/*
- * Create the primary surface and attach the clipper.
- * Used for both the initial surface creation and during
- * WM_DISPLAYCHANGE messages.
- */
-
-static Bool
-winCreatePrimarySurfaceShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-    HRESULT ddrval = DD_OK;
-    DDSURFACEDESC ddsd;
-
-    /* Describe the primary surface */
-    ZeroMemory(&ddsd, sizeof(ddsd));
-    ddsd.dwSize = sizeof(ddsd);
-    ddsd.dwFlags = DDSD_CAPS;
-    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
-    /* Create the primary surface */
-    ddrval = IDirectDraw2_CreateSurface(pScreenPriv->pdd2,
-                                        &ddsd, &pScreenPriv->pddsPrimary, NULL);
-    if (FAILED(ddrval)) {
-        ErrorF("winCreatePrimarySurfaceShadowDD - Could not create primary "
-               "surface: %08x\n", (unsigned int) ddrval);
-        return FALSE;
-    }
-
-#if CYGDEBUG
-    winDebug("winCreatePrimarySurfaceShadowDD - Created primary surface\n");
-#endif
-
-    /*
-     * Attach a clipper to the primary surface that will clip our blits to our
-     * display window.
-     */
-    ddrval = IDirectDrawSurface2_SetClipper(pScreenPriv->pddsPrimary,
-                                            pScreenPriv->pddcPrimary);
-    if (FAILED(ddrval)) {
-        ErrorF("winCreatePrimarySurfaceShadowDD - Primary attach clipper "
-               "failed: %08x\n", (unsigned int) ddrval);
-        return FALSE;
-    }
-
-#if CYGDEBUG
-    winDebug("winCreatePrimarySurfaceShadowDD - Attached clipper to "
-             "primary surface\n");
-#endif
-
-    /* Everything was correct */
-    return TRUE;
-}
-
-/*
- * Detach the clipper and release the primary surface.
- * Called from WM_DISPLAYCHANGE.
- */
-
-static Bool
-winReleasePrimarySurfaceShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-
-    ErrorF("winReleasePrimarySurfaceShadowDD - Hello\n");
-
-    /* Release the primary surface and clipper, if they exist */
-    if (pScreenPriv->pddsPrimary) {
-        /*
-         * Detach the clipper from the primary surface.
-         * NOTE: We do this explicity for clarity.  The Clipper is not released.
-         */
-        IDirectDrawSurface2_SetClipper(pScreenPriv->pddsPrimary, NULL);
-
-        ErrorF("winReleasePrimarySurfaceShadowDD - Detached clipper\n");
-
-        /* Release the primary surface */
-        IDirectDrawSurface2_Release(pScreenPriv->pddsPrimary);
-        pScreenPriv->pddsPrimary = NULL;
-    }
-
-    ErrorF("winReleasePrimarySurfaceShadowDD - Released primary surface\n");
-
-    return TRUE;
-}
-
-/*
- * Create a DirectDraw surface for the shadow framebuffer; also create
- * a primary surface object so we can blit to the display.
- *
- * Install a DirectDraw clipper on our primary surface object
- * that clips our blits to the unobscured client area of our display window.
- */
-
-static Bool
-winAllocateFBShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-    HRESULT ddrval = DD_OK;
-    DDSURFACEDESC ddsd;
-    DDSURFACEDESC *pddsdShadow = NULL;
-
-#if CYGDEBUG
-    winDebug("winAllocateFBShadowDD\n");
-#endif
-
-    /* Create a clipper */
-    ddrval = (*g_fpDirectDrawCreateClipper) (0,
-                                             &pScreenPriv->pddcPrimary, NULL);
-    if (FAILED(ddrval)) {
-        ErrorF("winAllocateFBShadowDD - Could not create clipper: %08x\n",
-               (unsigned int) ddrval);
-        return FALSE;
-    }
-
-#if CYGDEBUG
-    winDebug("winAllocateFBShadowDD - Created a clipper\n");
-#endif
-
-    /* Attach the clipper to our display window */
-    ddrval = IDirectDrawClipper_SetHWnd(pScreenPriv->pddcPrimary,
-                                        0, pScreenPriv->hwndScreen);
-    if (FAILED(ddrval)) {
-        ErrorF("winAllocateFBShadowDD - Clipper not attached to "
-               "window: %08x\n", (unsigned int) ddrval);
-        return FALSE;
-    }
-
-#if CYGDEBUG
-    winDebug("winAllocateFBShadowDD - Attached clipper to window\n");
-#endif
-
-    /* Create a DirectDraw object, store the address at lpdd */
-    ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL);
-    if (FAILED(ddrval)) {
-        ErrorF("winAllocateFBShadowDD - Could not start DirectDraw: %08x\n",
-               (unsigned int) ddrval);
-        return FALSE;
-    }
-
-#if CYGDEBUG
-    winDebug("winAllocateFBShadowDD () - Created and initialized DD\n");
-#endif
-
-    /* Get a DirectDraw2 interface pointer */
-    ddrval = IDirectDraw_QueryInterface(pScreenPriv->pdd,
-                                        &IID_IDirectDraw2,
-                                        (LPVOID *) &pScreenPriv->pdd2);
-    if (FAILED(ddrval)) {
-        ErrorF("winAllocateFBShadowDD - Failed DD2 query: %08x\n",
-               (unsigned int) ddrval);
-        return FALSE;
-    }
-
-    /* Are we full screen? */
-    if (pScreenInfo->fFullScreen) {
-        DDSURFACEDESC ddsdCurrent;
-        DWORD dwRefreshRateCurrent = 0;
-        HDC hdc = NULL;
-
-        /* Set the cooperative level to full screen */
-        ddrval = IDirectDraw2_SetCooperativeLevel(pScreenPriv->pdd2,
-                                                  pScreenPriv->hwndScreen,
-                                                  DDSCL_EXCLUSIVE
-                                                  | DDSCL_FULLSCREEN);
-        if (FAILED(ddrval)) {
-            ErrorF("winAllocateFBShadowDD - Could not set "
-                   "cooperative level: %08x\n", (unsigned int) ddrval);
-            return FALSE;
-        }
-
-        /*
-         * We only need to get the current refresh rate for comparison
-         * if a refresh rate has been passed on the command line.
-         */
-        if (pScreenInfo->dwRefreshRate != 0) {
-            ZeroMemory(&ddsdCurrent, sizeof(ddsdCurrent));
-            ddsdCurrent.dwSize = sizeof(ddsdCurrent);
-
-            /* Get information about current display settings */
-            ddrval = IDirectDraw2_GetDisplayMode(pScreenPriv->pdd2,
-                                                 &ddsdCurrent);
-            if (FAILED(ddrval)) {
-                ErrorF("winAllocateFBShadowDD - Could not get current "
-                       "refresh rate: %08x.  Continuing.\n",
-                       (unsigned int) ddrval);
-                dwRefreshRateCurrent = 0;
-            }
-            else {
-                /* Grab the current refresh rate */
-                dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate;
-            }
-        }
-
-        /* Clean up the refresh rate */
-        if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) {
-            /*
-             * Refresh rate is non-specified or equal to current.
-             */
-            pScreenInfo->dwRefreshRate = 0;
-        }
-
-        /* Grab a device context for the screen */
-        hdc = GetDC(NULL);
-        if (hdc == NULL) {
-            ErrorF("winAllocateFBShadowDD - GetDC () failed\n");
-            return FALSE;
-        }
-
-        /* Only change the video mode when different than current mode */
-        if (!pScreenInfo->fMultipleMonitors
-            && (pScreenInfo->dwWidth != GetSystemMetrics(SM_CXSCREEN)
-                || pScreenInfo->dwHeight != GetSystemMetrics(SM_CYSCREEN)
-                || pScreenInfo->dwBPP != GetDeviceCaps(hdc, BITSPIXEL)
-                || pScreenInfo->dwRefreshRate != 0)) {
-            ErrorF("winAllocateFBShadowDD - Changing video mode\n");
-
-            /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */
-            ddrval = IDirectDraw2_SetDisplayMode(pScreenPriv->pdd2,
-                                                 pScreenInfo->dwWidth,
-                                                 pScreenInfo->dwHeight,
-                                                 pScreenInfo->dwBPP,
-                                                 pScreenInfo->dwRefreshRate, 0);
-            if (FAILED(ddrval)) {
-                ErrorF("winAllocateFBShadowDD - Could not set "
-                       "full screen display mode: %08x\n",
-                       (unsigned int) ddrval);
-                ErrorF
-                    ("winAllocateFBShadowDD - Using default driver refresh rate\n");
-                ddrval =
-                    IDirectDraw2_SetDisplayMode(pScreenPriv->pdd2,
-                                                pScreenInfo->dwWidth,
-                                                pScreenInfo->dwHeight,
-                                                pScreenInfo->dwBPP, 0, 0);
-                if (FAILED(ddrval)) {
-                    ErrorF
-                        ("winAllocateFBShadowDD - Could not set default refresh rate "
-                         "full screen display mode: %08x\n",
-                         (unsigned int) ddrval);
-                    return FALSE;
-                }
-            }
-        }
-        else {
-            ErrorF("winAllocateFBShadowDD - Not changing video mode\n");
-        }
-
-        /* Release our DC */
-        ReleaseDC(NULL, hdc);
-        hdc = NULL;
-    }
-    else {
-        /* Set the cooperative level for windowed mode */
-        ddrval = IDirectDraw2_SetCooperativeLevel(pScreenPriv->pdd2,
-                                                  pScreenPriv->hwndScreen,
-                                                  DDSCL_NORMAL);
-        if (FAILED(ddrval)) {
-            ErrorF("winAllocateFBShadowDD - Could not set "
-                   "cooperative level: %08x\n", (unsigned int) ddrval);
-            return FALSE;
-        }
-    }
-
-    /* Create the primary surface */
-    if (!winCreatePrimarySurfaceShadowDD(pScreen)) {
-        ErrorF("winAllocateFBShadowDD - winCreatePrimarySurfaceShadowDD "
-               "failed\n");
-        return FALSE;
-    }
-
-    /* Describe the shadow surface to be created */
-    /* NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface,
-     * as drawing, locking, and unlocking take forever
-     * with video memory surfaces.  In addition,
-     * video memory is a somewhat scarce resource,
-     * so you shouldn't be allocating video memory when
-     * you have the option of using system memory instead.
-     */
-    ZeroMemory(&ddsd, sizeof(ddsd));
-    ddsd.dwSize = sizeof(ddsd);
-    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
-    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
-    ddsd.dwHeight = pScreenInfo->dwHeight;
-    ddsd.dwWidth = pScreenInfo->dwWidth;
-
-    /* Create the shadow surface */
-    ddrval = IDirectDraw2_CreateSurface(pScreenPriv->pdd2,
-                                        &ddsd, &pScreenPriv->pddsShadow, NULL);
-    if (FAILED(ddrval)) {
-        ErrorF("winAllocateFBShadowDD - Could not create shadow "
-               "surface: %08x\n", (unsigned int) ddrval);
-        return FALSE;
-    }
-
-#if CYGDEBUG
-    winDebug("winAllocateFBShadowDD - Created shadow\n");
-#endif
-
-    /* Allocate a DD surface description for our screen privates */
-    pddsdShadow = pScreenPriv->pddsdShadow = malloc(sizeof(DDSURFACEDESC));
-    if (pddsdShadow == NULL) {
-        ErrorF("winAllocateFBShadowDD - Could not allocate surface "
-               "description memory\n");
-        return FALSE;
-    }
-    ZeroMemory(pddsdShadow, sizeof(*pddsdShadow));
-    pddsdShadow->dwSize = sizeof(*pddsdShadow);
-
-#if CYGDEBUG
-    winDebug("winAllocateFBShadowDD - Locking shadow\n");
-#endif
-
-    /* Lock the shadow surface */
-    ddrval = IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
-                                      NULL, pddsdShadow, DDLOCK_WAIT, NULL);
-    if (FAILED(ddrval) || pddsdShadow->lpSurface == NULL) {
-        ErrorF("winAllocateFBShadowDD - Could not lock shadow "
-               "surface: %08x\n", (unsigned int) ddrval);
-        return FALSE;
-    }
-
-#if CYGDEBUG
-    winDebug("winAllocateFBShadowDD - Locked shadow\n");
-#endif
-
-    /* We don't know how to deal with anything other than RGB */
-    if (!(pddsdShadow->ddpfPixelFormat.dwFlags & DDPF_RGB)) {
-        ErrorF("winAllocateFBShadowDD - Color format other than RGB\n");
-        return FALSE;
-    }
-
-    /* Grab the pitch from the surface desc */
-    pScreenInfo->dwStride = (pddsdShadow->u1.lPitch * 8)
-        / pScreenInfo->dwBPP;
-
-    /* Save the pointer to our surface memory */
-    pScreenInfo->pfb = pddsdShadow->lpSurface;
-
-    /* Grab the color depth and masks from the surface description */
-    pScreenPriv->dwRedMask = pddsdShadow->ddpfPixelFormat.u2.dwRBitMask;
-    pScreenPriv->dwGreenMask = pddsdShadow->ddpfPixelFormat.u3.dwGBitMask;
-    pScreenPriv->dwBlueMask = pddsdShadow->ddpfPixelFormat.u4.dwBBitMask;
-
-#if CYGDEBUG
-    winDebug("winAllocateFBShadowDD - Returning\n");
-#endif
-
-    return TRUE;
-}
-
-static void
-winFreeFBShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-
-    /* Free the shadow surface, if there is one */
-    if (pScreenPriv->pddsShadow) {
-        IDirectDrawSurface2_Unlock(pScreenPriv->pddsShadow, NULL);
-        IDirectDrawSurface2_Release(pScreenPriv->pddsShadow);
-        pScreenPriv->pddsShadow = NULL;
-    }
-
-    /* Detach the clipper from the primary surface and release the primary surface, if there is one */
-    winReleasePrimarySurfaceShadowDD(pScreen);
-
-    /* Release the clipper object */
-    if (pScreenPriv->pddcPrimary) {
-        IDirectDrawClipper_Release(pScreenPriv->pddcPrimary);
-        pScreenPriv->pddcPrimary = NULL;
-    }
-
-    /* Free the DirectDraw2 object, if there is one */
-    if (pScreenPriv->pdd2) {
-        IDirectDraw2_RestoreDisplayMode(pScreenPriv->pdd2);
-        IDirectDraw2_Release(pScreenPriv->pdd2);
-        pScreenPriv->pdd2 = NULL;
-    }
-
-    /* Free the DirectDraw object, if there is one */
-    if (pScreenPriv->pdd) {
-        IDirectDraw_Release(pScreenPriv->pdd);
-        pScreenPriv->pdd = NULL;
-    }
-
-    /* Invalidate the ScreenInfo's fb pointer */
-    pScreenInfo->pfb = NULL;
-}
-
-/*
- * Transfer the damaged regions of the shadow framebuffer to the display.
- */
-
-static void
-winShadowUpdateDD(ScreenPtr pScreen, shadowBufPtr pBuf)
-{
-    winScreenPriv(pScreen);
-    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-    RegionPtr damage = shadowDamage(pBuf);
-    HRESULT ddrval = DD_OK;
-    RECT rcDest, rcSrc;
-    POINT ptOrigin;
-    DWORD dwBox = RegionNumRects(damage);
-    BoxPtr pBox = RegionRects(damage);
-    HRGN hrgnCombined = NULL;
-
-    /*
-     * Return immediately if the app is not active
-     * and we are fullscreen, or if we have a bad display depth
-     */
-    if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
-        || pScreenPriv->fBadDepth)
-        return;
-
-    /* Return immediately if we didn't get needed surfaces */
-    if (!pScreenPriv->pddsPrimary || !pScreenPriv->pddsShadow)
-        return;
-
-    /* Get the origin of the window in the screen coords */
-    ptOrigin.x = pScreenInfo->dwXOffset;
-    ptOrigin.y = pScreenInfo->dwYOffset;
-    MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
-
-    /* Unlock the shadow surface, so we can blit */
-    ddrval = IDirectDrawSurface2_Unlock(pScreenPriv->pddsShadow, NULL);
-    if (FAILED(ddrval)) {
-        ErrorF("winShadowUpdateDD - Unlock failed\n");
-        return;
-    }
-
-    /*
-     * Handle small regions with multiple blits,
-     * handle large regions by creating a clipping region and
-     * doing a single blit constrained to that clipping region.
-     */
-    if (pScreenInfo->dwClipUpdatesNBoxes == 0
-        || dwBox < pScreenInfo->dwClipUpdatesNBoxes) {
-        /* Loop through all boxes in the damaged region */
-        while (dwBox--) {
-            /* Assign damage box to source rectangle */
-            rcSrc.left = pBox->x1;
-            rcSrc.top = pBox->y1;
-            rcSrc.right = pBox->x2;
-            rcSrc.bottom = pBox->y2;
-
-            /* Calculate destination rectange */
-            rcDest.left = ptOrigin.x + rcSrc.left;
-            rcDest.top = ptOrigin.y + rcSrc.top;
-            rcDest.right = ptOrigin.x + rcSrc.right;
-            rcDest.bottom = ptOrigin.y + rcSrc.bottom;
-
-            /* Blit the damaged areas */
-            ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
-                                             &rcDest,
-                                             pScreenPriv->pddsShadow,
-                                             &rcSrc, DDBLT_WAIT, NULL);
-
-            /* Get a pointer to the next box */
-            ++pBox;
-        }
-    }
-    else {
-        BoxPtr pBoxExtents = RegionExtents(damage);
-
-        /* Compute a GDI region from the damaged region */
-        hrgnCombined =
-            CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
-                          pBoxExtents->y2);
-
-        /* Install the GDI region as a clipping region */
-        SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
-        DeleteObject(hrgnCombined);
-        hrgnCombined = NULL;
-
-        /* Calculating a bounding box for the source is easy */
-        rcSrc.left = pBoxExtents->x1;
-        rcSrc.top = pBoxExtents->y1;
-        rcSrc.right = pBoxExtents->x2;
-        rcSrc.bottom = pBoxExtents->y2;
-
-        /* Calculating a bounding box for the destination is trickier */
-        rcDest.left = ptOrigin.x + rcSrc.left;
-        rcDest.top = ptOrigin.y + rcSrc.top;
-        rcDest.right = ptOrigin.x + rcSrc.right;
-        rcDest.bottom = ptOrigin.y + rcSrc.bottom;
-
-        /* Our Blt should be clipped to the invalidated region */
-        ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
-                                         &rcDest,
-                                         pScreenPriv->pddsShadow,
-                                         &rcSrc, DDBLT_WAIT, NULL);
-
-        /* Reset the clip region */
-        SelectClipRgn(pScreenPriv->hdcScreen, NULL);
-    }
-
-    /* Relock the shadow surface */
-    ddrval = IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
-                                      NULL,
-                                      pScreenPriv->pddsdShadow,
-                                      DDLOCK_WAIT, NULL);
-    if (FAILED(ddrval)) {
-        ErrorF("winShadowUpdateDD - Lock failed\n");
-        return;
-    }
-
-    /* Has our memory pointer changed? */
-    if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) {
-        ErrorF("winShadowUpdateDD - Memory location of the shadow "
-               "surface has changed, trying to update the root window "
-               "pixmap header to point to the new address.  If you get "
-               "this message and " PROJECT_NAME " freezes or crashes "
-               "after this message then send a problem report and your "
-               "%s file to " BUILDERADDR "\n", g_pszLogFile);
-
-        /* Location of shadow framebuffer has changed */
-        winUpdateFBPointer(pScreen, pScreenPriv->pddsdShadow->lpSurface);
-    }
-}
-
-static Bool
-winInitScreenShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-
-    /* Get a device context for the screen  */
-    pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen);
-
-    return winAllocateFBShadowDD(pScreen);
-}
-
-/*
- * Call the wrapped CloseScreen function.
- *
- * Free our resources and private structures.
- */
-
-static Bool
-winCloseScreenShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-    Bool fReturn;
-
-#if CYGDEBUG
-    winDebug("winCloseScreenShadowDD - Freeing screen resources\n");
-#endif
-
-    /* Flag that the screen is closed */
-    pScreenPriv->fClosed = TRUE;
-    pScreenPriv->fActive = FALSE;
-
-    /* Call the wrapped CloseScreen procedure */
-    WIN_UNWRAP(CloseScreen);
-    if (pScreen->CloseScreen)
-        fReturn = (*pScreen->CloseScreen) (pScreen);
-
-    winFreeFBShadowDD(pScreen);
-
-    /* Free the screen DC */
-    ReleaseDC(pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
-
-    /* Delete the window property */
-    RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP);
-
-    /* Delete tray icon, if we have one */
-    if (!pScreenInfo->fNoTrayIcon)
-        winDeleteNotifyIcon(pScreenPriv);
-
-    /* Free the exit confirmation dialog box, if it exists */
-    if (g_hDlgExit != NULL) {
-        DestroyWindow(g_hDlgExit);
-        g_hDlgExit = NULL;
-    }
-
-    /* Kill our window */
-    if (pScreenPriv->hwndScreen) {
-        DestroyWindow(pScreenPriv->hwndScreen);
-        pScreenPriv->hwndScreen = NULL;
-    }
-
-#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
-    /* Destroy the thread startup mutex */
-    pthread_mutex_destroy(&pScreenPriv->pmServerStarted);
-#endif
-
-    /* Kill our screeninfo's pointer to the screen */
-    pScreenInfo->pScreen = NULL;
-
-    /* Free the screen privates for this screen */
-    free((void *) pScreenPriv);
-
-    return fReturn;
-}
-
-/*
- * Tell mi what sort of visuals we need.
- *
- * Generally we only need one visual, as our screen can only
- * handle one format at a time, I believe.  You may want
- * to verify that last sentence.
- */
-
-static Bool
-winInitVisualsShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-    DWORD dwRedBits, dwGreenBits, dwBlueBits;
-
-    /* Count the number of ones in each color mask */
-    dwRedBits = winCountBits(pScreenPriv->dwRedMask);
-    dwGreenBits = winCountBits(pScreenPriv->dwGreenMask);
-    dwBlueBits = winCountBits(pScreenPriv->dwBlueMask);
-
-    /* Store the maximum number of ones in a color mask as the bitsPerRGB */
-    if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0)
-        pScreenPriv->dwBitsPerRGB = 8;
-    else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
-        pScreenPriv->dwBitsPerRGB = dwRedBits;
-    else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
-        pScreenPriv->dwBitsPerRGB = dwGreenBits;
-    else
-        pScreenPriv->dwBitsPerRGB = dwBlueBits;
-
-    ErrorF("winInitVisualsShadowDD - Masks %08x %08x %08x BPRGB %d d %d "
-           "bpp %d\n",
-           (unsigned int) pScreenPriv->dwRedMask,
-           (unsigned int) pScreenPriv->dwGreenMask,
-           (unsigned int) pScreenPriv->dwBlueMask,
-           (int) pScreenPriv->dwBitsPerRGB,
-           (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP);
-
-    /* Create a single visual according to the Windows screen depth */
-    switch (pScreenInfo->dwDepth) {
-    case 24:
-    case 16:
-    case 15:
-        /* Create the real visual */
-        if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
-                                      TrueColorMask,
-                                      pScreenPriv->dwBitsPerRGB,
-                                      TrueColor,
-                                      pScreenPriv->dwRedMask,
-                                      pScreenPriv->dwGreenMask,
-                                      pScreenPriv->dwBlueMask)) {
-            ErrorF("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
-                   "failed for TrueColor\n");
-            return FALSE;
-        }
-
-#ifdef XWIN_EMULATEPSEUDO
-        if (!pScreenInfo->fEmulatePseudo)
-            break;
-
-        /* Setup a pseudocolor visual */
-        if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) {
-            ErrorF("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
-                   "failed for PseudoColor\n");
-            return FALSE;
-        }
-#endif
-        break;
-
-    case 8:
-        if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
-                                      pScreenInfo->fFullScreen
-                                      ? PseudoColorMask : StaticColorMask,
-                                      pScreenPriv->dwBitsPerRGB,
-                                      pScreenInfo->fFullScreen
-                                      ? PseudoColor : StaticColor,
-                                      pScreenPriv->dwRedMask,
-                                      pScreenPriv->dwGreenMask,
-                                      pScreenPriv->dwBlueMask)) {
-            ErrorF("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
-                   "failed\n");
-            return FALSE;
-        }
-        break;
-
-    default:
-        ErrorF("winInitVisualsShadowDD - Unknown screen depth\n");
-        return FALSE;
-    }
-
-#if CYGDEBUG
-    winDebug("winInitVisualsShadowDD - Returning\n");
-#endif
-
-    return TRUE;
-}
-
-/*
- * Adjust the user proposed video mode
- */
-
-static Bool
-winAdjustVideoModeShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-    HDC hdc = NULL;
-    DWORD dwBPP;
-
-    /* We're in serious trouble if we can't get a DC */
-    hdc = GetDC(NULL);
-    if (hdc == NULL) {
-        ErrorF("winAdjustVideoModeShadowDD - GetDC () failed\n");
-        return FALSE;
-    }
-
-    /* Query GDI for current display depth */
-    dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
-
-    /* DirectDraw can only change the depth in fullscreen mode */
-    if (!(pScreenInfo->fFullScreen && (pScreenInfo->dwBPP != WIN_DEFAULT_BPP))) {
-        /* Otherwise, We'll use GDI's depth */
-        pScreenInfo->dwBPP = dwBPP;
-    }
-
-    /* Release our DC */
-    ReleaseDC(NULL, hdc);
-    return TRUE;
-}
-
-/*
- * Blt exposed regions to the screen
- */
-
-static Bool
-winBltExposedRegionsShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-    RECT rcSrc, rcDest;
-    POINT ptOrigin;
-    HDC hdcUpdate = NULL;
-    PAINTSTRUCT ps;
-    HRESULT ddrval = DD_OK;
-    Bool fReturn = TRUE;
-    Bool fLocked = TRUE;
-    int i;
-
-    /* BeginPaint gives us an hdc that clips to the invalidated region */
-    hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps);
-    if (hdcUpdate == NULL) {
-        ErrorF("winBltExposedRegionsShadowDD - BeginPaint () returned "
-               "a NULL device context handle.  Aborting blit attempt.\n");
-        return FALSE;
-    }
-
-    /* Unlock the shadow surface, so we can blit */
-    ddrval = IDirectDrawSurface2_Unlock(pScreenPriv->pddsShadow, NULL);
-    if (FAILED(ddrval)) {
-        fReturn = FALSE;
-        goto winBltExposedRegionsShadowDD_Exit;
-    }
-    else {
-        /* Flag that we have unlocked the shadow surface */
-        fLocked = FALSE;
-    }
-
-    /* Get the origin of the window in the screen coords */
-    ptOrigin.x = pScreenInfo->dwXOffset;
-    ptOrigin.y = pScreenInfo->dwYOffset;
-
-    MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
-    rcDest.left = ptOrigin.x;
-    rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
-    rcDest.top = ptOrigin.y;
-    rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
-
-    /* Source can be enter shadow surface, as Blt should clip */
-    rcSrc.left = 0;
-    rcSrc.top = 0;
-    rcSrc.right = pScreenInfo->dwWidth;
-    rcSrc.bottom = pScreenInfo->dwHeight;
-
-    /* Try to regain the primary surface and blit again if we've lost it */
-    for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) {
-        /* Our Blt should be clipped to the invalidated region */
-        ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
-                                         &rcDest,
-                                         pScreenPriv->pddsShadow,
-                                         &rcSrc, DDBLT_WAIT, NULL);
-        if (ddrval == DDERR_SURFACELOST) {
-            /* Surface was lost */
-            ErrorF("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt "
-                   "reported that the primary surface was lost, "
-                   "trying to restore, retry: %d\n", i + 1);
-
-            /* Try to restore the surface, once */
-            ddrval = IDirectDrawSurface2_Restore(pScreenPriv->pddsPrimary);
-            ErrorF("winBltExposedRegionsShadowDD - "
-                   "IDirectDrawSurface2_Restore returned: ");
-            if (ddrval == DD_OK)
-                ErrorF("DD_OK\n");
-            else if (ddrval == DDERR_WRONGMODE)
-                ErrorF("DDERR_WRONGMODE\n");
-            else if (ddrval == DDERR_INCOMPATIBLEPRIMARY)
-                ErrorF("DDERR_INCOMPATIBLEPRIMARY\n");
-            else if (ddrval == DDERR_UNSUPPORTED)
-                ErrorF("DDERR_UNSUPPORTED\n");
-            else if (ddrval == DDERR_INVALIDPARAMS)
-                ErrorF("DDERR_INVALIDPARAMS\n");
-            else if (ddrval == DDERR_INVALIDOBJECT)
-                ErrorF("DDERR_INVALIDOBJECT\n");
-            else
-                ErrorF("unknown error: %08x\n", (unsigned int) ddrval);
-
-            /* Loop around to try the blit one more time */
-            continue;
-        }
-        else if (FAILED(ddrval)) {
-            fReturn = FALSE;
-            ErrorF("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt "
-                   "failed, but surface not lost: %08x %d\n",
-                   (unsigned int) ddrval, (int) ddrval);
-            goto winBltExposedRegionsShadowDD_Exit;
-        }
-        else {
-            /* Success, stop looping */
-            break;
-        }
-    }
-
-    /* Relock the shadow surface */
-    ddrval = IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
-                                      NULL,
-                                      pScreenPriv->pddsdShadow,
-                                      DDLOCK_WAIT, NULL);
-    if (FAILED(ddrval)) {
-        fReturn = FALSE;
-        ErrorF("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Lock "
-               "failed\n");
-        goto winBltExposedRegionsShadowDD_Exit;
-    }
-    else {
-        /* Indicate that we have relocked the shadow surface */
-        fLocked = TRUE;
-    }
-
-    /* Has our memory pointer changed? */
-    if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
-        winUpdateFBPointer(pScreen, pScreenPriv->pddsdShadow->lpSurface);
-
- winBltExposedRegionsShadowDD_Exit:
-    /* EndPaint frees the DC */
-    if (hdcUpdate != NULL)
-        EndPaint(pScreenPriv->hwndScreen, &ps);
-
-    /*
-     * Relock the surface if it is not locked.  We don't care if locking fails,
-     * as it will cause the server to shutdown within a few more operations.
-     */
-    if (!fLocked) {
-        IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
-                                 NULL,
-                                 pScreenPriv->pddsdShadow, DDLOCK_WAIT, NULL);
-
-        /* Has our memory pointer changed? */
-        if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
-            winUpdateFBPointer(pScreen, pScreenPriv->pddsdShadow->lpSurface);
-
-        fLocked = TRUE;
-    }
-    return fReturn;
-}
-
-/*
- * Do any engine-specific appliation-activation processing
- */
-
-static Bool
-winActivateAppShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-
-    /*
-     * Do we have a surface?
-     * Are we active?
-     * Are we fullscreen?
-     */
-    if (pScreenPriv != NULL
-        && pScreenPriv->pddsPrimary != NULL && pScreenPriv->fActive) {
-        /* Primary surface was lost, restore it */
-        IDirectDrawSurface2_Restore(pScreenPriv->pddsPrimary);
-    }
-
-    return TRUE;
-}
-
-/*
- * Reblit the shadow framebuffer to the screen.
- */
-
-static Bool
-winRedrawScreenShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-    HRESULT ddrval = DD_OK;
-    RECT rcSrc, rcDest;
-    POINT ptOrigin;
-
-    /* Get the origin of the window in the screen coords */
-    ptOrigin.x = pScreenInfo->dwXOffset;
-    ptOrigin.y = pScreenInfo->dwYOffset;
-    MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
-    rcDest.left = ptOrigin.x;
-    rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
-    rcDest.top = ptOrigin.y;
-    rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
-
-    /* Source can be entire shadow surface, as Blt should clip for us */
-    rcSrc.left = 0;
-    rcSrc.top = 0;
-    rcSrc.right = pScreenInfo->dwWidth;
-    rcSrc.bottom = pScreenInfo->dwHeight;
-
-    /* Redraw the whole window, to take account for the new colors */
-    ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
-                                     &rcDest,
-                                     pScreenPriv->pddsShadow,
-                                     &rcSrc, DDBLT_WAIT, NULL);
-    if (FAILED(ddrval)) {
-        ErrorF("winRedrawScreenShadowDD - IDirectDrawSurface_Blt () "
-               "failed: %08x\n", (unsigned int) ddrval);
-    }
-
-    return TRUE;
-}
-
-/*
- * Realize the currently installed colormap
- */
-
-static Bool
-winRealizeInstalledPaletteShadowDD(ScreenPtr pScreen)
-{
-    return TRUE;
-}
-
-/*
- * Install the specified colormap
- */
-
-static Bool
-winInstallColormapShadowDD(ColormapPtr pColormap)
-{
-    ScreenPtr pScreen = pColormap->pScreen;
-
-    winScreenPriv(pScreen);
-    winCmapPriv(pColormap);
-    HRESULT ddrval = DD_OK;
-
-    /* Install the DirectDraw palette on the primary surface */
-    ddrval = IDirectDrawSurface2_SetPalette(pScreenPriv->pddsPrimary,
-                                            pCmapPriv->lpDDPalette);
-    if (FAILED(ddrval)) {
-        ErrorF("winInstallColormapShadowDD - Failed installing the "
-               "DirectDraw palette.\n");
-        return FALSE;
-    }
-
-    /* Save a pointer to the newly installed colormap */
-    pScreenPriv->pcmapInstalled = pColormap;
-
-    return TRUE;
-}
-
-/*
- * Store the specified colors in the specified colormap
- */
-
-static Bool
-winStoreColorsShadowDD(ColormapPtr pColormap, int ndef, xColorItem * pdefs)
-{
-    ScreenPtr pScreen = pColormap->pScreen;
-
-    winScreenPriv(pScreen);
-    winCmapPriv(pColormap);
-    ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
-    HRESULT ddrval = DD_OK;
-
-    /* Put the X colormap entries into the Windows logical palette */
-    ddrval = IDirectDrawPalette_SetEntries(pCmapPriv->lpDDPalette,
-                                           0,
-                                           pdefs[0].pixel,
-                                           ndef,
-                                           pCmapPriv->peColors
-                                           + pdefs[0].pixel);
-    if (FAILED(ddrval)) {
-        ErrorF("winStoreColorsShadowDD - SetEntries () failed\n");
-        return FALSE;
-    }
-
-    /* Don't install the DirectDraw palette if the colormap is not installed */
-    if (pColormap != curpmap) {
-        return TRUE;
-    }
-
-    if (!winInstallColormapShadowDD(pColormap)) {
-        ErrorF("winStoreColorsShadowDD - Failed installing colormap\n");
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/*
- * Colormap initialization procedure
- */
-
-static Bool
-winCreateColormapShadowDD(ColormapPtr pColormap)
-{
-    HRESULT ddrval = DD_OK;
-    ScreenPtr pScreen = pColormap->pScreen;
-
-    winScreenPriv(pScreen);
-    winCmapPriv(pColormap);
-
-    /* Create a DirectDraw palette */
-    ddrval = IDirectDraw2_CreatePalette(pScreenPriv->pdd,
-                                        DDPCAPS_8BIT | DDPCAPS_ALLOW256,
-                                        pCmapPriv->peColors,
-                                        &pCmapPriv->lpDDPalette, NULL);
-    if (FAILED(ddrval)) {
-        ErrorF("winCreateColormapShadowDD - CreatePalette failed\n");
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/*
- * Colormap destruction procedure
- */
-
-static Bool
-winDestroyColormapShadowDD(ColormapPtr pColormap)
-{
-    winScreenPriv(pColormap->pScreen);
-    winCmapPriv(pColormap);
-    HRESULT ddrval = DD_OK;
-
-    /*
-     * Is colormap to be destroyed the default?
-     *
-     * Non-default colormaps should have had winUninstallColormap
-     * called on them before we get here.  The default colormap
-     * will not have had winUninstallColormap called on it.  Thus,
-     * we need to handle the default colormap in a special way.
-     */
-    if (pColormap->flags & IsDefault) {
-#if CYGDEBUG
-        winDebug("winDestroyColormapShadowDD - Destroying default "
-                 "colormap\n");
-#endif
-
-        /*
-         * FIXME: Walk the list of all screens, popping the default
-         * palette out of each screen device context.
-         */
-
-        /* Pop the palette out of the primary surface */
-        ddrval = IDirectDrawSurface2_SetPalette(pScreenPriv->pddsPrimary, NULL);
-        if (FAILED(ddrval)) {
-            ErrorF("winDestroyColormapShadowDD - Failed freeing the "
-                   "default colormap DirectDraw palette.\n");
-            return FALSE;
-        }
-
-        /* Clear our private installed colormap pointer */
-        pScreenPriv->pcmapInstalled = NULL;
-    }
-
-    /* Release the palette */
-    IDirectDrawPalette_Release(pCmapPriv->lpDDPalette);
-
-    /* Invalidate the colormap privates */
-    pCmapPriv->lpDDPalette = NULL;
-
-    return TRUE;
-}
-
-/*
- * Set engine specific functions
- */
-
-Bool
-winSetEngineFunctionsShadowDD(ScreenPtr pScreen)
-{
-    winScreenPriv(pScreen);
-    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-
-    /* Set our pointers */
-    pScreenPriv->pwinAllocateFB = winAllocateFBShadowDD;
-    pScreenPriv->pwinFreeFB = winFreeFBShadowDD;
-    pScreenPriv->pwinShadowUpdate = winShadowUpdateDD;
-    pScreenPriv->pwinInitScreen = winInitScreenShadowDD;
-    pScreenPriv->pwinCloseScreen = winCloseScreenShadowDD;
-    pScreenPriv->pwinInitVisuals = winInitVisualsShadowDD;
-    pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDD;
-    if (pScreenInfo->fFullScreen)
-        pScreenPriv->pwinCreateBoundingWindow =
-            winCreateBoundingWindowFullScreen;
-    else
-        pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
-    pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
-    pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDD;
-    pScreenPriv->pwinActivateApp = winActivateAppShadowDD;
-    pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDD;
-    pScreenPriv->pwinRealizeInstalledPalette
-        = winRealizeInstalledPaletteShadowDD;
-    pScreenPriv->pwinInstallColormap = winInstallColormapShadowDD;
-    pScreenPriv->pwinStoreColors = winStoreColorsShadowDD;
-    pScreenPriv->pwinCreateColormap = winCreateColormapShadowDD;
-    pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDD;
-    pScreenPriv->pwinHotKeyAltTab =
-        (winHotKeyAltTabProcPtr) (void (*)(void)) NoopDDA;
-    pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDD;
-    pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDD;
-#ifdef XWIN_MULTIWINDOW
-    pScreenPriv->pwinFinishCreateWindowsWindow =
-        (winFinishCreateWindowsWindowProcPtr) (void (*)(void)) NoopDDA;
-#endif
-
-    return TRUE;
-}
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 1bf3f5c..3228fa4 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -162,8 +162,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
          * their own mode when they become active.
          */
         if (s_pScreenInfo->fFullScreen
-            && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
-                || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)) {
+            || (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)) {
             break;
         }
 
@@ -186,8 +185,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
          */
         if (s_pScreenInfo->dwBPP !=
             GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL)) {
-            if ((s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD ||
-                 s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)) {
+            if (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL) {
                 /* Cannot display the visual until the depth is restored */
                 ErrorF("winWindowProc - Disruptive change in depth\n");
 
commit 55a84be085e9f479f7907bed5fb68fc66ce81ae8
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sat Mar 3 20:13:19 2012 +0000

    hw/xwin: Only set native positions if XINERAMA is enabled
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index ce0aada..31d5fdd 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -216,15 +216,19 @@ winScreenInit(ScreenPtr pScreen, int argc, char **argv)
     else
         winErrorFVerb(2, "winScreenInit - Using software cursor\n");
 
-    /*
-       Note the screen origin in a normalized coordinate space where (0,0) is at the top left
-       of the native virtual desktop area
-     */
-    pScreen->x = pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN);
-    pScreen->y = pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN);
+    if (!noPanoramiXExtension) {
+        /*
+           Note the screen origin in a normalized coordinate space where (0,0) is at the top left
+           of the native virtual desktop area
+         */
+        pScreen->x =
+            pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN);
+        pScreen->y =
+            pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN);
 
-    ErrorF("Screen %d added at virtual desktop coordinate (%d,%d).\n",
-           pScreen->myNum, pScreen->x, pScreen->y);
+        ErrorF("Screen %d added at virtual desktop coordinate (%d,%d).\n",
+               pScreen->myNum, pScreen->x, pScreen->y);
+    }
 
 #if CYGDEBUG || YES
     winDebug("winScreenInit - returning\n");
commit 23e07d71b607c99c3a0a0ea362c70dcae73485c6
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Nov 6 14:28:17 2014 +0000

    hw/xwin: Register native screens with pseudoramiX
    
    Update man page to document pseudo-xinerama
    
    v2: Make the use of PseudoramiXExtensionInit() match the prototype
    v3: Update for nonsdk_extinit.h
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 246cd12..3b1ef3f 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -58,6 +58,11 @@ typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner,
                                               HANDLE hToken,
                                               DWORD dwFlags, LPTSTR pszPath);
 #endif
+
+#include "winmonitors.h"
+#include "nonsdk_extinit.h"
+#include "pseudoramiX/pseudoramiX.h"
+
 #include "glx_extinit.h"
 #ifdef XWIN_GLX_WINDOWS
 #include "glx/glwindows.h"
@@ -973,6 +978,59 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
         }
     }
 
+  /*
+     Unless full xinerama has been explicitly enabled, register all native screens with pseudoramiX
+  */
+  if (!noPanoramiXExtension)
+      noPseudoramiXExtension = TRUE;
+
+  if ((g_ScreenInfo[0].fMultipleMonitors) && !noPseudoramiXExtension)
+    {
+      int pass;
+
+      PseudoramiXExtensionInit();
+
+      /* Add primary monitor on pass 0, other monitors on pass 1, to ensure
+       the primary monitor is first in XINERAMA list */
+      for (pass = 0; pass < 2; pass++)
+        {
+          int iMonitor;
+
+          for (iMonitor = 1; ; iMonitor++)
+            {
+              struct GetMonitorInfoData data;
+              QueryMonitor(iMonitor, &data);
+              if (data.bMonitorSpecifiedExists)
+                {
+                  MONITORINFO mi;
+                  mi.cbSize = sizeof(MONITORINFO);
+
+                  if (GetMonitorInfo(data.monitorHandle, &mi))
+                    {
+                      /* pass == 1 XOR primary monitor flags is set */
+                      if ((!(pass == 1)) != (!(mi.dwFlags & MONITORINFOF_PRIMARY)))
+                        {
+                          /*
+                            Note the screen origin in a normalized coordinate space where (0,0) is at the top left
+                            of the native virtual desktop area
+                          */
+                          data.monitorOffsetX = data.monitorOffsetX - GetSystemMetrics(SM_XVIRTUALSCREEN);
+                          data.monitorOffsetY = data.monitorOffsetY - GetSystemMetrics(SM_YVIRTUALSCREEN);
+
+                          winDebug ("InitOutput - screen %d added at virtual desktop coordinate (%d,%d) (pseudoramiX) \n",
+                                    iMonitor-1, data.monitorOffsetX, data.monitorOffsetY);
+
+                          PseudoramiXAddScreen(data.monitorOffsetX, data.monitorOffsetY,
+                                               data.monitorWidth, data.monitorHeight);
+                        }
+                    }
+                }
+              else
+                break;
+            }
+        }
+    }
+
 #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
 
     /* Generate a cookie used by internal clients for authorization */
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index ed93303..41019d1 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -76,6 +76,9 @@ preceeding \fB\-screen\fP parameter.
 .B \-[no]multimonitors or \-[no]multiplemonitors
 Create a screen 0 that covers all monitors [the primary monitor] on a system with
 multiple monitors.
+Fake XINERAMA data is created describing the individual monitors,
+(This is similar to the 'merged framebuffer' or 'pseudo-xinerama' mode provided by
+some drivers for the xorg X server).
 This option is currently enabled by default in \fB\-multiwindow\fP mode.
 .TP 8
 .B "\-screen \fIscreen_number\fP [\fIW\fP \fIH\fP [\fIX\fP \fIY\fP] | [[\fIW\fPx\fIH\fP[+\fIX\fP+\fIY\fP]][@\fIM\fP]] ] "
commit e036cbfccbe33775524a469082306913843c63df
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Nov 6 13:54:11 2014 +0000

    Make PseudoramiXExtensionInit() prototype more generally available
    
    Make PseudoramiXExtensionInit() prototype available to hw/xwin
    
    Rather than avoiding a reference to it being pulled in to Xorg by sdksyms by
    hiding this prototype behind the INXQUARTZ define, which is only defined when
    building Xquartz, introduce nonsdk_extinit.h and move it there.
    
    (The only remaining use of INXQUARTZ is in mi/miiniext.c, in order
    to do PseudoramiXExtensionInit() at the point apparently needed by Xquartz)
    
    Also remove duplicate declaration of noPseudoramiXExtension from pseudoramiX.h
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index d7229ce..851ce48 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -43,6 +43,7 @@
 #include "darwinEvents.h"
 #include "pseudoramiX.h"
 #include "extension.h"
+#include "nonsdk_extinit.h"
 #include "glx_extinit.h"
 #define _APPLEWM_SERVER_
 #include "applewmExt.h"
diff --git a/include/Makefile.am b/include/Makefile.am
index 168b00f..738b582 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -33,6 +33,7 @@ sdk_HEADERS =		\
 	misc.h		\
 	miscstruct.h	\
 	opaque.h	\
+	nonsdk_extinit.h	\
 	optionstr.h	\
 	os.h		\
 	pixmap.h	\
diff --git a/include/extinit.h b/include/extinit.h
index fa5f293..4ad4fca 100644
--- a/include/extinit.h
+++ b/include/extinit.h
@@ -163,11 +163,6 @@ extern void SELinuxExtensionInit(void);
 extern void XTestExtensionInit(void);
 #endif
 
-#ifdef INXQUARTZ
-extern _X_EXPORT Bool noPseudoramiXExtension;
-extern void PseudoramiXExtensionInit(void);
-#endif
-
 #if defined(XV)
 #include <X11/extensions/Xv.h>
 #include <X11/extensions/XvMC.h>
diff --git a/include/nonsdk_extinit.h b/include/nonsdk_extinit.h
new file mode 100644
index 0000000..da8d370
--- /dev/null
+++ b/include/nonsdk_extinit.h
@@ -0,0 +1,35 @@
+/***********************************************************
+
+Copyright 2014 Jon TURNEY
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef NONSDK_EXT_INIT_H
+#define NONSDK_EXT_INIT_H
+
+/* this is separate from extinit.h to avoid references to these symbols being
+   pulled in by sdksyms */
+
+extern _X_EXPORT Bool noPseudoramiXExtension;
+extern void PseudoramiXExtensionInit(void);
+
+#endif
diff --git a/pseudoramiX/pseudoramiX.c b/pseudoramiX/pseudoramiX.c
index f47c783..d0e2603 100644
--- a/pseudoramiX/pseudoramiX.c
+++ b/pseudoramiX/pseudoramiX.c
@@ -39,7 +39,7 @@
 
 #include "pseudoramiX.h"
 #include "extnsionst.h"
-#include "extinit.h"
+#include "nonsdk_extinit.h"
 #include "dixstruct.h"
 #include "window.h"
 #include <X11/extensions/panoramiXproto.h>
diff --git a/pseudoramiX/pseudoramiX.h b/pseudoramiX/pseudoramiX.h
index f063919..5393062 100644
--- a/pseudoramiX/pseudoramiX.h
+++ b/pseudoramiX/pseudoramiX.h
@@ -2,8 +2,6 @@
  * Minimal implementation of PanoramiX/Xinerama
  */
 
-extern int noPseudoramiXExtension;
-
 void
 PseudoramiXAddScreen(int x, int y, int w, int h);
 void
commit 3aad9b7556391b0f55e46ba13ced5e58d8fd47f7
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Nov 7 20:54:10 2011 +0000

    hw/xwin: Turn on -hostintitle by default
    
    Turn on -hostintitle by default
    Provide -nohostintitle to disable if needed
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 654c58c..246cd12 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -739,7 +739,7 @@ winUseMsg(void)
 
     ErrorF("-fullscreen\n" "\tRun the server in fullscreen mode.\n");
 
-    ErrorF("-hostintitle\n"
+    ErrorF("-[no]hostintitle\n"
            "\tIn multiwindow mode, add remote host names to window titles.\n");
 
     ErrorF("-ignoreinput\n" "\tIgnore keyboard and mouse input.\n");
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index 15a57db..ed93303 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -167,9 +167,10 @@ on its own is equivalent to \fB\-resize=randr\fP
 
 .SH OPTIONS FOR MULTIWINDOW MODE
 .TP 8
-.B \-hostintitle
+.B \-[no]hostintitle
 Add the host name to the window title for X applications which are running
 on remote hosts, when that information is available and it's useful to do so.
+The default is enabled.
 
 .SH OPTIONS CONTROLLING WINDOWS INTEGRATION
 .TP 8
diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c
index ad82b83..1382c89 100644
--- a/hw/xwin/winglobals.c
+++ b/hw/xwin/winglobals.c
@@ -78,7 +78,7 @@ Bool g_fNoHelpMessageBox = FALSE;
 Bool g_fSoftwareCursor = FALSE;
 Bool g_fSilentDupError = FALSE;
 Bool g_fNativeGl = TRUE;
-Bool g_fHostInTitle = FALSE;
+Bool g_fHostInTitle = TRUE;
 pthread_mutex_t g_pmTerminating = PTHREAD_MUTEX_INITIALIZER;
 
 #ifdef XWIN_CLIPBOARD
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 837cdb2..65bba81 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -1098,6 +1098,11 @@ ddxProcessArgument(int argc, char *argv[], int i)
         return 1;
     }
 
+    if (IS_OPTION("-nohostintitle")) {
+        g_fHostInTitle = FALSE;
+        return 1;
+    }
+
     return 0;
 }
 
commit b2aaf69e62f4109ffb8aaf39e9bd2571abb29dfb
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Jun 28 14:22:07 2012 +0100

    hw/xwin: Report Cygwin version information in log
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index e8cccb4..837cdb2 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -31,6 +31,10 @@ from The Open Group.
 #include <xwin-config.h>
 #endif
 
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
 #include <../xfree86/common/xorgVersion.h>
 #include "win.h"
 #include "winconfig.h"
@@ -1181,6 +1185,16 @@ winLogVersionInfo(void)
     ErrorF("Vendor: %s\n", XVENDORNAME);
     ErrorF("Release: %d.%d.%d.%d\n", XORG_VERSION_MAJOR,
            XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP);
+#ifdef HAVE_SYS_UTSNAME_H
+    {
+        struct utsname name;
+
+        if (uname(&name) >= 0) {
+            ErrorF("OS: %s %s %s %s %s\n", name.sysname, name.nodename,
+                   name.release, name.version, name.machine);
+        }
+    }
+#endif
     if (strlen(BUILDERSTRING))
         ErrorF("%s\n", BUILDERSTRING);
     ErrorF("Contact: %s\n", BUILDERADDR);
commit d02f9611c8d3bafca4be17c65efca3c5527f71e2
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Mar 16 16:29:29 2015 +0000

    hw/xwin/glx: Improve code generator to deal with latest Khronos OpenGL registry XML
    
    Improve the parsing of the <proto> XML element
    
    Include all text from the param element, in the order it appears in the xml
    document, as part of the formal parameter declaration
    
    This is needed to correctly handle the XML description added in svn r27498 of
    glPathGlyphIndexRangeNV()'s baseAndCount parameter of type GLuint[2]
    
    This fixes the way the parameter declaration is generated so it is in the
    correct form 'GLuint baseAndCount_[2]' and not 'GLuint baseAndCount[2]_'
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/glx/gen_gl_wrappers.py b/hw/xwin/glx/gen_gl_wrappers.py
index 9627ef4..b9e8dda 100755
--- a/hw/xwin/glx/gen_gl_wrappers.py
+++ b/hw/xwin/glx/gen_gl_wrappers.py
@@ -136,9 +136,20 @@ def ParseCmdParams(cmd):
     params = cmd.elem.findall('param')
     plist=[]
     for param in params:
-        paramlist = ([t for t in param.itertext()])
-        paramtype = ''.join(paramlist[:-1])
-        paramname = paramlist[-1]
+        # construct the formal parameter definition from ptype and name
+        # elements, also using any text found around these in the
+        # param element, in the order it appears in the document
+        paramtype = ''
+        # also extract the formal parameter name from the name element
+        paramname = ''
+        for t in param.iter():
+            if t.tag == 'ptype' or t.tag == 'param':
+                paramtype = paramtype + noneStr(t.text)
+            if t.tag == 'name':
+                paramname = t.text + '_'
+                paramtype = paramtype + ' ' + paramname
+            if t.tail is not None:
+                paramtype = paramtype + t.tail.strip()
         plist.append((paramtype, paramname))
     return plist
 
@@ -206,7 +217,7 @@ class WrapperOutputGenerator(OutputGenerator):
         Comma=""
         if len(plist):
             for ptype, pname in plist:
-                self.outFile.write("%s%s%s_"%(Comma, ptype, pname))
+                self.outFile.write("%s%s"%(Comma, ptype))
                 Comma=", "
         else:
             self.outFile.write("void")
@@ -227,7 +238,7 @@ class WrapperOutputGenerator(OutputGenerator):
 
             Comma=""
             for ptype, pname in plist:
-                self.outFile.write("%s%s_"%(Comma, pname))
+                self.outFile.write("%s%s"%(Comma, pname))
                 Comma=", "
 
         # for GL 1.2+ functions, generate stdcall wrappers which use wglGetProcAddress()
@@ -253,7 +264,7 @@ class WrapperOutputGenerator(OutputGenerator):
 
             Comma=""
             for ptype, pname in plist:
-                self.outFile.write("%s%s_"%(Comma, pname))
+                self.outFile.write("%s%s"%(Comma, pname))
                 Comma=", "
         self.outFile.write(" );\n}\n\n")
 
@@ -282,10 +293,11 @@ class ThunkOutputGenerator(OutputGenerator):
         rettype=ParseCmdRettype(cmd)
         self.outFile.write("%s %sWrapper("%(rettype, name))
         plist=ParseCmdParams(cmd)
+
         Comma=""
         if len(plist):
             for ptype, pname in plist:
-                self.outFile.write("%s%s%s_"%(Comma, ptype, pname))
+                self.outFile.write("%s%s"%(Comma, ptype))
                 Comma=", "
         else:
             self.outFile.write("void")
@@ -301,7 +313,7 @@ class ThunkOutputGenerator(OutputGenerator):
 
             Comma=""
             for ptype, pname in plist:
-                self.outFile.write("%s%s_"%(Comma, pname))
+                self.outFile.write("%s%s"%(Comma, pname))
                 Comma=", "
 
         # for GL 1.2+ functions, generate wrappers which use wglGetProcAddress()
@@ -315,7 +327,7 @@ class ThunkOutputGenerator(OutputGenerator):
 
             Comma=""
             for ptype, pname in plist:
-                self.outFile.write("%s%s_"%(Comma, pname))
+                self.outFile.write("%s%s"%(Comma, pname))
                 Comma=", "
         self.outFile.write(" );\n}\n\n")
 
@@ -373,10 +385,11 @@ class ShimOutputGenerator(OutputGenerator):
         rettype=ParseCmdRettype(cmd)
         self.outFile.write("%s %s("%(rettype, name))
         plist=ParseCmdParams(cmd)
+
         Comma=""
         if len(plist):
             for ptype, pname in plist:
-                self.outFile.write("%s%s%s_"%(Comma, ptype, pname))
+                self.outFile.write("%s%s"%(Comma, ptype))
                 Comma=", "
         else:
             self.outFile.write("void")
@@ -388,7 +401,7 @@ class ShimOutputGenerator(OutputGenerator):
         if len(plist):
             Comma=""
             for ptype, pname in plist:
-                self.outFile.write("%s %s %s_"%(Comma, ptype, pname))
+                self.outFile.write("%s %s"%(Comma, ptype))
                 Comma=", "
         else:
             self.outFile.write("void")
@@ -404,7 +417,7 @@ class ShimOutputGenerator(OutputGenerator):
 
         Comma=""
         for ptype, pname in plist:
-            self.outFile.write("%s%s_"%(Comma, pname))
+            self.outFile.write("%s%s"%(Comma, pname))
             Comma=", "
 
         self.outFile.write(" );\n}\n\n")
commit 5071cb7e0ac5f17c48ed7f3f3b6f242dec802f66
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Mar 16 16:14:10 2015 +0000

    hw/xwin/glx: Refactor parsing of the <proto> XML element
    
    Factor out duplicated code used in parsing of the <proto> XML element in the
    code generator
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/glx/gen_gl_wrappers.py b/hw/xwin/glx/gen_gl_wrappers.py
index 69ab1ef..9627ef4 100755
--- a/hw/xwin/glx/gen_gl_wrappers.py
+++ b/hw/xwin/glx/gen_gl_wrappers.py
@@ -123,6 +123,25 @@ else:
     errWarn = sys.stderr
 diag = open(diagFilename, 'w')
 
+def ParseCmdRettype(cmd):
+    proto=noneStr(cmd.elem.find('proto'))
+    rettype=noneStr(proto.text)
+    if rettype.lower()!="void ":
+        plist = ([t for t in proto.itertext()])
+        rettype = ''.join(plist[:-1])
+    rettype=rettype.strip()
+    return rettype
+
+def ParseCmdParams(cmd):
+    params = cmd.elem.findall('param')
+    plist=[]
+    for param in params:
+        paramlist = ([t for t in param.itertext()])
+        paramtype = ''.join(paramlist[:-1])
+        paramname = paramlist[-1]
+        plist.append((paramtype, paramname))
+    return plist
+
 class PreResolveOutputGenerator(OutputGenerator):
     def __init__(self,
                  errFile = sys.stderr,
@@ -179,21 +198,11 @@ class WrapperOutputGenerator(OutputGenerator):
         if prefix == 'wgl' and not name in used_wgl_ext_fns:
             return
 
-        proto=noneStr(cmd.elem.find('proto'))
-        rettype=noneStr(proto.text)
-        if rettype.lower()!="void ":
-            plist = ([t for t in proto.itertext()])
-            rettype = ''.join(plist[:-1])
-        rettype=rettype.strip()
+        rettype=ParseCmdRettype(cmd)
+
         if staticwrappers: self.outFile.write("static ")
         self.outFile.write("%s %sWrapper("%(rettype, name))
-        params = cmd.elem.findall('param')
-        plist=[]
-        for param in params:
-            paramlist = ([t for t in param.itertext()])
-            paramtype = ''.join(paramlist[:-1])
-            paramname = paramlist[-1]
-            plist.append((paramtype, paramname))
+        plist=ParseCmdParams(cmd)
         Comma=""
         if len(plist):
             for ptype, pname in plist:
@@ -270,20 +279,9 @@ class ThunkOutputGenerator(OutputGenerator):
     def genCmd(self, cmd, name):
         OutputGenerator.genCmd(self, cmd, name)
 
-        proto=noneStr(cmd.elem.find('proto'))
-        rettype=noneStr(proto.text)
-        if rettype.lower()!="void ":
-            plist = ([t for t in proto.itertext()])
-            rettype = ''.join(plist[:-1])
-        rettype=rettype.strip()
+        rettype=ParseCmdRettype(cmd)
         self.outFile.write("%s %sWrapper("%(rettype, name))
-        params = cmd.elem.findall('param')
-        plist=[]
-        for param in params:
-            paramlist = ([t for t in param.itertext()])
-            paramtype = ''.join(paramlist[:-1])
-            paramname = paramlist[-1]
-            plist.append((paramtype, paramname))
+        plist=ParseCmdParams(cmd)
         Comma=""
         if len(plist):
             for ptype, pname in plist:
@@ -372,20 +370,9 @@ class ShimOutputGenerator(OutputGenerator):
             return
 
         # for GL functions which are in the ABI, generate a shim which calls the function via GetProcAddress
-        proto=noneStr(cmd.elem.find('proto'))
-        rettype=noneStr(proto.text)
-        if rettype.lower()!="void ":
-            plist = ([t for t in proto.itertext()])
-            rettype = ''.join(plist[:-1])
-        rettype=rettype.strip()
+        rettype=ParseCmdRettype(cmd)
         self.outFile.write("%s %s("%(rettype, name))
-        params = cmd.elem.findall('param')
-        plist=[]
-        for param in params:
-            paramlist = ([t for t in param.itertext()])
-            paramtype = ''.join(paramlist[:-1])
-            paramname = paramlist[-1]
-            plist.append((paramtype, paramname))
+        plist=ParseCmdParams(cmd)
         Comma=""
         if len(plist):
             for ptype, pname in plist:
commit d3080d421bf0d91daea2e39bfc391c43d7fdad75
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Feb 5 20:29:48 2015 +0000

    os: Teach vpnprintf() how to handle "%*.*s"
    
    XdmcpFatal uses the format specifier %*.*s, which vpnprintf() doesn't
    understand, which causes a backtrace and prevents the reason for the XDMCP
    failure being logged.
    
    See also:
    https://bugs.freedesktop.org/show_bug.cgi?id=66862
    https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=758574
    
    "%*.*s" is also currently used in a few other places, so teach vpnprintf() how
    to handle it
    
    $ fgrep -r "%*.*s" *
    hw/dmx/config/scanner.l:    fprintf(stderr, "parse error on line %d at token \"%*.*s\"\n",
    hw/dmx/dmxlog.c:        ErrorF("(%s) dmx[i%d/%*.*s]: ", type,
    hw/dmx/input/dmxinputinit.c:                dmxLogCont(dmxInfo, "\t[i%d/%*.*s",
    os/access.c:        ErrorF("Xserver: siAddrMatch(): type = %s, value = %*.*s -- %s\n",
    os/access.c:                ("Xserver: siCheckAddr(): type = %s, value = %*.*s, len = %d -- %s\n",
    os/xdmcp.c:    FatalError("XDMCP fatal error: %s %*.*s\n", type,
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/os/log.c b/os/log.c
index 0532c2e..3db5c53 100644
--- a/os/log.c
+++ b/os/log.c
@@ -355,6 +355,7 @@ vpnprintf(char *string, int size_in, const char *f, va_list args)
     uint64_t ui;
     int64_t si;
     size_t size = size_in;
+    int precision;
 
     for (; f_idx < f_len && s_idx < size - 1; f_idx++) {
         int length_modifier = 0;
@@ -365,9 +366,29 @@ vpnprintf(char *string, int size_in, const char *f, va_list args)
 
         f_idx++;
 
-        /* silently swallow digit length modifiers */
-        while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.'))
+        /* silently swallow minimum field width */
+        if (f[f_idx] == '*') {
             f_idx++;
+            va_arg(args, int);
+        } else {
+            while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9')))
+                f_idx++;
+        }
+
+        /* is there a precision? */
+        precision = size;
+        if (f[f_idx] == '.') {
+            f_idx++;
+            if (f[f_idx] == '*') {
+                f_idx++;
+                /* precision is supplied in an int argument */
+                precision = va_arg(args, int);
+            } else {
+                /* silently swallow precision digits */
+                while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9')))
+                    f_idx++;
+            }
+        }
 
         /* non-digit length modifiers */
         if (f_idx < f_len) {
@@ -383,9 +404,8 @@ vpnprintf(char *string, int size_in, const char *f, va_list args)
         switch (f[f_idx]) {
         case 's':
             string_arg = va_arg(args, char*);
-            p_len = strlen_sigsafe(string_arg);
 
-            for (i = 0; i < p_len && s_idx < size - 1; i++)
+            for (i = 0; string_arg[i] != 0 && s_idx < size - 1 && s_idx < precision; i++)
                 string[s_idx++] = string_arg[i];
             break;
 
commit 491cf02e191e70c5ce24c19da880bb79bebfc03c
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Feb 10 14:37:26 2015 +0000

    os: XDMCP options like -query etc. should imply -listen tcp
    
    In X server 1.17, the default configuration is now -nolisten tcp.  In this
    configuration, XDMCP options don't work usefully, as the X server is not
    listening on the port for the display that it tells the display manager to
    connect to.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/os/xdmcp.c b/os/xdmcp.c
index b6e97c9..bc5a707 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -48,6 +48,11 @@
 #include <netdir.h>
 #endif
 
+#define XSERV_t
+#define TRANS_SERVER
+#define TRANS_REOPEN
+#include <X11/Xtrans/Xtrans.h>
+
 #ifdef XDMCP
 #undef REQUEST
 
@@ -242,6 +247,14 @@ XdmcpUseMsg(void)
     ErrorF("-displayID display-id  manufacturer display ID for request\n");
 }
 
+static void
+XdmcpDefaultListen(void)
+{
+    /* Even when configured --disable-listen-tcp, we should listen on tcp in
+       XDMCP modes */
+    _XSERVTransListen("tcp");
+}
+
 int
 XdmcpOptions(int argc, char **argv, int i)
 {
@@ -249,11 +262,13 @@ XdmcpOptions(int argc, char **argv, int i)
         get_manager_by_name(argc, argv, i++);
         XDM_INIT_STATE = XDM_QUERY;
         AccessUsingXdmcp();
+        XdmcpDefaultListen();
         return i + 1;
     }
     if (strcmp(argv[i], "-broadcast") == 0) {
         XDM_INIT_STATE = XDM_BROADCAST;
         AccessUsingXdmcp();
+        XdmcpDefaultListen();
         return i + 1;
     }
 #if defined(IPv6) && defined(AF_INET6)
@@ -261,6 +276,7 @@ XdmcpOptions(int argc, char **argv, int i)
         i = get_mcast_options(argc, argv, ++i);
         XDM_INIT_STATE = XDM_MULTICAST;
         AccessUsingXdmcp();
+        XdmcpDefaultListen();
         return i + 1;
     }
 #endif
@@ -268,6 +284,7 @@ XdmcpOptions(int argc, char **argv, int i)
         get_manager_by_name(argc, argv, i++);
         XDM_INIT_STATE = XDM_INDIRECT;
         AccessUsingXdmcp();
+        XdmcpDefaultListen();
         return i + 1;
     }
     if (strcmp(argv[i], "-port") == 0) {
commit f42520c5f151bda25e52ae8b0408a421c3fba7e5
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Feb 4 17:04:45 2015 +0000

    ephyr: Avoid a segfault with 'DISPLAY= Xephy -glamor'
    
    ephyr_glamor_connect() returns NULL if we failed, but applying
    xcb_connection_has_error() to NULL is not permitted.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Daniel Martin <consume.noise at gmail.com>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index f64861b..15edce8 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -443,7 +443,7 @@ hostx_init(void)
     else
 #endif
         HostX.conn = xcb_connect(NULL, &HostX.screen);
-    if (xcb_connection_has_error(HostX.conn)) {
+    if (!HostX.conn || xcb_connection_has_error(HostX.conn)) {
         fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n");
         exit(1);
     }
commit 0a78b599b34cc8b5fe6fe82f90e90234e8ab7a56
Author: Jürg Billeter <j at bitron.ch>
Date:   Sat Feb 7 18:13:21 2015 +0100

    int10: Fix error check for pci_device_map_legacy
    
    pci_device_map_legacy returns 0 on success.
    
    Signed-off-by: Jürg Billeter <j at bitron.ch>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/int10/generic.c b/hw/xfree86/int10/generic.c
index 012d194..8d5c4da 100644
--- a/hw/xfree86/int10/generic.c
+++ b/hw/xfree86/int10/generic.c
@@ -104,7 +104,7 @@ readIntVec(struct pci_device *dev, unsigned char *buf, int len)
 {
     void *map;
 
-    if (!pci_device_map_legacy(dev, 0, len, 0, &map))
+    if (pci_device_map_legacy(dev, 0, len, 0, &map))
         return FALSE;
 
     memcpy(buf, map, len);
diff --git a/hw/xfree86/os-support/linux/int10/linux.c b/hw/xfree86/os-support/linux/int10/linux.c
index 79b9a88..6ca118f 100644
--- a/hw/xfree86/os-support/linux/int10/linux.c
+++ b/hw/xfree86/os-support/linux/int10/linux.c
@@ -75,7 +75,7 @@ readLegacy(struct pci_device *dev, unsigned char *buf, int base, int len)
 {
     void *map;
 
-    if (!pci_device_map_legacy(dev, base, len, 0, &map))
+    if (pci_device_map_legacy(dev, base, len, 0, &map))
         return FALSE;
 
     memcpy(buf, map, len);
commit 21b896939c5bb242f3aacc37baf12379e43254b6
Author: Egbert Eich <eich at freedesktop.org>
Date:   Tue Mar 3 16:27:05 2015 +0100

    symbols: Fix sdksyms.sh to cope with gcc5
    
    Gcc5 adds additional lines stating line numbers before and
    after __attribute__() which need to be skipped.
    
    Signed-off-by: Egbert Eich <eich at freedesktop.org>
    Tested-by: Daniel Stone <daniels at collabora.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/sdksyms.sh b/hw/xfree86/sdksyms.sh
index 2305073..05ac410 100755
--- a/hw/xfree86/sdksyms.sh
+++ b/hw/xfree86/sdksyms.sh
@@ -350,13 +350,25 @@ BEGIN {
     if (sdk) {
 	n = 3;
 
+        # skip line numbers GCC 5 adds before __attribute__
+        while ($n == "" || $0 ~ /^# [0-9]+ "/) {
+           getline;
+           n = 1;
+        }
+
 	# skip attribute, if any
 	while ($n ~ /^(__attribute__|__global)/ ||
 	    # skip modifiers, if any
 	    $n ~ /^\*?(unsigned|const|volatile|struct|_X_EXPORT)$/ ||
 	    # skip pointer
-	    $n ~ /^[a-zA-Z0-9_]*\*$/)
+	    $n ~ /^[a-zA-Z0-9_]*\*$/) {
 	    n++;
+            # skip line numbers GCC 5 adds after __attribute__
+            while ($n == "" || $0 ~ /^# [0-9]+ "/) {
+               getline;
+               n = 1;
+            }
+        }
 
 	# type specifier may not be set, as in
 	#   extern _X_EXPORT unsigned name(...)
commit 7ea64fb4374504bd3d524fc08c90efdab9f253ea
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Mon Mar 9 09:55:57 2015 -0700

    Clear ListenTransConns entries in CloseWellKnownConnections
    
    Since _XSERVTransClose frees the connection pointer passed to it,
    remove that pointer from the array, so we don't try to double free it
    if we come back into CloseWellKnownConnections again.
    
    Should fix https://bugzilla.yoctoproject.org/show_bug.cgi?id=6665 in which
    the shutdown section of the main() loop called CloseWellKnownConnections()
    and then moved on to ddxGiveUp(), which failed to release the VT and thus
    called AbortServer(), which called CloseWellKnownConnections() again.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/os/connection.c b/os/connection.c
index ddfe50a..7ff44e1 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -513,8 +513,13 @@ CloseWellKnownConnections(void)
 {
     int i;
 
-    for (i = 0; i < ListenTransCount; i++)
-        _XSERVTransClose(ListenTransConns[i]);
+    for (i = 0; i < ListenTransCount; i++) {
+        if (ListenTransConns[i] != NULL) {
+            _XSERVTransClose(ListenTransConns[i]);
+            ListenTransConns[i] = NULL;
+        }
+    }
+    ListenTransCount = 0;
 }
 
 static void
commit 6d3cf35a6f0856ac44a7be560e2265461f9bb32b
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Mon Mar 9 12:00:52 2015 +0000

    autogen.sh: use quoted string variables
    
    Place quotes around the $srcdir, $ORIGDIR and $0 variables to prevent
    fall-outs, when they contain space.
    
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/autogen.sh b/autogen.sh
index dd0731a..aee4beb 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,14 +1,14 @@
 #! /bin/sh
 
-srcdir=`dirname $0`
+srcdir=`dirname "$0"`
 test -z "$srcdir" && srcdir=.
 
 ORIGDIR=`pwd`
-cd $srcdir
+cd "$srcdir"
 
 autoreconf --force -v --install || exit 1
-cd $ORIGDIR || exit $?
+cd "$ORIGDIR" || exit $?
 
 if test -z "$NOCONFIGURE"; then
-    exec $srcdir/configure "$@"
+    exec "$srcdir"/configure "$@"
 fi
commit 5c4202ea85aaea2a4dc7eb29776357a2ba13e191
Author: Michal Srb <msrb at suse.com>
Date:   Thu Feb 19 14:57:27 2015 +0200

    Expose GetMaster to modules.
    
    Add _X_EXPORT to GetMaster function. It is required by tigervnc's VNC module.
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/input.h b/include/input.h
index cb83cac..00a9cbd 100644
--- a/include/input.h
+++ b/include/input.h
@@ -504,7 +504,7 @@ extern int AttachDevice(ClientPtr client,
                         DeviceIntPtr slave, DeviceIntPtr master);
 
 extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd);
-extern DeviceIntPtr GetMaster(DeviceIntPtr dev, int type);
+extern _X_EXPORT DeviceIntPtr GetMaster(DeviceIntPtr dev, int type);
 
 extern _X_EXPORT int AllocDevicePair(ClientPtr client,
                                      const char *name,
commit f485a1af64bb00c696ea9f79961786bd791eaec1
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Dec 16 14:43:29 2014 +1000

    Drop valuator mask argument from GetKeyboardEvents
    
    Nothing was using it and if anyone had they would've gotten a warning and
    noticed that it doesn't actually work. Drop this, it has been unused for years.
    
    Input ABI 22
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 88df443..2371a69 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -421,7 +421,7 @@ ProcXTestFakeInput(ClientPtr client)
     case KeyPress:
     case KeyRelease:
         nevents =
-            GetKeyboardEvents(xtest_evlist, dev, type, ev->u.u.detail, NULL);
+            GetKeyboardEvents(xtest_evlist, dev, type, ev->u.u.detail);
         break;
     }
 
diff --git a/dix/devices.c b/dix/devices.c
index c4fdbe1..d8e7f9c 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2518,7 +2518,7 @@ ReleaseButtonsAndKeys(DeviceIntPtr dev)
     /* Release all keys */
     for (i = 0; k && i < MAP_LENGTH; i++) {
         if (BitIsOn(k->down, i)) {
-            nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i, NULL);
+            nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i);
             for (j = 0; j < nevents; j++)
                 mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
         }
diff --git a/dix/getevents.c b/dix/getevents.c
index bc7ffa6..d0a87f7 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1049,21 +1049,18 @@ event_set_root_coordinates(DeviceEvent *event, double x, double y)
  *
  * This function is not reentrant. Disable signals before calling.
  *
- * FIXME: flags for relative/abs motion?
- *
  * @param device The device to generate the event for
  * @param type Event type, one of KeyPress or KeyRelease
  * @param keycode Key code of the pressed/released key
- * @param mask Valuator mask for valuators present for this event.
  *
  */
 void
 QueueKeyboardEvents(DeviceIntPtr device, int type,
-                    int keycode, const ValuatorMask *mask)
+                    int keycode)
 {
     int nevents;
 
-    nevents = GetKeyboardEvents(InputEventList, device, type, keycode, mask);
+    nevents = GetKeyboardEvents(InputEventList, device, type, keycode);
     queueEventList(device, InputEventList, nevents);
 }
 
@@ -1078,20 +1075,17 @@ QueueKeyboardEvents(DeviceIntPtr device, int type,
  */
 int
 GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
-                  int key_code, const ValuatorMask *mask_in)
+                  int key_code)
 {
     int num_events = 0;
     CARD32 ms = 0;
     DeviceEvent *event;
     RawDeviceEvent *raw;
-    ValuatorMask mask;
 
 #if XSERVER_DTRACE
     if (XSERVER_INPUT_EVENT_ENABLED()) {
-        XSERVER_INPUT_EVENT(pDev->id, type, key_code, 0,
-                            mask_in ? mask_in->last_bit + 1 : 0,
-                            mask_in ? mask_in->mask : NULL,
-                            mask_in ? mask_in->valuators : NULL);
+        XSERVER_INPUT_EVENT(pDev->id, type, key_code, 0, 0,
+                            NULL, NULL);
     }
 #endif
 
@@ -1104,11 +1098,6 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
         (key_code < 8 || key_code > 255))
         return 0;
 
-    if (mask_in && valuator_mask_size(mask_in) > 1) {
-        ErrorF("[dix] the server does not handle valuator masks with "
-               "keyboard events. This is a bug. You may fix it.\n");
-    }
-
     num_events = 1;
 
     events =
@@ -1130,14 +1119,7 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
     events++;
     num_events++;
 
-    valuator_mask_copy(&mask, mask_in);
-
     init_raw(pDev, raw, ms, type, key_code);
-    set_raw_valuators(raw, &mask, raw->valuators.data_raw);
-
-    clipValuators(pDev, &mask);
-
-    set_raw_valuators(raw, &mask, raw->valuators.data);
 
     event = &events->device_event;
     init_device_event(event, pDev, ms);
@@ -1152,18 +1134,6 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
         set_key_up(pDev, key_code, KEY_POSTED);
     }
 
-    clipValuators(pDev, &mask);
-
-    set_valuators(pDev, event, &mask);
-
-    if (!IsFloating(pDev)) {
-        DeviceIntPtr master = GetMaster(pDev, MASTER_POINTER);
-
-        event_set_root_coordinates(event,
-                                   master->last.valuators[0],
-                                   master->last.valuators[1]);
-    }
-
     return num_events;
 }
 
diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c
index 14ac05f..2b579ee 100644
--- a/hw/dmx/input/dmxevents.c
+++ b/hw/dmx/input/dmxevents.c
@@ -488,12 +488,9 @@ dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     switch (type) {
     case XI_DeviceKeyPress:
     case XI_DeviceKeyRelease:
-        EXTRACT_VALUATORS(ke, valuators);
-        valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count,
-                                valuators);
         if (block)
             OsBlockSIGIO();
-        QueueKeyboardEvents(pDevice, event, ke->keycode, &mask);
+        QueueKeyboardEvents(pDevice, event, ke->keycode);
         if (block)
             OsReleaseSIGIO();
         break;
@@ -718,7 +715,7 @@ dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
             detail = dmxFixup(pDev, detail, keySym);
 
         /*ErrorF("KEY %d  sym %d\n", detail, (int) keySym); */
-        QueueKeyboardEvents(p, type, detail, NULL);
+        QueueKeyboardEvents(p, type, detail);
         return;
 
     case ButtonPress:
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index a539ca5..057f53b 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -1831,7 +1831,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo * ki,
         else
             type = KeyPress;
 
-        QueueKeyboardEvents(ki->dixdev, type, key_code, NULL);
+        QueueKeyboardEvents(ki->dixdev, type, key_code);
     }
     else {
         ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n",
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 16b3e28..c06aaae 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -403,7 +403,7 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
          i < keyc->xkbInfo->desc->max_key_code; i++) {
         if (key_is_down(pDev, i, KEY_POSTED)) {
             OsBlockSIGIO();
-            QueueKeyboardEvents(pDev, KeyRelease, i, NULL);
+            QueueKeyboardEvents(pDev, KeyRelease, i);
             OsReleaseSIGIO();
         }
     }
diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index e68fe9c..25a8869 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -81,7 +81,7 @@ typedef enum {
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
 #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(19, 0)
-#define ABI_XINPUT_VERSION	SET_ABI_VERSION(21, 0)
+#define ABI_XINPUT_VERSION	SET_ABI_VERSION(22, 0)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(9, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 1fb5b16..9fa3dc4 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -1326,47 +1326,21 @@ xf86PostButtonEventM(DeviceIntPtr device,
 }
 
 void
-xf86PostKeyEvent(DeviceIntPtr device,
-                 unsigned int key_code,
-                 int is_down,
-                 int is_absolute, int first_valuator, int num_valuators, ...)
+xf86PostKeyEvent(DeviceIntPtr device, unsigned int key_code, int is_down)
 {
-    va_list var;
-    int i = 0;
-    ValuatorMask mask;
-
-    XI_VERIFY_VALUATORS(num_valuators);
-
-    valuator_mask_zero(&mask);
-
-    va_start(var, num_valuators);
-    for (i = 0; i < num_valuators; i++)
-        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
-
-    va_end(var);
-
-    xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask);
+    xf86PostKeyEventM(device, key_code, is_down);
 }
 
 void
 xf86PostKeyEventP(DeviceIntPtr device,
                   unsigned int key_code,
-                  int is_down,
-                  int is_absolute,
-                  int first_valuator, int num_valuators, const int *valuators)
+                  int is_down)
 {
-    ValuatorMask mask;
-
-    XI_VERIFY_VALUATORS(num_valuators);
-
-    valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
-    xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask);
+    xf86PostKeyEventM(device, key_code, is_down);
 }
 
 void
-xf86PostKeyEventM(DeviceIntPtr device,
-                  unsigned int key_code,
-                  int is_down, int is_absolute, const ValuatorMask *mask)
+xf86PostKeyEventM(DeviceIntPtr device, unsigned int key_code, int is_down)
 {
 #if XFreeXDGA
     DeviceIntPtr pointer;
@@ -1382,8 +1356,7 @@ xf86PostKeyEventM(DeviceIntPtr device,
     }
 #endif
 
-    QueueKeyboardEvents(device,
-                        is_down ? KeyPress : KeyRelease, key_code, mask);
+    QueueKeyboardEvents(device, is_down ? KeyPress : KeyRelease, key_code);
 }
 
 void
@@ -1392,7 +1365,7 @@ xf86PostKeyboardEvent(DeviceIntPtr device, unsigned int key_code, int is_down)
     ValuatorMask mask;
 
     valuator_mask_zero(&mask);
-    xf86PostKeyEventM(device, key_code, is_down, 0, &mask);
+    xf86PostKeyEventM(device, key_code, is_down);
 }
 
 InputInfoPtr
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 42d66d2..0024053 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -148,18 +148,11 @@ extern _X_EXPORT void xf86PostButtonEventM(DeviceIntPtr device, int is_absolute,
                                            int button, int is_down,
                                            const ValuatorMask *mask);
 extern _X_EXPORT void xf86PostKeyEvent(DeviceIntPtr device,
-                                       unsigned int key_code, int is_down,
-                                       int is_absolute, int first_valuator,
-                                       int num_valuators, ...);
+                                       unsigned int key_code, int is_down);
 extern _X_EXPORT void xf86PostKeyEventM(DeviceIntPtr device,
-                                        unsigned int key_code, int is_down,
-                                        int is_absolute,
-                                        const ValuatorMask *mask);
+                                        unsigned int key_code, int is_down);
 extern _X_EXPORT void xf86PostKeyEventP(DeviceIntPtr device,
-                                        unsigned int key_code, int is_down,
-                                        int is_absolute, int first_valuator,
-                                        int num_valuators,
-                                        const int *valuators);
+                                        unsigned int key_code, int is_down);
 extern _X_EXPORT void xf86PostKeyboardEvent(DeviceIntPtr device,
                                             unsigned int key_code, int is_down);
 extern _X_EXPORT void xf86PostTouchEvent(DeviceIntPtr dev, uint32_t touchid,
diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c
index 3ff095b..f727557 100644
--- a/hw/xnest/Events.c
+++ b/hw/xnest/Events.c
@@ -103,7 +103,7 @@ void
 xnestQueueKeyEvent(int type, unsigned int keycode)
 {
     lastEventTime = GetTimeInMillis();
-    QueueKeyboardEvents(xnestKeyboardDevice, type, keycode, NULL);
+    QueueKeyboardEvents(xnestKeyboardDevice, type, keycode);
 }
 
 void
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 5a5e4da..9bf2f14 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -456,8 +456,7 @@ DarwinInputReleaseButtonsAndKeys(DeviceIntPtr pDev)
         if (pDev->key) {
             for (i = 0; i < NUM_KEYCODES; i++) {
                 if (BitIsOn(pDev->key->down, i + MIN_KEYCODE)) {
-                    QueueKeyboardEvents(pDev, KeyRelease, i + MIN_KEYCODE,
-                                        NULL);
+                    QueueKeyboardEvents(pDev, KeyRelease, i + MIN_KEYCODE);
                 }
             }
         }
@@ -611,8 +610,7 @@ DarwinSendKeyboardEvents(int ev_type, int keycode)
 
     darwinEvents_lock();
     {
-        QueueKeyboardEvents(darwinKeyboard, ev_type, keycode + MIN_KEYCODE,
-                            NULL);
+        QueueKeyboardEvents(darwinKeyboard, ev_type, keycode + MIN_KEYCODE);
         DarwinPokeEQ();
     } darwinEvents_unlock();
 }
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 5e20418..cc3bc53 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -323,7 +323,6 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
 {
     struct xwl_seat *xwl_seat = data;
     uint32_t *k, *end;
-    ValuatorMask mask;
 
     xwl_seat->xwl_screen->serial = serial;
 
@@ -338,9 +337,8 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
         *k = key;
     }
 
-    valuator_mask_zero(&mask);
     QueueKeyboardEvents(xwl_seat->keyboard,
-                        state ? KeyPress : KeyRelease, key + 8, &mask);
+                        state ? KeyPress : KeyRelease, key + 8);
 }
 
 static void
@@ -393,16 +391,14 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
                       struct wl_surface *surface, struct wl_array *keys)
 {
     struct xwl_seat *xwl_seat = data;
-    ValuatorMask mask;
     uint32_t *k;
 
     xwl_seat->xwl_screen->serial = serial;
     xwl_seat->keyboard_focus = surface;
 
     wl_array_copy(&xwl_seat->keys, keys);
-    valuator_mask_zero(&mask);
     wl_array_for_each(k, &xwl_seat->keys)
-        QueueKeyboardEvents(xwl_seat->keyboard, KeyPress, *k + 8, &mask);
+        QueueKeyboardEvents(xwl_seat->keyboard, KeyPress, *k + 8);
 }
 
 static void
@@ -410,14 +406,12 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
                       uint32_t serial, struct wl_surface *surface)
 {
     struct xwl_seat *xwl_seat = data;
-    ValuatorMask mask;
     uint32_t *k;
 
     xwl_seat->xwl_screen->serial = serial;
 
-    valuator_mask_zero(&mask);
     wl_array_for_each(k, &xwl_seat->keys)
-        QueueKeyboardEvents(xwl_seat->keyboard, KeyRelease, *k + 8, &mask);
+        QueueKeyboardEvents(xwl_seat->keyboard, KeyRelease, *k + 8);
 
     xwl_seat->keyboard_focus = NULL;
 }
diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c
index 3a75ab2..e7202a6 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -502,7 +502,7 @@ winSendKeyEvent(DWORD dwKey, Bool fDown)
     g_winKeyState[dwKey] = fDown;
 
     QueueKeyboardEvents(g_pwinKeyboard, fDown ? KeyPress : KeyRelease,
-                        dwKey + MIN_KEYCODE, NULL);
+                        dwKey + MIN_KEYCODE);
 
     winDebug("winSendKeyEvent: dwKey: %d, fDown: %d\n", dwKey, fDown);
 }
diff --git a/include/input.h b/include/input.h
index bf22dc7..cb83cac 100644
--- a/include/input.h
+++ b/include/input.h
@@ -448,12 +448,11 @@ extern _X_EXPORT void QueuePointerEvents(DeviceIntPtr pDev,
 extern _X_EXPORT int GetKeyboardEvents(InternalEvent *events,
                                        DeviceIntPtr pDev,
                                        int type,
-                                       int key_code, const ValuatorMask *mask);
+                                       int key_code);
 
 extern _X_EXPORT void QueueKeyboardEvents(DeviceIntPtr pDev,
                                           int type,
-                                          int key_code,
-                                          const ValuatorMask *mask);
+                                          int key_code);
 
 extern int GetTouchEvents(InternalEvent *events,
                           DeviceIntPtr pDev,
commit 9d9bd38fe1454590c303dc936ddac913808bf881
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Feb 17 14:40:27 2015 +1000

    os/access: fix regression in server interpreted auth
    
    This was reported on irc on Fedora when rawhide went to 1.17.1.
    
    regression occured in: 2566835b4374edb3e5a8353d4f7c9e7ec4851c57
     os: Eliminate uninitialized value warnings from access.c
    
    siAddrMatch doesn't need addr to be a useful value, it checks
    some things like localuser without having an address at all.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Tested-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/os/access.c b/os/access.c
index 28f2d32..8fa028e 100644
--- a/os/access.c
+++ b/os/access.c
@@ -1392,7 +1392,7 @@ InvalidHost(register struct sockaddr *saddr, int len, ClientPtr client)
     }
     for (host = validhosts; host; host = host->next) {
         if (host->family == FamilyServerInterpreted) {
-            if (addr && siAddrMatch(family, addr, len, host, client)) {
+            if (siAddrMatch(family, addr, len, host, client)) {
                 return 0;
             }
         }


More information about the Xquartz-changes mailing list