xserver: Branch 'server-1.18-branch' - 106 commits

Adam Jackson ajax at kemper.freedesktop.org
Fri Mar 11 18:37:21 UTC 2016


 Xext/Makefile.am                                 |    7 
 Xext/vidmode.c                                   | 2151 +++++++++++++++++++++++
 Xext/xvmain.c                                    |   11 
 Xext/xvmc.c                                      |   17 
 autogen.sh                                       |    3 
 configure.ac                                     |   23 
 dix/dixutils.c                                   |   22 
 dix/window.c                                     |   32 
 dri3/dri3_request.c                              |    4 
 glamor/Makefile.am                               |    6 
 glamor/glamor.c                                  |   16 
 glamor/glamor.h                                  |    4 
 glamor/glamor_composite_glyphs.c                 |   14 
 glamor/glamor_copy.c                             |   15 
 glamor/glamor_core.c                             |   22 
 glamor/glamor_dash.c                             |    6 
 glamor/glamor_egl.c                              |  189 +-
 glamor/glamor_egl_stubs.c                        |    6 
 glamor/glamor_fbo.c                              |   43 
 glamor/glamor_glyphblt.c                         |   12 
 glamor/glamor_gradient.c                         |   33 
 glamor/glamor_lines.c                            |    6 
 glamor/glamor_picture.c                          |   49 
 glamor/glamor_points.c                           |    7 
 glamor/glamor_priv.h                             |   50 
 glamor/glamor_program.c                          |   49 
 glamor/glamor_program.h                          |    1 
 glamor/glamor_rects.c                            |    7 
 glamor/glamor_render.c                           |  424 ++--
 glamor/glamor_segs.c                             |    6 
 glamor/glamor_spans.c                            |   23 
 glamor/glamor_text.c                             |    8 
 glamor/glamor_transfer.c                         |   18 
 glamor/glamor_transform.c                        |   23 
 glamor/glamor_transform.h                        |   15 
 glamor/glamor_utils.h                            |   52 
 glamor/glamor_vbo.c                              |    9 
 glamor/glamor_xv.c                               |  224 +-
 glx/extension_string.c                           |    2 
 glx/extension_string.h                           |    2 
 glx/glxcmds.c                                    |   59 
 glx/glxdri2.c                                    |    6 
 glx/glxdriswrast.c                               |    1 
 hw/dmx/glxProxy/glxcmds.c                        |    5 
 hw/kdrive/ephyr/ephyr_glamor_glx.c               |  122 +
 hw/kdrive/linux/evdev.c                          |   11 
 hw/kdrive/src/kdrive.c                           |    4 
 hw/vfb/InitOutput.c                              |    4 
 hw/xfree86/Makefile.am                           |    4 
 hw/xfree86/common/Makefile.am                    |    4 
 hw/xfree86/common/vidmodeproc.h                  |   83 
 hw/xfree86/common/xf86Config.c                   |    8 
 hw/xfree86/common/xf86Extensions.c               |    3 
 hw/xfree86/common/xf86Helper.c                   |    4 
 hw/xfree86/common/xf86Init.c                     |    1 
 hw/xfree86/common/xf86Privstr.h                  |   10 
 hw/xfree86/common/xf86VidMode.c                  |  582 ++----
 hw/xfree86/common/xf86str.h                      |   92 
 hw/xfree86/common/xf86vmode.c                    | 1955 --------------------
 hw/xfree86/dri/dri.c                             |    8 
 hw/xfree86/dri2/dri2.c                           |  130 -
 hw/xfree86/dri2/pci_ids/Makefile.am              |    1 
 hw/xfree86/dri2/pci_ids/pci_id_driver_map.h      |    7 
 hw/xfree86/dri2/pci_ids/virtio_gpu_pci_ids.h     |    2 
 hw/xfree86/drivers/modesetting/dri2.c            |    4 
 hw/xfree86/drivers/modesetting/drmmode_display.c |    1 
 hw/xfree86/modes/xf86Crtc.c                      |    6 
 hw/xfree86/modes/xf86Cursors.c                   |   21 
 hw/xfree86/modes/xf86RandR12.c                   |    4 
 hw/xfree86/ramdac/xf86Cursor.c                   |   24 
 hw/xfree86/ramdac/xf86Cursor.h                   |    1 
 hw/xquartz/darwinEvents.c                        |    2 
 hw/xquartz/quartz.c                              |    4 
 hw/xquartz/quartz.h                              |    2 
 hw/xwayland/Makefile.am                          |    9 
 hw/xwayland/xwayland-glamor-xv.c                 |  412 ++++
 hw/xwayland/xwayland-glamor.c                    |   29 
 hw/xwayland/xwayland-input.c                     |   10 
 hw/xwayland/xwayland-output.c                    |   10 
 hw/xwayland/xwayland-shm.c                       |   12 
 hw/xwayland/xwayland-vidmode.c                   |  408 ++++
 hw/xwayland/xwayland.c                           |   15 
 hw/xwayland/xwayland.h                           |   10 
 hw/xwin/winauth.c                                |   17 
 hw/xwin/winclipboard/internal.h                  |    8 
 hw/xwin/winclipboard/thread.c                    |    9 
 hw/xwin/winclipboard/wndproc.c                   |  109 -
 hw/xwin/winconfig.c                              |   74 
 hw/xwin/winlayouts.h                             |    5 
 hw/xwin/winmultiwindowclass.h                    |   28 
 hw/xwin/winmultiwindowwindow.c                   |   30 
 hw/xwin/winmultiwindowwm.c                       |    7 
 hw/xwin/winrandr.c                               |   96 -
 include/Makefile.am                              |    2 
 include/displaymode.h                            |  102 +
 include/dix-config.h.in                          |    3 
 include/dix.h                                    |    8 
 include/vidmodestr.h                             |  142 +
 include/window.h                                 |    8 
 os/osdep.h                                       |    6 
 present/present.c                                |  122 -
 randr/rrmonitor.c                                |   15 
 randr/rroutput.c                                 |   12 
 record/record.c                                  |    1 
 render/picture.c                                 |    3 
 test/Makefile.am                                 |    2 
 xfixes/cursor.c                                  |    4 
 107 files changed, 4955 insertions(+), 3559 deletions(-)

New commits:
commit 643359fb03c51244c9ed5f5efab4c84594259e8c
Author: Dave Airlie <airlied at gmail.com>
Date:   Tue Feb 9 16:54:22 2016 +1000

    present: fail flipping if we have any slave outputs
    
    Due to the way present currently works, we don't ever check with the
    secondary adapters if we can flip at all.
    
    We shouldn't flip if the secondary adapters are attached to the pixmap
    currently, however using the current check_flip callback isn't possible
    as it passes the Window to the driver (something we shouldn't be doing),
    so the slave driver can never get it's own screen ptr back.
    
    For now to fix the problem just block flips if we have any slaves
    configured. We can fix the ABI up later, but this fix can be backported
    to stable.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 47bc7fcaa567b0d9e2627b4a21b112e96f81725b)

diff --git a/present/present.c b/present/present.c
index 1ce16af..55f6aa7 100644
--- a/present/present.c
+++ b/present/present.c
@@ -144,6 +144,10 @@ present_check_flip(RRCrtcPtr    crtc,
     if (!screen_priv->info->flip)
         return FALSE;
 
+    /* Fail to flip if we have slave outputs */
+    if (!xorg_list_is_empty(&screen->output_slave_list))
+        return FALSE;
+
     /* Make sure the window hasn't been redirected with Composite */
     window_pixmap = screen->GetWindowPixmap(window);
     if (window_pixmap != screen->GetScreenPixmap(screen) &&
commit 3e480c6f5168e7da1521bdcc15ed8b5b8762612d
Author: Adam Jackson <ajax at redhat.com>
Date:   Thu Jan 21 12:47:57 2016 -0500

    glx: Implement GLX_EXT_fbconfig_packed_float
    
    The tokens for this are already defined by GLX_ARB_fbconfig_float, which
    we already support, so just add the extension to the list and let the
    driver provide those configs if it wants.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit ef3005da3d5dc92b3ee5a0ee78164e739a3216dc)

diff --git a/glx/extension_string.c b/glx/extension_string.c
index c3ddc4c..616c793 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -82,6 +82,7 @@ static const struct extension_info known_glx_extensions[] = {
 
     { GLX(EXT_create_context_es_profile), VER(0,0), N, },
     { GLX(EXT_create_context_es2_profile), VER(0,0), N, },
+    { GLX(EXT_fbconfig_packed_float),   VER(0,0), N, },
     { GLX(EXT_framebuffer_sRGB),        VER(0,0), N, },
     { GLX(EXT_import_context),          VER(0,0), Y, },
     { GLX(EXT_stereo_tree),             VER(0,0), N, },
diff --git a/glx/extension_string.h b/glx/extension_string.h
index c1df91b..425a805 100644
--- a/glx/extension_string.h
+++ b/glx/extension_string.h
@@ -45,6 +45,7 @@ enum {
     ARB_multisample_bit,
     EXT_create_context_es_profile_bit,
     EXT_create_context_es2_profile_bit,
+    EXT_fbconfig_packed_float_bit,
     EXT_import_context_bit,
     EXT_stereo_tree_bit,
     EXT_texture_from_pixmap_bit,
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 89ad808..58e60b9 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -895,6 +895,12 @@ initializeExtensions(__GLXDRIscreen * screen)
         LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_fbconfig_float\n");
     }
 
+    /* enable EXT_fbconfig_packed_float (even if there are no packed float fbconfigs) */
+    {
+        __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_fbconfig_packed_float");
+        LogMessage(X_INFO, "AIGLX: enabled GLX_EXT_fbconfig_packed_float\n");
+    }
+
     for (i = 0; extensions[i]; i++) {
         if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
             __glXEnableExtension(screen->glx_enable_bits,
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index be00f5f..924067c 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -413,6 +413,7 @@ initializeExtensions(__GLXDRIscreen * screen)
     /* these are harmless to enable unconditionally */
     __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_framebuffer_sRGB");
     __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_fbconfig_float");
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_fbconfig_packed_float");
     __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_make_current_read");
 
     extensions = screen->core->getExtensions(screen->driScreen);
commit b9f7edda0634955711870bb1389095525d4496e3
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon May 18 13:00:02 2015 -0400

    glx: Implement GLX_EXT_stereo_tree
    
    This is correct as it is, but only because we know no DRI drivers
    implement stereo.
    
    v2: Use new ATTRIB macro
    
    Reviewed-by: James Jones <jajones at nvidia.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit d15cb654b6ba365dac9a62064e277adebde2fdab)

diff --git a/glx/extension_string.c b/glx/extension_string.c
index cf90146..c3ddc4c 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -84,6 +84,7 @@ static const struct extension_info known_glx_extensions[] = {
     { GLX(EXT_create_context_es2_profile), VER(0,0), N, },
     { GLX(EXT_framebuffer_sRGB),        VER(0,0), N, },
     { GLX(EXT_import_context),          VER(0,0), Y, },
+    { GLX(EXT_stereo_tree),             VER(0,0), N, },
     { GLX(EXT_texture_from_pixmap),     VER(0,0), Y, },
     { GLX(EXT_visual_info),             VER(0,0), Y, },
     { GLX(EXT_visual_rating),           VER(0,0), Y, },
diff --git a/glx/extension_string.h b/glx/extension_string.h
index ffaab07..c1df91b 100644
--- a/glx/extension_string.h
+++ b/glx/extension_string.h
@@ -46,6 +46,7 @@ enum {
     EXT_create_context_es_profile_bit,
     EXT_create_context_es2_profile_bit,
     EXT_import_context_bit,
+    EXT_stereo_tree_bit,
     EXT_texture_from_pixmap_bit,
     EXT_visual_info_bit,
     EXT_visual_rating_bit,
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 139432e..561faeb 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -1921,6 +1921,11 @@ __glXDisp_CopySubBufferMESA(__GLXclientState * cl, GLbyte * pc)
     return Success;
 }
 
+/* hack for old glxext.h */
+#ifndef GLX_STEREO_TREE_EXT
+#define GLX_STEREO_TREE_EXT                 0x20F5
+#endif
+
 /*
 ** Get drawable attributes
 */
@@ -1931,7 +1936,7 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
     xGLXGetDrawableAttributesReply reply;
     __GLXdrawable *pGlxDraw = NULL;
     DrawablePtr pDraw;
-    CARD32 attributes[16];
+    CARD32 attributes[18];
     int num = 0, error;
 
     if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
@@ -1964,6 +1969,9 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
         if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) {
             ATTRIB(GLX_PRESERVED_CONTENTS, GL_TRUE);
         }
+        if (pGlxDraw->type == GLX_DRAWABLE_WINDOW) {
+            ATTRIB(GLX_STEREO_TREE_EXT, 0);
+        }
     }
 #undef ATTRIB
 
commit 2b3363418a425bf432b55927d8f8dd93c004c791
Author: Adam Jackson <ajax at redhat.com>
Date:   Thu Mar 3 16:50:02 2016 -0500

    glx: Add GLX_SCREEN to the GetDrawableAttributes response
    
    libglvnd would like to use this to map from drawable to screen, so it
    can know which driver to dispatch to. Refer to the spec proposal here:
    
    https://lists.freedesktop.org/archives/mesa-dev/2016-March/109543.html
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit a18238877bbf9aab95843d849a6f434275e9cd6c)

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index d8a144f..139432e 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -1931,7 +1931,7 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
     xGLXGetDrawableAttributesReply reply;
     __GLXdrawable *pGlxDraw = NULL;
     DrawablePtr pDraw;
-    CARD32 attributes[14];
+    CARD32 attributes[16];
     int num = 0, error;
 
     if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
@@ -1954,6 +1954,7 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
     ATTRIB(GLX_Y_INVERTED_EXT, GL_FALSE);
     ATTRIB(GLX_WIDTH, pDraw->width);
     ATTRIB(GLX_HEIGHT, pDraw->height);
+    ATTRIB(GLX_SCREEN, pDraw->pScreen->myNum);
     if (pGlxDraw) {
         ATTRIB(GLX_TEXTURE_TARGET_EXT,
                pGlxDraw->target == GL_TEXTURE_2D ?
commit 2541d765fdd1006d649063882e3a667438f1d30e
Author: Adam Jackson <ajax at redhat.com>
Date:   Thu Mar 10 12:29:34 2016 -0500

    glx: Macroize building the attribute list in DoGetDrawableAttributes
    
    No functional change, just a little easier to read and harder to get
    wrong.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit 47c1d6b7abcfb1c6b478367bbc2e869c91485bc0)

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 6eb3541..d8a144f 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -1945,33 +1945,26 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
     if (pGlxDraw)
         pDraw = pGlxDraw->pDraw;
 
-    attributes[2*num] = GLX_Y_INVERTED_EXT;
-    attributes[2*num+1] = GL_FALSE;
-    num++;
-    attributes[2*num] = GLX_WIDTH;
-    attributes[2*num+1] = pDraw->width;
-    num++;
-    attributes[2*num] = GLX_HEIGHT;
-    attributes[2*num+1] = pDraw->height;
-    num++;
+#define ATTRIB(a, v) do { \
+    attributes[2*num] = (a); \
+    attributes[2*num+1] = (v); \
+    num++; \
+    } while (0)
+
+    ATTRIB(GLX_Y_INVERTED_EXT, GL_FALSE);
+    ATTRIB(GLX_WIDTH, pDraw->width);
+    ATTRIB(GLX_HEIGHT, pDraw->height);
     if (pGlxDraw) {
-        attributes[2*num] = GLX_TEXTURE_TARGET_EXT;
-        attributes[2*num+1] = pGlxDraw->target == GL_TEXTURE_2D ?
-            GLX_TEXTURE_2D_EXT :
-            GLX_TEXTURE_RECTANGLE_EXT;
-        num++;
-        attributes[2*num] = GLX_EVENT_MASK;
-        attributes[2*num+1] = pGlxDraw->eventMask;
-        num++;
-        attributes[2*num] = GLX_FBCONFIG_ID;
-        attributes[2*num+1] = pGlxDraw->config->fbconfigID;
-        num++;
+        ATTRIB(GLX_TEXTURE_TARGET_EXT,
+               pGlxDraw->target == GL_TEXTURE_2D ?
+                GLX_TEXTURE_2D_EXT : GLX_TEXTURE_RECTANGLE_EXT);
+        ATTRIB(GLX_EVENT_MASK, pGlxDraw->eventMask);
+        ATTRIB(GLX_FBCONFIG_ID, pGlxDraw->config->fbconfigID);
         if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) {
-            attributes[2*num] = GLX_PRESERVED_CONTENTS;
-            attributes[2*num+1] = GL_TRUE;
-            num++;
+            ATTRIB(GLX_PRESERVED_CONTENTS, GL_TRUE);
         }
     }
+#undef ATTRIB
 
     reply = (xGLXGetDrawableAttributesReply) {
         .type = X_Reply,
commit 2a7b6ea1a54a4c8174669c1ca38c4665505c4637
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:15 2016 -0800

    ephyr: Fix redisplay with glamor on GLES.
    
    glamor_transfer.c is still totally broken, though.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    (cherry picked from commit c01094c5312fbd84146dd83122e5256a8e57d092)

diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c
index 636150d..2f21914 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -225,8 +225,10 @@ ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
     if (glamor->vao) {
         glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao);
         glBindVertexArray(glamor->vao);
-    } else
+    } else {
+        glBindBuffer(GL_ARRAY_BUFFER, glamor->vbo);
         ephyr_glamor_set_vertices(glamor);
+    }
 
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
     glUseProgram(glamor->texture_shader);
commit 5af20f15636aa2ede3dac1af9e9afa063564130c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Mar 9 16:45:18 2016 +0100

    glamor: do not build Xv support when --disable-xv
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 25ce263fd88684be9370025f93ba3a2bfc72ff1a)

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index c488029..c631c53 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -46,10 +46,14 @@ libglamor_la_SOURCES = \
 	glamor_compositerects.c\
 	glamor_utils.c\
 	glamor_utils.h\
-	glamor_xv.c \
 	glamor_sync.c \
 	glamor.h
 
+if XV
+libglamor_la_SOURCES += \
+	glamor_xv.c
+endif
+
 libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c
 
 sdk_HEADERS = glamor.h
commit 9fc05b85e544638ccc4b811c19e64312b387c799
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Mar 9 16:21:18 2016 +0100

    xwayland: add glamor Xv adaptor
    
    This adds an Xv adaptor using glamor.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit da7724d3d277c6c8a814881785b716896802629a)

diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am
index 0905082..0e6a1ea 100644
--- a/hw/xwayland/Makefile.am
+++ b/hw/xwayland/Makefile.am
@@ -32,7 +32,12 @@ Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
 
 
 if GLAMOR_EGL
-Xwayland_SOURCES += xwayland-glamor.c
+Xwayland_SOURCES += 				\
+	xwayland-glamor.c
+if XV
+Xwayland_SOURCES += 				\
+	xwayland-glamor-xv.c
+endif
 
 nodist_Xwayland_SOURCES =			\
 	drm-client-protocol.h			\
diff --git a/hw/xwayland/xwayland-glamor-xv.c b/hw/xwayland/xwayland-glamor-xv.c
new file mode 100644
index 0000000..c99418d
--- /dev/null
+++ b/hw/xwayland/xwayland-glamor-xv.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
+ * Copyright © 2013 Red Hat
+ * Copyright © 2014 Intel Corporation
+ * Copyright © 2016 Red Hat
+ *
+ * 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.
+ *
+ * Authors:
+ *      Olivier Fourdan <ofourdan at redhat.com>
+ *
+ * Derived from the glamor_xf86_xv, ephyr_glamor_xv and xf86xv
+ * implementations
+ */
+
+#include "xwayland.h"
+#include "glamor_priv.h"
+
+#include <X11/extensions/Xv.h>
+
+#define NUM_FORMATS    3
+#define NUM_PORTS      16
+#define ADAPTOR_NAME   "glamor textured video"
+#define ENCODER_NAME   "XV_IMAGE"
+
+static DevPrivateKeyRec xwlXvScreenPrivateKeyRec;
+#define xwlXvScreenPrivateKey (&xwlXvScreenPrivateKeyRec)
+
+typedef struct {
+    XvAdaptorPtr glxv_adaptor; /* We have only one adaptor, glamor Xv */
+    glamor_port_private *port_privates;
+
+    CloseScreenProcPtr CloseScreen;
+} xwlXvScreenRec, *xwlXvScreenPtr;
+
+typedef struct {
+    char depth;
+    short class;
+} xwlVideoFormatRec, *xwlVideoFormatPtr;
+
+static xwlVideoFormatRec Formats[NUM_FORMATS] = {
+    {15, TrueColor},
+    {16, TrueColor},
+    {24, TrueColor}
+};
+
+static int
+xwl_glamor_xv_stop_video(XvPortPtr   pPort,
+                         DrawablePtr pDraw)
+{
+    glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
+
+    if (pDraw->type != DRAWABLE_WINDOW)
+        return BadAlloc;
+
+    glamor_xv_stop_video(gpp);
+
+    return Success;
+}
+
+static int
+xwl_glamor_xv_set_port_attribute(XvPortPtr pPort,
+                                 Atom      attribute,
+                                 INT32     value)
+{
+    glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
+
+    return glamor_xv_set_port_attribute(gpp, attribute, value);
+}
+
+static int
+xwl_glamor_xv_get_port_attribute(XvPortPtr pPort,
+                                 Atom      attribute,
+                                 INT32    *pValue)
+{
+    glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
+
+    return glamor_xv_get_port_attribute(gpp, attribute, pValue);
+}
+
+static int
+xwl_glamor_xv_query_best_size(XvPortPtr     pPort,
+                              CARD8         motion,
+                              CARD16        vid_w,
+                              CARD16        vid_h,
+                              CARD16        drw_w,
+                              CARD16        drw_h,
+                              unsigned int *p_w,
+                              unsigned int *p_h)
+{
+    *p_w = drw_w;
+    *p_h = drw_h;
+
+    return Success;
+}
+
+static int
+xwl_glamor_xv_query_image_attributes(XvPortPtr  pPort,
+                                     XvImagePtr format,
+                                     CARD16    *width,
+                                     CARD16    *height,
+                                     int       *pitches,
+                                     int       *offsets)
+{
+    return glamor_xv_query_image_attributes(format->id,
+                                            width,
+                                            height,
+                                            pitches,
+                                            offsets);
+}
+
+static int
+xwl_glamor_xv_put_image(DrawablePtr    pDrawable,
+                        XvPortPtr      pPort,
+                        GCPtr          pGC,
+                        INT16          src_x,
+                        INT16          src_y,
+                        CARD16         src_w,
+                        CARD16         src_h,
+                        INT16          drw_x,
+                        INT16          drw_y,
+                        CARD16         drw_w,
+                        CARD16         drw_h,
+                        XvImagePtr     format,
+                        unsigned char *data,
+                        Bool           sync,
+                        CARD16         width,
+                        CARD16         height)
+{
+    glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
+
+    RegionRec WinRegion;
+    RegionRec ClipRegion;
+    BoxRec WinBox;
+    int ret = Success;
+
+    if (pDrawable->type != DRAWABLE_WINDOW)
+        return BadWindow;
+
+    WinBox.x1 = pDrawable->x + drw_x;
+    WinBox.y1 = pDrawable->y + drw_y;
+    WinBox.x2 = WinBox.x1 + drw_w;
+    WinBox.y2 = WinBox.y1 + drw_h;
+
+    RegionInit(&WinRegion, &WinBox, 1);
+    RegionInit(&ClipRegion, NullBox, 1);
+    RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+    if (RegionNotEmpty(&ClipRegion))
+        ret = glamor_xv_put_image(gpp,
+                                  pDrawable,
+                                  src_x,
+                                  src_y,
+                                  pDrawable->x + drw_x,
+                                  pDrawable->y + drw_y,
+                                  src_w,
+                                  src_h,
+                                  drw_w,
+                                  drw_h,
+                                  format->id,
+                                  data,
+                                  width,
+                                  height,
+                                  sync,
+                                  &ClipRegion);
+
+     RegionUninit(&WinRegion);
+     RegionUninit(&ClipRegion);
+
+     return ret;
+
+}
+
+static Bool
+xwl_glamor_xv_add_formats(XvAdaptorPtr pa)
+{
+    ScreenPtr pScreen;
+    XvFormatPtr pFormat, pf;
+    VisualPtr pVisual;
+    int numFormat;
+    int totFormat;
+    int numVisuals;
+    int i;
+
+    totFormat = NUM_FORMATS;
+    pFormat = xnfcalloc(totFormat, sizeof(XvFormatRec));
+    pScreen = pa->pScreen;
+    for (pf = pFormat, i = 0, numFormat = 0; i < NUM_FORMATS; i++) {
+        numVisuals = pScreen->numVisuals;
+        pVisual = pScreen->visuals;
+
+        while (numVisuals--) {
+           if ((pVisual->class == Formats[i].class) &&
+               (pVisual->nplanes == Formats[i].depth)) {
+                    if (numFormat >= totFormat) {
+                        void *moreSpace;
+
+                        totFormat *= 2;
+                        moreSpace = XNFreallocarray(pFormat, totFormat,
+                                                    sizeof(XvFormatRec));
+                        pFormat = moreSpace;
+                        pf = pFormat + numFormat;
+                    }
+
+                    pf->visual = pVisual->vid;
+                    pf->depth = Formats[i].depth;
+
+                    pf++;
+                    numFormat++;
+                }
+            pVisual++;
+        }
+    }
+    pa->nFormats = numFormat;
+    pa->pFormats = pFormat;
+
+    return numFormat != 0;
+}
+
+static Bool
+xwl_glamor_xv_add_ports(XvAdaptorPtr pa)
+{
+    XvPortPtr pPorts, pp;
+    xwlXvScreenPtr xwlXvScreen;
+    unsigned long PortResource = 0;
+    int nPorts;
+    int i;
+
+    pPorts = xnfcalloc(NUM_PORTS, sizeof(XvPortRec));
+    xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates,
+                                   xwlXvScreenPrivateKey);
+    xwlXvScreen->port_privates = xnfcalloc(NUM_PORTS,
+                                           sizeof(glamor_port_private));
+
+    PortResource = XvGetRTPort();
+    for (pp = pPorts, i = 0, nPorts = 0; i < NUM_PORTS; i++) {
+        if (!(pp->id = FakeClientID(0)))
+            continue;
+
+        pp->pAdaptor = pa;
+
+        glamor_xv_init_port(&xwlXvScreen->port_privates[i]);
+        pp->devPriv.ptr = &xwlXvScreen->port_privates[i];
+
+        if (AddResource(pp->id, PortResource, pp)) {
+            pp++;
+            nPorts++;
+        }
+    }
+
+    pa->base_id = pPorts->id;
+    pa->nPorts = nPorts;
+    pa->pPorts = pPorts;
+
+    return nPorts != 0;
+}
+
+static void
+xwl_glamor_xv_add_attributes(XvAdaptorPtr pa)
+{
+    int i;
+
+    pa->pAttributes = xnfcalloc(glamor_xv_num_attributes, sizeof(XvAttributeRec));
+    memcpy(pa->pAttributes, glamor_xv_attributes,
+           glamor_xv_num_attributes * sizeof(XvAttributeRec));
+
+    for (i = 0; i < glamor_xv_num_attributes; i++)
+        pa->pAttributes[i].name = strdup(glamor_xv_attributes[i].name);
+
+    pa->nAttributes = glamor_xv_num_attributes;
+}
+
+static void
+xwl_glamor_xv_add_images(XvAdaptorPtr pa)
+{
+    pa->pImages = xnfcalloc(glamor_xv_num_images, sizeof(XvImageRec));
+    memcpy(pa->pImages, glamor_xv_images, glamor_xv_num_images * sizeof(XvImageRec));
+
+    pa->nImages = glamor_xv_num_images;
+}
+
+static void
+xwl_glamor_xv_add_encodings(XvAdaptorPtr pa)
+{
+    XvEncodingPtr pe;
+    GLint texsize;
+
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texsize);
+
+    pe = xnfcalloc(1, sizeof(XvEncodingRec));
+    pe->id = 0;
+    pe->pScreen = pa->pScreen;
+    pe->name = strdup(ENCODER_NAME);
+    pe->width = texsize;
+    pe->height = texsize;
+    pe->rate.numerator = 1;
+    pe->rate.denominator = 1;
+
+    pa->pEncodings = pe;
+    pa->nEncodings = 1;
+}
+
+static Bool
+xwl_glamor_xv_add_adaptors(ScreenPtr pScreen)
+{
+    DevPrivateKey XvScreenKey;
+    XvScreenPtr XvScreen;
+    xwlXvScreenPtr xwlXvScreen;
+    XvAdaptorPtr pa;
+
+    if (XvScreenInit(pScreen) != Success)
+        return FALSE;
+
+    XvScreenKey = XvGetScreenKey();
+    XvScreen = dixLookupPrivate(&(pScreen)->devPrivates, XvScreenKey);
+
+    XvScreen->nAdaptors = 0;
+    XvScreen->pAdaptors = NULL;
+
+    pa = xnfcalloc(1, sizeof(XvAdaptorRec));
+    pa->pScreen = pScreen;
+    pa->type = (unsigned int) (XvWindowMask | XvInputMask | XvImageMask);
+    pa->ddStopVideo = xwl_glamor_xv_stop_video;
+    pa->ddPutImage = xwl_glamor_xv_put_image;
+    pa->ddSetPortAttribute = xwl_glamor_xv_set_port_attribute;
+    pa->ddGetPortAttribute = xwl_glamor_xv_get_port_attribute;
+    pa->ddQueryBestSize = xwl_glamor_xv_query_best_size;
+    pa->ddQueryImageAttributes = xwl_glamor_xv_query_image_attributes;
+    pa->name = strdup(ADAPTOR_NAME);
+
+    xwl_glamor_xv_add_encodings(pa);
+    xwl_glamor_xv_add_images(pa);
+    xwl_glamor_xv_add_attributes(pa);
+    if (!xwl_glamor_xv_add_formats(pa))
+        goto failed;
+    if (!xwl_glamor_xv_add_ports(pa))
+        goto failed;
+
+    /* We're good now with out Xv adaptor */
+    XvScreen->nAdaptors = 1;
+    XvScreen->pAdaptors = pa;
+
+    xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates,
+                                   xwlXvScreenPrivateKey);
+    xwlXvScreen->glxv_adaptor = pa;
+
+    return TRUE;
+
+failed:
+    XvFreeAdaptor(pa);
+    free(pa);
+
+    return FALSE;
+}
+
+static Bool
+xwl_glamor_xv_close_screen(ScreenPtr pScreen)
+{
+    xwlXvScreenPtr xwlXvScreen;
+
+    xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates,
+                                   xwlXvScreenPrivateKey);
+
+    if (xwlXvScreen->glxv_adaptor) {
+        XvFreeAdaptor(xwlXvScreen->glxv_adaptor);
+        free(xwlXvScreen->glxv_adaptor);
+    }
+    free(xwlXvScreen->port_privates);
+
+    pScreen->CloseScreen = xwlXvScreen->CloseScreen;
+
+    return pScreen->CloseScreen(pScreen);
+}
+
+Bool
+xwl_glamor_xv_init(ScreenPtr pScreen)
+{
+    xwlXvScreenPtr xwlXvScreen;
+
+    if (!dixRegisterPrivateKey(xwlXvScreenPrivateKey, PRIVATE_SCREEN,
+                               sizeof(xwlXvScreenRec)))
+        return FALSE;
+
+    xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates,
+                                    xwlXvScreenPrivateKey);
+
+    xwlXvScreen->port_privates = NULL;
+    xwlXvScreen->glxv_adaptor = NULL;
+    xwlXvScreen->CloseScreen = pScreen->CloseScreen;
+    pScreen->CloseScreen = xwl_glamor_xv_close_screen;
+
+    glamor_xv_core_init(pScreen);
+
+    return xwl_glamor_xv_add_adaptors(pScreen);
+}
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 40f22a3..04aa8f2 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -574,5 +574,10 @@ xwl_glamor_init(struct xwl_screen *xwl_screen)
     screen->CreatePixmap = xwl_glamor_create_pixmap;
     screen->DestroyPixmap = xwl_glamor_destroy_pixmap;
 
+#ifdef XV
+    if (!xwl_glamor_xv_init(screen))
+        ErrorF("Failed to initialize glamor Xv extension\n");
+#endif
+
     return TRUE;
 }
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 4b150ed..67b30cb 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -190,6 +190,11 @@ Bool xwl_screen_init_glamor(struct xwl_screen *xwl_screen,
                          uint32_t id, uint32_t version);
 struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap);
 
+#ifdef XV
+/* glamor Xv Adaptor */
+Bool xwl_glamor_xv_init(ScreenPtr pScreen);
+#endif
+
 #ifdef XF86VIDMODE
 void xwlVidModeExtensionInit(void);
 #endif
commit 1aa9a2be313c51a78af9bceea865dcf069e9cebe
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Mon Dec 21 17:54:08 2015 +0900

    modesetting: Allow CRTC transforms to actually take effect
    
    Setting crtc->transformPresent to FALSE was preventing the transform
    from actually taking effect and putting RandR into a confused state.
    
    Now that the RandR 1.2 cursor code handles transforms correctly, we can
    allow them to properly take effect.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 24042b4e367803dd64f3fcdc1bef7b2bf36c4145)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 4421578..bb5f56e 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -373,7 +373,6 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
         crtc->x = x;
         crtc->y = y;
         crtc->rotation = rotation;
-        crtc->transformPresent = FALSE;
     }
 
     output_ids = calloc(sizeof(uint32_t), xf86_config->num_output);
commit aa8770bf546a58e534ad2d0e0180f7e1013e24e9
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Oct 21 18:33:46 2015 +0900

    xfree86: Re-set current cursor after RandR 1.2 CRTC configuration change
    
    Add xf86CursorResetCursor, which allows switching between HW and SW
    cursor depending on the current state.
    
    Call it from xf86DisableUnusedFunctions, which is called after any CRTC
    configuration change such as setting a mode or disabling a CRTC. This
    makes sure that SW cursor is used e.g. while a transform is in use on
    any CRTC or while there are active PRIME output slaves, and enables HW
    cursor again once none of those conditions are true anymore.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit b04767c84deafc44993723add4b1c5163fc11711)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 38bc58c..2639a30 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -3121,6 +3121,12 @@ xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
         xf86_crtc_notify(pScrn->pScreen);
     if (pScrn->ModeSet)
         pScrn->ModeSet(pScrn);
+    if (pScrn->pScreen) {
+        if (pScrn->pScreen->isGPU)
+            xf86CursorResetCursor(pScrn->pScreen->current_master);
+        else
+            xf86CursorResetCursor(pScrn->pScreen);
+    }
 }
 
 #ifdef RANDR_12_INTERFACE
diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index 2a54571..c061b80 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -385,6 +385,30 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
     (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCurs, x, y);
 }
 
+/* Re-set the current cursor. This will switch between hardware and software
+ * cursor depending on whether hardware cursor is currently supported
+ * according to the driver.
+ */
+void
+xf86CursorResetCursor(ScreenPtr pScreen)
+{
+    xf86CursorScreenPtr ScreenPriv;
+
+    if (!inputInfo.pointer)
+        return;
+
+    if (!dixPrivateKeyRegistered(xf86CursorScreenKey))
+        return;
+
+    ScreenPriv = (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
+                                                        xf86CursorScreenKey);
+    if (!ScreenPriv)
+        return;
+
+    xf86CursorSetCursor(inputInfo.pointer, pScreen, ScreenPriv->CurrentCursor,
+                        ScreenPriv->x, ScreenPriv->y);
+}
+
 static void
 xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
 {
diff --git a/hw/xfree86/ramdac/xf86Cursor.h b/hw/xfree86/ramdac/xf86Cursor.h
index 8c98bb1..6e88240 100644
--- a/hw/xfree86/ramdac/xf86Cursor.h
+++ b/hw/xfree86/ramdac/xf86Cursor.h
@@ -59,6 +59,7 @@ extern _X_EXPORT Bool xf86InitCursor(ScreenPtr pScreen,
                                      xf86CursorInfoPtr infoPtr);
 extern _X_EXPORT xf86CursorInfoPtr xf86CreateCursorInfoRec(void);
 extern _X_EXPORT void xf86DestroyCursorInfoRec(xf86CursorInfoPtr);
+extern _X_EXPORT void xf86CursorResetCursor(ScreenPtr pScreen);
 extern _X_EXPORT void xf86ForceHWCursor(ScreenPtr pScreen, Bool on);
 
 #define HARDWARE_CURSOR_INVERT_MASK 			0x00000001
commit 870d4e2e6b40f911049a5286d605814d2401741d
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Dec 24 12:56:03 2015 +0900

    xfree86/modes: Check for CRTC transforms in xf86_use_hw_cursor(_argb) (v2)
    
    We currently don't handle transforms for the HW cursor image, so return
    FALSE to signal a software cursor must be used if a transform is in use
    on any CRTC.
    
    v2: Check crtc->transformPresent instead of crtc->transform_in_use. The
        latter is TRUE for rotation as well, which we handle correctly.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit a4ffa8721debb34bd36fd4624890d9c26886c618)

diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
index d3baf0d..5df1ab7 100644
--- a/hw/xfree86/modes/xf86Cursors.c
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -515,6 +515,7 @@ xf86_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
     xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+    int c;
 
     cursor = RefCursor(cursor);
     if (xf86_config->cursor)
@@ -525,6 +526,16 @@ xf86_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
         cursor->bits->height > cursor_info->MaxHeight)
         return FALSE;
 
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+        xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+        if (!crtc->enabled)
+            continue;
+
+        if (crtc->transformPresent)
+            return FALSE;
+    }
+
     return TRUE;
 }
 
commit af87ab62878334ee9d4e75c472fc80178329b4dd
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Dec 24 16:20:49 2015 +0900

    xfree86/modes: Refactor xf86_use_hw_cursor_argb to use xf86_use_hw_cursor (v2)
    
    This reduces code duplication.
    
    v2: No functional change this time.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit c3e4e9fc5d84bfc17b3ed63f67488ea25ba150ce)

diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
index 321cde7..d3baf0d 100644
--- a/hw/xfree86/modes/xf86Cursors.c
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -535,19 +535,13 @@ xf86_use_hw_cursor_argb(ScreenPtr screen, CursorPtr cursor)
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
     xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
 
-    cursor = RefCursor(cursor);
-    if (xf86_config->cursor)
-        FreeCursor(xf86_config->cursor, None);
-    xf86_config->cursor = cursor;
+    if (!xf86_use_hw_cursor(screen, cursor))
+        return FALSE;
 
     /* Make sure ARGB support is available */
     if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0)
         return FALSE;
 
-    if (cursor->bits->width > cursor_info->MaxWidth ||
-        cursor->bits->height > cursor_info->MaxHeight)
-        return FALSE;
-
     return TRUE;
 }
 
commit 87c23dc47160d7524b82b60abbc70d285708f7cb
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Feb 23 17:19:03 2016 +0900

    glamor: Source pictures are always depth 32
    
    We were using the destination pixmap depth to determine the source
    picture format.
    
    Fixes incorrect text rendering with some MATE desktop GTK3 themes.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94246
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    (cherry picked from commit a3e681eafa5355b8bb3b099d47983f14f0d5e197)

diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index ddab16f..0a94de6 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -508,9 +508,9 @@ 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);
+    glamor_set_color_depth(dst->pDrawable->pScreen, 32,
+                           src->pSourcePict->solidFill.color,
+                           prog->fg_uniform);
     return TRUE;
 }
 
commit 0220275531552a5400c22b56105257586f390260
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Feb 23 17:19:02 2016 +0900

    glamor: Factor out glamor_set_color_depth from glamor_set_color
    
    The former takes explicit screen and depth parameters instead of
    deriving them from a pixmap.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    (cherry picked from commit b05ae79ee3bebef9790c97eedc033d1ffb3ec39a)

diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index 17b1066..fc96fd6 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -104,20 +104,20 @@ glamor_set_destination_drawable(DrawablePtr     drawable,
  */
 
 void
-glamor_set_color(PixmapPtr      pixmap,
-                 CARD32         pixel,
-                 GLint          uniform)
+glamor_set_color_depth(ScreenPtr      pScreen,
+                       int            depth,
+                       CARD32         pixel,
+                       GLint          uniform)
 {
-    glamor_screen_private *glamor_priv =
-        glamor_get_screen_private((pixmap)->drawable.pScreen);
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
     float       color[4];
 
     glamor_get_rgba_from_pixel(pixel,
                                &color[0], &color[1], &color[2], &color[3],
-                               format_for_pixmap(pixmap));
+                               format_for_depth(depth));
 
-    if ((pixmap->drawable.depth == 1 || pixmap->drawable.depth == 8) &&
-	glamor_priv->one_channel_format == GL_RED)
+    if ((depth == 1 || depth == 8) &&
+        glamor_priv->one_channel_format == GL_RED)
       color[0] = color[3];
 
     glUniform4fv(uniform, 1, color);
diff --git a/glamor/glamor_transform.h b/glamor/glamor_transform.h
index ab7b2bc..5a520eb 100644
--- a/glamor/glamor_transform.h
+++ b/glamor/glamor_transform.h
@@ -33,9 +33,19 @@ glamor_set_destination_drawable(DrawablePtr     drawable,
                                 int             *p_off_y);
 
 void
+glamor_set_color_depth(ScreenPtr      pScreen,
+                       int            depth,
+                       CARD32         pixel,
+                       GLint          uniform);
+
+static inline void
 glamor_set_color(PixmapPtr      pixmap,
                  CARD32         pixel,
-                 GLint          uniform);
+                 GLint          uniform)
+{
+    glamor_set_color_depth(pixmap->drawable.pScreen,
+                           pixmap->drawable.depth, pixel, uniform);
+}
 
 Bool
 glamor_set_texture_pixmap(PixmapPtr    texture);
commit 79985270f1d63a8b186640b81d0eb142ac532e6e
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Wed Feb 10 16:40:43 2016 +0100

    glamor: Fix XvPutImage when src_y != 0
    
    We already take src_y into account when uploading the src data by
    starting at the top line of the src data when uploading.
    
    Adjust src_y accordingly when rendering.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    (cherry picked from commit 947e94a341fa153258e9e86060b83af95934672b)

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 9ac60af..3bcf909 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -495,7 +495,7 @@ glamor_xv_put_image(glamor_port_private *port_priv,
     RegionCopy(&port_priv->clip, clipBoxes);
 
     port_priv->src_x = src_x;
-    port_priv->src_y = src_y;
+    port_priv->src_y = src_y - top;
     port_priv->src_w = src_w;
     port_priv->src_h = src_h;
     port_priv->dst_w = drw_w;
commit ddca8e1647d3b79f803f4080be648e5475055fe8
Author: Rui Matos <tiagomatos at gmail.com>
Date:   Fri Mar 4 16:24:48 2016 +0100

    build: Enable vidmode independently from Xorg
    
    This allows building Xwayland without Xorg and still include the
    vidmode extension.
    
    v2: Use PKG_CHECK_EXISTS instead of PKG_CHECK_MODULES
    
    Signed-off-by: Rui Matos <tiagomatos at gmail.com>
    Reviewed-by: Emil Velikov <emil.l.velikov at gmail.com>
    (cherry picked from commit 40a164b8f4e720b0d6ebf228ee175eb397ffeec2)

diff --git a/configure.ac b/configure.ac
index 9a2d321..750fc58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1510,6 +1510,14 @@ if test "x$XDMAUTH" = xyes; then
 	fi
 fi
 
+if test "x$XF86VIDMODE" = xauto; then
+	PKG_CHECK_EXISTS($VIDMODEPROTO, [XF86VIDMODE=yes], [XF86VIDMODE=no])
+fi
+if test "x$XF86VIDMODE" = xyes; then
+	AC_DEFINE(XF86VIDMODE, 1, [Support XFree86 Video Mode extension])
+fi
+AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
+
 AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path])
 AC_DEFINE_DIR(SERVER_MISC_CONFIG_PATH, SERVERCONFIG, [Server miscellaneous config path])
 AC_DEFINE_DIR(BASE_FONT_PATH, FONTROOTDIR, [Default base font path])
@@ -2019,13 +2027,8 @@ if test "x$XORG" = xyes; then
 		AC_DEFINE(XFreeXDGA, 1, [Build XDGA support])
 	fi
 
-	if test "x$XF86VIDMODE" = xauto; then
-		PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO, [XF86VIDMODE=yes], [XF86VIDMODE=no])
-	fi
 	if test "x$XF86VIDMODE" = xyes; then
 		XORG_MODULES="$XORG_MODULES $VIDMODEPROTO"
-		PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO)
-		AC_DEFINE(XF86VIDMODE, 1, [Support XFree86 Video Mode extension])
 	fi
 
 	if test -n "$XORG_MODULES"; then
@@ -2107,7 +2110,6 @@ AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes])
 AM_CONDITIONAL([LNXAPM], [test "x$linux_apm" = xyes])
 AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes])
 AM_CONDITIONAL([DGA], [test "x$DGA" = xyes])
-AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
 AM_CONDITIONAL([XORG_BUS_PLATFORM], [test "x$CONFIG_UDEV_KMS" = xyes])
 AM_CONDITIONAL([XORG_DRIVER_MODESETTING], [test "x$XORG_DRIVER_MODESETTING" = xyes])
 
@@ -2453,7 +2455,11 @@ AM_CONDITIONAL(XFAKESERVER, [test "x$KDRIVE" = xyes && test "x$XFAKE" = xyes])
 
 dnl Xwayland DDX
 
-PKG_CHECK_MODULES(XWAYLANDMODULES, [wayland-client >= 1.3.0 libdrm epoxy], [have_xwayland=yes], [have_xwayland=no])
+XWAYLANDMODULES="wayland-client >= 1.3.0 libdrm epoxy"
+if test "x$XF86VIDMODE" = xyes; then
+	XWAYLANDMODULES="$XWAYLANDMODULES $VIDMODEPROTO"
+fi
+PKG_CHECK_MODULES(XWAYLANDMODULES, [$XWAYLANDMODULES], [have_xwayland=yes], [have_xwayland=no])
 AC_MSG_CHECKING([whether to build Xwayland DDX])
 if test "x$XWAYLAND" = xauto; then
    XWAYLAND="$have_xwayland"
commit 7680f558e1584a191554658ff7b3b75c75d35e06
Author: Julien Cristau <jcristau at debian.org>
Date:   Mon Mar 7 23:20:34 2016 +0100

    xfixes: avoid double free if AddResource fails
    
    pChc is already freed through CursorFreeHideCount →
    deleteCursorHideCount.
    
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit 2be527b1d4ce2b0412c4484539a8c9607645ec6d)

diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index 5619aad..10f9b23 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -774,10 +774,8 @@ createCursorHideCount(ClientPtr pClient, ScreenPtr pScreen)
      * Create a resource for this element so it can be deleted
      * when the client goes away.
      */
-    if (!AddResource(pChc->resource, CursorHideCountType, (void *) pChc)) {
-        free(pChc);
+    if (!AddResource(pChc->resource, CursorHideCountType, (void *) pChc))
         return BadAlloc;
-    }
 
     return Success;
 }
commit b7e1f25005f7b552870fe782fc927c9dc97f5ed0
Author: Julien Cristau <jcristau at debian.org>
Date:   Mon Mar 7 23:20:33 2016 +0100

    render: free already allocated formats in PictureInit failure case
    
    Probably pointless, if this fails you're not likely to get far...
    
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit 4217db89ecd480fda2ee74fecba06c6713c2a0f0)

diff --git a/render/picture.c b/render/picture.c
index 6d9c9df..9e4036e 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -665,6 +665,9 @@ PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
     for (n = 0; n < nformats; n++) {
         if (!AddResource
             (formats[n].id, PictFormatType, (void *) (formats + n))) {
+            int i;
+            for (i = 0; i < n; i++)
+                FreeResource(formats[i].id, RT_NONE);
             free(formats);
             return FALSE;
         }
commit 518a0c179f99e9ea33e9cd56ce215661d27cabb6
Author: Julien Cristau <jcristau at debian.org>
Date:   Mon Mar 7 23:20:32 2016 +0100

    record: don't call RecordDeleteContext when AddResource fails
    
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit 054f80717812d4781741cd05393623fe6f6c627f)

diff --git a/record/record.c b/record/record.c
index 1caf3f1..82bb060 100644
--- a/record/record.c
+++ b/record/record.c
@@ -1878,7 +1878,6 @@ ProcRecordCreateContext(ClientPtr client)
         return Success;
     }
     else {
-        RecordDeleteContext((void *) pContext, pContext->id);
         return BadAlloc;
     }
  bailout:
commit dae9c195a9db4d210855a16efce2037f3af454e1
Author: Julien Cristau <jcristau at debian.org>
Date:   Mon Mar 7 23:20:31 2016 +0100

    xwin: no need to free auth data if AddResource fails
    
    This is taken care of by SecurityDeleteAuthorization
    
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit d0c1a5bc61a3d151f2234aa3820862f16c0f00c7)

diff --git a/hw/xwin/winauth.c b/hw/xwin/winauth.c
index 7efa1c0..7be7dca 100644
--- a/hw/xwin/winauth.c
+++ b/hw/xwin/winauth.c
@@ -114,7 +114,6 @@ GenerateAuthorization(unsigned name_length,
 Bool
 winGenerateAuthorization(void)
 {
-    Bool fFreeAuth = FALSE;
     SecurityAuthorizationPtr pAuth = NULL;
 
     /* Call OS layer to generate authorization key */
@@ -123,7 +122,7 @@ winGenerateAuthorization(void)
                                      0, NULL, &g_uiAuthDataLen, &g_pAuthData);
     if ((XID) ~0L == g_authId) {
         ErrorF("winGenerateAuthorization - GenerateAuthorization failed\n");
-        goto auth_bailout;
+        return FALSE;
     }
 
     else {
@@ -139,7 +138,7 @@ winGenerateAuthorization(void)
     if (!(pAuth)) {
         ErrorF("winGenerateAuthorization - Failed allocating "
                "SecurityAuthorizationPtr.\n");
-        goto auth_bailout;
+        return FALSE;
     }
 
     /* Fill in the auth fields */
@@ -155,21 +154,11 @@ winGenerateAuthorization(void)
     /* Add the authorization to the server's auth list */
     if (!AddResource(g_authId, SecurityAuthorizationResType, pAuth)) {
         ErrorF("winGenerateAuthorization - AddResource failed for auth.\n");
-        fFreeAuth = TRUE;
-        goto auth_bailout;
+        return FALSE;
     }
-
-    /* Don't free the auth data, since it is still used internally */
-    pAuth = NULL;
 #endif
 
     return TRUE;
-
- auth_bailout:
-    if (fFreeAuth)
-        free(pAuth);
-
-    return FALSE;
 }
 
 /* Use our generated cookie for authentication */
commit 4bbaffc8134a72d4e2dd21d4def1afc9ad29e815
Author: Julien Cristau <jcristau at debian.org>
Date:   Mon Mar 7 23:20:30 2016 +0100

    modesetting: avoid double free if AddResource fails
    
    ms_dri2_frame_event_client_gone or ms_dri2_frame_event_drawable_gone
    already free the resource.
    
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit acf263df81ad6813e0233033610fb44521cab1b4)

diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c
index 0fe420c..83cb3e0 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -97,10 +97,8 @@ ms_get_resource(XID id, RESTYPE type)
     if (resource == NULL)
         return NULL;
 
-    if (!AddResource(id, type, resource)) {
-        free(resource);
+    if (!AddResource(id, type, resource))
         return NULL;
-    }
 
     resource->id = id;
     resource->type = type;
commit 8616bd95de43aa63c959b0c978f1001ac38c0222
Author: Julien Cristau <jcristau at debian.org>
Date:   Mon Mar 7 23:20:29 2016 +0100

    dmx/glxProxy: don't free the glx pixmap twice if AddResource fails
    
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit 164753f158e78f615f903467bfd234d7c58244ef)

diff --git a/hw/dmx/glxProxy/glxcmds.c b/hw/dmx/glxProxy/glxcmds.c
index ddcb981..a77d556 100644
--- a/hw/dmx/glxProxy/glxcmds.c
+++ b/hw/dmx/glxProxy/glxcmds.c
@@ -2010,11 +2010,8 @@ CreateGLXPixmap(__GLXclientState * cl,
         XFlush(dpy);
     }
 
-    if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) {
-        free(pGlxPixmap->be_xids);
-        free(pGlxPixmap);
+    if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap)))
         return BadAlloc;
-    }
 
     return Success;
 }
commit dcbf88aea74a00a8e09ffdc4de2b555911eb90fb
Author: Julien Cristau <jcristau at debian.org>
Date:   Mon Mar 7 23:20:28 2016 +0100

    glx: don't call pGlxDraw->destroy() if AddResource fails
    
    AddResource will have called DrawableGone, which takes care of the
    destruction.
    
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit 59b9c3d5e4bf05aeaaac2ee4ea12c301a67aae2c)

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 0416dac..6eb3541 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -544,7 +544,6 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
 
     /* since we are creating the drawablePrivate, drawId should be new */
     if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
-        pGlxDraw->destroy(pGlxDraw);
         *error = BadAlloc;
         return NULL;
     }
@@ -1239,20 +1238,16 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen * pGlxScreen,
     if (pGlxDraw == NULL)
         return BadAlloc;
 
-    if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) {
-        pGlxDraw->destroy(pGlxDraw);
+    if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw))
         return BadAlloc;
-    }
 
     /*
      * Windows aren't refcounted, so track both the X and the GLX window
      * so we get called regardless of destruction order.
      */
     if (drawableId != glxDrawableId && type == GLX_DRAWABLE_WINDOW &&
-        !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
-        pGlxDraw->destroy(pGlxDraw);
+        !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw))
         return BadAlloc;
-    }
 
     return Success;
 }
commit ab197ee9478a0e4e7a276c03645657b4f22ae9c0
Author: Julien Cristau <jcristau at debian.org>
Date:   Mon Mar 7 23:20:26 2016 +0100

    xvmc: Fix unchecked AddResource
    
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit 119d5c0e2f800737c949ef760c5fe25d963200bf)

diff --git a/Xext/xvmc.c b/Xext/xvmc.c
index 64eda92..7565c17 100644
--- a/Xext/xvmc.c
+++ b/Xext/xvmc.c
@@ -253,6 +253,10 @@ ProcXvMCCreateContext(ClientPtr client)
         free(pContext);
         return result;
     }
+    if (!AddResource(pContext->context_id, XvMCRTContext, pContext)) {
+        free(data);
+        return BadAlloc;
+    }
 
     rep = (xvmcCreateContextReply) {
         .type = X_Reply,
@@ -266,7 +270,6 @@ ProcXvMCCreateContext(ClientPtr client)
     WriteToClient(client, sizeof(xvmcCreateContextReply), &rep);
     if (dwords)
         WriteToClient(client, dwords << 2, data);
-    AddResource(pContext->context_id, XvMCRTContext, pContext);
 
     free(data);
 
@@ -329,6 +332,11 @@ ProcXvMCCreateSurface(ClientPtr client)
         free(pSurface);
         return result;
     }
+    if (!AddResource(pSurface->surface_id, XvMCRTSurface, pSurface)) {
+        free(data);
+        return BadAlloc;
+    }
+
     rep = (xvmcCreateSurfaceReply) {
         .type = X_Reply,
         .sequenceNumber = client->sequence,
@@ -338,7 +346,6 @@ ProcXvMCCreateSurface(ClientPtr client)
     WriteToClient(client, sizeof(xvmcCreateSurfaceReply), &rep);
     if (dwords)
         WriteToClient(client, dwords << 2, data);
-    AddResource(pSurface->surface_id, XvMCRTSurface, pSurface);
 
     free(data);
 
@@ -445,6 +452,11 @@ ProcXvMCCreateSubpicture(ClientPtr client)
         free(pSubpicture);
         return result;
     }
+    if (!AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture)) {
+        free(data);
+        return BadAlloc;
+    }
+
     rep = (xvmcCreateSubpictureReply) {
         .type = X_Reply,
         .sequenceNumber = client->sequence,
@@ -462,7 +474,6 @@ ProcXvMCCreateSubpicture(ClientPtr client)
     WriteToClient(client, sizeof(xvmcCreateSubpictureReply), &rep);
     if (dwords)
         WriteToClient(client, dwords << 2, data);
-    AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture);
 
     free(data);
 
commit bd022f03143723ac326b39d6e67853650aa1bf1d
Author: Jonas Ådahl <jadahl at gmail.com>
Date:   Tue Mar 8 20:05:33 2016 +0800

    xwayland: Correctly detect whether posix_fallocate exists
    
    We had HAVE_POSIX_FALLOCATE checks, but no such macros were ever
    defined anywhere. This commit makes it so that this macro is defined if
    the posix_fallocate is detected during configure.
    
    Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit a2c3c34b44b866440a152511e682c98879ee13b7)

diff --git a/configure.ac b/configure.ac
index 4808ef4..9a2d321 100644
--- a/configure.ac
+++ b/configure.ac
@@ -218,7 +218,8 @@ AC_SUBST(DLOPEN_LIBS)
 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])
+	mmap posix_fallocate seteuid shmctl64 strncasecmp vasprintf vsnprintf \
+	walkcontext])
 AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup])
 
 AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]])
diff --git a/hw/xwayland/xwayland-shm.c b/hw/xwayland/xwayland-shm.c
index 1beade9..e8545b3 100644
--- a/hw/xwayland/xwayland-shm.c
+++ b/hw/xwayland/xwayland-shm.c
@@ -24,6 +24,10 @@
  * SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include <dix-config.h>
+#endif
+
 #include "xwayland.h"
 
 #include <sys/mman.h>
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 112ab95..a2f7184 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -518,4 +518,7 @@
 /* Define if no local socket credentials interface exists */
 #undef NO_LOCAL_CLIENT_CRED
 
+/* Have posix_fallocate() */
+#undef HAVE_POSIX_FALLOCATE
+
 #endif /* _DIX_CONFIG_H_ */
commit 23d9b2a566cdaeff71deae9c3a221ebf0cb5f550
Author: Julien Cristau <jcristau at debian.org>
Date:   Tue Mar 1 21:39:01 2016 +0100

    xv: fix double free in AddResource failure case
    
    XvdiDestroyVideoNotifyList already frees the list if AddResource fails,
    so don't do it twice.  And set tpn->client to NULL explicitly to avoid
    confusing uninitialized memory with a valid value.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit 939ce0bae68b682b57675f65c901653c1a094ebb)

diff --git a/Xext/xvmain.c b/Xext/xvmain.c
index 3a02634..c9b11d4 100644
--- a/Xext/xvmain.c
+++ b/Xext/xvmain.c
@@ -800,10 +800,9 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff)
         if (!(tpn = malloc(sizeof(XvVideoNotifyRec))))
             return BadAlloc;
         tpn->next = NULL;
-        if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn)) {
-            free(tpn);
+        tpn->client = NULL;
+        if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn))
             return BadAlloc;
-        }
     }
     else {
         /* LOOK TO SEE IF ENTRY ALREADY EXISTS */
commit 90b854b2acc58a9936e9810f58b0bd1973697210
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Mar 1 14:09:30 2016 -0500

    dri1: Fix unchecked AddResource
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit 05e1bcf56e1c511a1ef539acfe11e37727e1179e)

diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 875c9cc..0046e52 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -1032,7 +1032,8 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
     }
 
     /* track this in case the client dies before cleanup */
-    AddResource(context, DRIContextPrivResType, (void *) pDRIContextPriv);
+    if (!AddResource(context, DRIContextPrivResType, (void *) pDRIContextPriv))
+        return FALSE;
 
     return TRUE;
 }
@@ -1263,8 +1264,9 @@ DRICreateDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable,
         }
 
         /* track this in case the client dies */
-        AddResource(FakeClientID(client->index), DRIDrawablePrivResType,
-                    (void *) (intptr_t) pDrawable->id);
+        if (!AddResource(FakeClientID(client->index), DRIDrawablePrivResType,
+                         (void *) (intptr_t) pDrawable->id))
+            return FALSE;
 
         if (pDRIDrawablePriv->hwDrawable) {
             drmUpdateDrawableInfo(pDRIPriv->drmFD,
commit 0e3cc3d042a2da1ed781f6691dd7aca72d87046b
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Mar 1 14:09:29 2016 -0500

    xv: Fix unchecked AddResource
    
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit 093f9505c12565cc19bdf6e33b263f31d104c3ef)

diff --git a/Xext/xvmain.c b/Xext/xvmain.c
index 0c6f25b..3a02634 100644
--- a/Xext/xvmain.c
+++ b/Xext/xvmain.c
@@ -844,7 +844,8 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff)
 
     tpn->client = NULL;
     tpn->id = FakeClientID(client->index);
-    AddResource(tpn->id, XvRTVideoNotify, tpn);
+    if (!AddResource(tpn->id, XvRTVideoNotify, tpn))
+        return BadAlloc;
 
     tpn->client = client;
     return Success;
@@ -893,7 +894,8 @@ XvdiSelectPortNotify(ClientPtr client, XvPortPtr pPort, BOOL onoff)
 
     tpn->client = client;
     tpn->id = FakeClientID(client->index);
-    AddResource(tpn->id, XvRTPortNotify, tpn);
+    if (!AddResource(tpn->id, XvRTPortNotify, tpn))
+        return BadAlloc;
 
     return Success;
 
commit 3d7bfe02cc3ad0f16403a073f1182d7019c98be3
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Mar 1 17:03:44 2016 +0100

    vidmode: build without xf86vidmodeproto
    
    git commit f175cf45:
    
      vidmode: move to a separate library of its own
    
    introduced a regression where the xserver would not build when
    xf86vidmodeproto is not installed even if the configure option
    "--disable-xf86vidmode" is specified.
    
    Fix build failure when xf86vidmodeproto is not installed.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit ac4d8c7cee13947b688ebb26035f06f7744db201)

diff --git a/Xext/vidmode.c b/Xext/vidmode.c
index 7ea5ddf..7c838f4 100644
--- a/Xext/vidmode.c
+++ b/Xext/vidmode.c
@@ -33,6 +33,8 @@ from Kaleb S. KEITHLEY
 #include <dix-config.h>
 #endif
 
+#ifdef XF86VIDMODE
+
 #include <X11/X.h>
 #include <X11/Xproto.h>
 #include <X11/extensions/xf86vmproto.h>
@@ -2145,3 +2147,5 @@ VidModePtr VidModeInit(ScreenPtr pScreen)
 
     return VidModeGetPtr(pScreen);
 }
+
+#endif /* XF86VIDMODE */
diff --git a/include/vidmodestr.h b/include/vidmodestr.h
index 3a44185..b47daa7 100644
--- a/include/vidmodestr.h
+++ b/include/vidmodestr.h
@@ -133,8 +133,10 @@ typedef struct {
     VidModeGetGammaRampSizeProcPtr    GetGammaRampSize;
 } VidModeRec, *VidModePtr;
 
+#ifdef XF86VIDMODE
 void VidModeAddExtension(Bool allow_non_local);
 VidModePtr VidModeGetPtr(ScreenPtr pScreen);
 VidModePtr VidModeInit(ScreenPtr pScreen);
+#endif /* XF86VIDMODE */
 
 #endif
commit a49e7b9c2ebeb2e2ccb922265798234a8ce9d242
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Mon Feb 8 17:48:26 2016 +0100

    xwayland: fix a crash on output removal
    
    On output removal, the CRTC that was added in xwl_output_create()
    is not removed in xwl_output_destroy() and would cause a segmentation
    fault later on in ProcRRGetMonitors():
    
      (EE) Segmentation fault at address 0x100000001
      (EE)
      (EE) 10: ? (?+0x29) [0x29]
      (EE) 9: /usr/bin/Xwayland (_start+0x29) [0x423299]
      (EE) 8: /lib64/libc.so.6 (__libc_start_main+0xf0) [0x7fdd80e7f580]
      (EE) 7: /usr/bin/Xwayland (dix_main+0x3b3) [0x544ef3]
      (EE) 6: /usr/bin/Xwayland (Dispatch+0x31e) [0x54109e]
      (EE) 5: /usr/bin/Xwayland (ProcRRGetMonitors+0x9b) [0x4ca18b]
      (EE) 4: /usr/bin/Xwayland (RRMonitorMakeList+0x269) [0x4c9ba9]
      (EE) 3: /usr/bin/Xwayland (RRMonitorSetFromServer+0x118) [0x4c9198]
      (EE) 2: /usr/bin/Xwayland (MakeAtom+0x30) [0x530710]
      (EE) 1: /lib64/libc.so.6 (__restore_rt+0x0) [0x7fdd80e93b1f]
      (EE) 0: /usr/bin/Xwayland (OsSigHandler+0x29) [0x5792d9]
    
    Remove the output CRTC in xwl_output_destroy() to avoid the crash.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Daniel Stone <daniels at collabora.com>
    (cherry picked from commit 2116f03be04240e961649ca750a7aa5438b8446c)

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 5263cb3..4903062 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -297,6 +297,7 @@ xwl_output_destroy(struct xwl_output *xwl_output)
 
     wl_output_destroy(xwl_output->output);
     xorg_list_del(&xwl_output->link);
+    RRCrtcDestroy(xwl_output->randr_crtc);
     RROutputDestroy(xwl_output->randr_output);
 
     xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
commit c7735f102aa9daa604f304f2e8a2131fcdd652e8
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Feb 18 17:33:19 2016 +0900

    present: Call present_restore_screen_pixmap from present_set_abort_flip
    
    After present_set_abort_flip, the screen pixmap will be used for all
    screen drawing, so we need to restore the current flip pixmap contents
    to the screen pixmap here as well.
    
    Improves flashing / stutter e.g. when something like a popup menu appears
    on top of a flipping fullscreen window or when switching out of
    fullscreen.
    
    Note that this means present_set_abort_flip now relies on screen->root
    being non-NULL, but that's already the case in other present code.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    (cherry picked from commit 1bee4e254ca0305cb23e574b4c8b250d276ee998)

diff --git a/present/present.c b/present/present.c
index ffb7a4a..1ce16af 100644
--- a/present/present.c
+++ b/present/present.c
@@ -418,8 +418,16 @@ present_restore_screen_pixmap(ScreenPtr screen)
 {
     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
     PixmapPtr screen_pixmap = (*screen->GetScreenPixmap)(screen);
-    PixmapPtr flip_pixmap = screen_priv->flip_pixmap;
-    WindowPtr flip_window = screen_priv->flip_window;
+    PixmapPtr flip_pixmap;
+    WindowPtr flip_window;
+
+    if (screen_priv->flip_pending) {
+        flip_window = screen_priv->flip_pending->window;
+        flip_pixmap = screen_priv->flip_pending->pixmap;
+    } else {
+        flip_window = screen_priv->flip_window;
+        flip_pixmap = screen_priv->flip_pixmap;
+    }
 
     assert (flip_pixmap);
 
@@ -430,6 +438,9 @@ present_restore_screen_pixmap(ScreenPtr screen)
     if (screen->GetWindowPixmap(screen->root) == flip_pixmap)
         present_copy_region(&screen_pixmap->drawable, flip_pixmap, NULL, 0, 0);
 
+    /* Switch back to using the screen pixmap now to avoid
+     * 2D applications drawing to the wrong pixmap.
+     */
     if (flip_window)
         present_set_tree_pixmap(flip_window, flip_pixmap, screen_pixmap);
     present_set_tree_pixmap(screen->root, NULL, screen_pixmap);
@@ -439,19 +450,8 @@ static void
 present_set_abort_flip(ScreenPtr screen)
 {
     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-    PixmapPtr pixmap = (*screen->GetScreenPixmap)(screen);
 
-    /* Switch back to using the screen pixmap now to avoid
-     * 2D applications drawing to the wrong pixmap.
-     */
-
-    if (screen_priv->flip_window)
-        present_set_tree_pixmap(screen_priv->flip_window,
-                                screen_priv->flip_pixmap,
-                                pixmap);
-
-    if (screen->root)
-        present_set_tree_pixmap(screen->root, NULL, pixmap);
+    present_restore_screen_pixmap(screen);
 
     screen_priv->flip_pending->abort_flip = TRUE;
 }
commit 05d9de4e9ac515176f41f9fd649935ae990d8fb3
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Feb 18 17:20:45 2016 +0900

    present: Factor code for restoring screen pixmap out of present_unflip (v2)
    
    The following fix will use the refactored function.
    
    The logic in the refactored function is slightly simplified, exploiting
    the fact that this function is only ever called with a valid flip
    pixmap.
    
    v2: Assert that flip_pixmap is non-NULL instead of testing and bailing
        on NULL, preserve test for flip_window being non-NULL before calling
        present_set_tree_pixmap for it (Keith Packard)
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk> (v1)
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 4611e902c291b8a789f374cff3300f74645bc2b2)

diff --git a/present/present.c b/present/present.c
index a9241d2..ffb7a4a 100644
--- a/present/present.c
+++ b/present/present.c
@@ -414,6 +414,28 @@ present_set_tree_pixmap(WindowPtr window,
 }
 
 static void
+present_restore_screen_pixmap(ScreenPtr screen)
+{
+    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
+    PixmapPtr screen_pixmap = (*screen->GetScreenPixmap)(screen);
+    PixmapPtr flip_pixmap = screen_priv->flip_pixmap;
+    WindowPtr flip_window = screen_priv->flip_window;
+
+    assert (flip_pixmap);
+
+    /* Update the screen pixmap with the current flip pixmap contents
+     * Only do this the first time for a particular unflip operation, or
+     * we'll probably scribble over other windows
+     */
+    if (screen->GetWindowPixmap(screen->root) == flip_pixmap)
+        present_copy_region(&screen_pixmap->drawable, flip_pixmap, NULL, 0, 0);
+
+    if (flip_window)
+        present_set_tree_pixmap(flip_window, flip_pixmap, screen_pixmap);
+    present_set_tree_pixmap(screen->root, NULL, screen_pixmap);
+}
+
+static void
 present_set_abort_flip(ScreenPtr screen)
 {
     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
@@ -438,26 +460,11 @@ 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);
 
-    /* Update the screen pixmap with the current flip pixmap contents
-     * Only do this the first time for a particular unflip operation, or
-     * we'll probably scribble over other windows
-     */
-    if (screen->GetWindowPixmap(screen->root) == screen_priv->flip_pixmap) {
-        present_copy_region(&pixmap->drawable, screen_priv->flip_pixmap,
-                            NULL, 0, 0);
-    }
-
-    if (screen_priv->flip_pixmap && screen_priv->flip_window)
-        present_set_tree_pixmap(screen_priv->flip_window,
-                                screen_priv->flip_pixmap,
-                                pixmap);
-
-    present_set_tree_pixmap(screen->root, NULL, pixmap);
+    present_restore_screen_pixmap(screen);
 
     screen_priv->unflip_event_id = ++present_event_id;
     DebugPresent(("u %lld\n", screen_priv->unflip_event_id));
commit 49b2a0fb0e6ae0793171b5dbfe517fe06647c06d
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Feb 18 18:23:47 2016 +0900

    present: Only update screen pixmap from flip pixmap once per unflip
    
    present_unflip may be called several times from present_check_flip_window
    during the same unflip. We can only copy to the screen pixmap the first
    time, otherwise we may scribble over other windows. The flip pixmap
    contents don't get updated after the first time anyway.
    
    Fixes at least the following problems, which were introduced by commit
    806470b9 ("present: Copy unflip contents back to the Screen Pixmap"):
    
    On xfwm4 without compositing, run glxgears and put its window into
    fullscreen mode to start flipping. While in fullscreen, open the xfwm4
    window menu by pressing Alt-Space. The window menu was invisible most
    of the time because it was getting scribbled over by a repeated unflip
    copy.
    
    When switching a flipping window out of fullscreen, a repeated unflip
    copy could leave artifacts of the flip pixmap on the desktop.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94325
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    (cherry picked from commit 72328e5eb98a3f27e1f0a0e17beae6db447bd87c)

diff --git a/present/present.c b/present/present.c
index 62865be..a9241d2 100644
--- a/present/present.c
+++ b/present/present.c
@@ -443,6 +443,15 @@ present_unflip(ScreenPtr screen)
     assert (!screen_priv->unflip_event_id);
     assert (!screen_priv->flip_pending);
 
+    /* Update the screen pixmap with the current flip pixmap contents
+     * Only do this the first time for a particular unflip operation, or
+     * we'll probably scribble over other windows
+     */
+    if (screen->GetWindowPixmap(screen->root) == screen_priv->flip_pixmap) {
+        present_copy_region(&pixmap->drawable, screen_priv->flip_pixmap,
+                            NULL, 0, 0);
+    }
+
     if (screen_priv->flip_pixmap && screen_priv->flip_window)
         present_set_tree_pixmap(screen_priv->flip_window,
                                 screen_priv->flip_pixmap,
@@ -450,13 +459,6 @@ present_unflip(ScreenPtr screen)
 
     present_set_tree_pixmap(screen->root, NULL, pixmap);
 
-    /* Update the screen pixmap with the current flip pixmap contents
-     */
-    if (screen_priv->flip_pixmap && screen_priv->flip_window) {
-        present_copy_region(&pixmap->drawable,
-                            screen_priv->flip_pixmap,
-                            NULL, 0, 0);
-    }
     screen_priv->unflip_event_id = ++present_event_id;
     DebugPresent(("u %lld\n", screen_priv->unflip_event_id));
     (*screen_priv->info->unflip) (screen, screen_priv->unflip_event_id);
commit d5b8bc69e2652d8b9b13065b6528d2e8b8188b57
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Dec 8 12:52:17 2015 +0900

    dri3: Refuse to work for remote clients (v2)
    
    Prevents clients forwarded via SSH from hanging while waiting for the
    reply from the DRI3Open request.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93261
    
    v2: Return BadMatch instead of BadRequest (Keith Packard)
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 43eb5b6047c9b35c337e553ec054f08bdc835abb)

diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c
index 2d75588..2b36221 100644
--- a/dri3/dri3_request.c
+++ b/dri3/dri3_request.c
@@ -312,6 +312,8 @@ int
 proc_dri3_dispatch(ClientPtr client)
 {
     REQUEST(xReq);
+    if (!client->local)
+        return BadMatch;
     if (stuff->data >= DRI3NumberRequests || !proc_dri3_vector[stuff->data])
         return BadRequest;
     return (*proc_dri3_vector[stuff->data]) (client);
@@ -405,6 +407,8 @@ int
 sproc_dri3_dispatch(ClientPtr client)
 {
     REQUEST(xReq);
+    if (!client->local)
+        return BadMatch;
     if (stuff->data >= DRI3NumberRequests || !sproc_dri3_vector[stuff->data])
         return BadRequest;
     return (*sproc_dri3_vector[stuff->data]) (client);
commit 15454c5d26b00931b2099ccc6da356a1e5b6f88c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Feb 10 09:35:39 2016 +0100

    xwayland: add partial xvidmode extension support
    
    Older games (mostly those based on SDL 1.x) rely on the XVidMode
    extension and would refuse to run without.
    
    Add a simple, limited and read-only xvidmode support that reports the
    current mode used so that games that rely on xvidmode extension can run
    on XWayland.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87806
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 6070a749d953951bacbfb149c5c36451293aad35)

diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am
index ab1bbb6..0905082 100644
--- a/hw/xwayland/Makefile.am
+++ b/hw/xwayland/Makefile.am
@@ -16,6 +16,7 @@ Xwayland_SOURCES =				\
 	xwayland-shm.c				\
 	xwayland-output.c			\
 	xwayland-cvt.c				\
+	xwayland-vidmode.c			\
 	xwayland.h				\
 	$(top_srcdir)/Xext/dpmsstubs.c		\
 	$(top_srcdir)/Xi/stubs.c		\
@@ -25,6 +26,7 @@ Xwayland_LDADD =				\
 	$(glamor_lib)				\
 	$(XWAYLAND_LIBS)			\
 	$(XWAYLAND_SYS_LIBS)			\
+	$(top_builddir)/Xext/libXvidmode.la	\
 	$(XSERVER_SYS_LIBS)
 Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
 
diff --git a/hw/xwayland/xwayland-vidmode.c b/hw/xwayland/xwayland-vidmode.c
new file mode 100644
index 0000000..6d70e39
--- /dev/null
+++ b/hw/xwayland/xwayland-vidmode.c
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 1999-2003 by The XFree86 Project, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(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 of the copyright holder(s)
+ * and author(s) 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 copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "os.h"
+#include "extinit.h"
+
+#ifdef XF86VIDMODE
+#include "xwayland.h"
+#include "randrstr.h"
+#include "vidmodestr.h"
+
+static DevPrivateKeyRec xwlVidModePrivateKeyRec;
+#define xwlVidModePrivateKey (&xwlVidModePrivateKeyRec)
+
+/* Taken from xrandr, h sync frequency in KHz */
+static double
+mode_hsync(const xRRModeInfo *mode_info)
+{
+    double rate;
+
+    if (mode_info->hTotal)
+        rate = (double) mode_info->dotClock / (double) mode_info->hTotal;
+    else
+        rate = 0.0;
+
+    return rate / 1000.0;
+}
+
+/* Taken from xrandr, v refresh frequency in Hz */
+static double
+mode_refresh(const xRRModeInfo *mode_info)
+{
+    double rate;
+    double vTotal = mode_info->vTotal;
+
+    if (mode_info->modeFlags & RR_DoubleScan)
+	vTotal *= 2.0;
+
+    if (mode_info->modeFlags & RR_Interlace)
+	vTotal /= 2.0;
+
+    if (mode_info->hTotal > 0.0 && vTotal > 0.0)
+	rate = ((double) mode_info->dotClock /
+		((double) mode_info->hTotal * (double) vTotal));
+    else
+        rate = 0.0;
+
+    return rate;
+}
+
+static Bool
+xwlVidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
+{
+    DisplayModePtr pMod;
+    RROutputPtr output;
+    RRCrtcPtr crtc;
+    xRRModeInfo rrmode;
+
+    pMod = dixLookupPrivate(&pScreen->devPrivates, xwlVidModePrivateKey);
+    if (pMod == NULL)
+        return FALSE;
+
+    output = RRFirstOutput(pScreen);
+    if (output == NULL)
+        return FALSE;
+
+    crtc = output->crtc;
+    if (crtc == NULL)
+        return FALSE;
+
+    rrmode = crtc->mode->mode;
+
+    pMod->next = pMod;
+    pMod->prev = pMod;
+    pMod->name = "";
+    pMod->VScan = 1;
+    pMod->Private = NULL;
+    pMod->HDisplay = rrmode.width;
+    pMod->HSyncStart = rrmode.hSyncStart;
+    pMod->HSyncEnd = rrmode.hSyncEnd;
+    pMod->HTotal = rrmode.hTotal;
+    pMod->HSkew = rrmode.hSkew;
+    pMod->VDisplay = rrmode.height;
+    pMod->VSyncStart = rrmode.vSyncStart;
+    pMod->VSyncEnd = rrmode.vSyncEnd;
+    pMod->VTotal = rrmode.vTotal;
+    pMod->Flags = rrmode.modeFlags;
+    pMod->Clock = rrmode.dotClock / 1000.0;
+    pMod->VRefresh = mode_refresh(&rrmode); /* Or RRVerticalRefresh() */
+    pMod->HSync = mode_hsync(&rrmode);
+    *mode = pMod;
+
+    if (dotClock != NULL)
+        *dotClock = rrmode.dotClock / 1000.0;
+
+    return TRUE;
+}
+
+static vidMonitorValue
+xwlVidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
+{
+    vidMonitorValue ret = { NULL, };
+    DisplayModePtr pMod;
+
+    if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL))
+        return ret;
+
+    switch (valtyp) {
+    case VIDMODE_MON_VENDOR:
+        ret.ptr = XVENDORNAME;
+        break;
+    case VIDMODE_MON_MODEL:
+        ret.ptr = "XWAYLAND";
+        break;
+    case VIDMODE_MON_NHSYNC:
+        ret.i = 1;
+        break;
+    case VIDMODE_MON_NVREFRESH:
+        ret.i = 1;
+        break;
+    case VIDMODE_MON_HSYNC_LO:
+    case VIDMODE_MON_HSYNC_HI:
+        ret.f = 100.0 * pMod->HSync;
+        break;
+    case VIDMODE_MON_VREFRESH_LO:
+    case VIDMODE_MON_VREFRESH_HI:
+        ret.f = 100.0 * pMod->VRefresh;
+        break;
+    }
+    return ret;
+}
+
+static int
+xwlVidModeGetDotClock(ScreenPtr pScreen, int Clock)
+{
+    DisplayModePtr pMod;
+
+    if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL))
+        return 0;
+
+    return pMod->Clock;
+
+}
+
+static int
+xwlVidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
+{
+    return 1;
+}
+
+static Bool
+xwlVidModeGetClocks(ScreenPtr pScreen, int *Clocks)
+{
+    *Clocks = xwlVidModeGetDotClock(pScreen, 0);
+
+    return TRUE;
+}
+
+static Bool
+xwlVidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
+{
+    return FALSE;
+}
+
+static Bool
+xwlVidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
+{
+    return xwlVidModeGetCurrentModeline(pScreen, mode, dotClock);
+}
+
+static Bool
+xwlVidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
+{
+    /* Unsupported */
+    return FALSE;
+}
+
+static Bool
+xwlVidModeZoomViewport(ScreenPtr pScreen, int zoom)
+{
+    /* Unsupported for now */
+    return FALSE;
+}
+
+static Bool
+xwlVidModeSetViewPort(ScreenPtr pScreen, int x, int y)
+{
+    /* Unsupported for now */
+    return FALSE;
+}
+
+static Bool
+xwlVidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
+{
+    RROutputPtr output;
+    RRCrtcPtr crtc;
+
+    output = RRFirstOutput(pScreen);
+    if (output == NULL)
+        return FALSE;
+
+    crtc = output->crtc;
+    if (crtc == NULL)
+        return FALSE;
+
+    *x = crtc->x;
+    *y = crtc->y;
+
+    return TRUE;
+}
+
+static Bool
+xwlVidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
+{
+    /* Unsupported for now */
+    return FALSE;
+}
+
+static Bool
+xwlVidModeLockZoom(ScreenPtr pScreen, Bool lock)
+{
+    /* Unsupported for now, but pretend it works */
+    return TRUE;
+}
+
+static ModeStatus
+xwlVidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
+{
+    DisplayModePtr pMod;
+
+    /* This should not happen */
+    if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL))
+        return MODE_ERROR;
+
+    /* Only support mode with the same HSync/VRefresh as we advertise */
+    if (mode->HSync == pMod->HSync && mode->VRefresh == pMod->VRefresh)
+        return MODE_OK;
+
+    /* All the rest is unsupported - If we want to succeed, return MODE_OK instead */
+    return MODE_ONE_SIZE;
+}
+
+static ModeStatus
+xwlVidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode)
+{
+    DisplayModePtr pMod;
+
+    /* This should not happen */
+    if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL))
+        return MODE_ERROR;
+
+    if (mode->HTotal != pMod->HTotal)
+        return MODE_BAD_HVALUE;
+
+    if (mode->VTotal != pMod->VTotal)
+        return MODE_BAD_VVALUE;
+
+    /* Unsupported for now, but pretend it works */
+    return MODE_OK;
+}
+
+static void
+xwlVidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode)
+{
+    /* Unsupported */
+    return;
+}
+
+static Bool
+xwlVidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
+{
+    /* Unsupported */
+    return FALSE;
+}
+
+static int
+xwlVidModeGetNumOfModes(ScreenPtr pScreen)
+{
+    /* We have only one mode */
+    return 1;
+}
+
+static Bool
+xwlVidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue)
+{
+    /* Unsupported for now, but pretend it works */
+    return TRUE;
+}
+
+static Bool
+xwlVidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
+{
+    /* Unsupported for now, but pretend it works */
+    return TRUE;
+}
+
+static Bool
+xwlVidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
+{
+    /* Unsupported for now */
+    return FALSE;
+}
+
+static Bool
+xwlVidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
+{
+    /* Unsupported for now */
+    return FALSE;
+}
+
+static int
+xwlVidModeGetGammaRampSize(ScreenPtr pScreen)
+{
+    /* Unsupported for now */
+    return 0;
+}
+
+static Bool
+xwlVidModeInit(ScreenPtr pScreen)
+{
+    VidModePtr pVidMode = NULL;
+
+    pVidMode = VidModeInit(pScreen);
+    if (!pVidMode)
+        return FALSE;
+
+    pVidMode->Flags = 0;
+    pVidMode->Next = NULL;
+
+    pVidMode->GetMonitorValue = xwlVidModeGetMonitorValue;
+    pVidMode->GetCurrentModeline = xwlVidModeGetCurrentModeline;
+    pVidMode->GetFirstModeline = xwlVidModeGetFirstModeline;
+    pVidMode->GetNextModeline = xwlVidModeGetNextModeline;
+    pVidMode->DeleteModeline = xwlVidModeDeleteModeline;
+    pVidMode->ZoomViewport = xwlVidModeZoomViewport;
+    pVidMode->GetViewPort = xwlVidModeGetViewPort;
+    pVidMode->SetViewPort = xwlVidModeSetViewPort;
+    pVidMode->SwitchMode = xwlVidModeSwitchMode;
+    pVidMode->LockZoom = xwlVidModeLockZoom;
+    pVidMode->GetNumOfClocks = xwlVidModeGetNumOfClocks;
+    pVidMode->GetClocks = xwlVidModeGetClocks;
+    pVidMode->CheckModeForMonitor = xwlVidModeCheckModeForMonitor;
+    pVidMode->CheckModeForDriver = xwlVidModeCheckModeForDriver;
+    pVidMode->SetCrtcForMode = xwlVidModeSetCrtcForMode;
+    pVidMode->AddModeline = xwlVidModeAddModeline;
+    pVidMode->GetDotClock = xwlVidModeGetDotClock;
+    pVidMode->GetNumOfModes = xwlVidModeGetNumOfModes;
+    pVidMode->SetGamma = xwlVidModeSetGamma;
+    pVidMode->GetGamma = xwlVidModeGetGamma;
+    pVidMode->SetGammaRamp = xwlVidModeSetGammaRamp;
+    pVidMode->GetGammaRamp = xwlVidModeGetGammaRamp;
+    pVidMode->GetGammaRampSize = xwlVidModeGetGammaRampSize;
+
+    return TRUE;
+}
+
+void
+xwlVidModeExtensionInit(void)
+{
+    int i;
+    Bool enabled = FALSE;
+
+    for (i = 0; i < screenInfo.numScreens; i++) {
+        if (xwlVidModeInit (screenInfo.screens[i]))
+            enabled = TRUE;
+    }
+    /* This means that the DDX doesn't want the vidmode extension enabled */
+    if (!enabled)
+        return;
+
+    if (!dixRegisterPrivateKey(xwlVidModePrivateKey, PRIVATE_SCREEN,
+                               sizeof(DisplayModeRec)))
+        return;
+
+    VidModeAddExtension(FALSE);
+}
+
+#endif                          /* XF86VIDMODE */
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 86a7543..2d44d07 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -33,6 +33,11 @@
 #include <compositeext.h>
 #include <glx_extinit.h>
 
+#ifdef XF86VIDMODE
+#include <X11/extensions/xf86vmproto.h>
+_X_EXPORT Bool noXFree86VidModeExtension;
+#endif
+
 void
 ddxGiveUp(enum ExitCode error)
 {
@@ -711,6 +716,9 @@ static const ExtensionModule xwayland_extensions[] = {
 #ifdef GLXEXT
     { GlxExtensionInit, "GLX", &noGlxExtension },
 #endif
+#ifdef XF86VIDMODE
+    { xwlVidModeExtensionInit, XF86VIDMODENAME, &noXFree86VidModeExtension },
+#endif
 };
 
 void
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 4fcdee5..4b150ed 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -190,4 +190,8 @@ Bool xwl_screen_init_glamor(struct xwl_screen *xwl_screen,
                          uint32_t id, uint32_t version);
 struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap);
 
+#ifdef XF86VIDMODE
+void xwlVidModeExtensionInit(void);
+#endif
+
 #endif
commit f2b346f9ba86ba304baac5ed29f8caf3fefbdba0
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Feb 5 09:48:25 2016 +0100

    vidmode: remove redundant DIX function
    
    The API signature of the DIX xf86VidModeGetGammaRampSize() is now
    identical to the xf86cmap's xf86GetGammaRampSize() and all it does is
    actually call xf86GetGammaRampSize() so we can save one vfunc.
    
    Remove uneeded xf86VidModeGetGammaRampSize() function.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit b430f53bb753f9b064ab62d014820c1c3c76a841)

diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index b7ccfb2..7e12ea2 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -393,12 +393,6 @@ xf86VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD1
     return TRUE;
 }
 
-static int
-xf86VidModeGetGammaRampSize(ScreenPtr pScreen)
-{
-    return xf86GetGammaRampSize(pScreen);
-}
-
 static Bool
 xf86VidModeInit(ScreenPtr pScreen)
 {
@@ -438,7 +432,7 @@ xf86VidModeInit(ScreenPtr pScreen)
     pVidMode->GetGamma = xf86VidModeGetGamma;
     pVidMode->SetGammaRamp = xf86VidModeSetGammaRamp;
     pVidMode->GetGammaRamp = xf86VidModeGetGammaRamp;
-    pVidMode->GetGammaRampSize = xf86VidModeGetGammaRampSize;
+    pVidMode->GetGammaRampSize = xf86GetGammaRampSize; /* use xf86cmap API directly */
 
     return TRUE;
 }
commit d381d59e44f675d01ca9ecab5a58c4864ae56c29
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Feb 5 09:48:24 2016 +0100

    vidmode: remove redundant check
    
    The DIX already checks for VidModePrivateKey to get the vfunc, so
    checking for this again in the DDX is redundant.
    
    Remove the redundant function xf86VidModeAvailable() from the DDX.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 48fccde2bfb60efdbf45a96fa53bcd9a6570bf89)

diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index d2bdf6b..b7ccfb2 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -50,17 +50,6 @@
 #include "xf86Extensions.h"
 #include "xf86cmap.h"
 
-static Bool
-xf86VidModeAvailable(ScreenPtr pScreen)
-{
-    if (VidModeGetPtr(pScreen))
-        return TRUE;
-    else {
-        DebugF("pVidMode == NULL\n");
-        return FALSE;
-    }
-}
-
 static vidMonitorValue
 xf86VidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
 {
@@ -68,9 +57,6 @@ xf86VidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
     MonPtr monitor;
     ScrnInfoPtr pScrn;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return ret;
-
     pScrn = xf86ScreenToScrn(pScreen);
     monitor = pScrn->monitor;
 
@@ -108,9 +94,6 @@ xf86VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotC
 {
     ScrnInfoPtr pScrn;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     pScrn = xf86ScreenToScrn(pScreen);
 
     if (pScrn->currentMode) {
@@ -127,9 +110,6 @@ xf86VidModeGetDotClock(ScreenPtr pScreen, int Clock)
 {
     ScrnInfoPtr pScrn;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return 0;
-
     pScrn = xf86ScreenToScrn(pScreen);
     if ((pScrn->progClock) || (Clock >= MAXCLOCKS))
         return Clock;
@@ -142,9 +122,6 @@ xf86VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
 {
     ScrnInfoPtr pScrn;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return 0;
-
     pScrn = xf86ScreenToScrn(pScreen);
     if (pScrn->progClock) {
         *progClock = TRUE;
@@ -162,9 +139,6 @@ xf86VidModeGetClocks(ScreenPtr pScreen, int *Clocks)
     ScrnInfoPtr pScrn;
     int i;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     pScrn = xf86ScreenToScrn(pScreen);
 
     if (pScrn->progClock)
@@ -182,9 +156,6 @@ xf86VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotCloc
     VidModePtr pVidMode;
     DisplayModePtr p;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     pVidMode = VidModeGetPtr(pScreen);
 
     for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
@@ -205,9 +176,6 @@ xf86VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClo
     ScrnInfoPtr pScrn;
     VidModePtr pVidMode;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     pScrn = xf86ScreenToScrn(pScreen);
     if (pScrn->modes == NULL)
         return FALSE;
@@ -230,7 +198,7 @@ xf86VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!xf86VidModeAvailable(pScreen)))
+    if (mode == NULL)
         return FALSE;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -241,9 +209,6 @@ xf86VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
 static Bool
 xf86VidModeZoomViewport(ScreenPtr pScreen, int zoom)
 {
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     xf86ZoomViewport(pScreen, zoom);
     return TRUE;
 }
@@ -253,9 +218,6 @@ xf86VidModeSetViewPort(ScreenPtr pScreen, int x, int y)
 {
     ScrnInfoPtr pScrn;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     pScrn = xf86ScreenToScrn(pScreen);
     pScrn->frameX0 = min(max(x, 0),
                          pScrn->virtualX - pScrn->currentMode->HDisplay);
@@ -274,9 +236,6 @@ xf86VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
 {
     ScrnInfoPtr pScrn;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     pScrn = xf86ScreenToScrn(pScreen);
     *x = pScrn->frameX0;
     *y = pScrn->frameY0;
@@ -290,9 +249,6 @@ xf86VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
     DisplayModePtr pTmpMode;
     Bool retval;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     pScrn = xf86ScreenToScrn(pScreen);
     /* save in case we fail */
     pTmpMode = pScrn->currentMode;
@@ -308,9 +264,6 @@ xf86VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
 static Bool
 xf86VidModeLockZoom(ScreenPtr pScreen, Bool lock)
 {
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     if (xf86Info.dontZoom)
         return FALSE;
 
@@ -323,7 +276,7 @@ xf86VidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!xf86VidModeAvailable(pScreen)))
+    if (mode == NULL)
         return MODE_ERROR;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -336,7 +289,7 @@ xf86VidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!xf86VidModeAvailable(pScreen)))
+    if (mode == NULL)
         return MODE_ERROR;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -350,7 +303,7 @@ xf86VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode)
     ScrnInfoPtr pScrn;
     DisplayModePtr ScreenModes;
 
-    if ((mode == NULL) || (!xf86VidModeAvailable(pScreen)))
+    if (mode == NULL)
         return;
 
     /* Ugly hack so that the xf86Mode.c function can be used without change */
@@ -368,7 +321,7 @@ xf86VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!xf86VidModeAvailable(pScreen)))
+    if (mode == NULL)
         return FALSE;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -405,9 +358,6 @@ xf86VidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue)
 {
     Gamma gamma;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     gamma.red = red;
     gamma.green = green;
     gamma.blue = blue;
@@ -422,9 +372,6 @@ xf86VidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
 {
     ScrnInfoPtr pScrn;
 
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     pScrn = xf86ScreenToScrn(pScreen);
     *red = pScrn->gamma.red;
     *green = pScrn->gamma.green;
@@ -435,9 +382,6 @@ xf86VidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
 static Bool
 xf86VidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
 {
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     xf86ChangeGammaRamp(pScreen, size, r, g, b);
     return TRUE;
 }
@@ -445,9 +389,6 @@ xf86VidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD1
 static Bool
 xf86VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
 {
-    if (!xf86VidModeAvailable(pScreen))
-        return FALSE;
-
     xf86GetGammaRamp(pScreen, size, r, g, b);
     return TRUE;
 }
@@ -455,9 +396,6 @@ xf86VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD1
 static int
 xf86VidModeGetGammaRampSize(ScreenPtr pScreen)
 {
-    if (!xf86VidModeAvailable(pScreen))
-        return 0;
-
     return xf86GetGammaRampSize(pScreen);
 }
 
commit 349b71a37e4a87e3650b5c0df9651b2ce967293e
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Feb 10 09:34:34 2016 +0100

    vidmode: move to a separate library of its own
    
    XVidMode extension might be useful to non hardware servers as well (e.g.
    Xwayand) so that applications that rely on it (e.g. lot of older games)
    can at least have read access to XVidMode.
    
    But the implementation is very XFree86 centric, so the idea is to add
    a bunch of vfunc that other non-XFree86 servers can hook up into to
    provide a similar functionality.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87806
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit f175cf45aebcdda53f3ae49c0eaf27da1f194e92)

diff --git a/Xext/Makefile.am b/Xext/Makefile.am
index a9a4468..1ceb980 100644
--- a/Xext/Makefile.am
+++ b/Xext/Makefile.am
@@ -1,4 +1,4 @@
-noinst_LTLIBRARIES = libXext.la libXextdpmsstubs.la
+noinst_LTLIBRARIES = libXext.la libXextdpmsstubs.la libXvidmode.la
 
 AM_CFLAGS = $(DIX_CFLAGS)
 
@@ -6,7 +6,7 @@ if XORG
 sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h syncsdk.h
 endif
 
-# Sources always included in libXextbuiltin.la & libXext.la
+# Sources always included in libXextbuiltin.la, libXext.la
 BUILTIN_SRCS =			\
 	bigreq.c		\
         geext.c			\
@@ -98,6 +98,9 @@ libXext_la_LIBADD =		$(BUILTIN_LIBS)
 
 libXextdpmsstubs_la_SOURCES = dpmsstubs.c
 
+# XVidMode extension
+libXvidmode_la_SOURCES = vidmode.c
+
 EXTRA_DIST = \
 	$(MITSHM_SRCS) \
 	$(XV_SRCS) \
diff --git a/Xext/vidmode.c b/Xext/vidmode.c
new file mode 100644
index 0000000..7ea5ddf
--- /dev/null
+++ b/Xext/vidmode.c
@@ -0,0 +1,2147 @@
+/*
+
+Copyright 1995  Kaleb S. KEITHLEY
+
+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 Kaleb S. KEITHLEY 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 Kaleb S. KEITHLEY
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+from Kaleb S. KEITHLEY
+
+*/
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/extensions/xf86vmproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "swaprep.h"
+#include "vidmodestr.h"
+#include "globals.h"
+#include "protocol-versions.h"
+
+static int VidModeErrorBase;
+static int VidModeAllowNonLocal;
+
+static DevPrivateKeyRec VidModeClientPrivateKeyRec;
+#define VidModeClientPrivateKey (&VidModeClientPrivateKeyRec)
+
+static DevPrivateKeyRec VidModePrivateKeyRec;
+#define VidModePrivateKey (&VidModePrivateKeyRec)
+
+/* This holds the client's version information */
+typedef struct {
+    int major;
+    int minor;
+} VidModePrivRec, *VidModePrivPtr;
+
+#define VM_GETPRIV(c) ((VidModePrivPtr) \
+    dixLookupPrivate(&(c)->devPrivates, VidModeClientPrivateKey))
+#define VM_SETPRIV(c,p) \
+    dixSetPrivate(&(c)->devPrivates, VidModeClientPrivateKey, p)
+
+#ifdef DEBUG
+#define DEBUG_P(x) LogMessage(X_INFO, x"\n");
+#else
+#define DEBUG_P(x) /**/
+#endif
+
+static DisplayModePtr
+VidModeCreateMode(void)
+{
+    DisplayModePtr mode;
+
+    mode = malloc(sizeof(DisplayModeRec));
+    if (mode != NULL) {
+        mode->name = "";
+        mode->VScan = 1;        /* divides refresh rate. default = 1 */
+        mode->Private = NULL;
+        mode->next = mode;
+        mode->prev = mode;
+    }
+    return mode;
+}
+
+static void
+VidModeCopyMode(DisplayModePtr modefrom, DisplayModePtr modeto)
+{
+    memcpy(modeto, modefrom, sizeof(DisplayModeRec));
+}
+
+static int
+VidModeGetModeValue(DisplayModePtr mode, int valtyp)
+{
+    int ret = 0;
+
+    switch (valtyp) {
+    case VIDMODE_H_DISPLAY:
+        ret = mode->HDisplay;
+        break;
+    case VIDMODE_H_SYNCSTART:
+        ret = mode->HSyncStart;
+        break;
+    case VIDMODE_H_SYNCEND:
+        ret = mode->HSyncEnd;
+        break;
+    case VIDMODE_H_TOTAL:
+        ret = mode->HTotal;
+        break;
+    case VIDMODE_H_SKEW:
+        ret = mode->HSkew;
+        break;
+    case VIDMODE_V_DISPLAY:
+        ret = mode->VDisplay;
+        break;
+    case VIDMODE_V_SYNCSTART:
+        ret = mode->VSyncStart;
+        break;
+    case VIDMODE_V_SYNCEND:
+        ret = mode->VSyncEnd;
+        break;
+    case VIDMODE_V_TOTAL:
+        ret = mode->VTotal;
+        break;
+    case VIDMODE_FLAGS:
+        ret = mode->Flags;
+        break;
+    case VIDMODE_CLOCK:
+        ret = mode->Clock;
+        break;
+    }
+    return ret;
+}
+
+static void
+VidModeSetModeValue(DisplayModePtr mode, int valtyp, int val)
+{
+    switch (valtyp) {
+    case VIDMODE_H_DISPLAY:
+        mode->HDisplay = val;
+        break;
+    case VIDMODE_H_SYNCSTART:
+        mode->HSyncStart = val;
+        break;
+    case VIDMODE_H_SYNCEND:
+        mode->HSyncEnd = val;
+        break;
+    case VIDMODE_H_TOTAL:
+        mode->HTotal = val;
+        break;
+    case VIDMODE_H_SKEW:
+        mode->HSkew = val;
+        break;
+    case VIDMODE_V_DISPLAY:
+        mode->VDisplay = val;
+        break;
+    case VIDMODE_V_SYNCSTART:
+        mode->VSyncStart = val;
+        break;
+    case VIDMODE_V_SYNCEND:
+        mode->VSyncEnd = val;
+        break;
+    case VIDMODE_V_TOTAL:
+        mode->VTotal = val;
+        break;
+    case VIDMODE_FLAGS:
+        mode->Flags = val;
+        break;
+    case VIDMODE_CLOCK:
+        mode->Clock = val;
+        break;
+    }
+    return;
+}
+
+static int
+ClientMajorVersion(ClientPtr client)
+{
+    VidModePrivPtr pPriv;
+
+    pPriv = VM_GETPRIV(client);
+    if (!pPriv)
+        return 0;
+    else
+        return pPriv->major;
+}
+
+static int
+ProcVidModeQueryVersion(ClientPtr client)
+{
+    xXF86VidModeQueryVersionReply rep = {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence,
+        .length = 0,
+        .majorVersion = SERVER_XF86VIDMODE_MAJOR_VERSION,
+        .minorVersion = SERVER_XF86VIDMODE_MINOR_VERSION
+    };
+
+    DEBUG_P("XF86VidModeQueryVersion");
+
+    REQUEST_SIZE_MATCH(xXF86VidModeQueryVersionReq);
+
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+        swaps(&rep.majorVersion);
+        swaps(&rep.minorVersion);
+    }
+    WriteToClient(client, sizeof(xXF86VidModeQueryVersionReply), &rep);
+    return Success;
+}
+
+static int
+ProcVidModeGetModeLine(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetModeLineReq);
+    xXF86VidModeGetModeLineReply rep = {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence
+    };
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+    DisplayModePtr mode;
+    int dotClock;
+    int ver;
+
+    DEBUG_P("XF86VidModeGetModeline");
+
+    ver = ClientMajorVersion(client);
+    REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
+
+    if (ver < 2) {
+        rep.length = bytes_to_int32(SIZEOF(xXF86OldVidModeGetModeLineReply) -
+                                    SIZEOF(xGenericReply));
+    }
+    else {
+        rep.length = bytes_to_int32(SIZEOF(xXF86VidModeGetModeLineReply) -
+                                    SIZEOF(xGenericReply));
+    }
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
+        return BadValue;
+
+    rep.dotclock = dotClock;
+    rep.hdisplay = VidModeGetModeValue(mode, VIDMODE_H_DISPLAY);
+    rep.hsyncstart = VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART);
+    rep.hsyncend = VidModeGetModeValue(mode, VIDMODE_H_SYNCEND);
+    rep.htotal = VidModeGetModeValue(mode, VIDMODE_H_TOTAL);
+    rep.hskew = VidModeGetModeValue(mode, VIDMODE_H_SKEW);
+    rep.vdisplay = VidModeGetModeValue(mode, VIDMODE_V_DISPLAY);
+    rep.vsyncstart = VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART);
+    rep.vsyncend = VidModeGetModeValue(mode, VIDMODE_V_SYNCEND);
+    rep.vtotal = VidModeGetModeValue(mode, VIDMODE_V_TOTAL);
+    rep.flags = VidModeGetModeValue(mode, VIDMODE_FLAGS);
+
+    LogMessage(X_INFO, "GetModeLine - scrn: %d clock: %ld\n",
+               stuff->screen, (unsigned long) rep.dotclock);
+    LogMessage(X_INFO, "GetModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
+               rep.hdisplay, rep.hsyncstart, rep.hsyncend, rep.htotal);
+    LogMessage(X_INFO, "              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+               rep.vdisplay, rep.vsyncstart, rep.vsyncend,
+               rep.vtotal, (unsigned long) rep.flags);
+
+    /*
+     * Older servers sometimes had server privates that the VidMode
+     * extention made available. So to be compatiable pretend that
+     * there are no server privates to pass to the client
+     */
+    rep.privsize = 0;
+
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+        swapl(&rep.dotclock);
+        swaps(&rep.hdisplay);
+        swaps(&rep.hsyncstart);
+        swaps(&rep.hsyncend);
+        swaps(&rep.htotal);
+        swaps(&rep.hskew);
+        swaps(&rep.vdisplay);
+        swaps(&rep.vsyncstart);
+        swaps(&rep.vsyncend);
+        swaps(&rep.vtotal);
+        swapl(&rep.flags);
+        swapl(&rep.privsize);
+    }
+    if (ver < 2) {
+        xXF86OldVidModeGetModeLineReply oldrep = {
+            .type = rep.type,
+            .sequenceNumber = rep.sequenceNumber,
+            .length = rep.length,
+            .dotclock = rep.dotclock,
+            .hdisplay = rep.hdisplay,
+            .hsyncstart = rep.hsyncstart,
+            .hsyncend = rep.hsyncend,
+            .htotal = rep.htotal,
+            .vdisplay = rep.vdisplay,
+            .vsyncstart = rep.vsyncstart,
+            .vsyncend = rep.vsyncend,
+            .vtotal = rep.vtotal,
+            .flags = rep.flags,
+            .privsize = rep.privsize
+        };
+        WriteToClient(client, sizeof(xXF86OldVidModeGetModeLineReply), &oldrep);
+    }
+    else {
+        WriteToClient(client, sizeof(xXF86VidModeGetModeLineReply), &rep);
+    }
+    return Success;
+}
+
+static int
+ProcVidModeGetAllModeLines(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetAllModeLinesReq);
+    xXF86VidModeGetAllModeLinesReply rep;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+    DisplayModePtr mode;
+    int modecount, dotClock;
+    int ver;
+
+    DEBUG_P("XF86VidModeGetAllModelines");
+
+    REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+    ver = ClientMajorVersion(client);
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    modecount = pVidMode->GetNumOfModes(pScreen);
+    if (modecount < 1)
+        return VidModeErrorBase + XF86VidModeExtensionDisabled;
+
+    if (!pVidMode->GetFirstModeline(pScreen, &mode, &dotClock))
+        return BadValue;
+
+    rep = (xXF86VidModeGetAllModeLinesReply) {
+        .type = X_Reply,
+        .length = SIZEOF(xXF86VidModeGetAllModeLinesReply) -
+            SIZEOF(xGenericReply),
+        .sequenceNumber = client->sequence,
+        .modecount = modecount
+    };
+    if (ver < 2)
+        rep.length += modecount * sizeof(xXF86OldVidModeModeInfo);
+    else
+        rep.length += modecount * sizeof(xXF86VidModeModeInfo);
+    rep.length >>= 2;
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+        swapl(&rep.modecount);
+    }
+    WriteToClient(client, sizeof(xXF86VidModeGetAllModeLinesReply), &rep);
+
+    do {
+        xXF86VidModeModeInfo mdinf = {
+            .dotclock = dotClock,
+            .hdisplay = VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
+            .hsyncstart = VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
+            .hsyncend = VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
+            .htotal = VidModeGetModeValue(mode, VIDMODE_H_TOTAL),
+            .hskew = VidModeGetModeValue(mode, VIDMODE_H_SKEW),
+            .vdisplay = VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
+            .vsyncstart = VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
+            .vsyncend = VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
+            .vtotal = VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
+            .flags = VidModeGetModeValue(mode, VIDMODE_FLAGS),
+            .privsize = 0
+        };
+        if (client->swapped) {
+            swapl(&mdinf.dotclock);
+            swaps(&mdinf.hdisplay);
+            swaps(&mdinf.hsyncstart);
+            swaps(&mdinf.hsyncend);
+            swaps(&mdinf.htotal);
+            swapl(&mdinf.hskew);
+            swaps(&mdinf.vdisplay);
+            swaps(&mdinf.vsyncstart);
+            swaps(&mdinf.vsyncend);
+            swaps(&mdinf.vtotal);
+            swapl(&mdinf.flags);
+            swapl(&mdinf.privsize);
+        }
+        if (ver < 2) {
+            xXF86OldVidModeModeInfo oldmdinf = {
+                .dotclock = mdinf.dotclock,
+                .hdisplay = mdinf.hdisplay,
+                .hsyncstart = mdinf.hsyncstart,
+                .hsyncend = mdinf.hsyncend,
+                .htotal = mdinf.htotal,
+                .vdisplay = mdinf.vdisplay,
+                .vsyncstart = mdinf.vsyncstart,
+                .vsyncend = mdinf.vsyncend,
+                .vtotal = mdinf.vtotal,
+                .flags = mdinf.flags,
+                .privsize = mdinf.privsize
+            };
+            WriteToClient(client, sizeof(xXF86OldVidModeModeInfo), &oldmdinf);
+        }
+        else {
+            WriteToClient(client, sizeof(xXF86VidModeModeInfo), &mdinf);
+        }
+
+    } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
+
+    return Success;
+}
+
+#define MODEMATCH(mode,stuff)	  \
+     (VidModeGetModeValue(mode, VIDMODE_H_DISPLAY)  == stuff->hdisplay \
+     && VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART)  == stuff->hsyncstart \
+     && VidModeGetModeValue(mode, VIDMODE_H_SYNCEND)  == stuff->hsyncend \
+     && VidModeGetModeValue(mode, VIDMODE_H_TOTAL)  == stuff->htotal \
+     && VidModeGetModeValue(mode, VIDMODE_V_DISPLAY)  == stuff->vdisplay \
+     && VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART)  == stuff->vsyncstart \
+     && VidModeGetModeValue(mode, VIDMODE_V_SYNCEND)  == stuff->vsyncend \
+     && VidModeGetModeValue(mode, VIDMODE_V_TOTAL)  == stuff->vtotal \
+     && VidModeGetModeValue(mode, VIDMODE_FLAGS)  == stuff->flags )
+
+static int
+ProcVidModeAddModeLine(ClientPtr client)
+{
+    REQUEST(xXF86VidModeAddModeLineReq);
+    xXF86OldVidModeAddModeLineReq *oldstuff =
+        (xXF86OldVidModeAddModeLineReq *) client->requestBuffer;
+    xXF86VidModeAddModeLineReq newstuff;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+    DisplayModePtr mode;
+    int len;
+    int dotClock;
+    int ver;
+
+    DEBUG_P("XF86VidModeAddModeline");
+
+    ver = ClientMajorVersion(client);
+    if (ver < 2) {
+        /* convert from old format */
+        stuff = &newstuff;
+        stuff->length = oldstuff->length;
+        stuff->screen = oldstuff->screen;
+        stuff->dotclock = oldstuff->dotclock;
+        stuff->hdisplay = oldstuff->hdisplay;
+        stuff->hsyncstart = oldstuff->hsyncstart;
+        stuff->hsyncend = oldstuff->hsyncend;
+        stuff->htotal = oldstuff->htotal;
+        stuff->hskew = 0;
+        stuff->vdisplay = oldstuff->vdisplay;
+        stuff->vsyncstart = oldstuff->vsyncstart;
+        stuff->vsyncend = oldstuff->vsyncend;
+        stuff->vtotal = oldstuff->vtotal;
+        stuff->flags = oldstuff->flags;
+        stuff->privsize = oldstuff->privsize;
+        stuff->after_dotclock = oldstuff->after_dotclock;
+        stuff->after_hdisplay = oldstuff->after_hdisplay;
+        stuff->after_hsyncstart = oldstuff->after_hsyncstart;
+        stuff->after_hsyncend = oldstuff->after_hsyncend;
+        stuff->after_htotal = oldstuff->after_htotal;
+        stuff->after_hskew = 0;
+        stuff->after_vdisplay = oldstuff->after_vdisplay;
+        stuff->after_vsyncstart = oldstuff->after_vsyncstart;
+        stuff->after_vsyncend = oldstuff->after_vsyncend;
+        stuff->after_vtotal = oldstuff->after_vtotal;
+        stuff->after_flags = oldstuff->after_flags;
+    }
+    LogMessage(X_INFO, "AddModeLine - scrn: %d clock: %ld\n",
+               (int) stuff->screen, (unsigned long) stuff->dotclock);
+    LogMessage(X_INFO, "AddModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
+               stuff->hdisplay, stuff->hsyncstart,
+               stuff->hsyncend, stuff->htotal);
+    LogMessage(X_INFO, "              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+               stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
+               stuff->vtotal, (unsigned long) stuff->flags);
+    LogMessage(X_INFO, "      after - scrn: %d clock: %ld\n",
+               (int) stuff->screen, (unsigned long) stuff->after_dotclock);
+    LogMessage(X_INFO, "              hdsp: %d hbeg: %d hend: %d httl: %d\n",
+               stuff->after_hdisplay, stuff->after_hsyncstart,
+               stuff->after_hsyncend, stuff->after_htotal);
+    LogMessage(X_INFO, "              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+               stuff->after_vdisplay, stuff->after_vsyncstart,
+               stuff->after_vsyncend, stuff->after_vtotal,
+               (unsigned long) stuff->after_flags);
+
+    if (ver < 2) {
+        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
+        len =
+            client->req_len -
+            bytes_to_int32(sizeof(xXF86OldVidModeAddModeLineReq));
+    }
+    else {
+        REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
+        len =
+            client->req_len -
+            bytes_to_int32(sizeof(xXF86VidModeAddModeLineReq));
+    }
+    if (len != stuff->privsize)
+        return BadLength;
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    if (stuff->hsyncstart < stuff->hdisplay ||
+        stuff->hsyncend < stuff->hsyncstart ||
+        stuff->htotal < stuff->hsyncend ||
+        stuff->vsyncstart < stuff->vdisplay ||
+        stuff->vsyncend < stuff->vsyncstart || stuff->vtotal < stuff->vsyncend)
+        return BadValue;
+
+    if (stuff->after_hsyncstart < stuff->after_hdisplay ||
+        stuff->after_hsyncend < stuff->after_hsyncstart ||
+        stuff->after_htotal < stuff->after_hsyncend ||
+        stuff->after_vsyncstart < stuff->after_vdisplay ||
+        stuff->after_vsyncend < stuff->after_vsyncstart ||
+        stuff->after_vtotal < stuff->after_vsyncend)
+        return BadValue;
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (stuff->after_htotal != 0 || stuff->after_vtotal != 0) {
+        Bool found = FALSE;
+
+        if (pVidMode->GetFirstModeline(pScreen, &mode, &dotClock)) {
+            do {
+                if ((pVidMode->GetDotClock(pScreen, stuff->dotclock)
+                     == dotClock) && MODEMATCH(mode, stuff)) {
+                    found = TRUE;
+                    break;
+                }
+            } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
+        }
+        if (!found)
+            return BadValue;
+    }
+
+    mode = VidModeCreateMode();
+    if (mode == NULL)
+        return BadValue;
+
+    VidModeSetModeValue(mode, VIDMODE_CLOCK, stuff->dotclock);
+    VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
+    VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
+    VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
+    VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
+    VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
+    VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
+    VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
+    VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
+    VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
+    VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
+
+    if (stuff->privsize)
+        LogMessage(X_INFO, "AddModeLine - Privates in request have been ignored\n");
+
+    /* Check that the mode is consistent with the monitor specs */
+    switch (pVidMode->CheckModeForMonitor(pScreen, mode)) {
+    case MODE_OK:
+        break;
+    case MODE_HSYNC:
+    case MODE_H_ILLEGAL:
+        free(mode);
+        return VidModeErrorBase + XF86VidModeBadHTimings;
+    case MODE_VSYNC:
+    case MODE_V_ILLEGAL:
+        free(mode);
+        return VidModeErrorBase + XF86VidModeBadVTimings;
+    default:
+        free(mode);
+        return VidModeErrorBase + XF86VidModeModeUnsuitable;
+    }
+
+    /* Check that the driver is happy with the mode */
+    if (pVidMode->CheckModeForDriver(pScreen, mode) != MODE_OK) {
+        free(mode);
+        return VidModeErrorBase + XF86VidModeModeUnsuitable;
+    }
+
+    pVidMode->SetCrtcForMode(pScreen, mode);
+
+    pVidMode->AddModeline(pScreen, mode);
+
+    LogMessage(X_INFO, "AddModeLine - Succeeded\n");
+
+    return Success;
+}
+
+static int
+ProcVidModeDeleteModeLine(ClientPtr client)
+{
+    REQUEST(xXF86VidModeDeleteModeLineReq);
+    xXF86OldVidModeDeleteModeLineReq *oldstuff =
+        (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer;
+    xXF86VidModeDeleteModeLineReq newstuff;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+    DisplayModePtr mode;
+    int len, dotClock;
+    int ver;
+
+    DEBUG_P("XF86VidModeDeleteModeline");
+
+    ver = ClientMajorVersion(client);
+    if (ver < 2) {
+        /* convert from old format */
+        stuff = &newstuff;
+        stuff->length = oldstuff->length;
+        stuff->screen = oldstuff->screen;
+        stuff->dotclock = oldstuff->dotclock;
+        stuff->hdisplay = oldstuff->hdisplay;
+        stuff->hsyncstart = oldstuff->hsyncstart;
+        stuff->hsyncend = oldstuff->hsyncend;
+        stuff->htotal = oldstuff->htotal;
+        stuff->hskew = 0;
+        stuff->vdisplay = oldstuff->vdisplay;
+        stuff->vsyncstart = oldstuff->vsyncstart;
+        stuff->vsyncend = oldstuff->vsyncend;
+        stuff->vtotal = oldstuff->vtotal;
+        stuff->flags = oldstuff->flags;
+        stuff->privsize = oldstuff->privsize;
+    }
+    LogMessage(X_INFO, "DeleteModeLine - scrn: %d clock: %ld\n",
+               (int) stuff->screen, (unsigned long) stuff->dotclock);
+    LogMessage(X_INFO, "                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
+               stuff->hdisplay, stuff->hsyncstart,
+               stuff->hsyncend, stuff->htotal);
+    LogMessage(X_INFO, "                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+             stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
+             (unsigned long) stuff->flags);
+
+    if (ver < 2) {
+        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
+        len =
+            client->req_len -
+            bytes_to_int32(sizeof(xXF86OldVidModeDeleteModeLineReq));
+    }
+    else {
+        REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
+        len =
+            client->req_len -
+            bytes_to_int32(sizeof(xXF86VidModeDeleteModeLineReq));
+    }
+    if (len != stuff->privsize) {
+        LogMessage(X_INFO, "req_len = %ld, sizeof(Req) = %d, privsize = %ld, "
+                   "len = %d, length = %d\n",
+                   (unsigned long) client->req_len,
+                   (int) sizeof(xXF86VidModeDeleteModeLineReq) >> 2,
+                   (unsigned long) stuff->privsize, len, stuff->length);
+        return BadLength;
+    }
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
+        return BadValue;
+
+    LogMessage(X_INFO, "Checking against clock: %d (%d)\n",
+               VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
+    LogMessage(X_INFO, "                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
+               VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
+               VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
+               VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
+               VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
+    LogMessage(X_INFO, "                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
+               VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
+               VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
+               VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
+               VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
+               VidModeGetModeValue(mode, VIDMODE_FLAGS));
+
+    if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) &&
+        MODEMATCH(mode, stuff))
+        return BadValue;
+
+    if (!pVidMode->GetFirstModeline(pScreen, &mode, &dotClock))
+        return BadValue;
+
+    do {
+        LogMessage(X_INFO, "Checking against clock: %d (%d)\n",
+                   VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
+        LogMessage(X_INFO, "                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
+                   VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
+                   VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
+                   VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
+                   VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
+        LogMessage(X_INFO, "                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
+                   VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
+                   VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
+                   VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
+                   VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
+                   VidModeGetModeValue(mode, VIDMODE_FLAGS));
+
+        if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) &&
+            MODEMATCH(mode, stuff)) {
+            pVidMode->DeleteModeline(pScreen, mode);
+            LogMessage(X_INFO, "DeleteModeLine - Succeeded\n");
+            return Success;
+        }
+    } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
+
+    return BadValue;
+}
+
+static int
+ProcVidModeModModeLine(ClientPtr client)
+{
+    REQUEST(xXF86VidModeModModeLineReq);
+    xXF86OldVidModeModModeLineReq *oldstuff =
+        (xXF86OldVidModeModModeLineReq *) client->requestBuffer;
+    xXF86VidModeModModeLineReq newstuff;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+    DisplayModePtr mode, modetmp;
+    int len, dotClock;
+    int ver;
+
+    DEBUG_P("XF86VidModeModModeline");
+
+    ver = ClientMajorVersion(client);
+    if (ver < 2) {
+        /* convert from old format */
+        stuff = &newstuff;
+        stuff->length = oldstuff->length;
+        stuff->screen = oldstuff->screen;
+        stuff->hdisplay = oldstuff->hdisplay;
+        stuff->hsyncstart = oldstuff->hsyncstart;
+        stuff->hsyncend = oldstuff->hsyncend;
+        stuff->htotal = oldstuff->htotal;
+        stuff->hskew = 0;
+        stuff->vdisplay = oldstuff->vdisplay;
+        stuff->vsyncstart = oldstuff->vsyncstart;
+        stuff->vsyncend = oldstuff->vsyncend;
+        stuff->vtotal = oldstuff->vtotal;
+        stuff->flags = oldstuff->flags;
+        stuff->privsize = oldstuff->privsize;
+    }
+    LogMessage(X_INFO, "ModModeLine - scrn: %d hdsp: %d hbeg: %d hend: %d httl: %d\n",
+               (int) stuff->screen, stuff->hdisplay, stuff->hsyncstart,
+               stuff->hsyncend, stuff->htotal);
+    LogMessage(X_INFO, "              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+               stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
+               stuff->vtotal, (unsigned long) stuff->flags);
+
+    if (ver < 2) {
+        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
+        len =
+            client->req_len -
+            bytes_to_int32(sizeof(xXF86OldVidModeModModeLineReq));
+    }
+    else {
+        REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
+        len =
+            client->req_len -
+            bytes_to_int32(sizeof(xXF86VidModeModModeLineReq));
+    }
+    if (len != stuff->privsize)
+        return BadLength;
+
+    if (stuff->hsyncstart < stuff->hdisplay ||
+        stuff->hsyncend < stuff->hsyncstart ||
+        stuff->htotal < stuff->hsyncend ||
+        stuff->vsyncstart < stuff->vdisplay ||
+        stuff->vsyncend < stuff->vsyncstart || stuff->vtotal < stuff->vsyncend)
+        return BadValue;
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
+        return BadValue;
+
+    modetmp = VidModeCreateMode();
+    VidModeCopyMode(mode, modetmp);
+
+    VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
+    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
+    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
+    VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
+    VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
+    VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
+    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
+    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
+    VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
+    VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
+
+    if (stuff->privsize)
+        LogMessage(X_INFO, "ModModeLine - Privates in request have been ignored\n");
+
+    /* Check that the mode is consistent with the monitor specs */
+    switch (pVidMode->CheckModeForMonitor(pScreen, modetmp)) {
+    case MODE_OK:
+        break;
+    case MODE_HSYNC:
+    case MODE_H_ILLEGAL:
+        free(modetmp);
+        return VidModeErrorBase + XF86VidModeBadHTimings;
+    case MODE_VSYNC:
+    case MODE_V_ILLEGAL:
+        free(modetmp);
+        return VidModeErrorBase + XF86VidModeBadVTimings;
+    default:
+        free(modetmp);
+        return VidModeErrorBase + XF86VidModeModeUnsuitable;
+    }
+
+    /* Check that the driver is happy with the mode */
+    if (pVidMode->CheckModeForDriver(pScreen, modetmp) != MODE_OK) {
+        free(modetmp);
+        return VidModeErrorBase + XF86VidModeModeUnsuitable;
+    }
+    free(modetmp);
+
+    VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
+    VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
+    VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
+    VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
+    VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
+    VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
+    VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
+    VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
+    VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
+    VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
+
+    pVidMode->SetCrtcForMode(pScreen, mode);
+    pVidMode->SwitchMode(pScreen, mode);
+
+    LogMessage(X_INFO, "ModModeLine - Succeeded\n");
+    return Success;
+}
+
+static int
+ProcVidModeValidateModeLine(ClientPtr client)
+{
+    REQUEST(xXF86VidModeValidateModeLineReq);
+    xXF86OldVidModeValidateModeLineReq *oldstuff =
+        (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer;
+    xXF86VidModeValidateModeLineReq newstuff;
+    xXF86VidModeValidateModeLineReply rep;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+    DisplayModePtr mode, modetmp = NULL;
+    int len, status, dotClock;
+    int ver;
+
+    DEBUG_P("XF86VidModeValidateModeline");
+
+    ver = ClientMajorVersion(client);
+    if (ver < 2) {
+        /* convert from old format */
+        stuff = &newstuff;
+        stuff->length = oldstuff->length;
+        stuff->screen = oldstuff->screen;
+        stuff->dotclock = oldstuff->dotclock;
+        stuff->hdisplay = oldstuff->hdisplay;
+        stuff->hsyncstart = oldstuff->hsyncstart;
+        stuff->hsyncend = oldstuff->hsyncend;
+        stuff->htotal = oldstuff->htotal;
+        stuff->hskew = 0;
+        stuff->vdisplay = oldstuff->vdisplay;
+        stuff->vsyncstart = oldstuff->vsyncstart;
+        stuff->vsyncend = oldstuff->vsyncend;
+        stuff->vtotal = oldstuff->vtotal;
+        stuff->flags = oldstuff->flags;
+        stuff->privsize = oldstuff->privsize;
+    }
+
+    LogMessage(X_INFO, "ValidateModeLine - scrn: %d clock: %ld\n",
+               (int) stuff->screen, (unsigned long) stuff->dotclock);
+    LogMessage(X_INFO, "                   hdsp: %d hbeg: %d hend: %d httl: %d\n",
+               stuff->hdisplay, stuff->hsyncstart,
+               stuff->hsyncend, stuff->htotal);
+    LogMessage(X_INFO, "                   vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+             stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
+             (unsigned long) stuff->flags);
+
+    if (ver < 2) {
+        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
+        len = client->req_len -
+            bytes_to_int32(sizeof(xXF86OldVidModeValidateModeLineReq));
+    }
+    else {
+        REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
+        len =
+            client->req_len -
+            bytes_to_int32(sizeof(xXF86VidModeValidateModeLineReq));
+    }
+    if (len != stuff->privsize)
+        return BadLength;
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    status = MODE_OK;
+
+    if (stuff->hsyncstart < stuff->hdisplay ||
+        stuff->hsyncend < stuff->hsyncstart ||
+        stuff->htotal < stuff->hsyncend ||
+        stuff->vsyncstart < stuff->vdisplay ||
+        stuff->vsyncend < stuff->vsyncstart ||
+        stuff->vtotal < stuff->vsyncend) {
+        status = MODE_BAD;
+        goto status_reply;
+    }
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
+        return BadValue;
+
+    modetmp = VidModeCreateMode();
+    VidModeCopyMode(mode, modetmp);
+
+    VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
+    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
+    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
+    VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
+    VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
+    VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
+    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
+    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
+    VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
+    VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
+    if (stuff->privsize)
+        LogMessage(X_INFO, "ValidateModeLine - Privates in request have been ignored\n");
+
+    /* Check that the mode is consistent with the monitor specs */
+    if ((status =
+         pVidMode->CheckModeForMonitor(pScreen, modetmp)) != MODE_OK)
+        goto status_reply;
+
+    /* Check that the driver is happy with the mode */
+    status = pVidMode->CheckModeForDriver(pScreen, modetmp);
+
+ status_reply:
+    free(modetmp);
+
+    rep = (xXF86VidModeValidateModeLineReply) {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence,
+        .length = bytes_to_int32(SIZEOF(xXF86VidModeValidateModeLineReply)
+                                 - SIZEOF(xGenericReply)),
+        .status = status
+    };
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+        swapl(&rep.status);
+    }
+    WriteToClient(client, sizeof(xXF86VidModeValidateModeLineReply), &rep);
+    LogMessage(X_INFO, "ValidateModeLine - Succeeded (status = %d)\n", status);
+
+    return Success;
+}
+
+static int
+ProcVidModeSwitchMode(ClientPtr client)
+{
+    REQUEST(xXF86VidModeSwitchModeReq);
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+
+    DEBUG_P("XF86VidModeSwitchMode");
+
+    REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    pVidMode->ZoomViewport(pScreen, (short) stuff->zoom);
+
+    return Success;
+}
+
+static int
+ProcVidModeSwitchToMode(ClientPtr client)
+{
+    REQUEST(xXF86VidModeSwitchToModeReq);
+    xXF86OldVidModeSwitchToModeReq *oldstuff =
+        (xXF86OldVidModeSwitchToModeReq *) client->requestBuffer;
+    xXF86VidModeSwitchToModeReq newstuff;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+    DisplayModePtr mode;
+    int len, dotClock;
+    int ver;
+
+    DEBUG_P("XF86VidModeSwitchToMode");
+
+    ver = ClientMajorVersion(client);
+    if (ver < 2) {
+        /* convert from old format */
+        stuff = &newstuff;
+        stuff->length = oldstuff->length;
+        stuff->screen = oldstuff->screen;
+        stuff->dotclock = oldstuff->dotclock;
+        stuff->hdisplay = oldstuff->hdisplay;
+        stuff->hsyncstart = oldstuff->hsyncstart;
+        stuff->hsyncend = oldstuff->hsyncend;
+        stuff->htotal = oldstuff->htotal;
+        stuff->hskew = 0;
+        stuff->vdisplay = oldstuff->vdisplay;
+        stuff->vsyncstart = oldstuff->vsyncstart;
+        stuff->vsyncend = oldstuff->vsyncend;
+        stuff->vtotal = oldstuff->vtotal;
+        stuff->flags = oldstuff->flags;
+        stuff->privsize = oldstuff->privsize;
+    }
+
+    LogMessage(X_INFO, "SwitchToMode - scrn: %d clock: %ld\n",
+               (int) stuff->screen, (unsigned long) stuff->dotclock);
+    LogMessage(X_INFO, "               hdsp: %d hbeg: %d hend: %d httl: %d\n",
+               stuff->hdisplay, stuff->hsyncstart,
+               stuff->hsyncend, stuff->htotal);
+    LogMessage(X_INFO, "               vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+               stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
+               (unsigned long) stuff->flags);
+
+    if (ver < 2) {
+        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeSwitchToModeReq);
+        len =
+            client->req_len -
+            bytes_to_int32(sizeof(xXF86OldVidModeSwitchToModeReq));
+    }
+    else {
+        REQUEST_AT_LEAST_SIZE(xXF86VidModeSwitchToModeReq);
+        len =
+            client->req_len -
+            bytes_to_int32(sizeof(xXF86VidModeSwitchToModeReq));
+    }
+    if (len != stuff->privsize)
+        return BadLength;
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
+        return BadValue;
+
+    if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock)
+        && MODEMATCH(mode, stuff))
+        return Success;
+
+    if (!pVidMode->GetFirstModeline(pScreen, &mode, &dotClock))
+        return BadValue;
+
+    do {
+        LogMessage(X_INFO, "Checking against clock: %d (%d)\n",
+                   VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
+        LogMessage(X_INFO, "                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
+                   VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
+                   VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
+                   VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
+                   VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
+        LogMessage(X_INFO, "                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
+                 VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
+                 VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
+                 VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
+                 VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
+                 VidModeGetModeValue(mode, VIDMODE_FLAGS));
+
+        if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) &&
+            MODEMATCH(mode, stuff)) {
+
+            if (!pVidMode->SwitchMode(pScreen, mode))
+                return BadValue;
+
+            LogMessage(X_INFO, "SwitchToMode - Succeeded\n");
+            return Success;
+        }
+    } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
+
+    return BadValue;
+}
+
+static int
+ProcVidModeLockModeSwitch(ClientPtr client)
+{
+    REQUEST(xXF86VidModeLockModeSwitchReq);
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+
+    REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
+
+    DEBUG_P("XF86VidModeLockModeSwitch");
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (!pVidMode->LockZoom(pScreen, (short) stuff->lock))
+        return VidModeErrorBase + XF86VidModeZoomLocked;
+
+    return Success;
+}
+
+static int
+ProcVidModeGetMonitor(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetMonitorReq);
+    xXF86VidModeGetMonitorReply rep = {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence
+    };
+    CARD32 *hsyncdata, *vsyncdata;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+    int i, nHsync, nVrefresh;
+
+    DEBUG_P("XF86VidModeGetMonitor");
+
+    REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    nHsync = pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_NHSYNC, 0).i;
+    nVrefresh = pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_NVREFRESH, 0).i;
+
+    if ((char *) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr)
+        rep.vendorLength = strlen((char *) (pVidMode->GetMonitorValue(pScreen,
+                                                                      VIDMODE_MON_VENDOR,
+                                                                      0)).ptr);
+    else
+        rep.vendorLength = 0;
+    if ((char *) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr)
+        rep.modelLength = strlen((char *) (pVidMode->GetMonitorValue(pScreen,
+                                                                     VIDMODE_MON_MODEL,
+                                                                     0)).ptr);
+    else
+        rep.modelLength = 0;
+    rep.length =
+        bytes_to_int32(SIZEOF(xXF86VidModeGetMonitorReply) -
+                       SIZEOF(xGenericReply) + (nHsync +
+                                                nVrefresh) * sizeof(CARD32) +
+                       pad_to_int32(rep.vendorLength) +
+                       pad_to_int32(rep.modelLength));
+    rep.nhsync = nHsync;
+    rep.nvsync = nVrefresh;
+    hsyncdata = xallocarray(nHsync, sizeof(CARD32));
+    if (!hsyncdata) {
+        return BadAlloc;
+    }
+    vsyncdata = xallocarray(nVrefresh, sizeof(CARD32));
+
+    if (!vsyncdata) {
+        free(hsyncdata);
+        return BadAlloc;
+    }
+
+    for (i = 0; i < nHsync; i++) {
+        hsyncdata[i] = (unsigned short) (pVidMode->GetMonitorValue(pScreen,
+                                                                   VIDMODE_MON_HSYNC_LO,
+                                                                   i)).f |
+            (unsigned
+             short) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_HSYNC_HI,
+                                               i)).f << 16;
+    }
+    for (i = 0; i < nVrefresh; i++) {
+        vsyncdata[i] = (unsigned short) (pVidMode->GetMonitorValue(pScreen,
+                                                                   VIDMODE_MON_VREFRESH_LO,
+                                                                   i)).f |
+            (unsigned
+             short) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VREFRESH_HI,
+                                               i)).f << 16;
+    }
+
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+    }
+    WriteToClient(client, SIZEOF(xXF86VidModeGetMonitorReply), &rep);
+    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+    WriteSwappedDataToClient(client, nHsync * sizeof(CARD32), hsyncdata);
+    WriteSwappedDataToClient(client, nVrefresh * sizeof(CARD32), vsyncdata);
+    if (rep.vendorLength)
+        WriteToClient(client, rep.vendorLength,
+                 (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr);
+    if (rep.modelLength)
+        WriteToClient(client, rep.modelLength,
+                 (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr);
+
+    free(hsyncdata);
+    free(vsyncdata);
+
+    return Success;
+}
+
+static int
+ProcVidModeGetViewPort(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetViewPortReq);
+    xXF86VidModeGetViewPortReply rep;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+    int x, y;
+
+    DEBUG_P("XF86VidModeGetViewPort");
+
+    REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    pVidMode->GetViewPort(pScreen, &x, &y);
+
+    rep = (xXF86VidModeGetViewPortReply) {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence,
+        .length = 0,
+        .x = x,
+        .y = y
+    };
+
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+        swapl(&rep.x);
+        swapl(&rep.y);
+    }
+    WriteToClient(client, SIZEOF(xXF86VidModeGetViewPortReply), &rep);
+    return Success;
+}
+
+static int
+ProcVidModeSetViewPort(ClientPtr client)
+{
+    REQUEST(xXF86VidModeSetViewPortReq);
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+
+    DEBUG_P("XF86VidModeSetViewPort");
+
+    REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (!pVidMode->SetViewPort(pScreen, stuff->x, stuff->y))
+        return BadValue;
+
+    return Success;
+}
+
+static int
+ProcVidModeGetDotClocks(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetDotClocksReq);
+    xXF86VidModeGetDotClocksReply rep;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+    int n;
+    int numClocks;
+    CARD32 dotclock;
+    int *Clocks = NULL;
+    Bool ClockProg;
+
+    DEBUG_P("XF86VidModeGetDotClocks");
+
+    REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    numClocks = pVidMode->GetNumOfClocks(pScreen, &ClockProg);
+
+    rep = (xXF86VidModeGetDotClocksReply) {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence,
+        .length = bytes_to_int32(SIZEOF(xXF86VidModeGetDotClocksReply)
+                                 - SIZEOF(xGenericReply) + numClocks),
+        .clocks = numClocks,
+        .maxclocks = MAXCLOCKS,
+        .flags = 0
+    };
+
+    if (!ClockProg) {
+        Clocks = calloc(numClocks, sizeof(int));
+        if (!Clocks)
+            return BadValue;
+        if (!pVidMode->GetClocks(pScreen, Clocks)) {
+            free(Clocks);
+            return BadValue;
+        }
+    }
+    if (ClockProg) {
+        rep.flags |= CLKFLAG_PROGRAMABLE;
+    }
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+        swapl(&rep.clocks);
+        swapl(&rep.maxclocks);
+        swapl(&rep.flags);
+    }
+    WriteToClient(client, sizeof(xXF86VidModeGetDotClocksReply), &rep);
+    if (!ClockProg) {
+        for (n = 0; n < numClocks; n++) {
+            dotclock = *Clocks++;
+            if (client->swapped) {
+                WriteSwappedDataToClient(client, 4, (char *) &dotclock);
+            }
+            else {
+                WriteToClient(client, 4, &dotclock);
+            }
+        }
+    }
+
+    free(Clocks);
+    return Success;
+}
+
+static int
+ProcVidModeSetGamma(ClientPtr client)
+{
+    REQUEST(xXF86VidModeSetGammaReq);
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+
+    DEBUG_P("XF86VidModeSetGamma");
+
+    REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (!pVidMode->SetGamma(pScreen, ((float) stuff->red) / 10000.,
+                         ((float) stuff->green) / 10000.,
+                         ((float) stuff->blue) / 10000.))
+        return BadValue;
+
+    return Success;
+}
+
+static int
+ProcVidModeGetGamma(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetGammaReq);
+    xXF86VidModeGetGammaReply rep;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+    float red, green, blue;
+
+    DEBUG_P("XF86VidModeGetGamma");
+
+    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (!pVidMode->GetGamma(pScreen, &red, &green, &blue))
+        return BadValue;
+    rep = (xXF86VidModeGetGammaReply) {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence,
+        .length = 0,
+        .red = (CARD32) (red * 10000.),
+        .green = (CARD32) (green * 10000.),
+        .blue = (CARD32) (blue * 10000.)
+    };
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+        swapl(&rep.red);
+        swapl(&rep.green);
+        swapl(&rep.blue);
+    }
+    WriteToClient(client, sizeof(xXF86VidModeGetGammaReply), &rep);
+
+    return Success;
+}
+
+static int
+ProcVidModeSetGammaRamp(ClientPtr client)
+{
+    CARD16 *r, *g, *b;
+    int length;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+
+    REQUEST(xXF86VidModeSetGammaRampReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (stuff->size != pVidMode->GetGammaRampSize(pScreen))
+        return BadValue;
+
+    length = (stuff->size + 1) & ~1;
+
+    REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length * 6);
+
+    r = (CARD16 *) &stuff[1];
+    g = r + length;
+    b = g + length;
+
+    if (!pVidMode->SetGammaRamp(pScreen, stuff->size, r, g, b))
+        return BadValue;
+
+    return Success;
+}
+
+static int
+ProcVidModeGetGammaRamp(ClientPtr client)
+{
+    CARD16 *ramp = NULL;
+    int length;
+    size_t ramplen = 0;
+    xXF86VidModeGetGammaRampReply rep;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+
+    REQUEST(xXF86VidModeGetGammaRampReq);
+
+    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    if (stuff->size != pVidMode->GetGammaRampSize(pScreen))
+        return BadValue;
+
+    length = (stuff->size + 1) & ~1;
+
+    if (stuff->size) {
+        if (!(ramp = xallocarray(length, 3 * sizeof(CARD16))))
+            return BadAlloc;
+        ramplen = length * 3 * sizeof(CARD16);
+
+        if (!pVidMode->GetGammaRamp(pScreen, stuff->size,
+                                 ramp, ramp + length, ramp + (length * 2))) {
+            free(ramp);
+            return BadValue;
+        }
+    }
+    rep = (xXF86VidModeGetGammaRampReply) {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence,
+        .length = (length >> 1) * 3,
+        .size = stuff->size
+    };
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+        swaps(&rep.size);
+        SwapShorts((short *) ramp, length * 3);
+    }
+    WriteToClient(client, sizeof(xXF86VidModeGetGammaRampReply), &rep);
+
+    if (stuff->size) {
+        WriteToClient(client, ramplen, ramp);
+        free(ramp);
+    }
+
+    return Success;
+}
+
+
+static int
+ProcVidModeGetGammaRampSize(ClientPtr client)
+{
+    xXF86VidModeGetGammaRampSizeReply rep;
+    ScreenPtr pScreen;
+    VidModePtr pVidMode;
+
+    REQUEST(xXF86VidModeGetGammaRampSizeReq);
+
+    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
+
+    pVidMode = VidModeGetPtr(pScreen);
+    if (pVidMode == NULL)
+        return BadImplementation;
+
+    rep = (xXF86VidModeGetGammaRampSizeReply) {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence,
+        .length = 0,
+        .size = pVidMode->GetGammaRampSize(pScreen)
+    };
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+        swaps(&rep.size);
+    }
+    WriteToClient(client, sizeof(xXF86VidModeGetGammaRampSizeReply), &rep);
+
+    return Success;
+}
+
+static int
+ProcVidModeGetPermissions(ClientPtr client)
+{
+    xXF86VidModeGetPermissionsReply rep =  {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence,
+        .length = 0,
+        .permissions = XF86VM_READ_PERMISSION
+    };
+
+    REQUEST(xXF86VidModeGetPermissionsReq);
+
+    REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
+
+    if (stuff->screen >= screenInfo.numScreens)
+        return BadValue;
+
+    if (VidModeAllowNonLocal || client->local) {
+        rep.permissions |= XF86VM_WRITE_PERMISSION;
+    }
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber);
+        swapl(&rep.length);
+        swapl(&rep.permissions);
+    }
+    WriteToClient(client, sizeof(xXF86VidModeGetPermissionsReply), &rep);
+
+    return Success;
+}
+
+static int
+ProcVidModeSetClientVersion(ClientPtr client)
+{
+    REQUEST(xXF86VidModeSetClientVersionReq);
+
+    VidModePrivPtr pPriv;
+
+    DEBUG_P("XF86VidModeSetClientVersion");
+
+    REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
+
+    if ((pPriv = VM_GETPRIV(client)) == NULL) {
+        pPriv = malloc(sizeof(VidModePrivRec));
+        if (!pPriv)
+            return BadAlloc;
+        VM_SETPRIV(client, pPriv);
+    }
+    pPriv->major = stuff->major;
+
+    pPriv->minor = stuff->minor;
+
+    return Success;
+}
+
+static int
+ProcVidModeDispatch(ClientPtr client)
+{
+    REQUEST(xReq);
+    switch (stuff->data) {
+    case X_XF86VidModeQueryVersion:
+        return ProcVidModeQueryVersion(client);
+    case X_XF86VidModeGetModeLine:
+        return ProcVidModeGetModeLine(client);
+    case X_XF86VidModeGetMonitor:
+        return ProcVidModeGetMonitor(client);
+    case X_XF86VidModeGetAllModeLines:
+        return ProcVidModeGetAllModeLines(client);
+    case X_XF86VidModeValidateModeLine:
+        return ProcVidModeValidateModeLine(client);
+    case X_XF86VidModeGetViewPort:
+        return ProcVidModeGetViewPort(client);
+    case X_XF86VidModeGetDotClocks:
+        return ProcVidModeGetDotClocks(client);
+    case X_XF86VidModeSetClientVersion:
+        return ProcVidModeSetClientVersion(client);
+    case X_XF86VidModeGetGamma:
+        return ProcVidModeGetGamma(client);
+    case X_XF86VidModeGetGammaRamp:
+        return ProcVidModeGetGammaRamp(client);
+    case X_XF86VidModeGetGammaRampSize:
+        return ProcVidModeGetGammaRampSize(client);
+    case X_XF86VidModeGetPermissions:
+        return ProcVidModeGetPermissions(client);
+    default:
+        if (VidModeAllowNonLocal || client->local) {
+            switch (stuff->data) {
+            case X_XF86VidModeAddModeLine:
+                return ProcVidModeAddModeLine(client);
+            case X_XF86VidModeDeleteModeLine:
+                return ProcVidModeDeleteModeLine(client);
+            case X_XF86VidModeModModeLine:
+                return ProcVidModeModModeLine(client);
+            case X_XF86VidModeSwitchMode:
+                return ProcVidModeSwitchMode(client);
+            case X_XF86VidModeSwitchToMode:
+                return ProcVidModeSwitchToMode(client);
+            case X_XF86VidModeLockModeSwitch:
+                return ProcVidModeLockModeSwitch(client);
+            case X_XF86VidModeSetViewPort:
+                return ProcVidModeSetViewPort(client);
+            case X_XF86VidModeSetGamma:
+                return ProcVidModeSetGamma(client);
+            case X_XF86VidModeSetGammaRamp:
+                return ProcVidModeSetGammaRamp(client);
+            default:
+                return BadRequest;
+            }
+        }
+        else
+            return VidModeErrorBase + XF86VidModeClientNotLocal;
+    }
+}
+
+static int
+SProcVidModeQueryVersion(ClientPtr client)
+{
+    REQUEST(xXF86VidModeQueryVersionReq);
+    swaps(&stuff->length);
+    return ProcVidModeQueryVersion(client);
+}
+
+static int
+SProcVidModeGetModeLine(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetModeLineReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
+    swaps(&stuff->screen);
+    return ProcVidModeGetModeLine(client);
+}
+
+static int
+SProcVidModeGetAllModeLines(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetAllModeLinesReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
+    swaps(&stuff->screen);
+    return ProcVidModeGetAllModeLines(client);
+}
+
+static int
+SProcVidModeAddModeLine(ClientPtr client)
+{
+    xXF86OldVidModeAddModeLineReq *oldstuff =
+        (xXF86OldVidModeAddModeLineReq *) client->requestBuffer;
+    int ver;
+
+    REQUEST(xXF86VidModeAddModeLineReq);
+    ver = ClientMajorVersion(client);
+    if (ver < 2) {
+        swaps(&oldstuff->length);
+        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
+        swapl(&oldstuff->screen);
+        swaps(&oldstuff->hdisplay);
+        swaps(&oldstuff->hsyncstart);
+        swaps(&oldstuff->hsyncend);
+        swaps(&oldstuff->htotal);
+        swaps(&oldstuff->vdisplay);
+        swaps(&oldstuff->vsyncstart);
+        swaps(&oldstuff->vsyncend);
+        swaps(&oldstuff->vtotal);
+        swapl(&oldstuff->flags);
+        swapl(&oldstuff->privsize);
+        SwapRestL(oldstuff);
+    }
+    else {
+        swaps(&stuff->length);
+        REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
+        swapl(&stuff->screen);
+        swaps(&stuff->hdisplay);
+        swaps(&stuff->hsyncstart);
+        swaps(&stuff->hsyncend);
+        swaps(&stuff->htotal);
+        swaps(&stuff->hskew);
+        swaps(&stuff->vdisplay);
+        swaps(&stuff->vsyncstart);
+        swaps(&stuff->vsyncend);
+        swaps(&stuff->vtotal);
+        swapl(&stuff->flags);
+        swapl(&stuff->privsize);
+        SwapRestL(stuff);
+    }
+    return ProcVidModeAddModeLine(client);
+}
+
+static int
+SProcVidModeDeleteModeLine(ClientPtr client)
+{
+    xXF86OldVidModeDeleteModeLineReq *oldstuff =
+        (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer;
+    int ver;
+
+    REQUEST(xXF86VidModeDeleteModeLineReq);
+    ver = ClientMajorVersion(client);
+    if (ver < 2) {
+        swaps(&oldstuff->length);
+        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
+        swapl(&oldstuff->screen);
+        swaps(&oldstuff->hdisplay);
+        swaps(&oldstuff->hsyncstart);
+        swaps(&oldstuff->hsyncend);
+        swaps(&oldstuff->htotal);
+        swaps(&oldstuff->vdisplay);
+        swaps(&oldstuff->vsyncstart);
+        swaps(&oldstuff->vsyncend);
+        swaps(&oldstuff->vtotal);
+        swapl(&oldstuff->flags);
+        swapl(&oldstuff->privsize);
+        SwapRestL(oldstuff);
+    }
+    else {
+        swaps(&stuff->length);
+        REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
+        swapl(&stuff->screen);
+        swaps(&stuff->hdisplay);
+        swaps(&stuff->hsyncstart);
+        swaps(&stuff->hsyncend);
+        swaps(&stuff->htotal);
+        swaps(&stuff->hskew);
+        swaps(&stuff->vdisplay);
+        swaps(&stuff->vsyncstart);
+        swaps(&stuff->vsyncend);
+        swaps(&stuff->vtotal);
+        swapl(&stuff->flags);
+        swapl(&stuff->privsize);
+        SwapRestL(stuff);
+    }
+    return ProcVidModeDeleteModeLine(client);
+}
+
+static int
+SProcVidModeModModeLine(ClientPtr client)
+{
+    xXF86OldVidModeModModeLineReq *oldstuff =
+        (xXF86OldVidModeModModeLineReq *) client->requestBuffer;
+    int ver;
+
+    REQUEST(xXF86VidModeModModeLineReq);
+    ver = ClientMajorVersion(client);
+    if (ver < 2) {
+        swaps(&oldstuff->length);
+        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
+        swapl(&oldstuff->screen);
+        swaps(&oldstuff->hdisplay);
+        swaps(&oldstuff->hsyncstart);
+        swaps(&oldstuff->hsyncend);
+        swaps(&oldstuff->htotal);
+        swaps(&oldstuff->vdisplay);
+        swaps(&oldstuff->vsyncstart);
+        swaps(&oldstuff->vsyncend);
+        swaps(&oldstuff->vtotal);
+        swapl(&oldstuff->flags);
+        swapl(&oldstuff->privsize);
+        SwapRestL(oldstuff);
+    }
+    else {
+        swaps(&stuff->length);
+        REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
+        swapl(&stuff->screen);
+        swaps(&stuff->hdisplay);
+        swaps(&stuff->hsyncstart);
+        swaps(&stuff->hsyncend);
+        swaps(&stuff->htotal);
+        swaps(&stuff->hskew);
+        swaps(&stuff->vdisplay);
+        swaps(&stuff->vsyncstart);
+        swaps(&stuff->vsyncend);
+        swaps(&stuff->vtotal);
+        swapl(&stuff->flags);
+        swapl(&stuff->privsize);
+        SwapRestL(stuff);
+    }
+    return ProcVidModeModModeLine(client);
+}
+
+static int
+SProcVidModeValidateModeLine(ClientPtr client)
+{
+    xXF86OldVidModeValidateModeLineReq *oldstuff =
+        (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer;
+    int ver;
+
+    REQUEST(xXF86VidModeValidateModeLineReq);
+    ver = ClientMajorVersion(client);
+    if (ver < 2) {
+        swaps(&oldstuff->length);
+        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
+        swapl(&oldstuff->screen);
+        swaps(&oldstuff->hdisplay);
+        swaps(&oldstuff->hsyncstart);
+        swaps(&oldstuff->hsyncend);
+        swaps(&oldstuff->htotal);
+        swaps(&oldstuff->vdisplay);
+        swaps(&oldstuff->vsyncstart);
+        swaps(&oldstuff->vsyncend);
+        swaps(&oldstuff->vtotal);
+        swapl(&oldstuff->flags);
+        swapl(&oldstuff->privsize);
+        SwapRestL(oldstuff);
+    }
+    else {
+        swaps(&stuff->length);
+        REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
+        swapl(&stuff->screen);
+        swaps(&stuff->hdisplay);
+        swaps(&stuff->hsyncstart);
+        swaps(&stuff->hsyncend);
+        swaps(&stuff->htotal);
+        swaps(&stuff->hskew);
+        swaps(&stuff->vdisplay);
+        swaps(&stuff->vsyncstart);
+        swaps(&stuff->vsyncend);
+        swaps(&stuff->vtotal);
+        swapl(&stuff->flags);
+        swapl(&stuff->privsize);
+        SwapRestL(stuff);
+    }
+    return ProcVidModeValidateModeLine(client);
+}
+
+static int
+SProcVidModeSwitchMode(ClientPtr client)
+{
+    REQUEST(xXF86VidModeSwitchModeReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
+    swaps(&stuff->screen);
+    swaps(&stuff->zoom);
+    return ProcVidModeSwitchMode(client);
+}
+
+static int
+SProcVidModeSwitchToMode(ClientPtr client)
+{
+    REQUEST(xXF86VidModeSwitchToModeReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeSwitchToModeReq);
+    swapl(&stuff->screen);
+    return ProcVidModeSwitchToMode(client);
+}
+
+static int
+SProcVidModeLockModeSwitch(ClientPtr client)
+{
+    REQUEST(xXF86VidModeLockModeSwitchReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
+    swaps(&stuff->screen);
+    swaps(&stuff->lock);
+    return ProcVidModeLockModeSwitch(client);
+}
+
+static int
+SProcVidModeGetMonitor(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetMonitorReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
+    swaps(&stuff->screen);
+    return ProcVidModeGetMonitor(client);
+}
+
+static int
+SProcVidModeGetViewPort(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetViewPortReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
+    swaps(&stuff->screen);
+    return ProcVidModeGetViewPort(client);
+}
+
+static int
+SProcVidModeSetViewPort(ClientPtr client)
+{
+    REQUEST(xXF86VidModeSetViewPortReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
+    swaps(&stuff->screen);
+    swapl(&stuff->x);
+    swapl(&stuff->y);
+    return ProcVidModeSetViewPort(client);
+}
+
+static int
+SProcVidModeGetDotClocks(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetDotClocksReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
+    swaps(&stuff->screen);
+    return ProcVidModeGetDotClocks(client);
+}
+
+static int
+SProcVidModeSetClientVersion(ClientPtr client)
+{
+    REQUEST(xXF86VidModeSetClientVersionReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
+    swaps(&stuff->major);
+    swaps(&stuff->minor);
+    return ProcVidModeSetClientVersion(client);
+}
+
+static int
+SProcVidModeSetGamma(ClientPtr client)
+{
+    REQUEST(xXF86VidModeSetGammaReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
+    swaps(&stuff->screen);
+    swapl(&stuff->red);
+    swapl(&stuff->green);
+    swapl(&stuff->blue);
+    return ProcVidModeSetGamma(client);
+}
+
+static int
+SProcVidModeGetGamma(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetGammaReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
+    swaps(&stuff->screen);
+    return ProcVidModeGetGamma(client);
+}
+
+static int
+SProcVidModeSetGammaRamp(ClientPtr client)
+{
+    int length;
+
+    REQUEST(xXF86VidModeSetGammaRampReq);
+    swaps(&stuff->length);
+    REQUEST_AT_LEAST_SIZE(xXF86VidModeSetGammaRampReq);
+    swaps(&stuff->size);
+    swaps(&stuff->screen);
+    length = ((stuff->size + 1) & ~1) * 6;
+    REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length);
+    SwapRestS(stuff);
+    return ProcVidModeSetGammaRamp(client);
+}
+
+static int
+SProcVidModeGetGammaRamp(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetGammaRampReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
+    swaps(&stuff->size);
+    swaps(&stuff->screen);
+    return ProcVidModeGetGammaRamp(client);
+}
+
+static int
+SProcVidModeGetGammaRampSize(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetGammaRampSizeReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
+    swaps(&stuff->screen);
+    return ProcVidModeGetGammaRampSize(client);
+}
+
+static int
+SProcVidModeGetPermissions(ClientPtr client)
+{
+    REQUEST(xXF86VidModeGetPermissionsReq);
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
+    swaps(&stuff->screen);
+    return ProcVidModeGetPermissions(client);
+}
+
+static int
+SProcVidModeDispatch(ClientPtr client)
+{
+    REQUEST(xReq);
+    switch (stuff->data) {
+    case X_XF86VidModeQueryVersion:
+        return SProcVidModeQueryVersion(client);
+    case X_XF86VidModeGetModeLine:
+        return SProcVidModeGetModeLine(client);
+    case X_XF86VidModeGetMonitor:
+        return SProcVidModeGetMonitor(client);
+    case X_XF86VidModeGetAllModeLines:
+        return SProcVidModeGetAllModeLines(client);
+    case X_XF86VidModeGetViewPort:
+        return SProcVidModeGetViewPort(client);
+    case X_XF86VidModeValidateModeLine:
+        return SProcVidModeValidateModeLine(client);
+    case X_XF86VidModeGetDotClocks:
+        return SProcVidModeGetDotClocks(client);
+    case X_XF86VidModeSetClientVersion:
+        return SProcVidModeSetClientVersion(client);
+    case X_XF86VidModeGetGamma:
+        return SProcVidModeGetGamma(client);
+    case X_XF86VidModeGetGammaRamp:
+        return SProcVidModeGetGammaRamp(client);
+    case X_XF86VidModeGetGammaRampSize:
+        return SProcVidModeGetGammaRampSize(client);
+    case X_XF86VidModeGetPermissions:
+        return SProcVidModeGetPermissions(client);
+    default:
+        if (VidModeAllowNonLocal || client->local) {
+            switch (stuff->data) {
+            case X_XF86VidModeAddModeLine:
+                return SProcVidModeAddModeLine(client);
+            case X_XF86VidModeDeleteModeLine:
+                return SProcVidModeDeleteModeLine(client);
+            case X_XF86VidModeModModeLine:
+                return SProcVidModeModModeLine(client);
+            case X_XF86VidModeSwitchMode:
+                return SProcVidModeSwitchMode(client);
+            case X_XF86VidModeSwitchToMode:
+                return SProcVidModeSwitchToMode(client);
+            case X_XF86VidModeLockModeSwitch:
+                return SProcVidModeLockModeSwitch(client);
+            case X_XF86VidModeSetViewPort:
+                return SProcVidModeSetViewPort(client);
+            case X_XF86VidModeSetGamma:
+                return SProcVidModeSetGamma(client);
+            case X_XF86VidModeSetGammaRamp:
+                return SProcVidModeSetGammaRamp(client);
+            default:
+                return BadRequest;
+            }
+        }
+        else
+            return VidModeErrorBase + XF86VidModeClientNotLocal;
+    }
+}
+
+void
+VidModeAddExtension(Bool allow_non_local)
+{
+    ExtensionEntry *extEntry;
+
+    DEBUG_P("VidModeAddExtension");
+
+    if (!dixRegisterPrivateKey(VidModeClientPrivateKey, PRIVATE_CLIENT, 0))
+        return;
+
+    if ((extEntry = AddExtension(XF86VIDMODENAME,
+                                 XF86VidModeNumberEvents,
+                                 XF86VidModeNumberErrors,
+                                 ProcVidModeDispatch,
+                                 SProcVidModeDispatch,
+                                 NULL, StandardMinorOpcode))) {
+        VidModeErrorBase = extEntry->errorBase;
+        VidModeAllowNonLocal = allow_non_local;
+    }
+}
+
+VidModePtr VidModeGetPtr(ScreenPtr pScreen)
+{
+    return (VidModePtr) (dixLookupPrivate(&pScreen->devPrivates, VidModePrivateKey));
+}
+
+VidModePtr VidModeInit(ScreenPtr pScreen)
+{
+    if (!dixRegisterPrivateKey(VidModePrivateKey, PRIVATE_SCREEN, sizeof(VidModeRec)))
+        return NULL;
+
+    return VidModeGetPtr(pScreen);
+}
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 64c4f74..85bd0be 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -72,7 +72,9 @@ LOCAL_LIBS = \
 	    $(DRI3_LIB) \
 	    $(top_builddir)/miext/sync/libsync.la \
             $(top_builddir)/mi/libmi.la \
-            $(top_builddir)/os/libos.la
+            $(top_builddir)/os/libos.la \
+	    $(top_builddir)/Xext/libXvidmode.la
+
 Xorg_LDADD = \
             $(LOCAL_LIBS) \
             $(XORG_SYS_LIBS) \
diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am
index 3bc0046..2eed5de 100644
--- a/hw/xfree86/common/Makefile.am
+++ b/hw/xfree86/common/Makefile.am
@@ -14,10 +14,6 @@ XVSOURCES = xf86xv.c xf86xvmc.c
 XVSDKINCS = xf86xv.h xf86xvmc.h xf86xvpriv.h
 endif
 
-if XF86VIDMODE
-XF86VMODESOURCES = xf86vmode.c
-endif
-
 if DGA
 DGASOURCES = xf86DGA.c
 DGA_SDK = dgaproc.h
diff --git a/hw/xfree86/common/vidmodeproc.h b/hw/xfree86/common/vidmodeproc.h
deleted file mode 100644
index 4410253..0000000
--- a/hw/xfree86/common/vidmodeproc.h
+++ /dev/null
@@ -1,78 +0,0 @@
-
-/* Prototypes for DGA functions that the DDX must provide */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _VIDMODEPROC_H_
-#define _VIDMODEPROC_H_
-
-typedef enum {
-    VIDMODE_H_DISPLAY,
-    VIDMODE_H_SYNCSTART,
-    VIDMODE_H_SYNCEND,
-    VIDMODE_H_TOTAL,
-    VIDMODE_H_SKEW,
-    VIDMODE_V_DISPLAY,
-    VIDMODE_V_SYNCSTART,
-    VIDMODE_V_SYNCEND,
-    VIDMODE_V_TOTAL,
-    VIDMODE_FLAGS,
-    VIDMODE_CLOCK
-} VidModeSelectMode;
-
-typedef enum {
-    VIDMODE_MON_VENDOR,
-    VIDMODE_MON_MODEL,
-    VIDMODE_MON_NHSYNC,
-    VIDMODE_MON_NVREFRESH,
-    VIDMODE_MON_HSYNC_LO,
-    VIDMODE_MON_HSYNC_HI,
-    VIDMODE_MON_VREFRESH_LO,
-    VIDMODE_MON_VREFRESH_HI
-} VidModeSelectMonitor;
-
-typedef union {
-    const void *ptr;
-    int i;
-    float f;
-} vidMonitorValue;
-
-extern Bool xf86VidModeExtensionInit(ScreenPtr pScreen);
-
-extern Bool xf86VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode,
-                                          int *dotClock);
-extern Bool xf86VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode,
-                                        int *dotClock);
-extern Bool xf86VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode,
-                                       int *dotClock);
-extern Bool xf86VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode);
-extern Bool xf86VidModeZoomViewport(ScreenPtr pScreen, int zoom);
-extern Bool xf86VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y);
-extern Bool xf86VidModeSetViewPort(ScreenPtr pScreen, int x, int y);
-extern Bool xf86VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode);
-extern Bool xf86VidModeLockZoom(ScreenPtr pScreen, Bool lock);
-extern int xf86VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock);
-extern Bool xf86VidModeGetClocks(ScreenPtr pScreen, int *Clocks);
-extern ModeStatus xf86VidModeCheckModeForMonitor(ScreenPtr pScreen,
-                                                 DisplayModePtr mode);
-extern ModeStatus xf86VidModeCheckModeForDriver(ScreenPtr pScreen,
-                                                DisplayModePtr mode);
-extern void xf86VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode);
-extern Bool xf86VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode);
-extern int xf86VidModeGetDotClock(ScreenPtr pScreen, int Clock);
-extern int xf86VidModeGetNumOfModes(ScreenPtr pScreen);
-extern Bool xf86VidModeSetGamma(ScreenPtr pScreen, float red, float green,
-                                float blue);
-extern Bool xf86VidModeGetGamma(ScreenPtr pScreen, float *red, float *green,
-                                float *blue);
-extern vidMonitorValue xf86VidModeGetMonitorValue(ScreenPtr pScreen,
-                                                  int valtyp, int indx);
-extern Bool xf86VidModeSetGammaRamp(ScreenPtr, int, CARD16 *, CARD16 *,
-                                    CARD16 *);
-extern Bool xf86VidModeGetGammaRamp(ScreenPtr, int, CARD16 *, CARD16 *,
-                                    CARD16 *);
-extern int xf86VidModeGetGammaRampSize(ScreenPtr pScreen);
-
-#endif
diff --git a/hw/xfree86/common/xf86Extensions.c b/hw/xfree86/common/xf86Extensions.c
index 25b2bc3..1b8b785 100644
--- a/hw/xfree86/common/xf86Extensions.c
+++ b/hw/xfree86/common/xf86Extensions.c
@@ -28,6 +28,7 @@
 #endif
 
 #include "extension.h"
+#include "extinit.h"
 #include "globals.h"
 
 #include "xf86.h"
@@ -47,7 +48,7 @@
 
 #ifdef XF86VIDMODE
 #include <X11/extensions/xf86vmproto.h>
-#include "vidmodeproc.h"
+#include "vidmodestr.h"
 #endif
 
 /*
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 017dcb6..de51497 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -72,6 +72,7 @@
 #include "mipointer.h"
 #include <X11/extensions/XI.h>
 #include <X11/extensions/XIproto.h>
+#include "xf86Extensions.h"
 #include "xf86DDC.h"
 #include "xf86Xinput.h"
 #include "xf86InPriv.h"
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index bddccf5..58d5a0f 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -115,15 +115,6 @@ typedef struct {
 } DPMSRec, *DPMSPtr;
 #endif
 
-#ifdef XF86VIDMODE
-/* Private info for Video Mode Extentsion */
-typedef struct {
-    DisplayModePtr First;
-    DisplayModePtr Next;
-    int Flags;
-} VidModeRec, *VidModePtr;
-#endif
-
 /* Information for root window properties. */
 typedef struct _RootWinProp {
     struct _RootWinProp *next;
diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index 5d04738..d2bdf6b 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -42,29 +42,18 @@
 #include "os.h"
 #include "xf86.h"
 #include "xf86Priv.h"
+#include "extinit.h"
 
 #ifdef XF86VIDMODE
-#include "vidmodeproc.h"
+#include "vidmodestr.h"
+#include "xf86Privstr.h"
+#include "xf86Extensions.h"
 #include "xf86cmap.h"
 
-static DevPrivateKeyRec VidModeKeyRec;
-#define VidModeKey (&VidModeKeyRec)
-
-#define VMPTR(p) ((VidModePtr)dixLookupPrivate(&(p)->devPrivates, VidModeKey))
-
-#endif
-
-#ifdef XF86VIDMODE
-
 static Bool
 xf86VidModeAvailable(ScreenPtr pScreen)
 {
-    if (pScreen == NULL) {
-        DebugF("pScreen == NULL\n");
-        return FALSE;
-    }
-
-    if (VMPTR(pScreen))
+    if (VidModeGetPtr(pScreen))
         return TRUE;
     else {
         DebugF("pVidMode == NULL\n");
@@ -72,7 +61,7 @@ xf86VidModeAvailable(ScreenPtr pScreen)
     }
 }
 
-vidMonitorValue
+static vidMonitorValue
 xf86VidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
 {
     vidMonitorValue ret = { NULL, };
@@ -114,7 +103,7 @@ xf86VidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
     return ret;
 }
 
-Bool
+static Bool
 xf86VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 {
     ScrnInfoPtr pScrn;
@@ -133,7 +122,7 @@ xf86VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotC
     return FALSE;
 }
 
-int
+static int
 xf86VidModeGetDotClock(ScreenPtr pScreen, int Clock)
 {
     ScrnInfoPtr pScrn;
@@ -148,7 +137,7 @@ xf86VidModeGetDotClock(ScreenPtr pScreen, int Clock)
         return pScrn->clock[Clock];
 }
 
-int
+static int
 xf86VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
 {
     ScrnInfoPtr pScrn;
@@ -167,7 +156,7 @@ xf86VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
     }
 }
 
-Bool
+static Bool
 xf86VidModeGetClocks(ScreenPtr pScreen, int *Clocks)
 {
     ScrnInfoPtr pScrn;
@@ -187,7 +176,7 @@ xf86VidModeGetClocks(ScreenPtr pScreen, int *Clocks)
     return TRUE;
 }
 
-Bool
+static Bool
 xf86VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 {
     VidModePtr pVidMode;
@@ -196,7 +185,7 @@ xf86VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotCloc
     if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
-    pVidMode = VMPTR(pScreen);
+    pVidMode = VidModeGetPtr(pScreen);
 
     for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
         if (p->status == MODE_OK) {
@@ -210,7 +199,7 @@ xf86VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotCloc
     return FALSE;
 }
 
-Bool
+static Bool
 xf86VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 {
     ScrnInfoPtr pScrn;
@@ -223,7 +212,7 @@ xf86VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClo
     if (pScrn->modes == NULL)
         return FALSE;
 
-    pVidMode = VMPTR(pScreen);
+    pVidMode = VidModeGetPtr(pScreen);
     pVidMode->First = pScrn->modes;
     pVidMode->Next = pVidMode->First->next;
 
@@ -236,7 +225,7 @@ xf86VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClo
     return xf86VidModeGetNextModeline(pScreen, mode, dotClock);
 }
 
-Bool
+static Bool
 xf86VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
@@ -249,7 +238,7 @@ xf86VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
     return TRUE;
 }
 
-Bool
+static Bool
 xf86VidModeZoomViewport(ScreenPtr pScreen, int zoom)
 {
     if (!xf86VidModeAvailable(pScreen))
@@ -259,7 +248,7 @@ xf86VidModeZoomViewport(ScreenPtr pScreen, int zoom)
     return TRUE;
 }
 
-Bool
+static Bool
 xf86VidModeSetViewPort(ScreenPtr pScreen, int x, int y)
 {
     ScrnInfoPtr pScrn;
@@ -280,7 +269,7 @@ xf86VidModeSetViewPort(ScreenPtr pScreen, int x, int y)
     return TRUE;
 }
 
-Bool
+static Bool
 xf86VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
 {
     ScrnInfoPtr pScrn;
@@ -294,7 +283,7 @@ xf86VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
     return TRUE;
 }
 
-Bool
+static Bool
 xf86VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
@@ -316,7 +305,7 @@ xf86VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
     return retval;
 }
 
-Bool
+static Bool
 xf86VidModeLockZoom(ScreenPtr pScreen, Bool lock)
 {
     if (!xf86VidModeAvailable(pScreen))
@@ -329,7 +318,7 @@ xf86VidModeLockZoom(ScreenPtr pScreen, Bool lock)
     return TRUE;
 }
 
-ModeStatus
+static ModeStatus
 xf86VidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
@@ -342,7 +331,7 @@ xf86VidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
     return xf86CheckModeForMonitor(mode, pScrn->monitor);
 }
 
-ModeStatus
+static ModeStatus
 xf86VidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
@@ -355,7 +344,7 @@ xf86VidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode)
     return xf86CheckModeForDriver(pScrn, mode, 0);
 }
 
-void
+static void
 xf86VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
@@ -374,7 +363,7 @@ xf86VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode)
     return;
 }
 
-Bool
+static Bool
 xf86VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
@@ -395,7 +384,7 @@ xf86VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
     return TRUE;
 }
 
-int
+static int
 xf86VidModeGetNumOfModes(ScreenPtr pScreen)
 {
     DisplayModePtr mode = NULL;
@@ -411,7 +400,7 @@ xf86VidModeGetNumOfModes(ScreenPtr pScreen)
     } while (TRUE);
 }
 
-Bool
+static Bool
 xf86VidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue)
 {
     Gamma gamma;
@@ -428,7 +417,7 @@ xf86VidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue)
         return TRUE;
 }
 
-Bool
+static Bool
 xf86VidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
 {
     ScrnInfoPtr pScrn;
@@ -443,7 +432,7 @@ xf86VidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
     return TRUE;
 }
 
-Bool
+static Bool
 xf86VidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
 {
     if (!xf86VidModeAvailable(pScreen))
@@ -453,7 +442,7 @@ xf86VidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD1
     return TRUE;
 }
 
-Bool
+static Bool
 xf86VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
 {
     if (!xf86VidModeAvailable(pScreen))
@@ -463,7 +452,7 @@ xf86VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD1
     return TRUE;
 }
 
-int
+static int
 xf86VidModeGetGammaRampSize(ScreenPtr pScreen)
 {
     if (!xf86VidModeAvailable(pScreen))
@@ -472,12 +461,9 @@ xf86VidModeGetGammaRampSize(ScreenPtr pScreen)
     return xf86GetGammaRampSize(pScreen);
 }
 
-#endif                          /* XF86VIDMODE */
-
-Bool
-xf86VidModeExtensionInit(ScreenPtr pScreen)
+static Bool
+xf86VidModeInit(ScreenPtr pScreen)
 {
-#ifdef XF86VIDMODE
     VidModePtr pVidMode;
 
     if (!xf86GetVidModeEnabled()) {
@@ -485,18 +471,61 @@ xf86VidModeExtensionInit(ScreenPtr pScreen)
         return FALSE;
     }
 
-    if (!dixRegisterPrivateKey(&VidModeKeyRec, PRIVATE_SCREEN, sizeof(VidModeRec)))
+    pVidMode = VidModeInit(pScreen);
+    if (!pVidMode)
         return FALSE;
 
-    pVidMode = VMPTR(pScreen);
-
     pVidMode->Flags = 0;
     pVidMode->Next = NULL;
 
+    pVidMode->GetMonitorValue = xf86VidModeGetMonitorValue;
+    pVidMode->GetCurrentModeline = xf86VidModeGetCurrentModeline;
+    pVidMode->GetFirstModeline = xf86VidModeGetFirstModeline;
+    pVidMode->GetNextModeline = xf86VidModeGetNextModeline;
+    pVidMode->DeleteModeline = xf86VidModeDeleteModeline;
+    pVidMode->ZoomViewport = xf86VidModeZoomViewport;
+    pVidMode->GetViewPort = xf86VidModeGetViewPort;
+    pVidMode->SetViewPort = xf86VidModeSetViewPort;
+    pVidMode->SwitchMode = xf86VidModeSwitchMode;
+    pVidMode->LockZoom = xf86VidModeLockZoom;
+    pVidMode->GetNumOfClocks = xf86VidModeGetNumOfClocks;
+    pVidMode->GetClocks = xf86VidModeGetClocks;
+    pVidMode->CheckModeForMonitor = xf86VidModeCheckModeForMonitor;
+    pVidMode->CheckModeForDriver = xf86VidModeCheckModeForDriver;
+    pVidMode->SetCrtcForMode = xf86VidModeSetCrtcForMode;
+    pVidMode->AddModeline = xf86VidModeAddModeline;
+    pVidMode->GetDotClock = xf86VidModeGetDotClock;
+    pVidMode->GetNumOfModes = xf86VidModeGetNumOfModes;
+    pVidMode->SetGamma = xf86VidModeSetGamma;
+    pVidMode->GetGamma = xf86VidModeGetGamma;
+    pVidMode->SetGammaRamp = xf86VidModeSetGammaRamp;
+    pVidMode->GetGammaRamp = xf86VidModeGetGammaRamp;
+    pVidMode->GetGammaRampSize = xf86VidModeGetGammaRampSize;
+
     return TRUE;
-#else
-    DebugF("no vidmode extension\n");
-    return FALSE;
-#endif
 }
 
+void
+XFree86VidModeExtensionInit(void)
+{
+    int i;
+    Bool enabled = FALSE;
+
+    DebugF("XFree86VidModeExtensionInit");
+
+    /* This means that the DDX doesn't want the vidmode extension enabled */
+    if (!xf86GetVidModeEnabled())
+        return;
+
+    for (i = 0; i < screenInfo.numScreens; i++) {
+        if (xf86VidModeInit (screenInfo.screens[i]))
+            enabled = TRUE;
+    }
+    /* This means that the DDX doesn't want the vidmode extension enabled */
+    if (!enabled)
+        return;
+
+   VidModeAddExtension(xf86GetVidModeAllowNonLocal());
+}
+
+#endif                          /* XF86VIDMODE */
diff --git a/hw/xfree86/common/xf86vmode.c b/hw/xfree86/common/xf86vmode.c
deleted file mode 100644
index 0ad1b8d..0000000
--- a/hw/xfree86/common/xf86vmode.c
+++ /dev/null
@@ -1,2093 +0,0 @@
-
-/*
-
-Copyright 1995  Kaleb S. KEITHLEY
-
-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 Kaleb S. KEITHLEY 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 Kaleb S. KEITHLEY
-shall not be used in advertising or otherwise to promote the sale, use
-or other dealings in this Software without prior written authorization
-from Kaleb S. KEITHLEY
-
-*/
-/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "xf86Extensions.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-#include <X11/extensions/xf86vmproto.h>
-#include "swaprep.h"
-#include "xf86.h"
-#include "vidmodeproc.h"
-#include "globals.h"
-#include "protocol-versions.h"
-
-#define DEFAULT_XF86VIDMODE_VERBOSITY	3
-
-static int VidModeErrorBase;
-static DevPrivateKeyRec VidModeClientPrivateKeyRec;
-
-#define VidModeClientPrivateKey (&VidModeClientPrivateKeyRec)
-
-/* This holds the client's version information */
-typedef struct {
-    int major;
-    int minor;
-} VidModePrivRec, *VidModePrivPtr;
-
-#define VM_GETPRIV(c) ((VidModePrivPtr) \
-    dixLookupPrivate(&(c)->devPrivates, VidModeClientPrivateKey))
-#define VM_SETPRIV(c,p) \
-    dixSetPrivate(&(c)->devPrivates, VidModeClientPrivateKey, p)
-
-#if 0
-static unsigned char XF86VidModeReqCode = 0;
-#endif
-
-#ifdef DEBUG
-#define DEBUG_P(x) ErrorF(x"\n");
-#else
-#define DEBUG_P(x) /**/
-#endif
-
-static DisplayModePtr
-VidModeCreateMode(void)
-{
-    DisplayModePtr mode;
-
-    mode = malloc(sizeof(DisplayModeRec));
-    if (mode != NULL) {
-        mode->name = "";
-        mode->VScan = 1;        /* divides refresh rate. default = 1 */
-        mode->Private = NULL;
-        mode->next = mode;
-        mode->prev = mode;
-    }
-    return mode;
-}
-
-static void
-VidModeCopyMode(DisplayModePtr modefrom, DisplayModePtr modeto)
-{
-    memcpy(modeto, modefrom, sizeof(DisplayModeRec));
-}
-
-static int
-VidModeGetModeValue(DisplayModePtr mode, int valtyp)
-{
-    int ret = 0;
-
-    switch (valtyp) {
-    case VIDMODE_H_DISPLAY:
-        ret = mode->HDisplay;
-        break;
-    case VIDMODE_H_SYNCSTART:
-        ret = mode->HSyncStart;
-        break;
-    case VIDMODE_H_SYNCEND:
-        ret = mode->HSyncEnd;
-        break;
-    case VIDMODE_H_TOTAL:
-        ret = mode->HTotal;
-        break;
-    case VIDMODE_H_SKEW:
-        ret = mode->HSkew;
-        break;
-    case VIDMODE_V_DISPLAY:
-        ret = mode->VDisplay;
-        break;
-    case VIDMODE_V_SYNCSTART:
-        ret = mode->VSyncStart;
-        break;
-    case VIDMODE_V_SYNCEND:
-        ret = mode->VSyncEnd;
-        break;
-    case VIDMODE_V_TOTAL:
-        ret = mode->VTotal;
-        break;
-    case VIDMODE_FLAGS:
-        ret = mode->Flags;
-        break;
-    case VIDMODE_CLOCK:
-        ret = mode->Clock;
-        break;
-    }
-    return ret;
-}
-
-static void
-VidModeSetModeValue(DisplayModePtr mode, int valtyp, int val)
-{
-    switch (valtyp) {
-    case VIDMODE_H_DISPLAY:
-        mode->HDisplay = val;
-        break;
-    case VIDMODE_H_SYNCSTART:
-        mode->HSyncStart = val;
-        break;
-    case VIDMODE_H_SYNCEND:
-        mode->HSyncEnd = val;
-        break;
-    case VIDMODE_H_TOTAL:
-        mode->HTotal = val;
-        break;
-    case VIDMODE_H_SKEW:
-        mode->HSkew = val;
-        break;
-    case VIDMODE_V_DISPLAY:
-        mode->VDisplay = val;
-        break;
-    case VIDMODE_V_SYNCSTART:
-        mode->VSyncStart = val;
-        break;
-    case VIDMODE_V_SYNCEND:
-        mode->VSyncEnd = val;
-        break;
-    case VIDMODE_V_TOTAL:
-        mode->VTotal = val;
-        break;
-    case VIDMODE_FLAGS:
-        mode->Flags = val;
-        break;
-    case VIDMODE_CLOCK:
-        mode->Clock = val;
-        break;
-    }
-    return;
-}
-
-static int
-ClientMajorVersion(ClientPtr client)
-{
-    VidModePrivPtr pPriv;
-
-    pPriv = VM_GETPRIV(client);
-    if (!pPriv)
-        return 0;
-    else
-        return pPriv->major;
-}
-
-static int
-ProcXF86VidModeQueryVersion(ClientPtr client)
-{
-    xXF86VidModeQueryVersionReply rep = {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .majorVersion = SERVER_XF86VIDMODE_MAJOR_VERSION,
-        .minorVersion = SERVER_XF86VIDMODE_MINOR_VERSION
-    };
-
-    DEBUG_P("XF86VidModeQueryVersion");
-
-    REQUEST_SIZE_MATCH(xXF86VidModeQueryVersionReq);
-
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-        swaps(&rep.majorVersion);
-        swaps(&rep.minorVersion);
-    }
-    WriteToClient(client, sizeof(xXF86VidModeQueryVersionReply), &rep);
-    return Success;
-}
-
-static int
-ProcXF86VidModeGetModeLine(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetModeLineReq);
-    xXF86VidModeGetModeLineReply rep = {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence
-    };
-    ScreenPtr pScreen;
-    DisplayModePtr mode;
-    int dotClock;
-    int ver;
-
-    DEBUG_P("XF86VidModeGetModeline");
-
-    ver = ClientMajorVersion(client);
-    REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
-
-    if (ver < 2) {
-        rep.length = bytes_to_int32(SIZEOF(xXF86OldVidModeGetModeLineReply) -
-                                    SIZEOF(xGenericReply));
-    }
-    else {
-        rep.length = bytes_to_int32(SIZEOF(xXF86VidModeGetModeLineReply) -
-                                    SIZEOF(xGenericReply));
-    }
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    if (!xf86VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
-        return BadValue;
-
-    rep.dotclock = dotClock;
-    rep.hdisplay = VidModeGetModeValue(mode, VIDMODE_H_DISPLAY);
-    rep.hsyncstart = VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART);
-    rep.hsyncend = VidModeGetModeValue(mode, VIDMODE_H_SYNCEND);
-    rep.htotal = VidModeGetModeValue(mode, VIDMODE_H_TOTAL);
-    rep.hskew = VidModeGetModeValue(mode, VIDMODE_H_SKEW);
-    rep.vdisplay = VidModeGetModeValue(mode, VIDMODE_V_DISPLAY);
-    rep.vsyncstart = VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART);
-    rep.vsyncend = VidModeGetModeValue(mode, VIDMODE_V_SYNCEND);
-    rep.vtotal = VidModeGetModeValue(mode, VIDMODE_V_TOTAL);
-    rep.flags = VidModeGetModeValue(mode, VIDMODE_FLAGS);
-
-    if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
-        ErrorF("GetModeLine - scrn: %d clock: %ld\n",
-               stuff->screen, (unsigned long) rep.dotclock);
-        ErrorF("GetModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
-               rep.hdisplay, rep.hsyncstart, rep.hsyncend, rep.htotal);
-        ErrorF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
-               rep.vdisplay, rep.vsyncstart, rep.vsyncend,
-               rep.vtotal, (unsigned long) rep.flags);
-    }
-
-    /*
-     * Older servers sometimes had server privates that the VidMode
-     * extention made available. So to be compatiable pretend that
-     * there are no server privates to pass to the client
-     */
-    rep.privsize = 0;
-
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-        swapl(&rep.dotclock);
-        swaps(&rep.hdisplay);
-        swaps(&rep.hsyncstart);
-        swaps(&rep.hsyncend);
-        swaps(&rep.htotal);
-        swaps(&rep.hskew);
-        swaps(&rep.vdisplay);
-        swaps(&rep.vsyncstart);
-        swaps(&rep.vsyncend);
-        swaps(&rep.vtotal);
-        swapl(&rep.flags);
-        swapl(&rep.privsize);
-    }
-    if (ver < 2) {
-        xXF86OldVidModeGetModeLineReply oldrep = {
-            .type = rep.type,
-            .sequenceNumber = rep.sequenceNumber,
-            .length = rep.length,
-            .dotclock = rep.dotclock,
-            .hdisplay = rep.hdisplay,
-            .hsyncstart = rep.hsyncstart,
-            .hsyncend = rep.hsyncend,
-            .htotal = rep.htotal,
-            .vdisplay = rep.vdisplay,
-            .vsyncstart = rep.vsyncstart,
-            .vsyncend = rep.vsyncend,
-            .vtotal = rep.vtotal,
-            .flags = rep.flags,
-            .privsize = rep.privsize
-        };
-        WriteToClient(client, sizeof(xXF86OldVidModeGetModeLineReply), &oldrep);
-    }
-    else {
-        WriteToClient(client, sizeof(xXF86VidModeGetModeLineReply), &rep);
-    }
-    return Success;
-}
-
-static int
-ProcXF86VidModeGetAllModeLines(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetAllModeLinesReq);
-    xXF86VidModeGetAllModeLinesReply rep;
-    ScreenPtr pScreen;
-    DisplayModePtr mode;
-    int modecount, dotClock;
-    int ver;
-
-    DEBUG_P("XF86VidModeGetAllModelines");
-
-    REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-    ver = ClientMajorVersion(client);
-
-    modecount = xf86VidModeGetNumOfModes(pScreen);
-    if (modecount < 1)
-        return VidModeErrorBase + XF86VidModeExtensionDisabled;
-
-    if (!xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock))
-        return BadValue;
-
-    rep = (xXF86VidModeGetAllModeLinesReply) {
-        .type = X_Reply,
-        .length = SIZEOF(xXF86VidModeGetAllModeLinesReply) -
-            SIZEOF(xGenericReply),
-        .sequenceNumber = client->sequence,
-        .modecount = modecount
-    };
-    if (ver < 2)
-        rep.length += modecount * sizeof(xXF86OldVidModeModeInfo);
-    else
-        rep.length += modecount * sizeof(xXF86VidModeModeInfo);
-    rep.length >>= 2;
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-        swapl(&rep.modecount);
-    }
-    WriteToClient(client, sizeof(xXF86VidModeGetAllModeLinesReply), &rep);
-
-    do {
-        xXF86VidModeModeInfo mdinf = {
-            .dotclock = dotClock,
-            .hdisplay = VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
-            .hsyncstart = VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
-            .hsyncend = VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
-            .htotal = VidModeGetModeValue(mode, VIDMODE_H_TOTAL),
-            .hskew = VidModeGetModeValue(mode, VIDMODE_H_SKEW),
-            .vdisplay = VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
-            .vsyncstart = VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
-            .vsyncend = VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
-            .vtotal = VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
-            .flags = VidModeGetModeValue(mode, VIDMODE_FLAGS),
-            .privsize = 0
-        };
-        if (client->swapped) {
-            swapl(&mdinf.dotclock);
-            swaps(&mdinf.hdisplay);
-            swaps(&mdinf.hsyncstart);
-            swaps(&mdinf.hsyncend);
-            swaps(&mdinf.htotal);
-            swapl(&mdinf.hskew);
-            swaps(&mdinf.vdisplay);
-            swaps(&mdinf.vsyncstart);
-            swaps(&mdinf.vsyncend);
-            swaps(&mdinf.vtotal);
-            swapl(&mdinf.flags);
-            swapl(&mdinf.privsize);
-        }
-        if (ver < 2) {
-            xXF86OldVidModeModeInfo oldmdinf = {
-                .dotclock = mdinf.dotclock,
-                .hdisplay = mdinf.hdisplay,
-                .hsyncstart = mdinf.hsyncstart,
-                .hsyncend = mdinf.hsyncend,
-                .htotal = mdinf.htotal,
-                .vdisplay = mdinf.vdisplay,
-                .vsyncstart = mdinf.vsyncstart,
-                .vsyncend = mdinf.vsyncend,
-                .vtotal = mdinf.vtotal,
-                .flags = mdinf.flags,
-                .privsize = mdinf.privsize
-            };
-            WriteToClient(client, sizeof(xXF86OldVidModeModeInfo), &oldmdinf);
-        }
-        else {
-            WriteToClient(client, sizeof(xXF86VidModeModeInfo), &mdinf);
-        }
-
-    } while (xf86VidModeGetNextModeline(pScreen, &mode, &dotClock));
-
-    return Success;
-}
-
-#define MODEMATCH(mode,stuff)	  \
-     (VidModeGetModeValue(mode, VIDMODE_H_DISPLAY)  == stuff->hdisplay \
-     && VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART)  == stuff->hsyncstart \
-     && VidModeGetModeValue(mode, VIDMODE_H_SYNCEND)  == stuff->hsyncend \
-     && VidModeGetModeValue(mode, VIDMODE_H_TOTAL)  == stuff->htotal \
-     && VidModeGetModeValue(mode, VIDMODE_V_DISPLAY)  == stuff->vdisplay \
-     && VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART)  == stuff->vsyncstart \
-     && VidModeGetModeValue(mode, VIDMODE_V_SYNCEND)  == stuff->vsyncend \
-     && VidModeGetModeValue(mode, VIDMODE_V_TOTAL)  == stuff->vtotal \
-     && VidModeGetModeValue(mode, VIDMODE_FLAGS)  == stuff->flags )
-
-static int
-ProcXF86VidModeAddModeLine(ClientPtr client)
-{
-    REQUEST(xXF86VidModeAddModeLineReq);
-    xXF86OldVidModeAddModeLineReq *oldstuff =
-        (xXF86OldVidModeAddModeLineReq *) client->requestBuffer;
-    xXF86VidModeAddModeLineReq newstuff;
-    ScreenPtr pScreen;
-    DisplayModePtr mode;
-    int len;
-    int dotClock;
-    int ver;
-
-    DEBUG_P("XF86VidModeAddModeline");
-
-    ver = ClientMajorVersion(client);
-    if (ver < 2) {
-        /* convert from old format */
-        stuff = &newstuff;
-        stuff->length = oldstuff->length;
-        stuff->screen = oldstuff->screen;
-        stuff->dotclock = oldstuff->dotclock;
-        stuff->hdisplay = oldstuff->hdisplay;
-        stuff->hsyncstart = oldstuff->hsyncstart;
-        stuff->hsyncend = oldstuff->hsyncend;
-        stuff->htotal = oldstuff->htotal;
-        stuff->hskew = 0;
-        stuff->vdisplay = oldstuff->vdisplay;
-        stuff->vsyncstart = oldstuff->vsyncstart;
-        stuff->vsyncend = oldstuff->vsyncend;
-        stuff->vtotal = oldstuff->vtotal;
-        stuff->flags = oldstuff->flags;
-        stuff->privsize = oldstuff->privsize;
-        stuff->after_dotclock = oldstuff->after_dotclock;
-        stuff->after_hdisplay = oldstuff->after_hdisplay;
-        stuff->after_hsyncstart = oldstuff->after_hsyncstart;
-        stuff->after_hsyncend = oldstuff->after_hsyncend;
-        stuff->after_htotal = oldstuff->after_htotal;
-        stuff->after_hskew = 0;
-        stuff->after_vdisplay = oldstuff->after_vdisplay;
-        stuff->after_vsyncstart = oldstuff->after_vsyncstart;
-        stuff->after_vsyncend = oldstuff->after_vsyncend;
-        stuff->after_vtotal = oldstuff->after_vtotal;
-        stuff->after_flags = oldstuff->after_flags;
-    }
-    if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
-        ErrorF("AddModeLine - scrn: %d clock: %ld\n",
-               (int) stuff->screen, (unsigned long) stuff->dotclock);
-        ErrorF("AddModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
-               stuff->hdisplay, stuff->hsyncstart,
-               stuff->hsyncend, stuff->htotal);
-        ErrorF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
-               stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
-               stuff->vtotal, (unsigned long) stuff->flags);
-        ErrorF("      after - scrn: %d clock: %ld\n",
-               (int) stuff->screen, (unsigned long) stuff->after_dotclock);
-        ErrorF("              hdsp: %d hbeg: %d hend: %d httl: %d\n",
-               stuff->after_hdisplay, stuff->after_hsyncstart,
-               stuff->after_hsyncend, stuff->after_htotal);
-        ErrorF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
-               stuff->after_vdisplay, stuff->after_vsyncstart,
-               stuff->after_vsyncend, stuff->after_vtotal,
-               (unsigned long) stuff->after_flags);
-    }
-
-    if (ver < 2) {
-        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
-        len =
-            client->req_len -
-            bytes_to_int32(sizeof(xXF86OldVidModeAddModeLineReq));
-    }
-    else {
-        REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
-        len =
-            client->req_len -
-            bytes_to_int32(sizeof(xXF86VidModeAddModeLineReq));
-    }
-    if (len != stuff->privsize)
-        return BadLength;
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    if (stuff->hsyncstart < stuff->hdisplay ||
-        stuff->hsyncend < stuff->hsyncstart ||
-        stuff->htotal < stuff->hsyncend ||
-        stuff->vsyncstart < stuff->vdisplay ||
-        stuff->vsyncend < stuff->vsyncstart || stuff->vtotal < stuff->vsyncend)
-        return BadValue;
-
-    if (stuff->after_hsyncstart < stuff->after_hdisplay ||
-        stuff->after_hsyncend < stuff->after_hsyncstart ||
-        stuff->after_htotal < stuff->after_hsyncend ||
-        stuff->after_vsyncstart < stuff->after_vdisplay ||
-        stuff->after_vsyncend < stuff->after_vsyncstart ||
-        stuff->after_vtotal < stuff->after_vsyncend)
-        return BadValue;
-
-    if (stuff->after_htotal != 0 || stuff->after_vtotal != 0) {
-        Bool found = FALSE;
-
-        if (xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock)) {
-            do {
-                if ((xf86VidModeGetDotClock(pScreen, stuff->dotclock)
-                     == dotClock) && MODEMATCH(mode, stuff)) {
-                    found = TRUE;
-                    break;
-                }
-            } while (xf86VidModeGetNextModeline(pScreen, &mode, &dotClock));
-        }
-        if (!found)
-            return BadValue;
-    }
-
-    mode = VidModeCreateMode();
-    if (mode == NULL)
-        return BadValue;
-
-    VidModeSetModeValue(mode, VIDMODE_CLOCK, stuff->dotclock);
-    VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
-    VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
-    VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
-    VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
-    VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
-    VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
-    VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
-    VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
-    VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
-    VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
-
-    if (stuff->privsize)
-        ErrorF("AddModeLine - Privates in request have been ignored\n");
-
-    /* Check that the mode is consistent with the monitor specs */
-    switch (xf86VidModeCheckModeForMonitor(pScreen, mode)) {
-    case MODE_OK:
-        break;
-    case MODE_HSYNC:
-    case MODE_H_ILLEGAL:
-        free(mode);
-        return VidModeErrorBase + XF86VidModeBadHTimings;
-    case MODE_VSYNC:
-    case MODE_V_ILLEGAL:
-        free(mode);
-        return VidModeErrorBase + XF86VidModeBadVTimings;
-    default:
-        free(mode);
-        return VidModeErrorBase + XF86VidModeModeUnsuitable;
-    }
-
-    /* Check that the driver is happy with the mode */
-    if (xf86VidModeCheckModeForDriver(pScreen, mode) != MODE_OK) {
-        free(mode);
-        return VidModeErrorBase + XF86VidModeModeUnsuitable;
-    }
-
-    xf86VidModeSetCrtcForMode(pScreen, mode);
-
-    xf86VidModeAddModeline(pScreen, mode);
-
-    if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
-        ErrorF("AddModeLine - Succeeded\n");
-    return Success;
-}
-
-static int
-ProcXF86VidModeDeleteModeLine(ClientPtr client)
-{
-    REQUEST(xXF86VidModeDeleteModeLineReq);
-    xXF86OldVidModeDeleteModeLineReq *oldstuff =
-        (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer;
-    xXF86VidModeDeleteModeLineReq newstuff;
-    ScreenPtr pScreen;
-    DisplayModePtr mode;
-    int len, dotClock;
-    int ver;
-
-    DEBUG_P("XF86VidModeDeleteModeline");
-
-    ver = ClientMajorVersion(client);
-    if (ver < 2) {
-        /* convert from old format */
-        stuff = &newstuff;
-        stuff->length = oldstuff->length;
-        stuff->screen = oldstuff->screen;
-        stuff->dotclock = oldstuff->dotclock;
-        stuff->hdisplay = oldstuff->hdisplay;
-        stuff->hsyncstart = oldstuff->hsyncstart;
-        stuff->hsyncend = oldstuff->hsyncend;
-        stuff->htotal = oldstuff->htotal;
-        stuff->hskew = 0;
-        stuff->vdisplay = oldstuff->vdisplay;
-        stuff->vsyncstart = oldstuff->vsyncstart;
-        stuff->vsyncend = oldstuff->vsyncend;
-        stuff->vtotal = oldstuff->vtotal;
-        stuff->flags = oldstuff->flags;
-        stuff->privsize = oldstuff->privsize;
-    }
-    if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
-        ErrorF("DeleteModeLine - scrn: %d clock: %ld\n",
-               (int) stuff->screen, (unsigned long) stuff->dotclock);
-        ErrorF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
-               stuff->hdisplay, stuff->hsyncstart,
-               stuff->hsyncend, stuff->htotal);
-        ErrorF
-            ("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
-             stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
-             (unsigned long) stuff->flags);
-    }
-
-    if (ver < 2) {
-        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
-        len =
-            client->req_len -
-            bytes_to_int32(sizeof(xXF86OldVidModeDeleteModeLineReq));
-    }
-    else {
-        REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
-        len =
-            client->req_len -
-            bytes_to_int32(sizeof(xXF86VidModeDeleteModeLineReq));
-    }
-    if (len != stuff->privsize) {
-        if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
-            ErrorF("req_len = %ld, sizeof(Req) = %d, privsize = %ld, "
-                   "len = %d, length = %d\n",
-                   (unsigned long) client->req_len,
-                   (int) sizeof(xXF86VidModeDeleteModeLineReq) >> 2,
-                   (unsigned long) stuff->privsize, len, stuff->length);
-        }
-        return BadLength;
-    }
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    if (!xf86VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
-        return BadValue;
-
-    if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
-        ErrorF("Checking against clock: %d (%d)\n",
-               VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
-        ErrorF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
-               VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
-               VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
-               VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
-               VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
-        ErrorF
-            ("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
-             VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
-             VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
-             VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
-             VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
-             VidModeGetModeValue(mode, VIDMODE_FLAGS));
-    }
-    if ((xf86VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
-        MODEMATCH(mode, stuff))
-        return BadValue;
-
-    if (!xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock))
-        return BadValue;
-
-    do {
-        if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
-            ErrorF("Checking against clock: %d (%d)\n",
-                   VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
-            ErrorF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
-                   VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
-                   VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
-                   VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
-                   VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
-            ErrorF
-                ("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
-                 VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
-                 VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
-                 VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
-                 VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
-                 VidModeGetModeValue(mode, VIDMODE_FLAGS));
-        }
-        if ((xf86VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
-            MODEMATCH(mode, stuff)) {
-            xf86VidModeDeleteModeline(pScreen, mode);
-            if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
-                ErrorF("DeleteModeLine - Succeeded\n");
-            return Success;
-        }
-    } while (xf86VidModeGetNextModeline(pScreen, &mode, &dotClock));
-
-    return BadValue;
-}
-
-static int
-ProcXF86VidModeModModeLine(ClientPtr client)
-{
-    REQUEST(xXF86VidModeModModeLineReq);
-    xXF86OldVidModeModModeLineReq *oldstuff =
-        (xXF86OldVidModeModModeLineReq *) client->requestBuffer;
-    xXF86VidModeModModeLineReq newstuff;
-    ScreenPtr pScreen;
-    DisplayModePtr mode, modetmp;
-    int len, dotClock;
-    int ver;
-
-    DEBUG_P("XF86VidModeModModeline");
-
-    ver = ClientMajorVersion(client);
-    if (ver < 2) {
-        /* convert from old format */
-        stuff = &newstuff;
-        stuff->length = oldstuff->length;
-        stuff->screen = oldstuff->screen;
-        stuff->hdisplay = oldstuff->hdisplay;
-        stuff->hsyncstart = oldstuff->hsyncstart;
-        stuff->hsyncend = oldstuff->hsyncend;
-        stuff->htotal = oldstuff->htotal;
-        stuff->hskew = 0;
-        stuff->vdisplay = oldstuff->vdisplay;
-        stuff->vsyncstart = oldstuff->vsyncstart;
-        stuff->vsyncend = oldstuff->vsyncend;
-        stuff->vtotal = oldstuff->vtotal;
-        stuff->flags = oldstuff->flags;
-        stuff->privsize = oldstuff->privsize;
-    }
-    if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
-        ErrorF("ModModeLine - scrn: %d hdsp: %d hbeg: %d hend: %d httl: %d\n",
-               (int) stuff->screen, stuff->hdisplay, stuff->hsyncstart,
-               stuff->hsyncend, stuff->htotal);
-        ErrorF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
-               stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
-               stuff->vtotal, (unsigned long) stuff->flags);
-    }
-
-    if (ver < 2) {
-        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
-        len =
-            client->req_len -
-            bytes_to_int32(sizeof(xXF86OldVidModeModModeLineReq));
-    }
-    else {
-        REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
-        len =
-            client->req_len -
-            bytes_to_int32(sizeof(xXF86VidModeModModeLineReq));
-    }
-    if (len != stuff->privsize)
-        return BadLength;
-
-    if (stuff->hsyncstart < stuff->hdisplay ||
-        stuff->hsyncend < stuff->hsyncstart ||
-        stuff->htotal < stuff->hsyncend ||
-        stuff->vsyncstart < stuff->vdisplay ||
-        stuff->vsyncend < stuff->vsyncstart || stuff->vtotal < stuff->vsyncend)
-        return BadValue;
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    if (!xf86VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
-        return BadValue;
-
-    modetmp = VidModeCreateMode();
-    VidModeCopyMode(mode, modetmp);
-
-    VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
-    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
-    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
-    VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
-    VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
-    VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
-    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
-    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
-    VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
-    VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
-
-    if (stuff->privsize)
-        ErrorF("ModModeLine - Privates in request have been ignored\n");
-
-    /* Check that the mode is consistent with the monitor specs */
-    switch (xf86VidModeCheckModeForMonitor(pScreen, modetmp)) {
-    case MODE_OK:
-        break;
-    case MODE_HSYNC:
-    case MODE_H_ILLEGAL:
-        free(modetmp);
-        return VidModeErrorBase + XF86VidModeBadHTimings;
-    case MODE_VSYNC:
-    case MODE_V_ILLEGAL:
-        free(modetmp);
-        return VidModeErrorBase + XF86VidModeBadVTimings;
-    default:
-        free(modetmp);
-        return VidModeErrorBase + XF86VidModeModeUnsuitable;
-    }
-
-    /* Check that the driver is happy with the mode */
-    if (xf86VidModeCheckModeForDriver(pScreen, modetmp) != MODE_OK) {
-        free(modetmp);
-        return VidModeErrorBase + XF86VidModeModeUnsuitable;
-    }
-    free(modetmp);
-
-    VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
-    VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
-    VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
-    VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
-    VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
-    VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
-    VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
-    VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
-    VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
-    VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
-
-    xf86VidModeSetCrtcForMode(pScreen, mode);
-    xf86VidModeSwitchMode(pScreen, mode);
-
-    if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
-        ErrorF("ModModeLine - Succeeded\n");
-    return Success;
-}
-
-static int
-ProcXF86VidModeValidateModeLine(ClientPtr client)
-{
-    REQUEST(xXF86VidModeValidateModeLineReq);
-    xXF86OldVidModeValidateModeLineReq *oldstuff =
-        (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer;
-    xXF86VidModeValidateModeLineReq newstuff;
-    xXF86VidModeValidateModeLineReply rep;
-    ScreenPtr pScreen;
-    DisplayModePtr mode, modetmp = NULL;
-    int len, status, dotClock;
-    int ver;
-
-    DEBUG_P("XF86VidModeValidateModeline");
-
-    ver = ClientMajorVersion(client);
-    if (ver < 2) {
-        /* convert from old format */
-        stuff = &newstuff;
-        stuff->length = oldstuff->length;
-        stuff->screen = oldstuff->screen;
-        stuff->dotclock = oldstuff->dotclock;
-        stuff->hdisplay = oldstuff->hdisplay;
-        stuff->hsyncstart = oldstuff->hsyncstart;
-        stuff->hsyncend = oldstuff->hsyncend;
-        stuff->htotal = oldstuff->htotal;
-        stuff->hskew = 0;
-        stuff->vdisplay = oldstuff->vdisplay;
-        stuff->vsyncstart = oldstuff->vsyncstart;
-        stuff->vsyncend = oldstuff->vsyncend;
-        stuff->vtotal = oldstuff->vtotal;
-        stuff->flags = oldstuff->flags;
-        stuff->privsize = oldstuff->privsize;
-    }
-    if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
-        ErrorF("ValidateModeLine - scrn: %d clock: %ld\n",
-               (int) stuff->screen, (unsigned long) stuff->dotclock);
-        ErrorF("                   hdsp: %d hbeg: %d hend: %d httl: %d\n",
-               stuff->hdisplay, stuff->hsyncstart,
-               stuff->hsyncend, stuff->htotal);
-        ErrorF
-            ("                   vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
-             stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
-             (unsigned long) stuff->flags);
-    }
-
-    if (ver < 2) {
-        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
-        len = client->req_len -
-            bytes_to_int32(sizeof(xXF86OldVidModeValidateModeLineReq));
-    }
-    else {
-        REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
-        len =
-            client->req_len -
-            bytes_to_int32(sizeof(xXF86VidModeValidateModeLineReq));
-    }
-    if (len != stuff->privsize)
-        return BadLength;
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    status = MODE_OK;
-
-    if (stuff->hsyncstart < stuff->hdisplay ||
-        stuff->hsyncend < stuff->hsyncstart ||
-        stuff->htotal < stuff->hsyncend ||
-        stuff->vsyncstart < stuff->vdisplay ||
-        stuff->vsyncend < stuff->vsyncstart ||
-        stuff->vtotal < stuff->vsyncend) {
-        status = MODE_BAD;
-        goto status_reply;
-    }
-
-    if (!xf86VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
-        return BadValue;
-
-    modetmp = VidModeCreateMode();
-    VidModeCopyMode(mode, modetmp);
-
-    VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
-    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
-    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
-    VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
-    VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
-    VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
-    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
-    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
-    VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
-    VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
-    if (stuff->privsize)
-        ErrorF("ValidateModeLine - Privates in request have been ignored\n");
-
-    /* Check that the mode is consistent with the monitor specs */
-    if ((status =
-         xf86VidModeCheckModeForMonitor(pScreen, modetmp)) != MODE_OK)
-        goto status_reply;
-
-    /* Check that the driver is happy with the mode */
-    status = xf86VidModeCheckModeForDriver(pScreen, modetmp);
-
- status_reply:
-    free(modetmp);
-
-    rep = (xXF86VidModeValidateModeLineReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = bytes_to_int32(SIZEOF(xXF86VidModeValidateModeLineReply)
-                                 - SIZEOF(xGenericReply)),
-        .status = status
-    };
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-        swapl(&rep.status);
-    }
-    WriteToClient(client, sizeof(xXF86VidModeValidateModeLineReply), &rep);
-    if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
-        ErrorF("ValidateModeLine - Succeeded (status = %d)\n", status);
-    return Success;
-}
-
-static int
-ProcXF86VidModeSwitchMode(ClientPtr client)
-{
-    REQUEST(xXF86VidModeSwitchModeReq);
-    ScreenPtr pScreen;
-
-    DEBUG_P("XF86VidModeSwitchMode");
-
-    REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    xf86VidModeZoomViewport(pScreen, (short) stuff->zoom);
-
-    return Success;
-}
-
-static int
-ProcXF86VidModeSwitchToMode(ClientPtr client)
-{
-    REQUEST(xXF86VidModeSwitchToModeReq);
-    xXF86OldVidModeSwitchToModeReq *oldstuff =
-        (xXF86OldVidModeSwitchToModeReq *) client->requestBuffer;
-    xXF86VidModeSwitchToModeReq newstuff;
-    ScreenPtr pScreen;
-    DisplayModePtr mode;
-    int len, dotClock;
-    int ver;
-
-    DEBUG_P("XF86VidModeSwitchToMode");
-
-    ver = ClientMajorVersion(client);
-    if (ver < 2) {
-        /* convert from old format */
-        stuff = &newstuff;
-        stuff->length = oldstuff->length;
-        stuff->screen = oldstuff->screen;
-        stuff->dotclock = oldstuff->dotclock;
-        stuff->hdisplay = oldstuff->hdisplay;
-        stuff->hsyncstart = oldstuff->hsyncstart;
-        stuff->hsyncend = oldstuff->hsyncend;
-        stuff->htotal = oldstuff->htotal;
-        stuff->hskew = 0;
-        stuff->vdisplay = oldstuff->vdisplay;
-        stuff->vsyncstart = oldstuff->vsyncstart;
-        stuff->vsyncend = oldstuff->vsyncend;
-        stuff->vtotal = oldstuff->vtotal;
-        stuff->flags = oldstuff->flags;
-        stuff->privsize = oldstuff->privsize;
-    }
-    if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
-        ErrorF("SwitchToMode - scrn: %d clock: %ld\n",
-               (int) stuff->screen, (unsigned long) stuff->dotclock);
-        ErrorF("               hdsp: %d hbeg: %d hend: %d httl: %d\n",
-               stuff->hdisplay, stuff->hsyncstart,
-               stuff->hsyncend, stuff->htotal);
-        ErrorF
-            ("               vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
-             stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
-             (unsigned long) stuff->flags);
-    }
-
-    if (ver < 2) {
-        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeSwitchToModeReq);
-        len =
-            client->req_len -
-            bytes_to_int32(sizeof(xXF86OldVidModeSwitchToModeReq));
-    }
-    else {
-        REQUEST_AT_LEAST_SIZE(xXF86VidModeSwitchToModeReq);
-        len =
-            client->req_len -
-            bytes_to_int32(sizeof(xXF86VidModeSwitchToModeReq));
-    }
-    if (len != stuff->privsize)
-        return BadLength;
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    if (!xf86VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
-        return BadValue;
-
-    if ((xf86VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock)
-        && MODEMATCH(mode, stuff))
-        return Success;
-
-    if (!xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock))
-        return BadValue;
-
-    do {
-        if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
-            ErrorF("Checking against clock: %d (%d)\n",
-                   VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
-            ErrorF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
-                   VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
-                   VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
-                   VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
-                   VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
-            ErrorF
-                ("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
-                 VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
-                 VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
-                 VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
-                 VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
-                 VidModeGetModeValue(mode, VIDMODE_FLAGS));
-        }
-        if ((xf86VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
-            MODEMATCH(mode, stuff)) {
-
-            if (!xf86VidModeSwitchMode(pScreen, mode))
-                return BadValue;
-
-            if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
-                ErrorF("SwitchToMode - Succeeded\n");
-            return Success;
-        }
-    } while (xf86VidModeGetNextModeline(pScreen, &mode, &dotClock));
-
-    return BadValue;
-}
-
-static int
-ProcXF86VidModeLockModeSwitch(ClientPtr client)
-{
-    REQUEST(xXF86VidModeLockModeSwitchReq);
-    ScreenPtr pScreen;
-
-    REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
-
-    DEBUG_P("XF86VidModeLockModeSwitch");
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    if (!xf86VidModeLockZoom(pScreen, (short) stuff->lock))
-        return VidModeErrorBase + XF86VidModeZoomLocked;
-
-    return Success;
-}
-
-static int
-ProcXF86VidModeGetMonitor(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetMonitorReq);
-    xXF86VidModeGetMonitorReply rep = {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence
-    };
-    CARD32 *hsyncdata, *vsyncdata;
-    int i, nHsync, nVrefresh;
-    ScreenPtr pScreen;
-
-    DEBUG_P("XF86VidModeGetMonitor");
-
-    REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    nHsync = xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_NHSYNC, 0).i;
-    nVrefresh = xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_NVREFRESH, 0).i;
-
-    if ((char *) (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr)
-        rep.vendorLength = strlen((char *) (xf86VidModeGetMonitorValue(pScreen,
-                                                                       VIDMODE_MON_VENDOR,
-                                                                       0)).ptr);
-    else
-        rep.vendorLength = 0;
-    if ((char *) (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr)
-        rep.modelLength = strlen((char *) (xf86VidModeGetMonitorValue(pScreen,
-                                                                      VIDMODE_MON_MODEL,
-                                                                      0)).ptr);
-    else
-        rep.modelLength = 0;
-    rep.length =
-        bytes_to_int32(SIZEOF(xXF86VidModeGetMonitorReply) -
-                       SIZEOF(xGenericReply) + (nHsync +
-                                                nVrefresh) * sizeof(CARD32) +
-                       pad_to_int32(rep.vendorLength) +
-                       pad_to_int32(rep.modelLength));
-    rep.nhsync = nHsync;
-    rep.nvsync = nVrefresh;
-    hsyncdata = xallocarray(nHsync, sizeof(CARD32));
-    if (!hsyncdata) {
-        return BadAlloc;
-    }
-    vsyncdata = xallocarray(nVrefresh, sizeof(CARD32));
-
-    if (!vsyncdata) {
-        free(hsyncdata);
-        return BadAlloc;
-    }
-
-    for (i = 0; i < nHsync; i++) {
-        hsyncdata[i] = (unsigned short) (xf86VidModeGetMonitorValue(pScreen,
-                                                                    VIDMODE_MON_HSYNC_LO,
-                                                                    i)).f |
-            (unsigned
-             short) (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_HSYNC_HI,
-                                            i)).f << 16;
-    }
-    for (i = 0; i < nVrefresh; i++) {
-        vsyncdata[i] = (unsigned short) (xf86VidModeGetMonitorValue(pScreen,
-                                                                    VIDMODE_MON_VREFRESH_LO,
-                                                                    i)).f |
-            (unsigned
-             short) (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_VREFRESH_HI,
-                                                i)).f << 16;
-    }
-
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-    }
-    WriteToClient(client, SIZEOF(xXF86VidModeGetMonitorReply), &rep);
-    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
-    WriteSwappedDataToClient(client, nHsync * sizeof(CARD32), hsyncdata);
-    WriteSwappedDataToClient(client, nVrefresh * sizeof(CARD32), vsyncdata);
-    if (rep.vendorLength)
-        WriteToClient(client, rep.vendorLength,
-                 (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr);
-    if (rep.modelLength)
-        WriteToClient(client, rep.modelLength,
-                 (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr);
-
-    free(hsyncdata);
-    free(vsyncdata);
-
-    return Success;
-}
-
-static int
-ProcXF86VidModeGetViewPort(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetViewPortReq);
-    xXF86VidModeGetViewPortReply rep;
-    ScreenPtr pScreen;
-    int x, y;
-
-    DEBUG_P("XF86VidModeGetViewPort");
-
-    REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    xf86VidModeGetViewPort(pScreen, &x, &y);
-
-    rep = (xXF86VidModeGetViewPortReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .x = x,
-        .y = y
-    };
-
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-        swapl(&rep.x);
-        swapl(&rep.y);
-    }
-    WriteToClient(client, SIZEOF(xXF86VidModeGetViewPortReply), &rep);
-    return Success;
-}
-
-static int
-ProcXF86VidModeSetViewPort(ClientPtr client)
-{
-    REQUEST(xXF86VidModeSetViewPortReq);
-    ScreenPtr pScreen;
-
-    DEBUG_P("XF86VidModeSetViewPort");
-
-    REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    if (!xf86VidModeSetViewPort(pScreen, stuff->x, stuff->y))
-        return BadValue;
-
-    return Success;
-}
-
-static int
-ProcXF86VidModeGetDotClocks(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetDotClocksReq);
-    xXF86VidModeGetDotClocksReply rep;
-    ScreenPtr pScreen;
-    int n;
-    int numClocks;
-    CARD32 dotclock;
-    int *Clocks = NULL;
-    Bool ClockProg;
-
-    DEBUG_P("XF86VidModeGetDotClocks");
-
-    REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    numClocks = xf86VidModeGetNumOfClocks(pScreen, &ClockProg);
-
-    rep = (xXF86VidModeGetDotClocksReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = bytes_to_int32(SIZEOF(xXF86VidModeGetDotClocksReply)
-                                 - SIZEOF(xGenericReply) + numClocks),
-        .clocks = numClocks,
-        .maxclocks = MAXCLOCKS,
-        .flags = 0
-    };
-
-    if (!ClockProg) {
-        Clocks = calloc(numClocks, sizeof(int));
-        if (!Clocks)
-            return BadValue;
-        if (!xf86VidModeGetClocks(pScreen, Clocks)) {
-            free(Clocks);
-            return BadValue;
-        }
-    }
-    if (ClockProg) {
-        rep.flags |= CLKFLAG_PROGRAMABLE;
-    }
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-        swapl(&rep.clocks);
-        swapl(&rep.maxclocks);
-        swapl(&rep.flags);
-    }
-    WriteToClient(client, sizeof(xXF86VidModeGetDotClocksReply), &rep);
-    if (!ClockProg) {
-        for (n = 0; n < numClocks; n++) {
-            dotclock = *Clocks++;
-            if (client->swapped) {
-                WriteSwappedDataToClient(client, 4, (char *) &dotclock);
-            }
-            else {
-                WriteToClient(client, 4, &dotclock);
-            }
-        }
-    }
-
-    free(Clocks);
-    return Success;
-}
-
-static int
-ProcXF86VidModeSetGamma(ClientPtr client)
-{
-    REQUEST(xXF86VidModeSetGammaReq);
-    ScreenPtr pScreen;
-
-    DEBUG_P("XF86VidModeSetGamma");
-
-    REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    if (!xf86VidModeSetGamma(pScreen, ((float) stuff->red) / 10000.,
-                                      ((float) stuff->green) / 10000.,
-                                      ((float) stuff->blue) / 10000.))
-        return BadValue;
-
-    return Success;
-}
-
-static int
-ProcXF86VidModeGetGamma(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetGammaReq);
-    xXF86VidModeGetGammaReply rep;
-    ScreenPtr pScreen;
-    float red, green, blue;
-
-    DEBUG_P("XF86VidModeGetGamma");
-
-    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    if (!xf86VidModeGetGamma(pScreen, &red, &green, &blue))
-        return BadValue;
-    rep = (xXF86VidModeGetGammaReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .red = (CARD32) (red * 10000.),
-        .green = (CARD32) (green * 10000.),
-        .blue = (CARD32) (blue * 10000.)
-    };
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-        swapl(&rep.red);
-        swapl(&rep.green);
-        swapl(&rep.blue);
-    }
-    WriteToClient(client, sizeof(xXF86VidModeGetGammaReply), &rep);
-
-    return Success;
-}
-
-static int
-ProcXF86VidModeSetGammaRamp(ClientPtr client)
-{
-    ScreenPtr pScreen;
-    CARD16 *r, *g, *b;
-    int length;
-
-    REQUEST(xXF86VidModeSetGammaRampReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    if (stuff->size != xf86VidModeGetGammaRampSize(pScreen))
-        return BadValue;
-
-    length = (stuff->size + 1) & ~1;
-
-    REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length * 6);
-
-    r = (CARD16 *) &stuff[1];
-    g = r + length;
-    b = g + length;
-
-    if (!xf86VidModeSetGammaRamp(pScreen, stuff->size, r, g, b))
-        return BadValue;
-
-    return Success;
-}
-
-static int
-ProcXF86VidModeGetGammaRamp(ClientPtr client)
-{
-    CARD16 *ramp = NULL;
-    int length;
-    size_t ramplen = 0;
-    xXF86VidModeGetGammaRampReply rep;
-    ScreenPtr pScreen;
-
-    REQUEST(xXF86VidModeGetGammaRampReq);
-
-    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    if (stuff->size != xf86VidModeGetGammaRampSize(pScreen))
-        return BadValue;
-
-    length = (stuff->size + 1) & ~1;
-
-    if (stuff->size) {
-        if (!(ramp = xallocarray(length, 3 * sizeof(CARD16))))
-            return BadAlloc;
-        ramplen = length * 3 * sizeof(CARD16);
-
-        if (!xf86VidModeGetGammaRamp(pScreen, stuff->size,
-                                     ramp, ramp + length, ramp + (length * 2))) {
-            free(ramp);
-            return BadValue;
-        }
-    }
-    rep = (xXF86VidModeGetGammaRampReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = (length >> 1) * 3,
-        .size = stuff->size
-    };
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-        swaps(&rep.size);
-        SwapShorts((short *) ramp, length * 3);
-    }
-    WriteToClient(client, sizeof(xXF86VidModeGetGammaRampReply), &rep);
-
-    if (stuff->size) {
-        WriteToClient(client, ramplen, ramp);
-        free(ramp);
-    }
-
-    return Success;
-}
-
-static int
-ProcXF86VidModeGetGammaRampSize(ClientPtr client)
-{
-    xXF86VidModeGetGammaRampSizeReply rep;
-    ScreenPtr pScreen;
-
-    REQUEST(xXF86VidModeGetGammaRampSizeReq);
-
-    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-    pScreen = screenInfo.screens[stuff->screen];
-
-    rep = (xXF86VidModeGetGammaRampSizeReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .size = xf86VidModeGetGammaRampSize(pScreen)
-    };
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-        swaps(&rep.size);
-    }
-    WriteToClient(client, sizeof(xXF86VidModeGetGammaRampSizeReply), &rep);
-
-    return Success;
-}
-
-static int
-ProcXF86VidModeGetPermissions(ClientPtr client)
-{
-    xXF86VidModeGetPermissionsReply rep =  {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .permissions = XF86VM_READ_PERMISSION
-    };
-
-    REQUEST(xXF86VidModeGetPermissionsReq);
-
-    REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
-
-    if (stuff->screen >= screenInfo.numScreens)
-        return BadValue;
-
-    if (xf86GetVidModeEnabled() &&
-        (xf86GetVidModeAllowNonLocal() || client->local)) {
-        rep.permissions |= XF86VM_WRITE_PERMISSION;
-    }
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-        swapl(&rep.permissions);
-    }
-    WriteToClient(client, sizeof(xXF86VidModeGetPermissionsReply), &rep);
-
-    return Success;
-}
-
-static int
-ProcXF86VidModeSetClientVersion(ClientPtr client)
-{
-    REQUEST(xXF86VidModeSetClientVersionReq);
-
-    VidModePrivPtr pPriv;
-
-    DEBUG_P("XF86VidModeSetClientVersion");
-
-    REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
-
-    if ((pPriv = VM_GETPRIV(client)) == NULL) {
-        pPriv = malloc(sizeof(VidModePrivRec));
-        if (!pPriv)
-            return BadAlloc;
-        VM_SETPRIV(client, pPriv);
-    }
-    pPriv->major = stuff->major;
-
-    pPriv->minor = stuff->minor;
-
-    return Success;
-}
-
-static int
-ProcXF86VidModeDispatch(ClientPtr client)
-{
-    REQUEST(xReq);
-    switch (stuff->data) {
-    case X_XF86VidModeQueryVersion:
-        return ProcXF86VidModeQueryVersion(client);
-    case X_XF86VidModeGetModeLine:
-        return ProcXF86VidModeGetModeLine(client);
-    case X_XF86VidModeGetMonitor:
-        return ProcXF86VidModeGetMonitor(client);
-    case X_XF86VidModeGetAllModeLines:
-        return ProcXF86VidModeGetAllModeLines(client);
-    case X_XF86VidModeValidateModeLine:
-        return ProcXF86VidModeValidateModeLine(client);
-    case X_XF86VidModeGetViewPort:
-        return ProcXF86VidModeGetViewPort(client);
-    case X_XF86VidModeGetDotClocks:
-        return ProcXF86VidModeGetDotClocks(client);
-    case X_XF86VidModeSetClientVersion:
-        return ProcXF86VidModeSetClientVersion(client);
-    case X_XF86VidModeGetGamma:
-        return ProcXF86VidModeGetGamma(client);
-    case X_XF86VidModeGetGammaRamp:
-        return ProcXF86VidModeGetGammaRamp(client);
-    case X_XF86VidModeGetGammaRampSize:
-        return ProcXF86VidModeGetGammaRampSize(client);
-    case X_XF86VidModeGetPermissions:
-        return ProcXF86VidModeGetPermissions(client);
-    default:
-        if (!xf86GetVidModeEnabled())
-            return VidModeErrorBase + XF86VidModeExtensionDisabled;
-        if (xf86GetVidModeAllowNonLocal() || client->local) {
-            switch (stuff->data) {
-            case X_XF86VidModeAddModeLine:
-                return ProcXF86VidModeAddModeLine(client);
-            case X_XF86VidModeDeleteModeLine:
-                return ProcXF86VidModeDeleteModeLine(client);
-            case X_XF86VidModeModModeLine:
-                return ProcXF86VidModeModModeLine(client);
-            case X_XF86VidModeSwitchMode:
-                return ProcXF86VidModeSwitchMode(client);
-            case X_XF86VidModeSwitchToMode:
-                return ProcXF86VidModeSwitchToMode(client);
-            case X_XF86VidModeLockModeSwitch:
-                return ProcXF86VidModeLockModeSwitch(client);
-            case X_XF86VidModeSetViewPort:
-                return ProcXF86VidModeSetViewPort(client);
-            case X_XF86VidModeSetGamma:
-                return ProcXF86VidModeSetGamma(client);
-            case X_XF86VidModeSetGammaRamp:
-                return ProcXF86VidModeSetGammaRamp(client);
-            default:
-                return BadRequest;
-            }
-        }
-        else
-            return VidModeErrorBase + XF86VidModeClientNotLocal;
-    }
-}
-
-static int
-SProcXF86VidModeQueryVersion(ClientPtr client)
-{
-    REQUEST(xXF86VidModeQueryVersionReq);
-    swaps(&stuff->length);
-    return ProcXF86VidModeQueryVersion(client);
-}
-
-static int
-SProcXF86VidModeGetModeLine(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetModeLineReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
-    swaps(&stuff->screen);
-    return ProcXF86VidModeGetModeLine(client);
-}
-
-static int
-SProcXF86VidModeGetAllModeLines(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetAllModeLinesReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
-    swaps(&stuff->screen);
-    return ProcXF86VidModeGetAllModeLines(client);
-}
-
-static int
-SProcXF86VidModeAddModeLine(ClientPtr client)
-{
-    xXF86OldVidModeAddModeLineReq *oldstuff =
-        (xXF86OldVidModeAddModeLineReq *) client->requestBuffer;
-    int ver;
-
-    REQUEST(xXF86VidModeAddModeLineReq);
-    ver = ClientMajorVersion(client);
-    if (ver < 2) {
-        swaps(&oldstuff->length);
-        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
-        swapl(&oldstuff->screen);
-        swaps(&oldstuff->hdisplay);
-        swaps(&oldstuff->hsyncstart);
-        swaps(&oldstuff->hsyncend);
-        swaps(&oldstuff->htotal);
-        swaps(&oldstuff->vdisplay);
-        swaps(&oldstuff->vsyncstart);
-        swaps(&oldstuff->vsyncend);
-        swaps(&oldstuff->vtotal);
-        swapl(&oldstuff->flags);
-        swapl(&oldstuff->privsize);
-        SwapRestL(oldstuff);
-    }
-    else {
-        swaps(&stuff->length);
-        REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
-        swapl(&stuff->screen);
-        swaps(&stuff->hdisplay);
-        swaps(&stuff->hsyncstart);
-        swaps(&stuff->hsyncend);
-        swaps(&stuff->htotal);
-        swaps(&stuff->hskew);
-        swaps(&stuff->vdisplay);
-        swaps(&stuff->vsyncstart);
-        swaps(&stuff->vsyncend);
-        swaps(&stuff->vtotal);
-        swapl(&stuff->flags);
-        swapl(&stuff->privsize);
-        SwapRestL(stuff);
-    }
-    return ProcXF86VidModeAddModeLine(client);
-}
-
-static int
-SProcXF86VidModeDeleteModeLine(ClientPtr client)
-{
-    xXF86OldVidModeDeleteModeLineReq *oldstuff =
-        (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer;
-    int ver;
-
-    REQUEST(xXF86VidModeDeleteModeLineReq);
-    ver = ClientMajorVersion(client);
-    if (ver < 2) {
-        swaps(&oldstuff->length);
-        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
-        swapl(&oldstuff->screen);
-        swaps(&oldstuff->hdisplay);
-        swaps(&oldstuff->hsyncstart);
-        swaps(&oldstuff->hsyncend);
-        swaps(&oldstuff->htotal);
-        swaps(&oldstuff->vdisplay);
-        swaps(&oldstuff->vsyncstart);
-        swaps(&oldstuff->vsyncend);
-        swaps(&oldstuff->vtotal);
-        swapl(&oldstuff->flags);
-        swapl(&oldstuff->privsize);
-        SwapRestL(oldstuff);
-    }
-    else {
-        swaps(&stuff->length);
-        REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
-        swapl(&stuff->screen);
-        swaps(&stuff->hdisplay);
-        swaps(&stuff->hsyncstart);
-        swaps(&stuff->hsyncend);
-        swaps(&stuff->htotal);
-        swaps(&stuff->hskew);
-        swaps(&stuff->vdisplay);
-        swaps(&stuff->vsyncstart);
-        swaps(&stuff->vsyncend);
-        swaps(&stuff->vtotal);
-        swapl(&stuff->flags);
-        swapl(&stuff->privsize);
-        SwapRestL(stuff);
-    }
-    return ProcXF86VidModeDeleteModeLine(client);
-}
-
-static int
-SProcXF86VidModeModModeLine(ClientPtr client)
-{
-    xXF86OldVidModeModModeLineReq *oldstuff =
-        (xXF86OldVidModeModModeLineReq *) client->requestBuffer;
-    int ver;
-
-    REQUEST(xXF86VidModeModModeLineReq);
-    ver = ClientMajorVersion(client);
-    if (ver < 2) {
-        swaps(&oldstuff->length);
-        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
-        swapl(&oldstuff->screen);
-        swaps(&oldstuff->hdisplay);
-        swaps(&oldstuff->hsyncstart);
-        swaps(&oldstuff->hsyncend);
-        swaps(&oldstuff->htotal);
-        swaps(&oldstuff->vdisplay);
-        swaps(&oldstuff->vsyncstart);
-        swaps(&oldstuff->vsyncend);
-        swaps(&oldstuff->vtotal);
-        swapl(&oldstuff->flags);
-        swapl(&oldstuff->privsize);
-        SwapRestL(oldstuff);
-    }
-    else {
-        swaps(&stuff->length);
-        REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
-        swapl(&stuff->screen);
-        swaps(&stuff->hdisplay);
-        swaps(&stuff->hsyncstart);
-        swaps(&stuff->hsyncend);
-        swaps(&stuff->htotal);
-        swaps(&stuff->hskew);
-        swaps(&stuff->vdisplay);
-        swaps(&stuff->vsyncstart);
-        swaps(&stuff->vsyncend);
-        swaps(&stuff->vtotal);
-        swapl(&stuff->flags);
-        swapl(&stuff->privsize);
-        SwapRestL(stuff);
-    }
-    return ProcXF86VidModeModModeLine(client);
-}
-
-static int
-SProcXF86VidModeValidateModeLine(ClientPtr client)
-{
-    xXF86OldVidModeValidateModeLineReq *oldstuff =
-        (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer;
-    int ver;
-
-    REQUEST(xXF86VidModeValidateModeLineReq);
-    ver = ClientMajorVersion(client);
-    if (ver < 2) {
-        swaps(&oldstuff->length);
-        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
-        swapl(&oldstuff->screen);
-        swaps(&oldstuff->hdisplay);
-        swaps(&oldstuff->hsyncstart);
-        swaps(&oldstuff->hsyncend);
-        swaps(&oldstuff->htotal);
-        swaps(&oldstuff->vdisplay);
-        swaps(&oldstuff->vsyncstart);
-        swaps(&oldstuff->vsyncend);
-        swaps(&oldstuff->vtotal);
-        swapl(&oldstuff->flags);
-        swapl(&oldstuff->privsize);
-        SwapRestL(oldstuff);
-    }
-    else {
-        swaps(&stuff->length);
-        REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
-        swapl(&stuff->screen);
-        swaps(&stuff->hdisplay);
-        swaps(&stuff->hsyncstart);
-        swaps(&stuff->hsyncend);
-        swaps(&stuff->htotal);
-        swaps(&stuff->hskew);
-        swaps(&stuff->vdisplay);
-        swaps(&stuff->vsyncstart);
-        swaps(&stuff->vsyncend);
-        swaps(&stuff->vtotal);
-        swapl(&stuff->flags);
-        swapl(&stuff->privsize);
-        SwapRestL(stuff);
-    }
-    return ProcXF86VidModeValidateModeLine(client);
-}
-
-static int
-SProcXF86VidModeSwitchMode(ClientPtr client)
-{
-    REQUEST(xXF86VidModeSwitchModeReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
-    swaps(&stuff->screen);
-    swaps(&stuff->zoom);
-    return ProcXF86VidModeSwitchMode(client);
-}
-
-static int
-SProcXF86VidModeSwitchToMode(ClientPtr client)
-{
-    REQUEST(xXF86VidModeSwitchToModeReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeSwitchToModeReq);
-    swapl(&stuff->screen);
-    return ProcXF86VidModeSwitchToMode(client);
-}
-
-static int
-SProcXF86VidModeLockModeSwitch(ClientPtr client)
-{
-    REQUEST(xXF86VidModeLockModeSwitchReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
-    swaps(&stuff->screen);
-    swaps(&stuff->lock);
-    return ProcXF86VidModeLockModeSwitch(client);
-}
-
-static int
-SProcXF86VidModeGetMonitor(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetMonitorReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
-    swaps(&stuff->screen);
-    return ProcXF86VidModeGetMonitor(client);
-}
-
-static int
-SProcXF86VidModeGetViewPort(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetViewPortReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
-    swaps(&stuff->screen);
-    return ProcXF86VidModeGetViewPort(client);
-}
-
-static int
-SProcXF86VidModeSetViewPort(ClientPtr client)
-{
-    REQUEST(xXF86VidModeSetViewPortReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
-    swaps(&stuff->screen);
-    swapl(&stuff->x);
-    swapl(&stuff->y);
-    return ProcXF86VidModeSetViewPort(client);
-}
-
-static int
-SProcXF86VidModeGetDotClocks(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetDotClocksReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
-    swaps(&stuff->screen);
-    return ProcXF86VidModeGetDotClocks(client);
-}
-
-static int
-SProcXF86VidModeSetClientVersion(ClientPtr client)
-{
-    REQUEST(xXF86VidModeSetClientVersionReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
-    swaps(&stuff->major);
-    swaps(&stuff->minor);
-    return ProcXF86VidModeSetClientVersion(client);
-}
-
-static int
-SProcXF86VidModeSetGamma(ClientPtr client)
-{
-    REQUEST(xXF86VidModeSetGammaReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
-    swaps(&stuff->screen);
-    swapl(&stuff->red);
-    swapl(&stuff->green);
-    swapl(&stuff->blue);
-    return ProcXF86VidModeSetGamma(client);
-}
-
-static int
-SProcXF86VidModeGetGamma(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetGammaReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
-    swaps(&stuff->screen);
-    return ProcXF86VidModeGetGamma(client);
-}
-
-static int
-SProcXF86VidModeSetGammaRamp(ClientPtr client)
-{
-    int length;
-
-    REQUEST(xXF86VidModeSetGammaRampReq);
-    swaps(&stuff->length);
-    REQUEST_AT_LEAST_SIZE(xXF86VidModeSetGammaRampReq);
-    swaps(&stuff->size);
-    swaps(&stuff->screen);
-    length = ((stuff->size + 1) & ~1) * 6;
-    REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length);
-    SwapRestS(stuff);
-    return ProcXF86VidModeSetGammaRamp(client);
-}
-
-static int
-SProcXF86VidModeGetGammaRamp(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetGammaRampReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
-    swaps(&stuff->size);
-    swaps(&stuff->screen);
-    return ProcXF86VidModeGetGammaRamp(client);
-}
-
-static int
-SProcXF86VidModeGetGammaRampSize(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetGammaRampSizeReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
-    swaps(&stuff->screen);
-    return ProcXF86VidModeGetGammaRampSize(client);
-}
-
-static int
-SProcXF86VidModeGetPermissions(ClientPtr client)
-{
-    REQUEST(xXF86VidModeGetPermissionsReq);
-    swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
-    swaps(&stuff->screen);
-    return ProcXF86VidModeGetPermissions(client);
-}
-
-static int
-SProcXF86VidModeDispatch(ClientPtr client)
-{
-    REQUEST(xReq);
-    switch (stuff->data) {
-    case X_XF86VidModeQueryVersion:
-        return SProcXF86VidModeQueryVersion(client);
-    case X_XF86VidModeGetModeLine:
-        return SProcXF86VidModeGetModeLine(client);
-    case X_XF86VidModeGetMonitor:
-        return SProcXF86VidModeGetMonitor(client);
-    case X_XF86VidModeGetAllModeLines:
-        return SProcXF86VidModeGetAllModeLines(client);
-    case X_XF86VidModeGetViewPort:
-        return SProcXF86VidModeGetViewPort(client);
-    case X_XF86VidModeValidateModeLine:
-        return SProcXF86VidModeValidateModeLine(client);
-    case X_XF86VidModeGetDotClocks:
-        return SProcXF86VidModeGetDotClocks(client);
-    case X_XF86VidModeSetClientVersion:
-        return SProcXF86VidModeSetClientVersion(client);
-    case X_XF86VidModeGetGamma:
-        return SProcXF86VidModeGetGamma(client);
-    case X_XF86VidModeGetGammaRamp:
-        return SProcXF86VidModeGetGammaRamp(client);
-    case X_XF86VidModeGetGammaRampSize:
-        return SProcXF86VidModeGetGammaRampSize(client);
-    case X_XF86VidModeGetPermissions:
-        return SProcXF86VidModeGetPermissions(client);
-    default:
-        if (!xf86GetVidModeEnabled())
-            return VidModeErrorBase + XF86VidModeExtensionDisabled;
-        if (xf86GetVidModeAllowNonLocal() || client->local) {
-            switch (stuff->data) {
-            case X_XF86VidModeAddModeLine:
-                return SProcXF86VidModeAddModeLine(client);
-            case X_XF86VidModeDeleteModeLine:
-                return SProcXF86VidModeDeleteModeLine(client);
-            case X_XF86VidModeModModeLine:
-                return SProcXF86VidModeModModeLine(client);
-            case X_XF86VidModeSwitchMode:
-                return SProcXF86VidModeSwitchMode(client);
-            case X_XF86VidModeSwitchToMode:
-                return SProcXF86VidModeSwitchToMode(client);
-            case X_XF86VidModeLockModeSwitch:
-                return SProcXF86VidModeLockModeSwitch(client);
-            case X_XF86VidModeSetViewPort:
-                return SProcXF86VidModeSetViewPort(client);
-            case X_XF86VidModeSetGamma:
-                return SProcXF86VidModeSetGamma(client);
-            case X_XF86VidModeSetGammaRamp:
-                return SProcXF86VidModeSetGammaRamp(client);
-            default:
-                return BadRequest;
-            }
-        }
-        else
-            return VidModeErrorBase + XF86VidModeClientNotLocal;
-    }
-}
-
-void
-XFree86VidModeExtensionInit(void)
-{
-    ExtensionEntry *extEntry;
-    ScreenPtr pScreen;
-    int i;
-    Bool enabled = FALSE;
-
-    DEBUG_P("XFree86VidModeExtensionInit");
-
-    if (!dixRegisterPrivateKey(&VidModeClientPrivateKeyRec, PRIVATE_CLIENT, 0))
-        return;
-
-    for (i = 0; i < screenInfo.numScreens; i++) {
-        pScreen = screenInfo.screens[i];
-        if (xf86VidModeExtensionInit(pScreen))
-            enabled = TRUE;
-    }
-    /* This means that the DDX doesn't want the vidmode extension enabled */
-    if (!enabled)
-        return;
-
-    if ((extEntry = AddExtension(XF86VIDMODENAME,
-                                 XF86VidModeNumberEvents,
-                                 XF86VidModeNumberErrors,
-                                 ProcXF86VidModeDispatch,
-                                 SProcXF86VidModeDispatch,
-                                 NULL, StandardMinorOpcode))) {
-#if 0
-        XF86VidModeReqCode = (unsigned char) extEntry->base;
-#endif
-        VidModeErrorBase = extEntry->errorBase;
-    }
-}
diff --git a/include/Makefile.am b/include/Makefile.am
index 4c8ea6a..b9cf584 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -76,4 +76,5 @@ EXTRA_DIST = 	\
 	swaprep.h \
 	swapreq.h \
 	systemd-logind.h \
+        vidmodestr.h \
 	xsha1.h
diff --git a/include/vidmodestr.h b/include/vidmodestr.h
new file mode 100644
index 0000000..3a44185
--- /dev/null
+++ b/include/vidmodestr.h
@@ -0,0 +1,140 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _VIDMODEPROC_H_
+#define _VIDMODEPROC_H_
+
+#include "displaymode.h"
+
+typedef enum {
+    VIDMODE_H_DISPLAY,
+    VIDMODE_H_SYNCSTART,
+    VIDMODE_H_SYNCEND,
+    VIDMODE_H_TOTAL,
+    VIDMODE_H_SKEW,
+    VIDMODE_V_DISPLAY,
+    VIDMODE_V_SYNCSTART,
+    VIDMODE_V_SYNCEND,
+    VIDMODE_V_TOTAL,
+    VIDMODE_FLAGS,
+    VIDMODE_CLOCK
+} VidModeSelectMode;
+
+typedef enum {
+    VIDMODE_MON_VENDOR,
+    VIDMODE_MON_MODEL,
+    VIDMODE_MON_NHSYNC,
+    VIDMODE_MON_NVREFRESH,
+    VIDMODE_MON_HSYNC_LO,
+    VIDMODE_MON_HSYNC_HI,
+    VIDMODE_MON_VREFRESH_LO,
+    VIDMODE_MON_VREFRESH_HI
+} VidModeSelectMonitor;
+
+typedef union {
+    const void *ptr;
+    int i;
+    float f;
+} vidMonitorValue;
+
+typedef Bool            (*VidModeExtensionInitProcPtr)       (ScreenPtr pScreen);
+typedef vidMonitorValue (*VidModeGetMonitorValueProcPtr)     (ScreenPtr pScreen,
+                                                              int valtyp,
+                                                              int indx);
+typedef Bool            (*VidModeGetEnabledProcPtr)          (void);
+typedef Bool            (*VidModeGetAllowNonLocalProcPtr)    (void);
+typedef Bool            (*VidModeGetCurrentModelineProcPtr)  (ScreenPtr pScreen,
+                                                              DisplayModePtr *mode,
+                                                              int *dotClock);
+typedef Bool            (*VidModeGetFirstModelineProcPtr)    (ScreenPtr pScreen,
+                                                              DisplayModePtr *mode,
+                                                              int *dotClock);
+typedef Bool            (*VidModeGetNextModelineProcPtr)     (ScreenPtr pScreen,
+                                                              DisplayModePtr *mode,
+                                                              int *dotClock);
+typedef Bool            (*VidModeDeleteModelineProcPtr)      (ScreenPtr pScreen,
+                                                              DisplayModePtr mode);
+typedef Bool            (*VidModeZoomViewportProcPtr)        (ScreenPtr pScreen,
+                                                              int zoom);
+typedef Bool            (*VidModeGetViewPortProcPtr)         (ScreenPtr pScreen,
+                                                              int *x,
+                                                              int *y);
+typedef Bool            (*VidModeSetViewPortProcPtr)         (ScreenPtr pScreen,
+                                                              int x,
+                                                              int y);
+typedef Bool            (*VidModeSwitchModeProcPtr)          (ScreenPtr pScreen,
+                                                              DisplayModePtr mode);
+typedef Bool            (*VidModeLockZoomProcPtr)            (ScreenPtr pScreen,
+                                                              Bool lock);
+typedef int             (*VidModeGetNumOfClocksProcPtr)      (ScreenPtr pScreen,
+                                                              Bool *progClock);
+typedef Bool            (*VidModeGetClocksProcPtr)           (ScreenPtr pScreen,
+                                                              int *Clocks);
+typedef ModeStatus      (*VidModeCheckModeForMonitorProcPtr) (ScreenPtr pScreen,
+                                                              DisplayModePtr mode);
+typedef ModeStatus      (*VidModeCheckModeForDriverProcPtr)  (ScreenPtr pScreen,
+                                                              DisplayModePtr mode);
+typedef void            (*VidModeSetCrtcForModeProcPtr)      (ScreenPtr pScreen,
+                                                              DisplayModePtr mode);
+typedef Bool            (*VidModeAddModelineProcPtr)         (ScreenPtr pScreen,
+                                                              DisplayModePtr mode);
+typedef int             (*VidModeGetDotClockProcPtr)         (ScreenPtr pScreen,
+                                                              int Clock);
+typedef int             (*VidModeGetNumOfModesProcPtr)       (ScreenPtr pScreen);
+typedef Bool            (*VidModeSetGammaProcPtr)            (ScreenPtr pScreen,
+                                                              float red,
+                                                              float green,
+                                                              float blue);
+typedef Bool            (*VidModeGetGammaProcPtr)            (ScreenPtr pScreen,
+                                                              float *red,
+                                                              float *green,
+                                                              float *blue);
+typedef Bool            (*VidModeSetGammaRampProcPtr)        (ScreenPtr pScreen,
+                                                              int size,
+                                                              CARD16 *red,
+                                                              CARD16 *green,
+                                                              CARD16 *blue);
+typedef Bool            (*VidModeGetGammaRampProcPtr)        (ScreenPtr pScreen,
+                                                              int size,
+                                                              CARD16 *red,
+                                                              CARD16 *green,
+                                                              CARD16 *blue);
+typedef int             (*VidModeGetGammaRampSizeProcPtr)    (ScreenPtr pScreen);
+
+typedef struct {
+    DisplayModePtr First;
+    DisplayModePtr Next;
+    int Flags;
+
+    VidModeExtensionInitProcPtr       ExtensionInit;
+    VidModeGetMonitorValueProcPtr     GetMonitorValue;
+    VidModeGetCurrentModelineProcPtr  GetCurrentModeline;
+    VidModeGetFirstModelineProcPtr    GetFirstModeline;
+    VidModeGetNextModelineProcPtr     GetNextModeline;
+    VidModeDeleteModelineProcPtr      DeleteModeline;
+    VidModeZoomViewportProcPtr        ZoomViewport;
+    VidModeGetViewPortProcPtr         GetViewPort;
+    VidModeSetViewPortProcPtr         SetViewPort;
+    VidModeSwitchModeProcPtr          SwitchMode;
+    VidModeLockZoomProcPtr            LockZoom;
+    VidModeGetNumOfClocksProcPtr      GetNumOfClocks;
+    VidModeGetClocksProcPtr           GetClocks;
+    VidModeCheckModeForMonitorProcPtr CheckModeForMonitor;
+    VidModeCheckModeForDriverProcPtr  CheckModeForDriver;
+    VidModeSetCrtcForModeProcPtr      SetCrtcForMode;
+    VidModeAddModelineProcPtr         AddModeline;
+    VidModeGetDotClockProcPtr         GetDotClock;
+    VidModeGetNumOfModesProcPtr       GetNumOfModes;
+    VidModeSetGammaProcPtr            SetGamma;
+    VidModeGetGammaProcPtr            GetGamma;
+    VidModeSetGammaRampProcPtr        SetGammaRamp;
+    VidModeGetGammaRampProcPtr        GetGammaRamp;
+    VidModeGetGammaRampSizeProcPtr    GetGammaRampSize;
+} VidModeRec, *VidModePtr;
+
+void VidModeAddExtension(Bool allow_non_local);
+VidModePtr VidModeGetPtr(ScreenPtr pScreen);
+VidModePtr VidModeInit(ScreenPtr pScreen);
+
+#endif
diff --git a/test/Makefile.am b/test/Makefile.am
index d151b02..9f13e26 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -56,6 +56,7 @@ libxservertest_la_LIBADD += \
             $(top_builddir)/hw/xfree86/ddc/libddc.la \
             $(top_builddir)/hw/xfree86/i2c/libi2c.la \
             $(top_builddir)/hw/xfree86/dixmods/libxorgxkb.la \
+            $(top_builddir)/Xext/libXvidmode.la \
             @XORG_LIBS@
 
 BUILT_SOURCES = sdksyms.c
@@ -91,6 +92,7 @@ libxservertest_la_LIBADD += \
             $(top_builddir)/render/librender.la \
             $(top_builddir)/Xext/libXext.la \
             $(top_builddir)/Xext/libXextdpmsstubs.la \
+            $(top_builddir)/Xext/libXvidmode.la \
             $(top_builddir)/Xi/libXi.la \
             $(top_builddir)/Xi/libXistubs.la \
             $(top_builddir)/xfixes/libxfixes.la \
commit 860669b1867178fe46df9da98591ea5a47f427f1
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Feb 5 09:48:22 2016 +0100

    vidmode: rename DDX functions
    
    To avoid confusion as to what belongs on the DDX and what not.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 17097e083b2392c8989474f6e0da8cc234329e9c)

diff --git a/hw/xfree86/common/vidmodeproc.h b/hw/xfree86/common/vidmodeproc.h
index 3919a0c..4410253 100644
--- a/hw/xfree86/common/vidmodeproc.h
+++ b/hw/xfree86/common/vidmodeproc.h
@@ -39,40 +39,40 @@ typedef union {
     float f;
 } vidMonitorValue;
 
-extern Bool VidModeExtensionInit(ScreenPtr pScreen);
+extern Bool xf86VidModeExtensionInit(ScreenPtr pScreen);
 
-extern Bool VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode,
-                                      int *dotClock);
-extern Bool VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode,
-                                    int *dotClock);
-extern Bool VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode,
-                                   int *dotClock);
-extern Bool VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode);
-extern Bool VidModeZoomViewport(ScreenPtr pScreen, int zoom);
-extern Bool VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y);
-extern Bool VidModeSetViewPort(ScreenPtr pScreen, int x, int y);
-extern Bool VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode);
-extern Bool VidModeLockZoom(ScreenPtr pScreen, Bool lock);
-extern int VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock);
-extern Bool VidModeGetClocks(ScreenPtr pScreen, int *Clocks);
-extern ModeStatus VidModeCheckModeForMonitor(ScreenPtr pScreen,
-                                             DisplayModePtr mode);
-extern ModeStatus VidModeCheckModeForDriver(ScreenPtr pScreen,
-                                            DisplayModePtr mode);
-extern void VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode);
-extern Bool VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode);
-extern int VidModeGetDotClock(ScreenPtr pScreen, int Clock);
-extern int VidModeGetNumOfModes(ScreenPtr pScreen);
-extern Bool VidModeSetGamma(ScreenPtr pScreen, float red, float green,
-                            float blue);
-extern Bool VidModeGetGamma(ScreenPtr pScreen, float *red, float *green,
-                            float *blue);
-extern vidMonitorValue VidModeGetMonitorValue(ScreenPtr pScreen,
-                                              int valtyp, int indx);
-extern Bool VidModeSetGammaRamp(ScreenPtr, int, CARD16 *, CARD16 *,
-                                CARD16 *);
-extern Bool VidModeGetGammaRamp(ScreenPtr, int, CARD16 *, CARD16 *,
-                                CARD16 *);
-extern int VidModeGetGammaRampSize(ScreenPtr pScreen);
+extern Bool xf86VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode,
+                                          int *dotClock);
+extern Bool xf86VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode,
+                                        int *dotClock);
+extern Bool xf86VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode,
+                                       int *dotClock);
+extern Bool xf86VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode);
+extern Bool xf86VidModeZoomViewport(ScreenPtr pScreen, int zoom);
+extern Bool xf86VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y);
+extern Bool xf86VidModeSetViewPort(ScreenPtr pScreen, int x, int y);
+extern Bool xf86VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode);
+extern Bool xf86VidModeLockZoom(ScreenPtr pScreen, Bool lock);
+extern int xf86VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock);
+extern Bool xf86VidModeGetClocks(ScreenPtr pScreen, int *Clocks);
+extern ModeStatus xf86VidModeCheckModeForMonitor(ScreenPtr pScreen,
+                                                 DisplayModePtr mode);
+extern ModeStatus xf86VidModeCheckModeForDriver(ScreenPtr pScreen,
+                                                DisplayModePtr mode);
+extern void xf86VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode);
+extern Bool xf86VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode);
+extern int xf86VidModeGetDotClock(ScreenPtr pScreen, int Clock);
+extern int xf86VidModeGetNumOfModes(ScreenPtr pScreen);
+extern Bool xf86VidModeSetGamma(ScreenPtr pScreen, float red, float green,
+                                float blue);
+extern Bool xf86VidModeGetGamma(ScreenPtr pScreen, float *red, float *green,
+                                float *blue);
+extern vidMonitorValue xf86VidModeGetMonitorValue(ScreenPtr pScreen,
+                                                  int valtyp, int indx);
+extern Bool xf86VidModeSetGammaRamp(ScreenPtr, int, CARD16 *, CARD16 *,
+                                    CARD16 *);
+extern Bool xf86VidModeGetGammaRamp(ScreenPtr, int, CARD16 *, CARD16 *,
+                                    CARD16 *);
+extern int xf86VidModeGetGammaRampSize(ScreenPtr pScreen);
 
 #endif
diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index 2d87daa..5d04738 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -54,36 +54,10 @@ static DevPrivateKeyRec VidModeKeyRec;
 
 #endif
 
-Bool
-VidModeExtensionInit(ScreenPtr pScreen)
-{
-#ifdef XF86VIDMODE
-    VidModePtr pVidMode;
-
-    if (!xf86GetVidModeEnabled()) {
-        DebugF("!xf86GetVidModeEnabled()\n");
-        return FALSE;
-    }
-
-    if (!dixRegisterPrivateKey(&VidModeKeyRec, PRIVATE_SCREEN, sizeof(VidModeRec)))
-        return FALSE;
-
-    pVidMode = VMPTR(pScreen);
-
-    pVidMode->Flags = 0;
-    pVidMode->Next = NULL;
-
-    return TRUE;
-#else
-    DebugF("no vidmode extension\n");
-    return FALSE;
-#endif
-}
-
 #ifdef XF86VIDMODE
 
 static Bool
-VidModeAvailable(ScreenPtr pScreen)
+xf86VidModeAvailable(ScreenPtr pScreen)
 {
     if (pScreen == NULL) {
         DebugF("pScreen == NULL\n");
@@ -98,12 +72,54 @@ VidModeAvailable(ScreenPtr pScreen)
     }
 }
 
+vidMonitorValue
+xf86VidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
+{
+    vidMonitorValue ret = { NULL, };
+    MonPtr monitor;
+    ScrnInfoPtr pScrn;
+
+    if (!xf86VidModeAvailable(pScreen))
+        return ret;
+
+    pScrn = xf86ScreenToScrn(pScreen);
+    monitor = pScrn->monitor;
+
+    switch (valtyp) {
+    case VIDMODE_MON_VENDOR:
+        ret.ptr = monitor->vendor;
+        break;
+    case VIDMODE_MON_MODEL:
+        ret.ptr = monitor->model;
+        break;
+    case VIDMODE_MON_NHSYNC:
+        ret.i = monitor->nHsync;
+        break;
+    case VIDMODE_MON_NVREFRESH:
+        ret.i = monitor->nVrefresh;
+        break;
+    case VIDMODE_MON_HSYNC_LO:
+        ret.f = (100.0 * monitor->hsync[indx].lo);
+        break;
+    case VIDMODE_MON_HSYNC_HI:
+        ret.f = (100.0 * monitor->hsync[indx].hi);
+        break;
+    case VIDMODE_MON_VREFRESH_LO:
+        ret.f = (100.0 * monitor->vrefresh[indx].lo);
+        break;
+    case VIDMODE_MON_VREFRESH_HI:
+        ret.f = (100.0 * monitor->vrefresh[indx].hi);
+        break;
+    }
+    return ret;
+}
+
 Bool
-VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
+xf86VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -118,11 +134,11 @@ VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock
 }
 
 int
-VidModeGetDotClock(ScreenPtr pScreen, int Clock)
+xf86VidModeGetDotClock(ScreenPtr pScreen, int Clock)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return 0;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -133,11 +149,11 @@ VidModeGetDotClock(ScreenPtr pScreen, int Clock)
 }
 
 int
-VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
+xf86VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return 0;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -152,12 +168,12 @@ VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
 }
 
 Bool
-VidModeGetClocks(ScreenPtr pScreen, int *Clocks)
+xf86VidModeGetClocks(ScreenPtr pScreen, int *Clocks)
 {
     ScrnInfoPtr pScrn;
     int i;
 
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -172,60 +188,60 @@ VidModeGetClocks(ScreenPtr pScreen, int *Clocks)
 }
 
 Bool
-VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
+xf86VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 {
-    ScrnInfoPtr pScrn;
     VidModePtr pVidMode;
+    DisplayModePtr p;
 
-    if (!VidModeAvailable(pScreen))
-        return FALSE;
-
-    pScrn = xf86ScreenToScrn(pScreen);
-    if (pScrn->modes == NULL)
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     pVidMode = VMPTR(pScreen);
-    pVidMode->First = pScrn->modes;
-    pVidMode->Next = pVidMode->First->next;
 
-    if (pVidMode->First->status == MODE_OK) {
-        *mode = pVidMode->First;
-        *dotClock = VidModeGetDotClock(pScreen, pVidMode->First->Clock);
-        return TRUE;
+    for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
+        if (p->status == MODE_OK) {
+            pVidMode->Next = p->next;
+            *mode = p;
+            *dotClock = xf86VidModeGetDotClock(pScreen, p->Clock);
+            return TRUE;
+        }
     }
 
-    return VidModeGetNextModeline(pScreen, mode, dotClock);
+    return FALSE;
 }
 
 Bool
-VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
+xf86VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 {
+    ScrnInfoPtr pScrn;
     VidModePtr pVidMode;
-    DisplayModePtr p;
 
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
+        return FALSE;
+
+    pScrn = xf86ScreenToScrn(pScreen);
+    if (pScrn->modes == NULL)
         return FALSE;
 
     pVidMode = VMPTR(pScreen);
+    pVidMode->First = pScrn->modes;
+    pVidMode->Next = pVidMode->First->next;
 
-    for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
-        if (p->status == MODE_OK) {
-            pVidMode->Next = p->next;
-            *mode = p;
-            *dotClock = VidModeGetDotClock(pScreen, p->Clock);
-            return TRUE;
-        }
+    if (pVidMode->First->status == MODE_OK) {
+        *mode = pVidMode->First;
+        *dotClock = xf86VidModeGetDotClock(pScreen, pVidMode->First->Clock);
+        return TRUE;
     }
 
-    return FALSE;
+    return xf86VidModeGetNextModeline(pScreen, mode, dotClock);
 }
 
 Bool
-VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
+xf86VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!VidModeAvailable(pScreen)))
+    if ((mode == NULL) || (!xf86VidModeAvailable(pScreen)))
         return FALSE;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -234,9 +250,9 @@ VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
 }
 
 Bool
-VidModeZoomViewport(ScreenPtr pScreen, int zoom)
+xf86VidModeZoomViewport(ScreenPtr pScreen, int zoom)
 {
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     xf86ZoomViewport(pScreen, zoom);
@@ -244,11 +260,11 @@ VidModeZoomViewport(ScreenPtr pScreen, int zoom)
 }
 
 Bool
-VidModeSetViewPort(ScreenPtr pScreen, int x, int y)
+xf86VidModeSetViewPort(ScreenPtr pScreen, int x, int y)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -265,11 +281,11 @@ VidModeSetViewPort(ScreenPtr pScreen, int x, int y)
 }
 
 Bool
-VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
+xf86VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -279,13 +295,13 @@ VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
 }
 
 Bool
-VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
+xf86VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
     DisplayModePtr pTmpMode;
     Bool retval;
 
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -301,9 +317,9 @@ VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
 }
 
 Bool
-VidModeLockZoom(ScreenPtr pScreen, Bool lock)
+xf86VidModeLockZoom(ScreenPtr pScreen, Bool lock)
 {
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     if (xf86Info.dontZoom)
@@ -314,11 +330,11 @@ VidModeLockZoom(ScreenPtr pScreen, Bool lock)
 }
 
 ModeStatus
-VidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
+xf86VidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!VidModeAvailable(pScreen)))
+    if ((mode == NULL) || (!xf86VidModeAvailable(pScreen)))
         return MODE_ERROR;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -327,11 +343,11 @@ VidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
 }
 
 ModeStatus
-VidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode)
+xf86VidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!VidModeAvailable(pScreen)))
+    if ((mode == NULL) || (!xf86VidModeAvailable(pScreen)))
         return MODE_ERROR;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -340,12 +356,12 @@ VidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode)
 }
 
 void
-VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode)
+xf86VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
     DisplayModePtr ScreenModes;
 
-    if ((mode == NULL) || (!VidModeAvailable(pScreen)))
+    if ((mode == NULL) || (!xf86VidModeAvailable(pScreen)))
         return;
 
     /* Ugly hack so that the xf86Mode.c function can be used without change */
@@ -359,11 +375,11 @@ VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode)
 }
 
 Bool
-VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
+xf86VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!VidModeAvailable(pScreen)))
+    if ((mode == NULL) || (!xf86VidModeAvailable(pScreen)))
         return FALSE;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -380,27 +396,27 @@ VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
 }
 
 int
-VidModeGetNumOfModes(ScreenPtr pScreen)
+xf86VidModeGetNumOfModes(ScreenPtr pScreen)
 {
     DisplayModePtr mode = NULL;
     int dotClock = 0, nummodes = 0;
 
-    if (!VidModeGetFirstModeline(pScreen, &mode, &dotClock))
+    if (!xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock))
         return nummodes;
 
     do {
         nummodes++;
-        if (!VidModeGetNextModeline(pScreen, &mode, &dotClock))
+        if (!xf86VidModeGetNextModeline(pScreen, &mode, &dotClock))
             return nummodes;
     } while (TRUE);
 }
 
 Bool
-VidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue)
+xf86VidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue)
 {
     Gamma gamma;
 
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     gamma.red = red;
@@ -413,11 +429,11 @@ VidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue)
 }
 
 Bool
-VidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
+xf86VidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     pScrn = xf86ScreenToScrn(pScreen);
@@ -428,9 +444,9 @@ VidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
 }
 
 Bool
-VidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
+xf86VidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
 {
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     xf86ChangeGammaRamp(pScreen, size, r, g, b);
@@ -438,9 +454,9 @@ VidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b
 }
 
 Bool
-VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
+xf86VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
 {
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return FALSE;
 
     xf86GetGammaRamp(pScreen, size, r, g, b);
@@ -448,54 +464,39 @@ VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b
 }
 
 int
-VidModeGetGammaRampSize(ScreenPtr pScreen)
+xf86VidModeGetGammaRampSize(ScreenPtr pScreen)
 {
-    if (!VidModeAvailable(pScreen))
+    if (!xf86VidModeAvailable(pScreen))
         return 0;
 
     return xf86GetGammaRampSize(pScreen);
 }
 
-vidMonitorValue
-VidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
+#endif                          /* XF86VIDMODE */
+
+Bool
+xf86VidModeExtensionInit(ScreenPtr pScreen)
 {
-    vidMonitorValue ret = { NULL, };
-    MonPtr monitor;
-    ScrnInfoPtr pScrn;
+#ifdef XF86VIDMODE
+    VidModePtr pVidMode;
 
-    if (!VidModeAvailable(pScreen))
-        return ret;
+    if (!xf86GetVidModeEnabled()) {
+        DebugF("!xf86GetVidModeEnabled()\n");
+        return FALSE;
+    }
 
-    pScrn = xf86ScreenToScrn(pScreen);
-    monitor = pScrn->monitor;
+    if (!dixRegisterPrivateKey(&VidModeKeyRec, PRIVATE_SCREEN, sizeof(VidModeRec)))
+        return FALSE;
 
-    switch (valtyp) {
-    case VIDMODE_MON_VENDOR:
-        ret.ptr = monitor->vendor;
-        break;
-    case VIDMODE_MON_MODEL:
-        ret.ptr = monitor->model;
-        break;
-    case VIDMODE_MON_NHSYNC:
-        ret.i = monitor->nHsync;
-        break;
-    case VIDMODE_MON_NVREFRESH:
-        ret.i = monitor->nVrefresh;
-        break;
-    case VIDMODE_MON_HSYNC_LO:
-        ret.f = (100.0 * monitor->hsync[indx].lo);
-        break;
-    case VIDMODE_MON_HSYNC_HI:
-        ret.f = (100.0 * monitor->hsync[indx].hi);
-        break;
-    case VIDMODE_MON_VREFRESH_LO:
-        ret.f = (100.0 * monitor->vrefresh[indx].lo);
-        break;
-    case VIDMODE_MON_VREFRESH_HI:
-        ret.f = (100.0 * monitor->vrefresh[indx].hi);
-        break;
-    }
-    return ret;
+    pVidMode = VMPTR(pScreen);
+
+    pVidMode->Flags = 0;
+    pVidMode->Next = NULL;
+
+    return TRUE;
+#else
+    DebugF("no vidmode extension\n");
+    return FALSE;
+#endif
 }
 
-#endif                          /* XF86VIDMODE */
diff --git a/hw/xfree86/common/xf86vmode.c b/hw/xfree86/common/xf86vmode.c
index 90216cc..0ad1b8d 100644
--- a/hw/xfree86/common/xf86vmode.c
+++ b/hw/xfree86/common/xf86vmode.c
@@ -251,7 +251,7 @@ ProcXF86VidModeGetModeLine(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
+    if (!xf86VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     rep.dotclock = dotClock;
@@ -343,11 +343,11 @@ ProcXF86VidModeGetAllModeLines(ClientPtr client)
     pScreen = screenInfo.screens[stuff->screen];
     ver = ClientMajorVersion(client);
 
-    modecount = VidModeGetNumOfModes(pScreen);
+    modecount = xf86VidModeGetNumOfModes(pScreen);
     if (modecount < 1)
         return VidModeErrorBase + XF86VidModeExtensionDisabled;
 
-    if (!VidModeGetFirstModeline(pScreen, &mode, &dotClock))
+    if (!xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     rep = (xXF86VidModeGetAllModeLinesReply) {
@@ -418,7 +418,7 @@ ProcXF86VidModeGetAllModeLines(ClientPtr client)
             WriteToClient(client, sizeof(xXF86VidModeModeInfo), &mdinf);
         }
 
-    } while (VidModeGetNextModeline(pScreen, &mode, &dotClock));
+    } while (xf86VidModeGetNextModeline(pScreen, &mode, &dotClock));
 
     return Success;
 }
@@ -536,14 +536,14 @@ ProcXF86VidModeAddModeLine(ClientPtr client)
     if (stuff->after_htotal != 0 || stuff->after_vtotal != 0) {
         Bool found = FALSE;
 
-        if (VidModeGetFirstModeline(pScreen, &mode, &dotClock)) {
+        if (xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock)) {
             do {
-                if ((VidModeGetDotClock(pScreen, stuff->dotclock)
+                if ((xf86VidModeGetDotClock(pScreen, stuff->dotclock)
                      == dotClock) && MODEMATCH(mode, stuff)) {
                     found = TRUE;
                     break;
                 }
-            } while (VidModeGetNextModeline(pScreen, &mode, &dotClock));
+            } while (xf86VidModeGetNextModeline(pScreen, &mode, &dotClock));
         }
         if (!found)
             return BadValue;
@@ -569,7 +569,7 @@ ProcXF86VidModeAddModeLine(ClientPtr client)
         ErrorF("AddModeLine - Privates in request have been ignored\n");
 
     /* Check that the mode is consistent with the monitor specs */
-    switch (VidModeCheckModeForMonitor(pScreen, mode)) {
+    switch (xf86VidModeCheckModeForMonitor(pScreen, mode)) {
     case MODE_OK:
         break;
     case MODE_HSYNC:
@@ -586,14 +586,14 @@ ProcXF86VidModeAddModeLine(ClientPtr client)
     }
 
     /* Check that the driver is happy with the mode */
-    if (VidModeCheckModeForDriver(pScreen, mode) != MODE_OK) {
+    if (xf86VidModeCheckModeForDriver(pScreen, mode) != MODE_OK) {
         free(mode);
         return VidModeErrorBase + XF86VidModeModeUnsuitable;
     }
 
-    VidModeSetCrtcForMode(pScreen, mode);
+    xf86VidModeSetCrtcForMode(pScreen, mode);
 
-    VidModeAddModeline(pScreen, mode);
+    xf86VidModeAddModeline(pScreen, mode);
 
     if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
         ErrorF("AddModeLine - Succeeded\n");
@@ -672,7 +672,7 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
+    if (!xf86VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
@@ -691,11 +691,11 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client)
              VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
              VidModeGetModeValue(mode, VIDMODE_FLAGS));
     }
-    if ((VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
+    if ((xf86VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
         MODEMATCH(mode, stuff))
         return BadValue;
 
-    if (!VidModeGetFirstModeline(pScreen, &mode, &dotClock))
+    if (!xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     do {
@@ -715,14 +715,14 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client)
                  VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
                  VidModeGetModeValue(mode, VIDMODE_FLAGS));
         }
-        if ((VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
+        if ((xf86VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
             MODEMATCH(mode, stuff)) {
-            VidModeDeleteModeline(pScreen, mode);
+            xf86VidModeDeleteModeline(pScreen, mode);
             if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
                 ErrorF("DeleteModeLine - Succeeded\n");
             return Success;
         }
-    } while (VidModeGetNextModeline(pScreen, &mode, &dotClock));
+    } while (xf86VidModeGetNextModeline(pScreen, &mode, &dotClock));
 
     return BadValue;
 }
@@ -794,7 +794,7 @@ ProcXF86VidModeModModeLine(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
+    if (!xf86VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     modetmp = VidModeCreateMode();
@@ -815,7 +815,7 @@ ProcXF86VidModeModModeLine(ClientPtr client)
         ErrorF("ModModeLine - Privates in request have been ignored\n");
 
     /* Check that the mode is consistent with the monitor specs */
-    switch (VidModeCheckModeForMonitor(pScreen, modetmp)) {
+    switch (xf86VidModeCheckModeForMonitor(pScreen, modetmp)) {
     case MODE_OK:
         break;
     case MODE_HSYNC:
@@ -832,7 +832,7 @@ ProcXF86VidModeModModeLine(ClientPtr client)
     }
 
     /* Check that the driver is happy with the mode */
-    if (VidModeCheckModeForDriver(pScreen, modetmp) != MODE_OK) {
+    if (xf86VidModeCheckModeForDriver(pScreen, modetmp) != MODE_OK) {
         free(modetmp);
         return VidModeErrorBase + XF86VidModeModeUnsuitable;
     }
@@ -849,8 +849,8 @@ ProcXF86VidModeModModeLine(ClientPtr client)
     VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
     VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
 
-    VidModeSetCrtcForMode(pScreen, mode);
-    VidModeSwitchMode(pScreen, mode);
+    xf86VidModeSetCrtcForMode(pScreen, mode);
+    xf86VidModeSwitchMode(pScreen, mode);
 
     if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
         ErrorF("ModModeLine - Succeeded\n");
@@ -933,7 +933,7 @@ ProcXF86VidModeValidateModeLine(ClientPtr client)
         goto status_reply;
     }
 
-    if (!VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
+    if (!xf86VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     modetmp = VidModeCreateMode();
@@ -954,11 +954,11 @@ ProcXF86VidModeValidateModeLine(ClientPtr client)
 
     /* Check that the mode is consistent with the monitor specs */
     if ((status =
-         VidModeCheckModeForMonitor(pScreen, modetmp)) != MODE_OK)
+         xf86VidModeCheckModeForMonitor(pScreen, modetmp)) != MODE_OK)
         goto status_reply;
 
     /* Check that the driver is happy with the mode */
-    status = VidModeCheckModeForDriver(pScreen, modetmp);
+    status = xf86VidModeCheckModeForDriver(pScreen, modetmp);
 
  status_reply:
     free(modetmp);
@@ -995,7 +995,7 @@ ProcXF86VidModeSwitchMode(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    VidModeZoomViewport(pScreen, (short) stuff->zoom);
+    xf86VidModeZoomViewport(pScreen, (short) stuff->zoom);
 
     return Success;
 }
@@ -1064,14 +1064,14 @@ ProcXF86VidModeSwitchToMode(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
+    if (!xf86VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
-    if ((VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock)
+    if ((xf86VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock)
         && MODEMATCH(mode, stuff))
         return Success;
 
-    if (!VidModeGetFirstModeline(pScreen, &mode, &dotClock))
+    if (!xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     do {
@@ -1091,17 +1091,17 @@ ProcXF86VidModeSwitchToMode(ClientPtr client)
                  VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
                  VidModeGetModeValue(mode, VIDMODE_FLAGS));
         }
-        if ((VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
+        if ((xf86VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
             MODEMATCH(mode, stuff)) {
 
-            if (!VidModeSwitchMode(pScreen, mode))
+            if (!xf86VidModeSwitchMode(pScreen, mode))
                 return BadValue;
 
             if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
                 ErrorF("SwitchToMode - Succeeded\n");
             return Success;
         }
-    } while (VidModeGetNextModeline(pScreen, &mode, &dotClock));
+    } while (xf86VidModeGetNextModeline(pScreen, &mode, &dotClock));
 
     return BadValue;
 }
@@ -1120,7 +1120,7 @@ ProcXF86VidModeLockModeSwitch(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeLockZoom(pScreen, (short) stuff->lock))
+    if (!xf86VidModeLockZoom(pScreen, (short) stuff->lock))
         return VidModeErrorBase + XF86VidModeZoomLocked;
 
     return Success;
@@ -1146,19 +1146,19 @@ ProcXF86VidModeGetMonitor(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    nHsync = VidModeGetMonitorValue(pScreen, VIDMODE_MON_NHSYNC, 0).i;
-    nVrefresh = VidModeGetMonitorValue(pScreen, VIDMODE_MON_NVREFRESH, 0).i;
+    nHsync = xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_NHSYNC, 0).i;
+    nVrefresh = xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_NVREFRESH, 0).i;
 
-    if ((char *) (VidModeGetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr)
-        rep.vendorLength = strlen((char *) (VidModeGetMonitorValue(pScreen,
-                                                                   VIDMODE_MON_VENDOR,
-                                                                   0)).ptr);
+    if ((char *) (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr)
+        rep.vendorLength = strlen((char *) (xf86VidModeGetMonitorValue(pScreen,
+                                                                       VIDMODE_MON_VENDOR,
+                                                                       0)).ptr);
     else
         rep.vendorLength = 0;
-    if ((char *) (VidModeGetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr)
-        rep.modelLength = strlen((char *) (VidModeGetMonitorValue(pScreen,
-                                                                  VIDMODE_MON_MODEL,
-                                                                  0)).ptr);
+    if ((char *) (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr)
+        rep.modelLength = strlen((char *) (xf86VidModeGetMonitorValue(pScreen,
+                                                                      VIDMODE_MON_MODEL,
+                                                                      0)).ptr);
     else
         rep.modelLength = 0;
     rep.length =
@@ -1181,20 +1181,20 @@ ProcXF86VidModeGetMonitor(ClientPtr client)
     }
 
     for (i = 0; i < nHsync; i++) {
-        hsyncdata[i] = (unsigned short) (VidModeGetMonitorValue(pScreen,
-                                                                VIDMODE_MON_HSYNC_LO,
-                                                                i)).f |
+        hsyncdata[i] = (unsigned short) (xf86VidModeGetMonitorValue(pScreen,
+                                                                    VIDMODE_MON_HSYNC_LO,
+                                                                    i)).f |
             (unsigned
-             short) (VidModeGetMonitorValue(pScreen, VIDMODE_MON_HSYNC_HI,
+             short) (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_HSYNC_HI,
                                             i)).f << 16;
     }
     for (i = 0; i < nVrefresh; i++) {
-        vsyncdata[i] = (unsigned short) (VidModeGetMonitorValue(pScreen,
-                                                                VIDMODE_MON_VREFRESH_LO,
-                                                                i)).f |
+        vsyncdata[i] = (unsigned short) (xf86VidModeGetMonitorValue(pScreen,
+                                                                    VIDMODE_MON_VREFRESH_LO,
+                                                                    i)).f |
             (unsigned
-             short) (VidModeGetMonitorValue(pScreen, VIDMODE_MON_VREFRESH_HI,
-                                            i)).f << 16;
+             short) (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_VREFRESH_HI,
+                                                i)).f << 16;
     }
 
     if (client->swapped) {
@@ -1207,10 +1207,10 @@ ProcXF86VidModeGetMonitor(ClientPtr client)
     WriteSwappedDataToClient(client, nVrefresh * sizeof(CARD32), vsyncdata);
     if (rep.vendorLength)
         WriteToClient(client, rep.vendorLength,
-                 (VidModeGetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr);
+                 (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr);
     if (rep.modelLength)
         WriteToClient(client, rep.modelLength,
-                 (VidModeGetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr);
+                 (xf86VidModeGetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr);
 
     free(hsyncdata);
     free(vsyncdata);
@@ -1234,7 +1234,7 @@ ProcXF86VidModeGetViewPort(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    VidModeGetViewPort(pScreen, &x, &y);
+    xf86VidModeGetViewPort(pScreen, &x, &y);
 
     rep = (xXF86VidModeGetViewPortReply) {
         .type = X_Reply,
@@ -1268,7 +1268,7 @@ ProcXF86VidModeSetViewPort(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeSetViewPort(pScreen, stuff->x, stuff->y))
+    if (!xf86VidModeSetViewPort(pScreen, stuff->x, stuff->y))
         return BadValue;
 
     return Success;
@@ -1294,7 +1294,7 @@ ProcXF86VidModeGetDotClocks(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    numClocks = VidModeGetNumOfClocks(pScreen, &ClockProg);
+    numClocks = xf86VidModeGetNumOfClocks(pScreen, &ClockProg);
 
     rep = (xXF86VidModeGetDotClocksReply) {
         .type = X_Reply,
@@ -1310,7 +1310,7 @@ ProcXF86VidModeGetDotClocks(ClientPtr client)
         Clocks = calloc(numClocks, sizeof(int));
         if (!Clocks)
             return BadValue;
-        if (!VidModeGetClocks(pScreen, Clocks)) {
+        if (!xf86VidModeGetClocks(pScreen, Clocks)) {
             free(Clocks);
             return BadValue;
         }
@@ -1356,9 +1356,9 @@ ProcXF86VidModeSetGamma(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeSetGamma(pScreen, ((float) stuff->red) / 10000.,
-                         ((float) stuff->green) / 10000.,
-                         ((float) stuff->blue) / 10000.))
+    if (!xf86VidModeSetGamma(pScreen, ((float) stuff->red) / 10000.,
+                                      ((float) stuff->green) / 10000.,
+                                      ((float) stuff->blue) / 10000.))
         return BadValue;
 
     return Success;
@@ -1380,7 +1380,7 @@ ProcXF86VidModeGetGamma(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetGamma(pScreen, &red, &green, &blue))
+    if (!xf86VidModeGetGamma(pScreen, &red, &green, &blue))
         return BadValue;
     rep = (xXF86VidModeGetGammaReply) {
         .type = X_Reply,
@@ -1415,7 +1415,7 @@ ProcXF86VidModeSetGammaRamp(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    if (stuff->size != VidModeGetGammaRampSize(pScreen))
+    if (stuff->size != xf86VidModeGetGammaRampSize(pScreen))
         return BadValue;
 
     length = (stuff->size + 1) & ~1;
@@ -1426,7 +1426,7 @@ ProcXF86VidModeSetGammaRamp(ClientPtr client)
     g = r + length;
     b = g + length;
 
-    if (!VidModeSetGammaRamp(pScreen, stuff->size, r, g, b))
+    if (!xf86VidModeSetGammaRamp(pScreen, stuff->size, r, g, b))
         return BadValue;
 
     return Success;
@@ -1449,7 +1449,7 @@ ProcXF86VidModeGetGammaRamp(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    if (stuff->size != VidModeGetGammaRampSize(pScreen))
+    if (stuff->size != xf86VidModeGetGammaRampSize(pScreen))
         return BadValue;
 
     length = (stuff->size + 1) & ~1;
@@ -1459,8 +1459,8 @@ ProcXF86VidModeGetGammaRamp(ClientPtr client)
             return BadAlloc;
         ramplen = length * 3 * sizeof(CARD16);
 
-        if (!VidModeGetGammaRamp(pScreen, stuff->size,
-                                 ramp, ramp + length, ramp + (length * 2))) {
+        if (!xf86VidModeGetGammaRamp(pScreen, stuff->size,
+                                     ramp, ramp + length, ramp + (length * 2))) {
             free(ramp);
             return BadValue;
         }
@@ -1505,7 +1505,7 @@ ProcXF86VidModeGetGammaRampSize(ClientPtr client)
         .type = X_Reply,
         .sequenceNumber = client->sequence,
         .length = 0,
-        .size = VidModeGetGammaRampSize(pScreen)
+        .size = xf86VidModeGetGammaRampSize(pScreen)
     };
     if (client->swapped) {
         swaps(&rep.sequenceNumber);
@@ -2072,7 +2072,7 @@ XFree86VidModeExtensionInit(void)
 
     for (i = 0; i < screenInfo.numScreens; i++) {
         pScreen = screenInfo.screens[i];
-        if (VidModeExtensionInit(pScreen))
+        if (xf86VidModeExtensionInit(pScreen))
             enabled = TRUE;
     }
     /* This means that the DDX doesn't want the vidmode extension enabled */
commit 64053645cfd950bb0b6c3fda8deb60e1e540ce69
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Feb 5 09:48:21 2016 +0100

    vidmode: move display mode definitions
    
    To be able to reuse the VidMode extension in a non-hardware server, the
    display mode definitions need to be accessible from DIX.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit ddfb8c009ac651209eb0087aaf86b54e1446e8b2)

diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index a58fafe..5e6e977 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -41,6 +41,7 @@
 #include "colormapst.h"
 #include "xf86Module.h"
 #include "xf86Opt.h"
+#include "displaymode.h"
 
 /**
  * Integer type that is of the size of the addressable memory (machine size).
@@ -84,48 +85,6 @@ typedef enum {
     MODECHECK_FINAL = 1
 } ModeCheckFlags;
 
-/* These are possible return values for xf86CheckMode() and ValidMode() */
-typedef enum {
-    MODE_OK = 0,                /* Mode OK */
-    MODE_HSYNC,                 /* hsync out of range */
-    MODE_VSYNC,                 /* vsync out of range */
-    MODE_H_ILLEGAL,             /* mode has illegal horizontal timings */
-    MODE_V_ILLEGAL,             /* mode has illegal horizontal timings */
-    MODE_BAD_WIDTH,             /* requires an unsupported linepitch */
-    MODE_NOMODE,                /* no mode with a maching name */
-    MODE_NO_INTERLACE,          /* interlaced mode not supported */
-    MODE_NO_DBLESCAN,           /* doublescan mode not supported */
-    MODE_NO_VSCAN,              /* multiscan mode not supported */
-    MODE_MEM,                   /* insufficient video memory */
-    MODE_VIRTUAL_X,             /* mode width too large for specified virtual size */
-    MODE_VIRTUAL_Y,             /* mode height too large for specified virtual size */
-    MODE_MEM_VIRT,              /* insufficient video memory given virtual size */
-    MODE_NOCLOCK,               /* no fixed clock available */
-    MODE_CLOCK_HIGH,            /* clock required is too high */
-    MODE_CLOCK_LOW,             /* clock required is too low */
-    MODE_CLOCK_RANGE,           /* clock/mode isn't in a ClockRange */
-    MODE_BAD_HVALUE,            /* horizontal timing was out of range */
-    MODE_BAD_VVALUE,            /* vertical timing was out of range */
-    MODE_BAD_VSCAN,             /* VScan value out of range */
-    MODE_HSYNC_NARROW,          /* horizontal sync too narrow */
-    MODE_HSYNC_WIDE,            /* horizontal sync too wide */
-    MODE_HBLANK_NARROW,         /* horizontal blanking too narrow */
-    MODE_HBLANK_WIDE,           /* horizontal blanking too wide */
-    MODE_VSYNC_NARROW,          /* vertical sync too narrow */
-    MODE_VSYNC_WIDE,            /* vertical sync too wide */
-    MODE_VBLANK_NARROW,         /* vertical blanking too narrow */
-    MODE_VBLANK_WIDE,           /* vertical blanking too wide */
-    MODE_PANEL,                 /* exceeds panel dimensions */
-    MODE_INTERLACE_WIDTH,       /* width too large for interlaced mode */
-    MODE_ONE_WIDTH,             /* only one width is supported */
-    MODE_ONE_HEIGHT,            /* only one height is supported */
-    MODE_ONE_SIZE,              /* only one resolution is supported */
-    MODE_NO_REDUCED,            /* monitor doesn't accept reduced blanking */
-    MODE_BANDWIDTH,             /* mode requires too much memory bandwidth */
-    MODE_BAD = -2,              /* unspecified reason */
-    MODE_ERROR = -1             /* error condition */
-} ModeStatus;
-
 /*
  * The mode sets are, from best to worst: USERDEF, DRIVER, and DEFAULT/BUILTIN.
  * Preferred will bubble a mode to the top within a set.
@@ -141,54 +100,6 @@ typedef enum {
 #define M_T_DRIVER  0x40        /* Supplied by the driver (EDID, etc) */
 #define M_T_USERPREF 0x80       /* mode preferred by the user config */
 
-/* Video mode */
-typedef struct _DisplayModeRec {
-    struct _DisplayModeRec *prev;
-    struct _DisplayModeRec *next;
-    const char *name;           /* identifier for the mode */
-    ModeStatus status;
-    int type;
-
-    /* These are the values that the user sees/provides */
-    int Clock;                  /* pixel clock freq (kHz) */
-    int HDisplay;               /* horizontal timing */
-    int HSyncStart;
-    int HSyncEnd;
-    int HTotal;
-    int HSkew;
-    int VDisplay;               /* vertical timing */
-    int VSyncStart;
-    int VSyncEnd;
-    int VTotal;
-    int VScan;
-    int Flags;
-
-    /* These are the values the hardware uses */
-    int ClockIndex;
-    int SynthClock;             /* Actual clock freq to
-                                 * be programmed  (kHz) */
-    int CrtcHDisplay;
-    int CrtcHBlankStart;
-    int CrtcHSyncStart;
-    int CrtcHSyncEnd;
-    int CrtcHBlankEnd;
-    int CrtcHTotal;
-    int CrtcHSkew;
-    int CrtcVDisplay;
-    int CrtcVBlankStart;
-    int CrtcVSyncStart;
-    int CrtcVSyncEnd;
-    int CrtcVBlankEnd;
-    int CrtcVTotal;
-    Bool CrtcHAdjusted;
-    Bool CrtcVAdjusted;
-    int PrivSize;
-    INT32 *Private;
-    int PrivFlags;
-
-    float HSync, VRefresh;
-} DisplayModeRec, *DisplayModePtr;
-
 /* The monitor description */
 
 #define MAX_HSYNC 8
@@ -377,7 +288,6 @@ typedef struct _bus {
     } id;
 } BusRec, *BusPtr;
 
-#define MAXCLOCKS   128
 typedef enum {
     DAC_BPP8 = 0,
     DAC_BPP16,
diff --git a/include/Makefile.am b/include/Makefile.am
index 70b83ff..4c8ea6a 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -53,6 +53,7 @@ sdk_HEADERS =		\
 	servermd.h	\
 	site.h		\
 	validate.h	\
+	displaymode.h    \
 	window.h	\
 	windowstr.h	\
 	xkbfile.h	\
diff --git a/include/displaymode.h b/include/displaymode.h
new file mode 100644
index 0000000..ad01b87
--- /dev/null
+++ b/include/displaymode.h
@@ -0,0 +1,102 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _DISMODEPROC_H_
+#define _DISMODEPROC_H_
+
+#include "scrnintstr.h"
+
+#define MAXCLOCKS   128
+
+/* These are possible return values for xf86CheckMode() and ValidMode() */
+typedef enum {
+    MODE_OK = 0,                /* Mode OK */
+    MODE_HSYNC,                 /* hsync out of range */
+    MODE_VSYNC,                 /* vsync out of range */
+    MODE_H_ILLEGAL,             /* mode has illegal horizontal timings */
+    MODE_V_ILLEGAL,             /* mode has illegal horizontal timings */
+    MODE_BAD_WIDTH,             /* requires an unsupported linepitch */
+    MODE_NOMODE,                /* no mode with a matching name */
+    MODE_NO_INTERLACE,          /* interlaced mode not supported */
+    MODE_NO_DBLESCAN,           /* doublescan mode not supported */
+    MODE_NO_VSCAN,              /* multiscan mode not supported */
+    MODE_MEM,                   /* insufficient video memory */
+    MODE_VIRTUAL_X,             /* mode width too large for specified virtual size */
+    MODE_VIRTUAL_Y,             /* mode height too large for specified virtual size */
+    MODE_MEM_VIRT,              /* insufficient video memory given virtual size */
+    MODE_NOCLOCK,               /* no fixed clock available */
+    MODE_CLOCK_HIGH,            /* clock required is too high */
+    MODE_CLOCK_LOW,             /* clock required is too low */
+    MODE_CLOCK_RANGE,           /* clock/mode isn't in a ClockRange */
+    MODE_BAD_HVALUE,            /* horizontal timing was out of range */
+    MODE_BAD_VVALUE,            /* vertical timing was out of range */
+    MODE_BAD_VSCAN,             /* VScan value out of range */
+    MODE_HSYNC_NARROW,          /* horizontal sync too narrow */
+    MODE_HSYNC_WIDE,            /* horizontal sync too wide */
+    MODE_HBLANK_NARROW,         /* horizontal blanking too narrow */
+    MODE_HBLANK_WIDE,           /* horizontal blanking too wide */
+    MODE_VSYNC_NARROW,          /* vertical sync too narrow */
+    MODE_VSYNC_WIDE,            /* vertical sync too wide */
+    MODE_VBLANK_NARROW,         /* vertical blanking too narrow */
+    MODE_VBLANK_WIDE,           /* vertical blanking too wide */
+    MODE_PANEL,                 /* exceeds panel dimensions */
+    MODE_INTERLACE_WIDTH,       /* width too large for interlaced mode */
+    MODE_ONE_WIDTH,             /* only one width is supported */
+    MODE_ONE_HEIGHT,            /* only one height is supported */
+    MODE_ONE_SIZE,              /* only one resolution is supported */
+    MODE_NO_REDUCED,            /* monitor doesn't accept reduced blanking */
+    MODE_BANDWIDTH,             /* mode requires too much memory bandwidth */
+    MODE_BAD = -2,              /* unspecified reason */
+    MODE_ERROR = -1             /* error condition */
+} ModeStatus;
+
+/* Video mode */
+typedef struct _DisplayModeRec {
+    struct _DisplayModeRec *prev;
+    struct _DisplayModeRec *next;
+    const char *name;           /* identifier for the mode */
+    ModeStatus status;
+    int type;
+
+    /* These are the values that the user sees/provides */
+    int Clock;                  /* pixel clock freq (kHz) */
+    int HDisplay;               /* horizontal timing */
+    int HSyncStart;
+    int HSyncEnd;
+    int HTotal;
+    int HSkew;
+    int VDisplay;               /* vertical timing */
+    int VSyncStart;
+    int VSyncEnd;
+    int VTotal;
+    int VScan;
+    int Flags;
+
+    /* These are the values the hardware uses */
+    int ClockIndex;
+    int SynthClock;             /* Actual clock freq to
+                                 * be programmed  (kHz) */
+    int CrtcHDisplay;
+    int CrtcHBlankStart;
+    int CrtcHSyncStart;
+    int CrtcHSyncEnd;
+    int CrtcHBlankEnd;
+    int CrtcHTotal;
+    int CrtcHSkew;
+    int CrtcVDisplay;
+    int CrtcVBlankStart;
+    int CrtcVSyncStart;
+    int CrtcVSyncEnd;
+    int CrtcVBlankEnd;
+    int CrtcVTotal;
+    Bool CrtcHAdjusted;
+    Bool CrtcVAdjusted;
+    int PrivSize;
+    INT32 *Private;
+    int PrivFlags;
+
+    float HSync, VRefresh;
+} DisplayModeRec, *DisplayModePtr;
+
+#endif
commit 227b533bf414e03e9a73d0d9e47a761fc597c360
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Feb 5 09:48:20 2016 +0100

    vidmode: remove mode access from public API
    
    The mode access functions (namely VidModeCreateMode(),
    VidModeCopyMode(), VidModeGetModeValue() and VidModeSetModeValue()) are
    used only in xf86VidMode code and do not need to be available anywhere
    else.
    
    Remove these functions from the public VidMode API and move them as
    static where they are used.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit e29a64de662112b8ebcd3f20c89df0e8c51890ef)

diff --git a/hw/xfree86/common/vidmodeproc.h b/hw/xfree86/common/vidmodeproc.h
index 3cc8fc1..3919a0c 100644
--- a/hw/xfree86/common/vidmodeproc.h
+++ b/hw/xfree86/common/vidmodeproc.h
@@ -67,10 +67,6 @@ extern Bool VidModeSetGamma(ScreenPtr pScreen, float red, float green,
                             float blue);
 extern Bool VidModeGetGamma(ScreenPtr pScreen, float *red, float *green,
                             float *blue);
-extern DisplayModePtr VidModeCreateMode(void);
-extern void VidModeCopyMode(DisplayModePtr modefrom, DisplayModePtr modeto);
-extern int VidModeGetModeValue(DisplayModePtr mode, int valtyp);
-extern void VidModeSetModeValue(DisplayModePtr mode, int valtyp, int val);
 extern vidMonitorValue VidModeGetMonitorValue(ScreenPtr pScreen,
                                               int valtyp, int indx);
 extern Bool VidModeSetGammaRamp(ScreenPtr, int, CARD16 *, CARD16 *,
diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index 5f596b5..2d87daa 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -456,112 +456,6 @@ VidModeGetGammaRampSize(ScreenPtr pScreen)
     return xf86GetGammaRampSize(pScreen);
 }
 
-DisplayModePtr
-VidModeCreateMode(void)
-{
-    DisplayModePtr mode;
-
-    mode = malloc(sizeof(DisplayModeRec));
-    if (mode != NULL) {
-        mode->name = "";
-        mode->VScan = 1;        /* divides refresh rate. default = 1 */
-        mode->Private = NULL;
-        mode->next = mode;
-        mode->prev = mode;
-    }
-    return mode;
-}
-
-void
-VidModeCopyMode(DisplayModePtr modefrom, DisplayModePtr modeto)
-{
-    memcpy(modeto, modefrom, sizeof(DisplayModeRec));
-}
-
-int
-VidModeGetModeValue(DisplayModePtr mode, int valtyp)
-{
-    int ret = 0;
-
-    switch (valtyp) {
-    case VIDMODE_H_DISPLAY:
-        ret = mode->HDisplay;
-        break;
-    case VIDMODE_H_SYNCSTART:
-        ret = mode->HSyncStart;
-        break;
-    case VIDMODE_H_SYNCEND:
-        ret = mode->HSyncEnd;
-        break;
-    case VIDMODE_H_TOTAL:
-        ret = mode->HTotal;
-        break;
-    case VIDMODE_H_SKEW:
-        ret = mode->HSkew;
-        break;
-    case VIDMODE_V_DISPLAY:
-        ret = mode->VDisplay;
-        break;
-    case VIDMODE_V_SYNCSTART:
-        ret = mode->VSyncStart;
-        break;
-    case VIDMODE_V_SYNCEND:
-        ret = mode->VSyncEnd;
-        break;
-    case VIDMODE_V_TOTAL:
-        ret = mode->VTotal;
-        break;
-    case VIDMODE_FLAGS:
-        ret = mode->Flags;
-        break;
-    case VIDMODE_CLOCK:
-        ret = mode->Clock;
-        break;
-    }
-    return ret;
-}
-
-void
-VidModeSetModeValue(DisplayModePtr mode, int valtyp, int val)
-{
-    switch (valtyp) {
-    case VIDMODE_H_DISPLAY:
-        mode->HDisplay = val;
-        break;
-    case VIDMODE_H_SYNCSTART:
-        mode->HSyncStart = val;
-        break;
-    case VIDMODE_H_SYNCEND:
-        mode->HSyncEnd = val;
-        break;
-    case VIDMODE_H_TOTAL:
-        mode->HTotal = val;
-        break;
-    case VIDMODE_H_SKEW:
-        mode->HSkew = val;
-        break;
-    case VIDMODE_V_DISPLAY:
-        mode->VDisplay = val;
-        break;
-    case VIDMODE_V_SYNCSTART:
-        mode->VSyncStart = val;
-        break;
-    case VIDMODE_V_SYNCEND:
-        mode->VSyncEnd = val;
-        break;
-    case VIDMODE_V_TOTAL:
-        mode->VTotal = val;
-        break;
-    case VIDMODE_FLAGS:
-        mode->Flags = val;
-        break;
-    case VIDMODE_CLOCK:
-        mode->Clock = val;
-        break;
-    }
-    return;
-}
-
 vidMonitorValue
 VidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
 {
diff --git a/hw/xfree86/common/xf86vmode.c b/hw/xfree86/common/xf86vmode.c
index b74ec6e..90216cc 100644
--- a/hw/xfree86/common/xf86vmode.c
+++ b/hw/xfree86/common/xf86vmode.c
@@ -76,7 +76,114 @@ static unsigned char XF86VidModeReqCode = 0;
 #else
 #define DEBUG_P(x) /**/
 #endif
-    static int
+
+static DisplayModePtr
+VidModeCreateMode(void)
+{
+    DisplayModePtr mode;
+
+    mode = malloc(sizeof(DisplayModeRec));
+    if (mode != NULL) {
+        mode->name = "";
+        mode->VScan = 1;        /* divides refresh rate. default = 1 */
+        mode->Private = NULL;
+        mode->next = mode;
+        mode->prev = mode;
+    }
+    return mode;
+}
+
+static void
+VidModeCopyMode(DisplayModePtr modefrom, DisplayModePtr modeto)
+{
+    memcpy(modeto, modefrom, sizeof(DisplayModeRec));
+}
+
+static int
+VidModeGetModeValue(DisplayModePtr mode, int valtyp)
+{
+    int ret = 0;
+
+    switch (valtyp) {
+    case VIDMODE_H_DISPLAY:
+        ret = mode->HDisplay;
+        break;
+    case VIDMODE_H_SYNCSTART:
+        ret = mode->HSyncStart;
+        break;
+    case VIDMODE_H_SYNCEND:
+        ret = mode->HSyncEnd;
+        break;
+    case VIDMODE_H_TOTAL:
+        ret = mode->HTotal;
+        break;
+    case VIDMODE_H_SKEW:
+        ret = mode->HSkew;
+        break;
+    case VIDMODE_V_DISPLAY:
+        ret = mode->VDisplay;
+        break;
+    case VIDMODE_V_SYNCSTART:
+        ret = mode->VSyncStart;
+        break;
+    case VIDMODE_V_SYNCEND:
+        ret = mode->VSyncEnd;
+        break;
+    case VIDMODE_V_TOTAL:
+        ret = mode->VTotal;
+        break;
+    case VIDMODE_FLAGS:
+        ret = mode->Flags;
+        break;
+    case VIDMODE_CLOCK:
+        ret = mode->Clock;
+        break;
+    }
+    return ret;
+}
+
+static void
+VidModeSetModeValue(DisplayModePtr mode, int valtyp, int val)
+{
+    switch (valtyp) {
+    case VIDMODE_H_DISPLAY:
+        mode->HDisplay = val;
+        break;
+    case VIDMODE_H_SYNCSTART:
+        mode->HSyncStart = val;
+        break;
+    case VIDMODE_H_SYNCEND:
+        mode->HSyncEnd = val;
+        break;
+    case VIDMODE_H_TOTAL:
+        mode->HTotal = val;
+        break;
+    case VIDMODE_H_SKEW:
+        mode->HSkew = val;
+        break;
+    case VIDMODE_V_DISPLAY:
+        mode->VDisplay = val;
+        break;
+    case VIDMODE_V_SYNCSTART:
+        mode->VSyncStart = val;
+        break;
+    case VIDMODE_V_SYNCEND:
+        mode->VSyncEnd = val;
+        break;
+    case VIDMODE_V_TOTAL:
+        mode->VTotal = val;
+        break;
+    case VIDMODE_FLAGS:
+        mode->Flags = val;
+        break;
+    case VIDMODE_CLOCK:
+        mode->Clock = val;
+        break;
+    }
+    return;
+}
+
+static int
 ClientMajorVersion(ClientPtr client)
 {
     VidModePrivPtr pPriv;
commit 9824faaa58efe55a372d7dd0f6c5cbf84e77af61
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Feb 5 09:48:19 2016 +0100

    vidmode: use appropriate DisplayModePtr type
    
    The API uses an untyped pointer (void *) where a DisplayModePtr is
    expected.
    
    Clean up the API to use the appropriate type, as DisplayModePtr is
    really all that will be passed there.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit b7962ade5265a21ac7c60da6cc07ece15ef7e648)

diff --git a/hw/xfree86/common/vidmodeproc.h b/hw/xfree86/common/vidmodeproc.h
index 792be9b..3cc8fc1 100644
--- a/hw/xfree86/common/vidmodeproc.h
+++ b/hw/xfree86/common/vidmodeproc.h
@@ -41,36 +41,36 @@ typedef union {
 
 extern Bool VidModeExtensionInit(ScreenPtr pScreen);
 
-extern Bool VidModeGetCurrentModeline(ScreenPtr pScreen, void **mode,
+extern Bool VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode,
                                       int *dotClock);
-extern Bool VidModeGetFirstModeline(ScreenPtr pScreen, void **mode,
+extern Bool VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode,
                                     int *dotClock);
-extern Bool VidModeGetNextModeline(ScreenPtr pScreen, void **mode,
+extern Bool VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode,
                                    int *dotClock);
-extern Bool VidModeDeleteModeline(ScreenPtr pScreen, void *mode);
+extern Bool VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode);
 extern Bool VidModeZoomViewport(ScreenPtr pScreen, int zoom);
 extern Bool VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y);
 extern Bool VidModeSetViewPort(ScreenPtr pScreen, int x, int y);
-extern Bool VidModeSwitchMode(ScreenPtr pScreen, void *mode);
+extern Bool VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode);
 extern Bool VidModeLockZoom(ScreenPtr pScreen, Bool lock);
 extern int VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock);
 extern Bool VidModeGetClocks(ScreenPtr pScreen, int *Clocks);
 extern ModeStatus VidModeCheckModeForMonitor(ScreenPtr pScreen,
-                                             void *mode);
+                                             DisplayModePtr mode);
 extern ModeStatus VidModeCheckModeForDriver(ScreenPtr pScreen,
-                                            void *mode);
-extern void VidModeSetCrtcForMode(ScreenPtr pScreen, void *mode);
-extern Bool VidModeAddModeline(ScreenPtr pScreen, void *mode);
+                                            DisplayModePtr mode);
+extern void VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode);
+extern Bool VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode);
 extern int VidModeGetDotClock(ScreenPtr pScreen, int Clock);
 extern int VidModeGetNumOfModes(ScreenPtr pScreen);
 extern Bool VidModeSetGamma(ScreenPtr pScreen, float red, float green,
                             float blue);
 extern Bool VidModeGetGamma(ScreenPtr pScreen, float *red, float *green,
                             float *blue);
-extern void *VidModeCreateMode(void);
-extern void VidModeCopyMode(void *modefrom, void *modeto);
-extern int VidModeGetModeValue(void *mode, int valtyp);
-extern void VidModeSetModeValue(void *mode, int valtyp, int val);
+extern DisplayModePtr VidModeCreateMode(void);
+extern void VidModeCopyMode(DisplayModePtr modefrom, DisplayModePtr modeto);
+extern int VidModeGetModeValue(DisplayModePtr mode, int valtyp);
+extern void VidModeSetModeValue(DisplayModePtr mode, int valtyp, int val);
 extern vidMonitorValue VidModeGetMonitorValue(ScreenPtr pScreen,
                                               int valtyp, int indx);
 extern Bool VidModeSetGammaRamp(ScreenPtr, int, CARD16 *, CARD16 *,
diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index 9182d93..5f596b5 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -99,7 +99,7 @@ VidModeAvailable(ScreenPtr pScreen)
 }
 
 Bool
-VidModeGetCurrentModeline(ScreenPtr pScreen, void **mode, int *dotClock)
+VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 {
     ScrnInfoPtr pScrn;
 
@@ -109,7 +109,7 @@ VidModeGetCurrentModeline(ScreenPtr pScreen, void **mode, int *dotClock)
     pScrn = xf86ScreenToScrn(pScreen);
 
     if (pScrn->currentMode) {
-        *mode = (void *) (pScrn->currentMode);
+        *mode = pScrn->currentMode;
         *dotClock = pScrn->currentMode->Clock;
 
         return TRUE;
@@ -172,7 +172,7 @@ VidModeGetClocks(ScreenPtr pScreen, int *Clocks)
 }
 
 Bool
-VidModeGetFirstModeline(ScreenPtr pScreen, void **mode, int *dotClock)
+VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 {
     ScrnInfoPtr pScrn;
     VidModePtr pVidMode;
@@ -189,7 +189,7 @@ VidModeGetFirstModeline(ScreenPtr pScreen, void **mode, int *dotClock)
     pVidMode->Next = pVidMode->First->next;
 
     if (pVidMode->First->status == MODE_OK) {
-        *mode = (void *) (pVidMode->First);
+        *mode = pVidMode->First;
         *dotClock = VidModeGetDotClock(pScreen, pVidMode->First->Clock);
         return TRUE;
     }
@@ -198,7 +198,7 @@ VidModeGetFirstModeline(ScreenPtr pScreen, void **mode, int *dotClock)
 }
 
 Bool
-VidModeGetNextModeline(ScreenPtr pScreen, void **mode, int *dotClock)
+VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
 {
     VidModePtr pVidMode;
     DisplayModePtr p;
@@ -211,7 +211,7 @@ VidModeGetNextModeline(ScreenPtr pScreen, void **mode, int *dotClock)
     for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
         if (p->status == MODE_OK) {
             pVidMode->Next = p->next;
-            *mode = (void *) p;
+            *mode = p;
             *dotClock = VidModeGetDotClock(pScreen, p->Clock);
             return TRUE;
         }
@@ -221,7 +221,7 @@ VidModeGetNextModeline(ScreenPtr pScreen, void **mode, int *dotClock)
 }
 
 Bool
-VidModeDeleteModeline(ScreenPtr pScreen, void *mode)
+VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
@@ -229,7 +229,7 @@ VidModeDeleteModeline(ScreenPtr pScreen, void *mode)
         return FALSE;
 
     pScrn = xf86ScreenToScrn(pScreen);
-    xf86DeleteMode(&(pScrn->modes), (DisplayModePtr) mode);
+    xf86DeleteMode(&(pScrn->modes), mode);
     return TRUE;
 }
 
@@ -279,7 +279,7 @@ VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
 }
 
 Bool
-VidModeSwitchMode(ScreenPtr pScreen, void *mode)
+VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
     DisplayModePtr pTmpMode;
@@ -314,7 +314,7 @@ VidModeLockZoom(ScreenPtr pScreen, Bool lock)
 }
 
 ModeStatus
-VidModeCheckModeForMonitor(ScreenPtr pScreen, void *mode)
+VidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
@@ -323,11 +323,11 @@ VidModeCheckModeForMonitor(ScreenPtr pScreen, void *mode)
 
     pScrn = xf86ScreenToScrn(pScreen);
 
-    return xf86CheckModeForMonitor((DisplayModePtr) mode, pScrn->monitor);
+    return xf86CheckModeForMonitor(mode, pScrn->monitor);
 }
 
 ModeStatus
-VidModeCheckModeForDriver(ScreenPtr pScreen, void *mode)
+VidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
@@ -336,11 +336,11 @@ VidModeCheckModeForDriver(ScreenPtr pScreen, void *mode)
 
     pScrn = xf86ScreenToScrn(pScreen);
 
-    return xf86CheckModeForDriver(pScrn, (DisplayModePtr) mode, 0);
+    return xf86CheckModeForDriver(pScrn, mode, 0);
 }
 
 void
-VidModeSetCrtcForMode(ScreenPtr pScreen, void *mode)
+VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
     DisplayModePtr ScreenModes;
@@ -351,7 +351,7 @@ VidModeSetCrtcForMode(ScreenPtr pScreen, void *mode)
     /* Ugly hack so that the xf86Mode.c function can be used without change */
     pScrn = xf86ScreenToScrn(pScreen);
     ScreenModes = pScrn->modes;
-    pScrn->modes = (DisplayModePtr) mode;
+    pScrn->modes = mode;
 
     xf86SetCrtcForModes(pScrn, pScrn->adjustFlags);
     pScrn->modes = ScreenModes;
@@ -359,7 +359,7 @@ VidModeSetCrtcForMode(ScreenPtr pScreen, void *mode)
 }
 
 Bool
-VidModeAddModeline(ScreenPtr pScreen, void *mode)
+VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn;
 
@@ -368,13 +368,13 @@ VidModeAddModeline(ScreenPtr pScreen, void *mode)
 
     pScrn = xf86ScreenToScrn(pScreen);
 
-    ((DisplayModePtr) mode)->name = strdup(""); /* freed by deletemode */
-    ((DisplayModePtr) mode)->status = MODE_OK;
-    ((DisplayModePtr) mode)->next = pScrn->modes->next;
-    ((DisplayModePtr) mode)->prev = pScrn->modes;
-    pScrn->modes->next = (DisplayModePtr) mode;
-    if (((DisplayModePtr) mode)->next != NULL)
-        ((DisplayModePtr) mode)->next->prev = (DisplayModePtr) mode;
+    mode->name = strdup(""); /* freed by deletemode */
+    mode->status = MODE_OK;
+    mode->next = pScrn->modes->next;
+    mode->prev = pScrn->modes;
+    pScrn->modes->next = mode;
+    if (mode->next != NULL)
+        mode->next->prev = mode;
 
     return TRUE;
 }
@@ -382,7 +382,7 @@ VidModeAddModeline(ScreenPtr pScreen, void *mode)
 int
 VidModeGetNumOfModes(ScreenPtr pScreen)
 {
-    void *mode = NULL;
+    DisplayModePtr mode = NULL;
     int dotClock = 0, nummodes = 0;
 
     if (!VidModeGetFirstModeline(pScreen, &mode, &dotClock))
@@ -456,7 +456,7 @@ VidModeGetGammaRampSize(ScreenPtr pScreen)
     return xf86GetGammaRampSize(pScreen);
 }
 
-void *
+DisplayModePtr
 VidModeCreateMode(void)
 {
     DisplayModePtr mode;
@@ -473,90 +473,90 @@ VidModeCreateMode(void)
 }
 
 void
-VidModeCopyMode(void *modefrom, void *modeto)
+VidModeCopyMode(DisplayModePtr modefrom, DisplayModePtr modeto)
 {
     memcpy(modeto, modefrom, sizeof(DisplayModeRec));
 }
 
 int
-VidModeGetModeValue(void *mode, int valtyp)
+VidModeGetModeValue(DisplayModePtr mode, int valtyp)
 {
     int ret = 0;
 
     switch (valtyp) {
     case VIDMODE_H_DISPLAY:
-        ret = ((DisplayModePtr) mode)->HDisplay;
+        ret = mode->HDisplay;
         break;
     case VIDMODE_H_SYNCSTART:
-        ret = ((DisplayModePtr) mode)->HSyncStart;
+        ret = mode->HSyncStart;
         break;
     case VIDMODE_H_SYNCEND:
-        ret = ((DisplayModePtr) mode)->HSyncEnd;
+        ret = mode->HSyncEnd;
         break;
     case VIDMODE_H_TOTAL:
-        ret = ((DisplayModePtr) mode)->HTotal;
+        ret = mode->HTotal;
         break;
     case VIDMODE_H_SKEW:
-        ret = ((DisplayModePtr) mode)->HSkew;
+        ret = mode->HSkew;
         break;
     case VIDMODE_V_DISPLAY:
-        ret = ((DisplayModePtr) mode)->VDisplay;
+        ret = mode->VDisplay;
         break;
     case VIDMODE_V_SYNCSTART:
-        ret = ((DisplayModePtr) mode)->VSyncStart;
+        ret = mode->VSyncStart;
         break;
     case VIDMODE_V_SYNCEND:
-        ret = ((DisplayModePtr) mode)->VSyncEnd;
+        ret = mode->VSyncEnd;
         break;
     case VIDMODE_V_TOTAL:
-        ret = ((DisplayModePtr) mode)->VTotal;
+        ret = mode->VTotal;
         break;
     case VIDMODE_FLAGS:
-        ret = ((DisplayModePtr) mode)->Flags;
+        ret = mode->Flags;
         break;
     case VIDMODE_CLOCK:
-        ret = ((DisplayModePtr) mode)->Clock;
+        ret = mode->Clock;
         break;
     }
     return ret;
 }
 
 void
-VidModeSetModeValue(void *mode, int valtyp, int val)
+VidModeSetModeValue(DisplayModePtr mode, int valtyp, int val)
 {
     switch (valtyp) {
     case VIDMODE_H_DISPLAY:
-        ((DisplayModePtr) mode)->HDisplay = val;
+        mode->HDisplay = val;
         break;
     case VIDMODE_H_SYNCSTART:
-        ((DisplayModePtr) mode)->HSyncStart = val;
+        mode->HSyncStart = val;
         break;
     case VIDMODE_H_SYNCEND:
-        ((DisplayModePtr) mode)->HSyncEnd = val;
+        mode->HSyncEnd = val;
         break;
     case VIDMODE_H_TOTAL:
-        ((DisplayModePtr) mode)->HTotal = val;
+        mode->HTotal = val;
         break;
     case VIDMODE_H_SKEW:
-        ((DisplayModePtr) mode)->HSkew = val;
+        mode->HSkew = val;
         break;
     case VIDMODE_V_DISPLAY:
-        ((DisplayModePtr) mode)->VDisplay = val;
+        mode->VDisplay = val;
         break;
     case VIDMODE_V_SYNCSTART:
-        ((DisplayModePtr) mode)->VSyncStart = val;
+        mode->VSyncStart = val;
         break;
     case VIDMODE_V_SYNCEND:
-        ((DisplayModePtr) mode)->VSyncEnd = val;
+        mode->VSyncEnd = val;
         break;
     case VIDMODE_V_TOTAL:
-        ((DisplayModePtr) mode)->VTotal = val;
+        mode->VTotal = val;
         break;
     case VIDMODE_FLAGS:
-        ((DisplayModePtr) mode)->Flags = val;
+        mode->Flags = val;
         break;
     case VIDMODE_CLOCK:
-        ((DisplayModePtr) mode)->Clock = val;
+        mode->Clock = val;
         break;
     }
     return;
diff --git a/hw/xfree86/common/xf86vmode.c b/hw/xfree86/common/xf86vmode.c
index d4f0234..b74ec6e 100644
--- a/hw/xfree86/common/xf86vmode.c
+++ b/hw/xfree86/common/xf86vmode.c
@@ -122,7 +122,7 @@ ProcXF86VidModeGetModeLine(ClientPtr client)
         .sequenceNumber = client->sequence
     };
     ScreenPtr pScreen;
-    void *mode;
+    DisplayModePtr mode;
     int dotClock;
     int ver;
 
@@ -223,7 +223,7 @@ ProcXF86VidModeGetAllModeLines(ClientPtr client)
     REQUEST(xXF86VidModeGetAllModeLinesReq);
     xXF86VidModeGetAllModeLinesReply rep;
     ScreenPtr pScreen;
-    void *mode;
+    DisplayModePtr mode;
     int modecount, dotClock;
     int ver;
 
@@ -335,7 +335,7 @@ ProcXF86VidModeAddModeLine(ClientPtr client)
         (xXF86OldVidModeAddModeLineReq *) client->requestBuffer;
     xXF86VidModeAddModeLineReq newstuff;
     ScreenPtr pScreen;
-    void *mode;
+    DisplayModePtr mode;
     int len;
     int dotClock;
     int ver;
@@ -501,7 +501,7 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client)
         (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer;
     xXF86VidModeDeleteModeLineReq newstuff;
     ScreenPtr pScreen;
-    void *mode;
+    DisplayModePtr mode;
     int len, dotClock;
     int ver;
 
@@ -628,7 +628,7 @@ ProcXF86VidModeModModeLine(ClientPtr client)
         (xXF86OldVidModeModModeLineReq *) client->requestBuffer;
     xXF86VidModeModModeLineReq newstuff;
     ScreenPtr pScreen;
-    void *mode, *modetmp;
+    DisplayModePtr mode, modetmp;
     int len, dotClock;
     int ver;
 
@@ -759,7 +759,7 @@ ProcXF86VidModeValidateModeLine(ClientPtr client)
     xXF86VidModeValidateModeLineReq newstuff;
     xXF86VidModeValidateModeLineReply rep;
     ScreenPtr pScreen;
-    void *mode, *modetmp = NULL;
+    DisplayModePtr mode, modetmp = NULL;
     int len, status, dotClock;
     int ver;
 
@@ -901,7 +901,7 @@ ProcXF86VidModeSwitchToMode(ClientPtr client)
         (xXF86OldVidModeSwitchToModeReq *) client->requestBuffer;
     xXF86VidModeSwitchToModeReq newstuff;
     ScreenPtr pScreen;
-    void *mode;
+    DisplayModePtr mode;
     int len, dotClock;
     int ver;
 
commit 3b52aee6dddc2cd2780f729e9389a1515c544c61
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Feb 5 09:48:18 2016 +0100

    vidmode: remove VidModeGetMonitor()
    
    VidModeGetMonitor() is used solely in ProcXF86VidModeGetMonitor() to
    get a untyped monitor pointer that is passed back straight again to
    VidModeGetMonitorValue().
    
    This is actually useless as VidModeGetMonitorValue() could as well get
    the monitor from the ScreenPtr just like VidModeGetMonitor() does.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 12f714fd95dc9d912c0bf2524005a73ec6e8ee4f)

diff --git a/hw/xfree86/common/vidmodeproc.h b/hw/xfree86/common/vidmodeproc.h
index 53d5835..792be9b 100644
--- a/hw/xfree86/common/vidmodeproc.h
+++ b/hw/xfree86/common/vidmodeproc.h
@@ -53,7 +53,6 @@ extern Bool VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y);
 extern Bool VidModeSetViewPort(ScreenPtr pScreen, int x, int y);
 extern Bool VidModeSwitchMode(ScreenPtr pScreen, void *mode);
 extern Bool VidModeLockZoom(ScreenPtr pScreen, Bool lock);
-extern Bool VidModeGetMonitor(ScreenPtr pScreen, void **monitor);
 extern int VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock);
 extern Bool VidModeGetClocks(ScreenPtr pScreen, int *Clocks);
 extern ModeStatus VidModeCheckModeForMonitor(ScreenPtr pScreen,
@@ -72,7 +71,7 @@ extern void *VidModeCreateMode(void);
 extern void VidModeCopyMode(void *modefrom, void *modeto);
 extern int VidModeGetModeValue(void *mode, int valtyp);
 extern void VidModeSetModeValue(void *mode, int valtyp, int val);
-extern vidMonitorValue VidModeGetMonitorValue(void *monitor,
+extern vidMonitorValue VidModeGetMonitorValue(ScreenPtr pScreen,
                                               int valtyp, int indx);
 extern Bool VidModeSetGammaRamp(ScreenPtr, int, CARD16 *, CARD16 *,
                                 CARD16 *);
diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index 414700e..9182d93 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -313,20 +313,6 @@ VidModeLockZoom(ScreenPtr pScreen, Bool lock)
     return TRUE;
 }
 
-Bool
-VidModeGetMonitor(ScreenPtr pScreen, void **monitor)
-{
-    ScrnInfoPtr pScrn;
-
-    if (!VidModeAvailable(pScreen))
-        return FALSE;
-
-    pScrn = xf86ScreenToScrn(pScreen);
-    *monitor = (void *) (pScrn->monitor);
-
-    return TRUE;
-}
-
 ModeStatus
 VidModeCheckModeForMonitor(ScreenPtr pScreen, void *mode)
 {
@@ -577,34 +563,42 @@ VidModeSetModeValue(void *mode, int valtyp, int val)
 }
 
 vidMonitorValue
-VidModeGetMonitorValue(void *monitor, int valtyp, int indx)
+VidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
 {
     vidMonitorValue ret = { NULL, };
+    MonPtr monitor;
+    ScrnInfoPtr pScrn;
+
+    if (!VidModeAvailable(pScreen))
+        return ret;
+
+    pScrn = xf86ScreenToScrn(pScreen);
+    monitor = pScrn->monitor;
 
     switch (valtyp) {
     case VIDMODE_MON_VENDOR:
-        ret.ptr = (((MonPtr) monitor)->vendor);
+        ret.ptr = monitor->vendor;
         break;
     case VIDMODE_MON_MODEL:
-        ret.ptr = (((MonPtr) monitor)->model);
+        ret.ptr = monitor->model;
         break;
     case VIDMODE_MON_NHSYNC:
-        ret.i = ((MonPtr) monitor)->nHsync;
+        ret.i = monitor->nHsync;
         break;
     case VIDMODE_MON_NVREFRESH:
-        ret.i = ((MonPtr) monitor)->nVrefresh;
+        ret.i = monitor->nVrefresh;
         break;
     case VIDMODE_MON_HSYNC_LO:
-        ret.f = (100.0 * ((MonPtr) monitor)->hsync[indx].lo);
+        ret.f = (100.0 * monitor->hsync[indx].lo);
         break;
     case VIDMODE_MON_HSYNC_HI:
-        ret.f = (100.0 * ((MonPtr) monitor)->hsync[indx].hi);
+        ret.f = (100.0 * monitor->hsync[indx].hi);
         break;
     case VIDMODE_MON_VREFRESH_LO:
-        ret.f = (100.0 * ((MonPtr) monitor)->vrefresh[indx].lo);
+        ret.f = (100.0 * monitor->vrefresh[indx].lo);
         break;
     case VIDMODE_MON_VREFRESH_HI:
-        ret.f = (100.0 * ((MonPtr) monitor)->vrefresh[indx].hi);
+        ret.f = (100.0 * monitor->vrefresh[indx].hi);
         break;
     }
     return ret;
diff --git a/hw/xfree86/common/xf86vmode.c b/hw/xfree86/common/xf86vmode.c
index 3a2df59..d4f0234 100644
--- a/hw/xfree86/common/xf86vmode.c
+++ b/hw/xfree86/common/xf86vmode.c
@@ -1029,7 +1029,6 @@ ProcXF86VidModeGetMonitor(ClientPtr client)
     };
     CARD32 *hsyncdata, *vsyncdata;
     int i, nHsync, nVrefresh;
-    void *monitor;
     ScreenPtr pScreen;
 
     DEBUG_P("XF86VidModeGetMonitor");
@@ -1040,20 +1039,17 @@ ProcXF86VidModeGetMonitor(ClientPtr client)
         return BadValue;
     pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetMonitor(pScreen, &monitor))
-        return BadValue;
-
-    nHsync = VidModeGetMonitorValue(monitor, VIDMODE_MON_NHSYNC, 0).i;
-    nVrefresh = VidModeGetMonitorValue(monitor, VIDMODE_MON_NVREFRESH, 0).i;
+    nHsync = VidModeGetMonitorValue(pScreen, VIDMODE_MON_NHSYNC, 0).i;
+    nVrefresh = VidModeGetMonitorValue(pScreen, VIDMODE_MON_NVREFRESH, 0).i;
 
-    if ((char *) (VidModeGetMonitorValue(monitor, VIDMODE_MON_VENDOR, 0)).ptr)
-        rep.vendorLength = strlen((char *) (VidModeGetMonitorValue(monitor,
+    if ((char *) (VidModeGetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr)
+        rep.vendorLength = strlen((char *) (VidModeGetMonitorValue(pScreen,
                                                                    VIDMODE_MON_VENDOR,
                                                                    0)).ptr);
     else
         rep.vendorLength = 0;
-    if ((char *) (VidModeGetMonitorValue(monitor, VIDMODE_MON_MODEL, 0)).ptr)
-        rep.modelLength = strlen((char *) (VidModeGetMonitorValue(monitor,
+    if ((char *) (VidModeGetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr)
+        rep.modelLength = strlen((char *) (VidModeGetMonitorValue(pScreen,
                                                                   VIDMODE_MON_MODEL,
                                                                   0)).ptr);
     else
@@ -1078,19 +1074,19 @@ ProcXF86VidModeGetMonitor(ClientPtr client)
     }
 
     for (i = 0; i < nHsync; i++) {
-        hsyncdata[i] = (unsigned short) (VidModeGetMonitorValue(monitor,
+        hsyncdata[i] = (unsigned short) (VidModeGetMonitorValue(pScreen,
                                                                 VIDMODE_MON_HSYNC_LO,
                                                                 i)).f |
             (unsigned
-             short) (VidModeGetMonitorValue(monitor, VIDMODE_MON_HSYNC_HI,
+             short) (VidModeGetMonitorValue(pScreen, VIDMODE_MON_HSYNC_HI,
                                             i)).f << 16;
     }
     for (i = 0; i < nVrefresh; i++) {
-        vsyncdata[i] = (unsigned short) (VidModeGetMonitorValue(monitor,
+        vsyncdata[i] = (unsigned short) (VidModeGetMonitorValue(pScreen,
                                                                 VIDMODE_MON_VREFRESH_LO,
                                                                 i)).f |
             (unsigned
-             short) (VidModeGetMonitorValue(monitor, VIDMODE_MON_VREFRESH_HI,
+             short) (VidModeGetMonitorValue(pScreen, VIDMODE_MON_VREFRESH_HI,
                                             i)).f << 16;
     }
 
@@ -1104,10 +1100,10 @@ ProcXF86VidModeGetMonitor(ClientPtr client)
     WriteSwappedDataToClient(client, nVrefresh * sizeof(CARD32), vsyncdata);
     if (rep.vendorLength)
         WriteToClient(client, rep.vendorLength,
-                 (VidModeGetMonitorValue(monitor, VIDMODE_MON_VENDOR, 0)).ptr);
+                 (VidModeGetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr);
     if (rep.modelLength)
         WriteToClient(client, rep.modelLength,
-                 (VidModeGetMonitorValue(monitor, VIDMODE_MON_MODEL, 0)).ptr);
+                 (VidModeGetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr);
 
     free(hsyncdata);
     free(vsyncdata);
commit b241fd6413775f76a5faaea0f685a8294322e2fc
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Feb 5 09:48:17 2016 +0100

    vidmode: use ScreenPtr instead of screen index
    
    New code passes ScreenPtr instead of the screen index.
    
    Change the VidMode functions to take a ScreenPtr.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit f6f7e21133c13c34f306a191137d566e83b40929)

diff --git a/hw/xfree86/common/vidmodeproc.h b/hw/xfree86/common/vidmodeproc.h
index 59d714c..53d5835 100644
--- a/hw/xfree86/common/vidmodeproc.h
+++ b/hw/xfree86/common/vidmodeproc.h
@@ -41,32 +41,32 @@ typedef union {
 
 extern Bool VidModeExtensionInit(ScreenPtr pScreen);
 
-extern Bool VidModeGetCurrentModeline(int scrnIndex, void **mode,
+extern Bool VidModeGetCurrentModeline(ScreenPtr pScreen, void **mode,
                                       int *dotClock);
-extern Bool VidModeGetFirstModeline(int scrnIndex, void **mode,
+extern Bool VidModeGetFirstModeline(ScreenPtr pScreen, void **mode,
                                     int *dotClock);
-extern Bool VidModeGetNextModeline(int scrnIndex, void **mode,
+extern Bool VidModeGetNextModeline(ScreenPtr pScreen, void **mode,
                                    int *dotClock);
-extern Bool VidModeDeleteModeline(int scrnIndex, void *mode);
-extern Bool VidModeZoomViewport(int scrnIndex, int zoom);
-extern Bool VidModeGetViewPort(int scrnIndex, int *x, int *y);
-extern Bool VidModeSetViewPort(int scrnIndex, int x, int y);
-extern Bool VidModeSwitchMode(int scrnIndex, void *mode);
-extern Bool VidModeLockZoom(int scrnIndex, Bool lock);
-extern Bool VidModeGetMonitor(int scrnIndex, void **monitor);
-extern int VidModeGetNumOfClocks(int scrnIndex, Bool *progClock);
-extern Bool VidModeGetClocks(int scrnIndex, int *Clocks);
-extern ModeStatus VidModeCheckModeForMonitor(int scrnIndex,
+extern Bool VidModeDeleteModeline(ScreenPtr pScreen, void *mode);
+extern Bool VidModeZoomViewport(ScreenPtr pScreen, int zoom);
+extern Bool VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y);
+extern Bool VidModeSetViewPort(ScreenPtr pScreen, int x, int y);
+extern Bool VidModeSwitchMode(ScreenPtr pScreen, void *mode);
+extern Bool VidModeLockZoom(ScreenPtr pScreen, Bool lock);
+extern Bool VidModeGetMonitor(ScreenPtr pScreen, void **monitor);
+extern int VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock);
+extern Bool VidModeGetClocks(ScreenPtr pScreen, int *Clocks);
+extern ModeStatus VidModeCheckModeForMonitor(ScreenPtr pScreen,
                                              void *mode);
-extern ModeStatus VidModeCheckModeForDriver(int scrnIndex,
+extern ModeStatus VidModeCheckModeForDriver(ScreenPtr pScreen,
                                             void *mode);
-extern void VidModeSetCrtcForMode(int scrnIndex, void *mode);
-extern Bool VidModeAddModeline(int scrnIndex, void *mode);
-extern int VidModeGetDotClock(int scrnIndex, int Clock);
-extern int VidModeGetNumOfModes(int scrnIndex);
-extern Bool VidModeSetGamma(int scrnIndex, float red, float green,
+extern void VidModeSetCrtcForMode(ScreenPtr pScreen, void *mode);
+extern Bool VidModeAddModeline(ScreenPtr pScreen, void *mode);
+extern int VidModeGetDotClock(ScreenPtr pScreen, int Clock);
+extern int VidModeGetNumOfModes(ScreenPtr pScreen);
+extern Bool VidModeSetGamma(ScreenPtr pScreen, float red, float green,
                             float blue);
-extern Bool VidModeGetGamma(int scrnIndex, float *red, float *green,
+extern Bool VidModeGetGamma(ScreenPtr pScreen, float *red, float *green,
                             float *blue);
 extern void *VidModeCreateMode(void);
 extern void VidModeCopyMode(void *modefrom, void *modeto);
@@ -74,10 +74,10 @@ extern int VidModeGetModeValue(void *mode, int valtyp);
 extern void VidModeSetModeValue(void *mode, int valtyp, int val);
 extern vidMonitorValue VidModeGetMonitorValue(void *monitor,
                                               int valtyp, int indx);
-extern Bool VidModeSetGammaRamp(int, int, CARD16 *, CARD16 *,
+extern Bool VidModeSetGammaRamp(ScreenPtr, int, CARD16 *, CARD16 *,
                                 CARD16 *);
-extern Bool VidModeGetGammaRamp(int, int, CARD16 *, CARD16 *,
+extern Bool VidModeGetGammaRamp(ScreenPtr, int, CARD16 *, CARD16 *,
                                 CARD16 *);
-extern int VidModeGetGammaRampSize(int scrnIndex);
+extern int VidModeGetGammaRampSize(ScreenPtr pScreen);
 
 #endif
diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index 04637f1..414700e 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -83,19 +83,14 @@ VidModeExtensionInit(ScreenPtr pScreen)
 #ifdef XF86VIDMODE
 
 static Bool
-VidModeAvailable(int scrnIndex)
+VidModeAvailable(ScreenPtr pScreen)
 {
-    ScrnInfoPtr pScrn;
-    VidModePtr pVidMode;
-
-    pScrn = xf86Screens[scrnIndex];
-    if (pScrn == NULL) {
-        DebugF("pScrn == NULL\n");
+    if (pScreen == NULL) {
+        DebugF("pScreen == NULL\n");
         return FALSE;
     }
 
-    pVidMode = VMPTR(pScrn->pScreen);
-    if (pVidMode)
+    if (VMPTR(pScreen))
         return TRUE;
     else {
         DebugF("pVidMode == NULL\n");
@@ -104,14 +99,14 @@ VidModeAvailable(int scrnIndex)
 }
 
 Bool
-VidModeGetCurrentModeline(int scrnIndex, void **mode, int *dotClock)
+VidModeGetCurrentModeline(ScreenPtr pScreen, void **mode, int *dotClock)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
 
     if (pScrn->currentMode) {
         *mode = (void *) (pScrn->currentMode);
@@ -123,14 +118,14 @@ VidModeGetCurrentModeline(int scrnIndex, void **mode, int *dotClock)
 }
 
 int
-VidModeGetDotClock(int scrnIndex, int Clock)
+VidModeGetDotClock(ScreenPtr pScreen, int Clock)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return 0;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
     if ((pScrn->progClock) || (Clock >= MAXCLOCKS))
         return Clock;
     else
@@ -138,14 +133,14 @@ VidModeGetDotClock(int scrnIndex, int Clock)
 }
 
 int
-VidModeGetNumOfClocks(int scrnIndex, Bool *progClock)
+VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return 0;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
     if (pScrn->progClock) {
         *progClock = TRUE;
         return 0;
@@ -157,15 +152,15 @@ VidModeGetNumOfClocks(int scrnIndex, Bool *progClock)
 }
 
 Bool
-VidModeGetClocks(int scrnIndex, int *Clocks)
+VidModeGetClocks(ScreenPtr pScreen, int *Clocks)
 {
     ScrnInfoPtr pScrn;
     int i;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
 
     if (pScrn->progClock)
         return FALSE;
@@ -177,49 +172,47 @@ VidModeGetClocks(int scrnIndex, int *Clocks)
 }
 
 Bool
-VidModeGetFirstModeline(int scrnIndex, void **mode, int *dotClock)
+VidModeGetFirstModeline(ScreenPtr pScreen, void **mode, int *dotClock)
 {
     ScrnInfoPtr pScrn;
     VidModePtr pVidMode;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
     if (pScrn->modes == NULL)
         return FALSE;
 
-    pVidMode = VMPTR(pScrn->pScreen);
+    pVidMode = VMPTR(pScreen);
     pVidMode->First = pScrn->modes;
     pVidMode->Next = pVidMode->First->next;
 
     if (pVidMode->First->status == MODE_OK) {
         *mode = (void *) (pVidMode->First);
-        *dotClock = VidModeGetDotClock(scrnIndex, pVidMode->First->Clock);
+        *dotClock = VidModeGetDotClock(pScreen, pVidMode->First->Clock);
         return TRUE;
     }
 
-    return VidModeGetNextModeline(scrnIndex, mode, dotClock);
+    return VidModeGetNextModeline(pScreen, mode, dotClock);
 }
 
 Bool
-VidModeGetNextModeline(int scrnIndex, void **mode, int *dotClock)
+VidModeGetNextModeline(ScreenPtr pScreen, void **mode, int *dotClock)
 {
-    ScrnInfoPtr pScrn;
     VidModePtr pVidMode;
     DisplayModePtr p;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
-    pVidMode = VMPTR(pScrn->pScreen);
+    pVidMode = VMPTR(pScreen);
 
     for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
         if (p->status == MODE_OK) {
             pVidMode->Next = p->next;
             *mode = (void *) p;
-            *dotClock = VidModeGetDotClock(scrnIndex, p->Clock);
+            *dotClock = VidModeGetDotClock(pScreen, p->Clock);
             return TRUE;
         }
     }
@@ -228,40 +221,37 @@ VidModeGetNextModeline(int scrnIndex, void **mode, int *dotClock)
 }
 
 Bool
-VidModeDeleteModeline(int scrnIndex, void *mode)
+VidModeDeleteModeline(ScreenPtr pScreen, void *mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+    if ((mode == NULL) || (!VidModeAvailable(pScreen)))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
     xf86DeleteMode(&(pScrn->modes), (DisplayModePtr) mode);
     return TRUE;
 }
 
 Bool
-VidModeZoomViewport(int scrnIndex, int zoom)
+VidModeZoomViewport(ScreenPtr pScreen, int zoom)
 {
-    ScrnInfoPtr pScrn;
-
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
-    xf86ZoomViewport(pScrn->pScreen, zoom);
+    xf86ZoomViewport(pScreen, zoom);
     return TRUE;
 }
 
 Bool
-VidModeSetViewPort(int scrnIndex, int x, int y)
+VidModeSetViewPort(ScreenPtr pScreen, int x, int y)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
     pScrn->frameX0 = min(max(x, 0),
                          pScrn->virtualX - pScrn->currentMode->HDisplay);
     pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1;
@@ -275,30 +265,30 @@ VidModeSetViewPort(int scrnIndex, int x, int y)
 }
 
 Bool
-VidModeGetViewPort(int scrnIndex, int *x, int *y)
+VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
     *x = pScrn->frameX0;
     *y = pScrn->frameY0;
     return TRUE;
 }
 
 Bool
-VidModeSwitchMode(int scrnIndex, void *mode)
+VidModeSwitchMode(ScreenPtr pScreen, void *mode)
 {
     ScrnInfoPtr pScrn;
     DisplayModePtr pTmpMode;
     Bool retval;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
     /* save in case we fail */
     pTmpMode = pScrn->currentMode;
     /* Force a mode switch */
@@ -311,73 +301,69 @@ VidModeSwitchMode(int scrnIndex, void *mode)
 }
 
 Bool
-VidModeLockZoom(int scrnIndex, Bool lock)
+VidModeLockZoom(ScreenPtr pScreen, Bool lock)
 {
-    ScrnInfoPtr pScrn;
-
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
-
     if (xf86Info.dontZoom)
         return FALSE;
 
-    xf86LockZoom(pScrn->pScreen, lock);
+    xf86LockZoom(pScreen, lock);
     return TRUE;
 }
 
 Bool
-VidModeGetMonitor(int scrnIndex, void **monitor)
+VidModeGetMonitor(ScreenPtr pScreen, void **monitor)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
     *monitor = (void *) (pScrn->monitor);
 
     return TRUE;
 }
 
 ModeStatus
-VidModeCheckModeForMonitor(int scrnIndex, void *mode)
+VidModeCheckModeForMonitor(ScreenPtr pScreen, void *mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+    if ((mode == NULL) || (!VidModeAvailable(pScreen)))
         return MODE_ERROR;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
 
     return xf86CheckModeForMonitor((DisplayModePtr) mode, pScrn->monitor);
 }
 
 ModeStatus
-VidModeCheckModeForDriver(int scrnIndex, void *mode)
+VidModeCheckModeForDriver(ScreenPtr pScreen, void *mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+    if ((mode == NULL) || (!VidModeAvailable(pScreen)))
         return MODE_ERROR;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
 
     return xf86CheckModeForDriver(pScrn, (DisplayModePtr) mode, 0);
 }
 
 void
-VidModeSetCrtcForMode(int scrnIndex, void *mode)
+VidModeSetCrtcForMode(ScreenPtr pScreen, void *mode)
 {
     ScrnInfoPtr pScrn;
     DisplayModePtr ScreenModes;
 
-    if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+    if ((mode == NULL) || (!VidModeAvailable(pScreen)))
         return;
 
     /* Ugly hack so that the xf86Mode.c function can be used without change */
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
     ScreenModes = pScrn->modes;
     pScrn->modes = (DisplayModePtr) mode;
 
@@ -387,14 +373,14 @@ VidModeSetCrtcForMode(int scrnIndex, void *mode)
 }
 
 Bool
-VidModeAddModeline(int scrnIndex, void *mode)
+VidModeAddModeline(ScreenPtr pScreen, void *mode)
 {
     ScrnInfoPtr pScrn;
 
-    if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+    if ((mode == NULL) || (!VidModeAvailable(pScreen)))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
 
     ((DisplayModePtr) mode)->name = strdup(""); /* freed by deletemode */
     ((DisplayModePtr) mode)->status = MODE_OK;
@@ -408,49 +394,47 @@ VidModeAddModeline(int scrnIndex, void *mode)
 }
 
 int
-VidModeGetNumOfModes(int scrnIndex)
+VidModeGetNumOfModes(ScreenPtr pScreen)
 {
     void *mode = NULL;
     int dotClock = 0, nummodes = 0;
 
-    if (!VidModeGetFirstModeline(scrnIndex, &mode, &dotClock))
+    if (!VidModeGetFirstModeline(pScreen, &mode, &dotClock))
         return nummodes;
 
     do {
         nummodes++;
-        if (!VidModeGetNextModeline(scrnIndex, &mode, &dotClock))
+        if (!VidModeGetNextModeline(pScreen, &mode, &dotClock))
             return nummodes;
     } while (TRUE);
 }
 
 Bool
-VidModeSetGamma(int scrnIndex, float red, float green, float blue)
+VidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue)
 {
-    ScrnInfoPtr pScrn;
     Gamma gamma;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
     gamma.red = red;
     gamma.green = green;
     gamma.blue = blue;
-    if (xf86ChangeGamma(pScrn->pScreen, gamma) != Success)
+    if (xf86ChangeGamma(pScreen, gamma) != Success)
         return FALSE;
     else
         return TRUE;
 }
 
 Bool
-VidModeGetGamma(int scrnIndex, float *red, float *green, float *blue)
+VidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
 {
     ScrnInfoPtr pScrn;
 
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
+    pScrn = xf86ScreenToScrn(pScreen);
     *red = pScrn->gamma.red;
     *green = pScrn->gamma.green;
     *blue = pScrn->gamma.blue;
@@ -458,38 +442,32 @@ VidModeGetGamma(int scrnIndex, float *red, float *green, float *blue)
 }
 
 Bool
-VidModeSetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
+VidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
 {
-    ScrnInfoPtr pScrn;
-
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
-    xf86ChangeGammaRamp(pScrn->pScreen, size, r, g, b);
+    xf86ChangeGammaRamp(pScreen, size, r, g, b);
     return TRUE;
 }
 
 Bool
-VidModeGetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
+VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
 {
-    ScrnInfoPtr pScrn;
-
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return FALSE;
 
-    pScrn = xf86Screens[scrnIndex];
-    xf86GetGammaRamp(pScrn->pScreen, size, r, g, b);
+    xf86GetGammaRamp(pScreen, size, r, g, b);
     return TRUE;
 }
 
 int
-VidModeGetGammaRampSize(int scrnIndex)
+VidModeGetGammaRampSize(ScreenPtr pScreen)
 {
-    if (!VidModeAvailable(scrnIndex))
+    if (!VidModeAvailable(pScreen))
         return 0;
 
-    return xf86GetGammaRampSize(xf86Screens[scrnIndex]->pScreen);
+    return xf86GetGammaRampSize(pScreen);
 }
 
 void *
diff --git a/hw/xfree86/common/xf86vmode.c b/hw/xfree86/common/xf86vmode.c
index d133687..3a2df59 100644
--- a/hw/xfree86/common/xf86vmode.c
+++ b/hw/xfree86/common/xf86vmode.c
@@ -121,6 +121,7 @@ ProcXF86VidModeGetModeLine(ClientPtr client)
         .type = X_Reply,
         .sequenceNumber = client->sequence
     };
+    ScreenPtr pScreen;
     void *mode;
     int dotClock;
     int ver;
@@ -141,8 +142,9 @@ ProcXF86VidModeGetModeLine(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
+    if (!VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     rep.dotclock = dotClock;
@@ -220,6 +222,7 @@ ProcXF86VidModeGetAllModeLines(ClientPtr client)
 {
     REQUEST(xXF86VidModeGetAllModeLinesReq);
     xXF86VidModeGetAllModeLinesReply rep;
+    ScreenPtr pScreen;
     void *mode;
     int modecount, dotClock;
     int ver;
@@ -230,14 +233,14 @@ ProcXF86VidModeGetAllModeLines(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
-
+    pScreen = screenInfo.screens[stuff->screen];
     ver = ClientMajorVersion(client);
 
-    modecount = VidModeGetNumOfModes(stuff->screen);
+    modecount = VidModeGetNumOfModes(pScreen);
     if (modecount < 1)
         return VidModeErrorBase + XF86VidModeExtensionDisabled;
 
-    if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock))
+    if (!VidModeGetFirstModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     rep = (xXF86VidModeGetAllModeLinesReply) {
@@ -308,7 +311,7 @@ ProcXF86VidModeGetAllModeLines(ClientPtr client)
             WriteToClient(client, sizeof(xXF86VidModeModeInfo), &mdinf);
         }
 
-    } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
+    } while (VidModeGetNextModeline(pScreen, &mode, &dotClock));
 
     return Success;
 }
@@ -331,6 +334,7 @@ ProcXF86VidModeAddModeLine(ClientPtr client)
     xXF86OldVidModeAddModeLineReq *oldstuff =
         (xXF86OldVidModeAddModeLineReq *) client->requestBuffer;
     xXF86VidModeAddModeLineReq newstuff;
+    ScreenPtr pScreen;
     void *mode;
     int len;
     int dotClock;
@@ -405,6 +409,7 @@ ProcXF86VidModeAddModeLine(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
     if (stuff->hsyncstart < stuff->hdisplay ||
         stuff->hsyncend < stuff->hsyncstart ||
@@ -424,14 +429,14 @@ ProcXF86VidModeAddModeLine(ClientPtr client)
     if (stuff->after_htotal != 0 || stuff->after_vtotal != 0) {
         Bool found = FALSE;
 
-        if (VidModeGetFirstModeline(stuff->screen, &mode, &dotClock)) {
+        if (VidModeGetFirstModeline(pScreen, &mode, &dotClock)) {
             do {
-                if ((VidModeGetDotClock(stuff->screen, stuff->dotclock)
+                if ((VidModeGetDotClock(pScreen, stuff->dotclock)
                      == dotClock) && MODEMATCH(mode, stuff)) {
                     found = TRUE;
                     break;
                 }
-            } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
+            } while (VidModeGetNextModeline(pScreen, &mode, &dotClock));
         }
         if (!found)
             return BadValue;
@@ -457,7 +462,7 @@ ProcXF86VidModeAddModeLine(ClientPtr client)
         ErrorF("AddModeLine - Privates in request have been ignored\n");
 
     /* Check that the mode is consistent with the monitor specs */
-    switch (VidModeCheckModeForMonitor(stuff->screen, mode)) {
+    switch (VidModeCheckModeForMonitor(pScreen, mode)) {
     case MODE_OK:
         break;
     case MODE_HSYNC:
@@ -474,14 +479,14 @@ ProcXF86VidModeAddModeLine(ClientPtr client)
     }
 
     /* Check that the driver is happy with the mode */
-    if (VidModeCheckModeForDriver(stuff->screen, mode) != MODE_OK) {
+    if (VidModeCheckModeForDriver(pScreen, mode) != MODE_OK) {
         free(mode);
         return VidModeErrorBase + XF86VidModeModeUnsuitable;
     }
 
-    VidModeSetCrtcForMode(stuff->screen, mode);
+    VidModeSetCrtcForMode(pScreen, mode);
 
-    VidModeAddModeline(stuff->screen, mode);
+    VidModeAddModeline(pScreen, mode);
 
     if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
         ErrorF("AddModeLine - Succeeded\n");
@@ -495,6 +500,7 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client)
     xXF86OldVidModeDeleteModeLineReq *oldstuff =
         (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer;
     xXF86VidModeDeleteModeLineReq newstuff;
+    ScreenPtr pScreen;
     void *mode;
     int len, dotClock;
     int ver;
@@ -557,8 +563,9 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
+    if (!VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
@@ -577,11 +584,11 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client)
              VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
              VidModeGetModeValue(mode, VIDMODE_FLAGS));
     }
-    if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) &&
+    if ((VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
         MODEMATCH(mode, stuff))
         return BadValue;
 
-    if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock))
+    if (!VidModeGetFirstModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     do {
@@ -601,14 +608,14 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client)
                  VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
                  VidModeGetModeValue(mode, VIDMODE_FLAGS));
         }
-        if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) &&
+        if ((VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
             MODEMATCH(mode, stuff)) {
-            VidModeDeleteModeline(stuff->screen, mode);
+            VidModeDeleteModeline(pScreen, mode);
             if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
                 ErrorF("DeleteModeLine - Succeeded\n");
             return Success;
         }
-    } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
+    } while (VidModeGetNextModeline(pScreen, &mode, &dotClock));
 
     return BadValue;
 }
@@ -620,6 +627,7 @@ ProcXF86VidModeModModeLine(ClientPtr client)
     xXF86OldVidModeModModeLineReq *oldstuff =
         (xXF86OldVidModeModModeLineReq *) client->requestBuffer;
     xXF86VidModeModModeLineReq newstuff;
+    ScreenPtr pScreen;
     void *mode, *modetmp;
     int len, dotClock;
     int ver;
@@ -677,8 +685,9 @@ ProcXF86VidModeModModeLine(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
+    if (!VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     modetmp = VidModeCreateMode();
@@ -699,7 +708,7 @@ ProcXF86VidModeModModeLine(ClientPtr client)
         ErrorF("ModModeLine - Privates in request have been ignored\n");
 
     /* Check that the mode is consistent with the monitor specs */
-    switch (VidModeCheckModeForMonitor(stuff->screen, modetmp)) {
+    switch (VidModeCheckModeForMonitor(pScreen, modetmp)) {
     case MODE_OK:
         break;
     case MODE_HSYNC:
@@ -716,7 +725,7 @@ ProcXF86VidModeModModeLine(ClientPtr client)
     }
 
     /* Check that the driver is happy with the mode */
-    if (VidModeCheckModeForDriver(stuff->screen, modetmp) != MODE_OK) {
+    if (VidModeCheckModeForDriver(pScreen, modetmp) != MODE_OK) {
         free(modetmp);
         return VidModeErrorBase + XF86VidModeModeUnsuitable;
     }
@@ -733,8 +742,8 @@ ProcXF86VidModeModModeLine(ClientPtr client)
     VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
     VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
 
-    VidModeSetCrtcForMode(stuff->screen, mode);
-    VidModeSwitchMode(stuff->screen, mode);
+    VidModeSetCrtcForMode(pScreen, mode);
+    VidModeSwitchMode(pScreen, mode);
 
     if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
         ErrorF("ModModeLine - Succeeded\n");
@@ -749,6 +758,7 @@ ProcXF86VidModeValidateModeLine(ClientPtr client)
         (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer;
     xXF86VidModeValidateModeLineReq newstuff;
     xXF86VidModeValidateModeLineReply rep;
+    ScreenPtr pScreen;
     void *mode, *modetmp = NULL;
     int len, status, dotClock;
     int ver;
@@ -802,6 +812,7 @@ ProcXF86VidModeValidateModeLine(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
     status = MODE_OK;
 
@@ -815,7 +826,7 @@ ProcXF86VidModeValidateModeLine(ClientPtr client)
         goto status_reply;
     }
 
-    if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
+    if (!VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     modetmp = VidModeCreateMode();
@@ -836,11 +847,11 @@ ProcXF86VidModeValidateModeLine(ClientPtr client)
 
     /* Check that the mode is consistent with the monitor specs */
     if ((status =
-         VidModeCheckModeForMonitor(stuff->screen, modetmp)) != MODE_OK)
+         VidModeCheckModeForMonitor(pScreen, modetmp)) != MODE_OK)
         goto status_reply;
 
     /* Check that the driver is happy with the mode */
-    status = VidModeCheckModeForDriver(stuff->screen, modetmp);
+    status = VidModeCheckModeForDriver(pScreen, modetmp);
 
  status_reply:
     free(modetmp);
@@ -867,6 +878,7 @@ static int
 ProcXF86VidModeSwitchMode(ClientPtr client)
 {
     REQUEST(xXF86VidModeSwitchModeReq);
+    ScreenPtr pScreen;
 
     DEBUG_P("XF86VidModeSwitchMode");
 
@@ -874,8 +886,9 @@ ProcXF86VidModeSwitchMode(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    VidModeZoomViewport(stuff->screen, (short) stuff->zoom);
+    VidModeZoomViewport(pScreen, (short) stuff->zoom);
 
     return Success;
 }
@@ -887,6 +900,7 @@ ProcXF86VidModeSwitchToMode(ClientPtr client)
     xXF86OldVidModeSwitchToModeReq *oldstuff =
         (xXF86OldVidModeSwitchToModeReq *) client->requestBuffer;
     xXF86VidModeSwitchToModeReq newstuff;
+    ScreenPtr pScreen;
     void *mode;
     int len, dotClock;
     int ver;
@@ -941,15 +955,16 @@ ProcXF86VidModeSwitchToMode(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
+    if (!VidModeGetCurrentModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
-    if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock)
+    if ((VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock)
         && MODEMATCH(mode, stuff))
         return Success;
 
-    if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock))
+    if (!VidModeGetFirstModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
     do {
@@ -969,17 +984,17 @@ ProcXF86VidModeSwitchToMode(ClientPtr client)
                  VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
                  VidModeGetModeValue(mode, VIDMODE_FLAGS));
         }
-        if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) &&
+        if ((VidModeGetDotClock(pScreen, stuff->dotclock) == dotClock) &&
             MODEMATCH(mode, stuff)) {
 
-            if (!VidModeSwitchMode(stuff->screen, mode))
+            if (!VidModeSwitchMode(pScreen, mode))
                 return BadValue;
 
             if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
                 ErrorF("SwitchToMode - Succeeded\n");
             return Success;
         }
-    } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
+    } while (VidModeGetNextModeline(pScreen, &mode, &dotClock));
 
     return BadValue;
 }
@@ -988,6 +1003,7 @@ static int
 ProcXF86VidModeLockModeSwitch(ClientPtr client)
 {
     REQUEST(xXF86VidModeLockModeSwitchReq);
+    ScreenPtr pScreen;
 
     REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
 
@@ -995,8 +1011,9 @@ ProcXF86VidModeLockModeSwitch(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeLockZoom(stuff->screen, (short) stuff->lock))
+    if (!VidModeLockZoom(pScreen, (short) stuff->lock))
         return VidModeErrorBase + XF86VidModeZoomLocked;
 
     return Success;
@@ -1013,6 +1030,7 @@ ProcXF86VidModeGetMonitor(ClientPtr client)
     CARD32 *hsyncdata, *vsyncdata;
     int i, nHsync, nVrefresh;
     void *monitor;
+    ScreenPtr pScreen;
 
     DEBUG_P("XF86VidModeGetMonitor");
 
@@ -1020,8 +1038,9 @@ ProcXF86VidModeGetMonitor(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetMonitor(stuff->screen, &monitor))
+    if (!VidModeGetMonitor(pScreen, &monitor))
         return BadValue;
 
     nHsync = VidModeGetMonitorValue(monitor, VIDMODE_MON_NHSYNC, 0).i;
@@ -1101,6 +1120,7 @@ ProcXF86VidModeGetViewPort(ClientPtr client)
 {
     REQUEST(xXF86VidModeGetViewPortReq);
     xXF86VidModeGetViewPortReply rep;
+    ScreenPtr pScreen;
     int x, y;
 
     DEBUG_P("XF86VidModeGetViewPort");
@@ -1109,8 +1129,9 @@ ProcXF86VidModeGetViewPort(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    VidModeGetViewPort(stuff->screen, &x, &y);
+    VidModeGetViewPort(pScreen, &x, &y);
 
     rep = (xXF86VidModeGetViewPortReply) {
         .type = X_Reply,
@@ -1134,6 +1155,7 @@ static int
 ProcXF86VidModeSetViewPort(ClientPtr client)
 {
     REQUEST(xXF86VidModeSetViewPortReq);
+    ScreenPtr pScreen;
 
     DEBUG_P("XF86VidModeSetViewPort");
 
@@ -1141,8 +1163,9 @@ ProcXF86VidModeSetViewPort(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeSetViewPort(stuff->screen, stuff->x, stuff->y))
+    if (!VidModeSetViewPort(pScreen, stuff->x, stuff->y))
         return BadValue;
 
     return Success;
@@ -1153,6 +1176,7 @@ ProcXF86VidModeGetDotClocks(ClientPtr client)
 {
     REQUEST(xXF86VidModeGetDotClocksReq);
     xXF86VidModeGetDotClocksReply rep;
+    ScreenPtr pScreen;
     int n;
     int numClocks;
     CARD32 dotclock;
@@ -1165,8 +1189,9 @@ ProcXF86VidModeGetDotClocks(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    numClocks = VidModeGetNumOfClocks(stuff->screen, &ClockProg);
+    numClocks = VidModeGetNumOfClocks(pScreen, &ClockProg);
 
     rep = (xXF86VidModeGetDotClocksReply) {
         .type = X_Reply,
@@ -1182,7 +1207,7 @@ ProcXF86VidModeGetDotClocks(ClientPtr client)
         Clocks = calloc(numClocks, sizeof(int));
         if (!Clocks)
             return BadValue;
-        if (!VidModeGetClocks(stuff->screen, Clocks)) {
+        if (!VidModeGetClocks(pScreen, Clocks)) {
             free(Clocks);
             return BadValue;
         }
@@ -1218,6 +1243,7 @@ static int
 ProcXF86VidModeSetGamma(ClientPtr client)
 {
     REQUEST(xXF86VidModeSetGammaReq);
+    ScreenPtr pScreen;
 
     DEBUG_P("XF86VidModeSetGamma");
 
@@ -1225,8 +1251,9 @@ ProcXF86VidModeSetGamma(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeSetGamma(stuff->screen, ((float) stuff->red) / 10000.,
+    if (!VidModeSetGamma(pScreen, ((float) stuff->red) / 10000.,
                          ((float) stuff->green) / 10000.,
                          ((float) stuff->blue) / 10000.))
         return BadValue;
@@ -1239,6 +1266,7 @@ ProcXF86VidModeGetGamma(ClientPtr client)
 {
     REQUEST(xXF86VidModeGetGammaReq);
     xXF86VidModeGetGammaReply rep;
+    ScreenPtr pScreen;
     float red, green, blue;
 
     DEBUG_P("XF86VidModeGetGamma");
@@ -1247,8 +1275,9 @@ ProcXF86VidModeGetGamma(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    if (!VidModeGetGamma(stuff->screen, &red, &green, &blue))
+    if (!VidModeGetGamma(pScreen, &red, &green, &blue))
         return BadValue;
     rep = (xXF86VidModeGetGammaReply) {
         .type = X_Reply,
@@ -1273,6 +1302,7 @@ ProcXF86VidModeGetGamma(ClientPtr client)
 static int
 ProcXF86VidModeSetGammaRamp(ClientPtr client)
 {
+    ScreenPtr pScreen;
     CARD16 *r, *g, *b;
     int length;
 
@@ -1280,8 +1310,9 @@ ProcXF86VidModeSetGammaRamp(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    if (stuff->size != VidModeGetGammaRampSize(stuff->screen))
+    if (stuff->size != VidModeGetGammaRampSize(pScreen))
         return BadValue;
 
     length = (stuff->size + 1) & ~1;
@@ -1292,7 +1323,7 @@ ProcXF86VidModeSetGammaRamp(ClientPtr client)
     g = r + length;
     b = g + length;
 
-    if (!VidModeSetGammaRamp(stuff->screen, stuff->size, r, g, b))
+    if (!VidModeSetGammaRamp(pScreen, stuff->size, r, g, b))
         return BadValue;
 
     return Success;
@@ -1305,6 +1336,7 @@ ProcXF86VidModeGetGammaRamp(ClientPtr client)
     int length;
     size_t ramplen = 0;
     xXF86VidModeGetGammaRampReply rep;
+    ScreenPtr pScreen;
 
     REQUEST(xXF86VidModeGetGammaRampReq);
 
@@ -1312,8 +1344,9 @@ ProcXF86VidModeGetGammaRamp(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
-    if (stuff->size != VidModeGetGammaRampSize(stuff->screen))
+    if (stuff->size != VidModeGetGammaRampSize(pScreen))
         return BadValue;
 
     length = (stuff->size + 1) & ~1;
@@ -1323,7 +1356,7 @@ ProcXF86VidModeGetGammaRamp(ClientPtr client)
             return BadAlloc;
         ramplen = length * 3 * sizeof(CARD16);
 
-        if (!VidModeGetGammaRamp(stuff->screen, stuff->size,
+        if (!VidModeGetGammaRamp(pScreen, stuff->size,
                                  ramp, ramp + length, ramp + (length * 2))) {
             free(ramp);
             return BadValue;
@@ -1355,6 +1388,7 @@ static int
 ProcXF86VidModeGetGammaRampSize(ClientPtr client)
 {
     xXF86VidModeGetGammaRampSizeReply rep;
+    ScreenPtr pScreen;
 
     REQUEST(xXF86VidModeGetGammaRampSizeReq);
 
@@ -1362,12 +1396,13 @@ ProcXF86VidModeGetGammaRampSize(ClientPtr client)
 
     if (stuff->screen >= screenInfo.numScreens)
         return BadValue;
+    pScreen = screenInfo.screens[stuff->screen];
 
     rep = (xXF86VidModeGetGammaRampSizeReply) {
         .type = X_Reply,
         .sequenceNumber = client->sequence,
         .length = 0,
-        .size = VidModeGetGammaRampSize(stuff->screen)
+        .size = VidModeGetGammaRampSize(pScreen)
     };
     if (client->swapped) {
         swaps(&rep.sequenceNumber);
commit 2028b9066ddbbeaf585e154d19c2672cccdda9bb
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Feb 5 09:48:16 2016 +0100

    vidmode: get rid of the CloseScreen wrapper
    
    As we rely on dixRegisterPrivateKey() to allocate the memory for us that
    will be free automatically, we do not need the CloseScreen wrapper
    anymore.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 6e898ef080df93e885ead9d6fee8854b34e0216f)

diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index cffa14d..bddccf5 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -121,7 +121,6 @@ typedef struct {
     DisplayModePtr First;
     DisplayModePtr Next;
     int Flags;
-    CloseScreenProcPtr CloseScreen;
 } VidModeRec, *VidModePtr;
 #endif
 
diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index b25fe26..04637f1 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -49,7 +49,6 @@
 
 static DevPrivateKeyRec VidModeKeyRec;
 #define VidModeKey (&VidModeKeyRec)
-static Bool VidModeClose(ScreenPtr pScreen);
 
 #define VMPTR(p) ((VidModePtr)dixLookupPrivate(&(p)->devPrivates, VidModeKey))
 
@@ -73,8 +72,6 @@ VidModeExtensionInit(ScreenPtr pScreen)
 
     pVidMode->Flags = 0;
     pVidMode->Next = NULL;
-    pVidMode->CloseScreen = pScreen->CloseScreen;
-    pScreen->CloseScreen = VidModeClose;
 
     return TRUE;
 #else
@@ -86,20 +83,6 @@ VidModeExtensionInit(ScreenPtr pScreen)
 #ifdef XF86VIDMODE
 
 static Bool
-VidModeClose(ScreenPtr pScreen)
-{
-    VidModePtr pVidMode = VMPTR(pScreen);
-
-    /* This shouldn't happen */
-    if (!pVidMode)
-        return FALSE;
-
-    pScreen->CloseScreen = pVidMode->CloseScreen;
-
-    return pScreen->CloseScreen(pScreen);
-}
-
-static Bool
 VidModeAvailable(int scrnIndex)
 {
     ScrnInfoPtr pScrn;
commit cb3a8768db1b7b2f98f62e3075aa0dd2a46edd9d
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Feb 5 09:48:15 2016 +0100

    vidmode: use appropriate API
    
    dixRegisterPrivateKey() can allocate memory that will be freed when the
    screen is teared down.
    
    No need to calloc() and free the memory ourself using a broken ref
    counting method.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 341f3bccafde71754a9ed2303df9908e509c6d31)

diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index 10c7b4b..b25fe26 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -48,8 +48,7 @@
 #include "xf86cmap.h"
 
 static DevPrivateKeyRec VidModeKeyRec;
-static DevPrivateKey VidModeKey;
-static int VidModeCount = 0;
+#define VidModeKey (&VidModeKeyRec)
 static Bool VidModeClose(ScreenPtr pScreen);
 
 #define VMPTR(p) ((VidModePtr)dixLookupPrivate(&(p)->devPrivates, VidModeKey))
@@ -67,22 +66,16 @@ VidModeExtensionInit(ScreenPtr pScreen)
         return FALSE;
     }
 
-    VidModeKey = &VidModeKeyRec;
-
-    if (!dixRegisterPrivateKey(&VidModeKeyRec, PRIVATE_SCREEN, 0))
+    if (!dixRegisterPrivateKey(&VidModeKeyRec, PRIVATE_SCREEN, sizeof(VidModeRec)))
         return FALSE;
 
-    pVidMode = calloc(sizeof(VidModeRec), 1);
-    if (!pVidMode)
-        return FALSE;
-
-    dixSetPrivate(&pScreen->devPrivates, VidModeKey, pVidMode);
+    pVidMode = VMPTR(pScreen);
 
     pVidMode->Flags = 0;
     pVidMode->Next = NULL;
     pVidMode->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = VidModeClose;
-    VidModeCount++;
+
     return TRUE;
 #else
     DebugF("no vidmode extension\n");
@@ -103,11 +96,6 @@ VidModeClose(ScreenPtr pScreen)
 
     pScreen->CloseScreen = pVidMode->CloseScreen;
 
-    if (--VidModeCount == 0) {
-        free(dixLookupPrivate(&pScreen->devPrivates, VidModeKey));
-        dixSetPrivate(&pScreen->devPrivates, VidModeKey, NULL);
-        VidModeKey = NULL;
-    }
     return pScreen->CloseScreen(pScreen);
 }
 
@@ -117,11 +105,6 @@ VidModeAvailable(int scrnIndex)
     ScrnInfoPtr pScrn;
     VidModePtr pVidMode;
 
-    if (VidModeKey == NULL) {
-        DebugF("VidModeKey == NULL\n");
-        return FALSE;
-    }
-
     pScrn = xf86Screens[scrnIndex];
     if (pScrn == NULL) {
         DebugF("pScrn == NULL\n");
commit 45d17e6bb0ee35662913cd6ce378460aa7e461cc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Feb 12 11:59:53 2016 +0000

    dri2: Allow many blocked clients per-drawable
    
    This patch was motivated by the need to fix the use-after-free in
    dri2ClientWake, but in doing so removes an arbitrary restriction that
    limits DRI2 to only blocking the first client on each drawable. In order
    to fix the use-after-free, we need to avoid touching our privates in the
    ClientSleep callback and so we want to only use that external list as
    our means of controlling sleeps and wakeups. We thus have a list of
    sleeping clients at our disposal and can manage multiple events and
    sources.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    (cherry picked from commit d8882954570aba656d5a7be7d357feaba21cb099)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index f9d818c..d55be19 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -90,8 +90,6 @@ typedef struct _DRI2Drawable {
     DRI2BufferPtr *buffers;
     int bufferCount;
     unsigned int swapsPending;
-    ClientPtr blockedClient;
-    Bool blockedOnMsc;
     int swap_interval;
     CARD64 swap_count;
     int64_t target_sbc;         /* -1 means no SBC wait outstanding */
@@ -99,6 +97,7 @@ typedef struct _DRI2Drawable {
     CARD64 last_swap_msc;       /* msc at completion of most recent swap */
     CARD64 last_swap_ust;       /* ust at completion of most recent swap */
     int swap_limit;             /* for N-buffering */
+    unsigned blocked[3];
     Bool needInvalidate;
     int prime_id;
     PixmapPtr prime_slave_pixmap;
@@ -139,6 +138,44 @@ typedef struct _DRI2Screen {
 static void
 destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, int prime_id);
 
+enum DRI2WakeType {
+    WAKE_SBC,
+    WAKE_MSC,
+    WAKE_SWAP,
+};
+
+#define Wake(c, t) (void *)((uintptr_t)(c) | (t))
+
+static Bool
+dri2WakeClient(ClientPtr client, void *closure)
+{
+    ClientWakeup(client);
+    return TRUE;
+}
+
+static Bool
+dri2WakeAll(ClientPtr client, DRI2DrawablePtr pPriv, enum DRI2WakeType t)
+{
+    int count;
+
+    if (!pPriv->blocked[t])
+        return FALSE;
+
+    count = ClientSignalAll(client, dri2WakeClient, Wake(pPriv, t));
+    pPriv->blocked[t] -= count;
+    return count;
+}
+
+static Bool
+dri2Sleep(ClientPtr client, DRI2DrawablePtr pPriv, enum DRI2WakeType t)
+{
+    if (ClientSleep(client, dri2WakeClient, Wake(pPriv, t))) {
+        pPriv->blocked[t]++;
+        return TRUE;
+    }
+    return FALSE;
+}
+
 static DRI2ScreenPtr
 DRI2GetScreen(ScreenPtr pScreen)
 {
@@ -210,8 +247,6 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
     pPriv->buffers = NULL;
     pPriv->bufferCount = 0;
     pPriv->swapsPending = 0;
-    pPriv->blockedClient = NULL;
-    pPriv->blockedOnMsc = FALSE;
     pPriv->swap_count = 0;
     pPriv->target_sbc = -1;
     pPriv->swap_interval = 1;
@@ -219,6 +254,7 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
     if (!ds->GetMSC || !(*ds->GetMSC) (pDraw, &ust, &pPriv->last_swap_target))
         pPriv->last_swap_target = 0;
 
+    memset(pPriv->blocked, 0, sizeof(pPriv->blocked));
     pPriv->swap_limit = 1;      /* default to double buffering */
     pPriv->last_swap_msc = 0;
     pPriv->last_swap_ust = 0;
@@ -258,12 +294,7 @@ DRI2SwapLimit(DrawablePtr pDraw, int swap_limit)
     if (pPriv->swapsPending >= pPriv->swap_limit)
         return TRUE;
 
-    if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
-        if (pPriv->blockedClient) {
-            ClientSignal(pPriv->blockedClient);
-        }
-    }
-
+    dri2WakeAll(CLIENT_SIGNAL_ANY, pPriv, WAKE_SWAP);
     return TRUE;
 }
 
@@ -412,8 +443,9 @@ DRI2DrawableGone(void *p, XID id)
         (*pDraw->pScreen->DestroyPixmap)(pPriv->redirectpixmap);
     }
 
-    if (pPriv->blockedClient)
-        ClientSignal(pPriv->blockedClient);
+    dri2WakeAll(CLIENT_SIGNAL_ANY, pPriv, WAKE_SWAP);
+    dri2WakeAll(CLIENT_SIGNAL_ANY, pPriv, WAKE_MSC);
+    dri2WakeAll(CLIENT_SIGNAL_ANY, pPriv, WAKE_SBC);
 
     free(pPriv);
 
@@ -689,15 +721,6 @@ DRI2InvalidateDrawable(DrawablePtr pDraw)
         ref->invalidate(pDraw, ref->priv, ref->id);
 }
 
-static Bool
-dri2ClientWake(ClientPtr client, void *closure)
-{
-    DRI2DrawablePtr pPriv = closure;
-    ClientWakeup(client);
-    pPriv->blockedClient = NULL;
-    return TRUE;
-}
-
 /*
  * In the direct rendered case, we throttle the clients that have more
  * than their share of outstanding swaps (and thus busy buffers) when a
@@ -715,26 +738,17 @@ DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw)
         return FALSE;
 
     /* Throttle to swap limit */
-    if ((pPriv->swapsPending >= pPriv->swap_limit) && !pPriv->blockedClient) {
-        ResetCurrentRequest(client);
-        client->sequence--;
-        ClientSleep(client, dri2ClientWake, pPriv);
-        pPriv->blockedClient = client;
-        return TRUE;
+    if (pPriv->swapsPending >= pPriv->swap_limit) {
+        if (dri2Sleep(client, pPriv, WAKE_SWAP)) {
+            ResetCurrentRequest(client);
+            client->sequence--;
+            return TRUE;
+        }
     }
 
     return FALSE;
 }
 
-static void
-__DRI2BlockClient(ClientPtr client, DRI2DrawablePtr pPriv)
-{
-    if (pPriv->blockedClient == NULL) {
-        ClientSleep(client, dri2ClientWake, pPriv);
-        pPriv->blockedClient = client;
-    }
-}
-
 void
 DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
 {
@@ -744,8 +758,7 @@ DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
     if (pPriv == NULL)
         return;
 
-    __DRI2BlockClient(client, pPriv);
-    pPriv->blockedOnMsc = TRUE;
+    dri2Sleep(client, pPriv, WAKE_MSC);
 }
 
 static inline PixmapPtr GetDrawablePixmap(DrawablePtr drawable)
@@ -978,10 +991,7 @@ DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
     ProcDRI2WaitMSCReply(client, ((CARD64) tv_sec * 1000000) + tv_usec,
                          frame, pPriv->swap_count);
 
-    if (pPriv->blockedClient)
-        ClientSignal(pPriv->blockedClient);
-
-    pPriv->blockedOnMsc = FALSE;
+    dri2WakeAll(client, pPriv, WAKE_MSC);
 }
 
 static void
@@ -1007,16 +1017,14 @@ DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
      *   - is not blocked due to an MSC wait
      */
     if (pPriv->target_sbc != -1 && pPriv->target_sbc <= pPriv->swap_count) {
-        ProcDRI2WaitMSCReply(client, ((CARD64) tv_sec * 1000000) + tv_usec,
-                             frame, pPriv->swap_count);
-        pPriv->target_sbc = -1;
-        ClientSignal(pPriv->blockedClient);
-    }
-    else if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
-        if (pPriv->blockedClient) {
-            ClientSignal(pPriv->blockedClient);
+        if (dri2WakeAll(client, pPriv, WAKE_SBC)) {
+            ProcDRI2WaitMSCReply(client, ((CARD64) tv_sec * 1000000) + tv_usec,
+                                 frame, pPriv->swap_count);
+            pPriv->target_sbc = -1;
         }
     }
+
+    dri2WakeAll(CLIENT_SIGNAL_ANY, pPriv, WAKE_SWAP);
 }
 
 void
@@ -1064,13 +1072,13 @@ DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
     DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
 
     /* If we're currently waiting for a swap on this drawable, reset
-     * the request and suspend the client.  We only support one
-     * blocked client per drawable. */
-    if (pPriv && pPriv->swapsPending && pPriv->blockedClient == NULL) {
-        ResetCurrentRequest(client);
-        client->sequence--;
-        __DRI2BlockClient(client, pPriv);
-        return TRUE;
+     * the request and suspend the client. */
+    if (pPriv && pPriv->swapsPending) {
+        if (dri2Sleep(client, pPriv, WAKE_SWAP)) {
+            ResetCurrentRequest(client);
+            client->sequence--;
+            return TRUE;
+        }
     }
 
     return FALSE;
@@ -1271,6 +1279,9 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc)
     if (pPriv == NULL)
         return BadDrawable;
 
+    if (pPriv->target_sbc != -1) /* already in use */
+        return BadDrawable;
+
     /* target_sbc == 0 means to block until all pending swaps are
      * finished. Recalculate target_sbc to get that behaviour.
      */
@@ -1287,9 +1298,10 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc)
         return Success;
     }
 
-    pPriv->target_sbc = target_sbc;
-    __DRI2BlockClient(client, pPriv);
+    if (!dri2Sleep(client, pPriv, WAKE_SBC))
+        return BadAlloc;
 
+    pPriv->target_sbc = target_sbc;
     return Success;
 }
 
commit 204e85786f24c1ab734ab9ee015efbb790dee130
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Feb 12 11:59:52 2016 +0000

    dix: Add ClientSignalAll()
    
    This is a variant of ClientSignal() that signals all clients with an
    optional matching sleeping client, function and closure.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    (cherry picked from commit bc3634010c096dffd1935c0c6cf8ba37534ae3d8)

diff --git a/dix/dixutils.c b/dix/dixutils.c
index 205550e..b6b0023 100644
--- a/dix/dixutils.c
+++ b/dix/dixutils.c
@@ -620,6 +620,28 @@ ClientSignal(ClientPtr client)
     return FALSE;
 }
 
+int
+ClientSignalAll(ClientPtr client, ClientSleepProcPtr function, void *closure)
+{
+    SleepQueuePtr q;
+    int count = 0;
+
+    for (q = sleepQueue; q; q = q->next) {
+        if (!(client == CLIENT_SIGNAL_ANY || q->client == client))
+            continue;
+
+        if (!(function == CLIENT_SIGNAL_ANY || q->function == function))
+            continue;
+
+        if (!(closure == CLIENT_SIGNAL_ANY || q->closure == closure))
+            continue;
+
+        count += QueueWorkProc(q->function, q->client, q->closure);
+    }
+
+    return count;
+}
+
 void
 ClientWakeup(ClientPtr client)
 {
diff --git a/include/dix.h b/include/dix.h
index 921156b..d49d055 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -255,6 +255,14 @@ extern _X_EXPORT Bool ClientSleep(ClientPtr client,
 extern _X_EXPORT Bool ClientSignal(ClientPtr /*client */ );
 #endif                          /* ___CLIENTSIGNAL_DEFINED___ */
 
+#ifndef ___CLIENTSIGNALALL_DEFINED___
+#define ___CLIENTSIGNALALL_DEFINED___
+#define CLIENT_SIGNAL_ANY ((void *)-1)
+extern _X_EXPORT int ClientSignalAll(ClientPtr /*client*/,
+                                     ClientSleepProcPtr /*function*/,
+                                     void * /*closure*/);
+#endif                          /* ___CLIENTSIGNALALL_DEFINED___ */
+
 extern _X_EXPORT void ClientWakeup(ClientPtr /*client */ );
 
 extern _X_EXPORT Bool ClientIsAsleep(ClientPtr /*client */ );
commit c06a4b4a2422e937eda36a4ec10bdafc71001be7
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Tue Aug 11 15:45:57 2015 +0100

    xwin: Add SKIPTASKBAR hint to _NET_WM_WINDOW_TYPE_DOCK type windows
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    (cherry picked from commit f7d1e5acdf5ed4ab4ed5c18727aa6f3d379ef560)

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index c010134..a693274 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -1772,7 +1772,7 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
                            (unsigned char **) &pAtom) == Success) {
         if (pAtom && nitems == 1) {
             if (*pAtom == dockWindow) {
-                hint = (hint & ~HINT_NOFRAME) | HINT_SIZEBOX;   /* Xming puts a sizebox on dock windows */
+                hint = (hint & ~HINT_NOFRAME) | HINT_SKIPTASKBAR | HINT_SIZEBOX;
                 *zstyle = HWND_TOPMOST;
             }
         }
commit 6f099c7bd59039834c7b45289310b003b81cb3e3
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Thu Jul 2 19:21:11 2015 +0100

    xwin: In multiwindow mode, look up the HWND for the parent window
    
    Rather than only looking at the foreground window to see if it matches
    the WM_TRANSIENT_FOR window XID, lookup that XID and fetch the HWND from
    the window privates.
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    (cherry picked from commit e7f87f8f76e5ac9479a71e3daf2cfdefd4b5f684)

diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index 79ea108..8b85785 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -523,9 +523,13 @@ winCreateWindowsWindow(WindowPtr pWin)
 
     if (winMultiWindowGetTransientFor(pWin, &daddyId)) {
         if (daddyId) {
-            hFore = GetForegroundWindow();
-            if (hFore && (daddyId != (Window) (INT_PTR) GetProp(hFore, WIN_WID_PROP)))
-                hFore = NULL;
+            WindowPtr pParent;
+            int res = dixLookupWindow(&pParent, daddyId, serverClient, DixReadAccess);
+            if (res == Success)
+                {
+                    winPrivWinPtr pParentPriv = winGetWindowPriv(pParent);
+                    hFore = pParentPriv->hWnd;
+                }
         }
     }
     else {
commit 41cbb7da4e9337d4136d378f5fa45365f41f02e4
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Mon Feb 22 17:41:14 2016 +0000

    xwin: Keyboard layout updates
    
    layout zh_TW doesn't exist (anymore), try something else for that.
    
    layout it variant mac doesn't seem to exist anymore, try to handle
    Macintosh keyboards (running under Parallels on Mac) and other oddities
    in a more generic way, by falling back to matching only on the language
    identifer part of the input locale identifer.
    
    v2:
    Fix typo of 0xa0000 for 0xa000
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    (cherry picked from commit 8c2006ddc5abbd4ac374dabf1cfdd3df8fc88779)

diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c
index d26cc93..fb99113 100644
--- a/hw/xwin/winconfig.c
+++ b/hw/xwin/winconfig.c
@@ -224,7 +224,8 @@ winConfigKeyboard(DeviceIntPtr pDevice)
 {
     char layoutName[KL_NAMELENGTH];
     unsigned char layoutFriendlyName[256];
-    static unsigned int layoutNum = 0;
+    unsigned int layoutNum = 0;
+    unsigned int deviceIdentifier = 0;
     int keyboardType;
 
 #ifdef XWIN_XF86CONFIG
@@ -272,15 +273,10 @@ winConfigKeyboard(DeviceIntPtr pDevice)
     if (keyboardType > 0 && GetKeyboardLayoutName(layoutName)) {
         WinKBLayoutPtr pLayout;
         Bool bfound = FALSE;
+        int pass;
 
-        if (!layoutNum)
-            layoutNum = strtoul(layoutName, (char **) NULL, 16);
+        layoutNum = strtoul(layoutName, (char **) NULL, 16);
         if ((layoutNum & 0xffff) == 0x411) {
-            /* The japanese layouts know a lot of different IMEs which all have
-               different layout numbers set. Map them to a single entry.
-               Same might apply for chinese, korean and other symbol languages
-               too */
-            layoutNum = (layoutNum & 0xffff);
             if (keyboardType == 7) {
                 /* Japanese layouts have problems with key event messages
                    such as the lack of WM_KEYUP for Caps Lock key.
@@ -318,31 +314,47 @@ winConfigKeyboard(DeviceIntPtr pDevice)
                "Windows keyboard layout: \"%s\" (%08x) \"%s\", type %d\n",
                layoutName, layoutNum, layoutFriendlyName, keyboardType);
 
-        for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++) {
-            if (pLayout->winlayout != layoutNum)
-                continue;
-            if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType)
-                continue;
-
-            bfound = TRUE;
-            winMsg(X_PROBED,
-                   "Found matching XKB configuration \"%s\"\n",
-                   pLayout->layoutname);
-
-            winMsg(X_PROBED,
-                   "Model = \"%s\" Layout = \"%s\""
-                   " Variant = \"%s\" Options = \"%s\"\n",
-                   pLayout->xkbmodel ? pLayout->xkbmodel : "none",
-                   pLayout->xkblayout ? pLayout->xkblayout : "none",
-                   pLayout->xkbvariant ? pLayout->xkbvariant : "none",
-                   pLayout->xkboptions ? pLayout->xkboptions : "none");
+        deviceIdentifier = layoutNum >> 16;
+        for (pass = 0; pass < 2; pass++) {
+            /* If we didn't find an exact match for the input locale identifer,
+               try to find an match on the language identifier part only  */
+            if (pass == 1)
+                layoutNum = (layoutNum & 0xffff);
+
+            for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++) {
+                if (pLayout->winlayout != layoutNum)
+                    continue;
+                if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType)
+                    continue;
+
+                bfound = TRUE;
+                winMsg(X_PROBED,
+                       "Found matching XKB configuration \"%s\"\n",
+                       pLayout->layoutname);
+
+                winMsg(X_PROBED,
+                       "Model = \"%s\" Layout = \"%s\""
+                       " Variant = \"%s\" Options = \"%s\"\n",
+                       pLayout->xkbmodel ? pLayout->xkbmodel : "none",
+                       pLayout->xkblayout ? pLayout->xkblayout : "none",
+                       pLayout->xkbvariant ? pLayout->xkbvariant : "none",
+                       pLayout->xkboptions ? pLayout->xkboptions : "none");
+
+                g_winInfo.xkb.model = pLayout->xkbmodel;
+                g_winInfo.xkb.layout = pLayout->xkblayout;
+                g_winInfo.xkb.variant = pLayout->xkbvariant;
+                g_winInfo.xkb.options = pLayout->xkboptions;
+
+                if (deviceIdentifier == 0xa000) {
+                    winMsg(X_PROBED, "Windows keyboard layout device identifier indicates Macintosh, setting Model = \"macintosh\"");
+                    g_winInfo.xkb.model = "macintosh";
+                }
 
-            g_winInfo.xkb.model = pLayout->xkbmodel;
-            g_winInfo.xkb.layout = pLayout->xkblayout;
-            g_winInfo.xkb.variant = pLayout->xkbvariant;
-            g_winInfo.xkb.options = pLayout->xkboptions;
+                break;
+            }
 
-            break;
+            if (bfound)
+                break;
         }
 
         if (!bfound) {
diff --git a/hw/xwin/winlayouts.h b/hw/xwin/winlayouts.h
index d3d5c6d..c7905e3 100644
--- a/hw/xwin/winlayouts.h
+++ b/hw/xwin/winlayouts.h
@@ -42,7 +42,8 @@ typedef struct {
 */
 
 WinKBLayoutRec winKBLayouts[] = {
-    {0x00000404, -1, "pc105", "zh_TW", NULL, NULL, "Chinese (Taiwan)"},
+    {0x00000404, -1, "pc105", "cn", NULL, NULL, "Chinese (Traditional)"},
+    {0x00000804, -1, "pc105", "cn", NULL, NULL, "Chinese (Simplified)"},
     {0x00000405, -1, "pc105", "cz", NULL, NULL, "Czech"},
     {0x00010405, -1, "pc105", "cz_qwerty", NULL, NULL, "Czech (QWERTY)"},
     {0x00000406, -1, "pc105", "dk", NULL, NULL, "Danish"},
@@ -72,7 +73,6 @@ WinKBLayoutRec winKBLayouts[] = {
     {0x0000040f, -1, "pc105", "is", NULL, NULL, "Icelandic"},
     {0x00000410, -1, "pc105", "it", NULL, NULL, "Italian"},
     {0x00010410, -1, "pc105", "it", NULL, NULL, "Italian (142)"},
-    {0xa0000410, -1, "macbook79", "it", "mac", NULL, "Italiano (Apple)"},
     {0x00000411, 7, "jp106", "jp", NULL, NULL, "Japanese"},
     {0x00000412, -1, "kr106", "kr", NULL, NULL, "Korean"},
     {0x00000413, -1, "pc105", "nl", NULL, NULL, "Dutch"},
commit da7745065ee27d62cc2eba4e860118459917dad9
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Wed Nov 19 22:33:39 2014 +0000

    xwin: Add a tentative entry for the Korean keyboard to the list of known keyboard layouts
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Jon Turney <jon.turney at dronecode.org.uk>
    (cherry picked from commit 8c97a0078e7fe22e6159fa53490dfca2f4d267a9)

diff --git a/hw/xwin/winlayouts.h b/hw/xwin/winlayouts.h
index a61fd7a..d3d5c6d 100644
--- a/hw/xwin/winlayouts.h
+++ b/hw/xwin/winlayouts.h
@@ -74,6 +74,7 @@ WinKBLayoutRec winKBLayouts[] = {
     {0x00010410, -1, "pc105", "it", NULL, NULL, "Italian (142)"},
     {0xa0000410, -1, "macbook79", "it", "mac", NULL, "Italiano (Apple)"},
     {0x00000411, 7, "jp106", "jp", NULL, NULL, "Japanese"},
+    {0x00000412, -1, "kr106", "kr", NULL, NULL, "Korean"},
     {0x00000413, -1, "pc105", "nl", NULL, NULL, "Dutch"},
     {0x00000813, -1, "pc105", "be", NULL, NULL, "Dutch (Belgian)"},
     {0x00000414, -1, "pc105", "no", NULL, NULL, "Norwegian"},
commit c1eb12f89c2391cd99a834da6b342f104da1eb5c
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Tue Feb 10 14:36:37 2015 +0000

    xwin: Update to XRANDR 1.2 internal interface to ensure an output is reported by XRANDR
    
    If using the X server internal XRANDR 1.0 interface, it seems we must
    register a display size with RRRegisterSize() in order to make
    RRGetInfo() call RRScanOldConfig() to generate an output and crtc for
    us.
    
    Without this, the following GDM bug means that an XDMCP session to GDM
    cannot be started.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=736054
    
    Instead, use the more recent XRANDR 1.2 internal interface to explicitly
    create the output and crtc, and maintain a single mode which represents
    the current display size.
    
    Also don't emit a RRScreenSizeNotify when a RRScreenSizeSize is done
    which has no effect, this seems to throw the GDM greeter into a loop...
    
    v2: Maintain reference count for the mode we maintain more correctly, to
    avoid double free causing a crash on shutdown
    
    Connect crtc to output, so a subsequent RRSetCrtcConfig request doesn't
    change anything, so we don't fail due to our lack of rrSetConfig or
    rrCrtcSet hooks.
    
    See https://cygwin.com/ml/cygwin-xfree/2015-02/msg00032.html
    
    v3:
    Raise limit on X display size from 4Kx4K to 32Kx32K
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    (cherry picked from commit a4d8a64c4ba467964476c4a1486da698bd6aed9e)

diff --git a/hw/xwin/winrandr.c b/hw/xwin/winrandr.c
index c29d7b3..1560199 100644
--- a/hw/xwin/winrandr.c
+++ b/hw/xwin/winrandr.c
@@ -34,11 +34,6 @@
 #include <xwin-config.h>
 #endif
 #include "win.h"
-#include "mivalidate.h"         // for union _Validate used by windowstr.h
-
-#ifndef RANDR_12_INTERFACE
-#error X server must have RandR 1.2 interface
-#endif
 
 /*
  * Answer queries about the RandR features supported.
@@ -47,17 +42,47 @@
 static Bool
 winRandRGetInfo(ScreenPtr pScreen, Rotation * pRotations)
 {
+    rrScrPrivPtr pRRScrPriv;
+    RROutputPtr output;
+
+    pRRScrPriv = rrGetScrPriv(pScreen);
+    output = pRRScrPriv->outputs[0];
+
     winDebug("winRandRGetInfo ()\n");
 
     /* Don't support rotations */
     *pRotations = RR_Rotate_0;
 
-    /*
-       The screen doesn't have to be limited to the actual
-       monitor size (we can have scrollbars :-), so what is
-       the upper limit?
-     */
-    RRScreenSetSizeRange(pScreen, 0, 0, 4096, 4096);
+    /* Delete previous mode */
+    if (output->modes[0])
+        {
+            RRModeDestroy(output->modes[0]);
+            RRModeDestroy(output->crtc->mode);
+        }
+
+    /* Register current mode */
+    {
+        xRRModeInfo modeInfo;
+        RRModePtr mode;
+        char name[100];
+
+        memset(&modeInfo, '\0', sizeof(modeInfo));
+        snprintf(name, sizeof(name), "%dx%d", pScreen->width, pScreen->height);
+
+        modeInfo.width = pScreen->width;
+        modeInfo.height = pScreen->height;
+        modeInfo.hTotal = pScreen->width;
+        modeInfo.vTotal = pScreen->height;
+        modeInfo.dotClock = 0;
+        modeInfo.nameLength = strlen(name);
+        mode = RRModeGet(&modeInfo, name);
+
+        output->modes[0] = mode;
+        output->numModes = 1;
+
+        mode = RRModeGet(&modeInfo, name);
+        output->crtc->mode = mode;
+    }
 
     return TRUE;
 }
@@ -74,6 +99,11 @@ winDoRandRScreenSetSize(ScreenPtr pScreen,
     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
     WindowPtr pRoot = pScreen->root;
 
+    /* Ignore changes which do nothing */
+    if ((pScreen->width == width) && (pScreen->height == height) &&
+        (pScreen->mmWidth == mmWidth) && (pScreen->mmHeight == mmHeight))
+        return;
+
     // Prevent screen updates while we change things around
     SetRootClip(pScreen, ROOT_CLIP_NONE);
 
@@ -214,5 +244,45 @@ winRandRInit(ScreenPtr pScreen)
     pRRScrPriv->rrCrtcSet = NULL;
     pRRScrPriv->rrCrtcSetGamma = NULL;
 
+    /* Create a CRTC and an output for the screen, and hook them together */
+    {
+        RRCrtcPtr crtc;
+        RROutputPtr output;
+
+        crtc = RRCrtcCreate(pScreen, NULL);
+        if (!crtc)
+            return FALSE;
+
+        crtc->rotations = RR_Rotate_0;
+
+        output = RROutputCreate(pScreen, "default", 7, NULL);
+        if (!output)
+            return FALSE;
+
+        RROutputSetCrtcs(output, &crtc, 1);
+        RROutputSetConnection(output, RR_Connected);
+        RROutputSetSubpixelOrder(output, PictureGetSubpixelOrder(pScreen));
+
+        output->crtc = crtc;
+
+        /* Set crtc outputs (should use RRCrtcNotify?) */
+        crtc->outputs = malloc(sizeof(RROutputPtr));
+        crtc->outputs[0] = output;
+        crtc->numOutputs = 1;
+
+        pRRScrPriv->primaryOutput = output;
+
+        /* Ensure we have space for exactly one mode */
+        output->modes = malloc(sizeof(RRModePtr));
+        output->modes[0] = NULL;
+    }
+
+    /*
+       The screen doesn't have to be limited to the actual
+       monitor size (we can have scrollbars :-), so set the
+       upper limit to the maximum coordinates X11 can use.
+     */
+    RRScreenSetSizeRange(pScreen, 0, 0, 32768, 32768);
+
     return TRUE;
 }
commit 771a668188793e7261ae2cbf7d7289b8a133316a
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Sat Oct 18 17:31:57 2014 +0100

    xwin: Use WM_CLIPBOARDUPDATE clipboard API
    
    Windows Vista and later have a saner clipboard API where the clipboard
    viewer linked list is no longer maintained by applications.  Use it
    where available.
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    (cherry picked from commit 008efebda801b9b80e2ab3f2c95aeef8c82102ee)

diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h
index 6c26caf..d0d8fbd 100644
--- a/hw/xwin/winclipboard/internal.h
+++ b/hw/xwin/winclipboard/internal.h
@@ -77,6 +77,14 @@ typedef struct
     Atom atomTargets;
 } ClipboardAtoms;
 
+/* Modern clipboard API functions */
+typedef wBOOL WINAPI (*ADDCLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
+typedef wBOOL WINAPI (*REMOVECLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
+
+extern Bool g_fHasModernClipboardApi;
+extern ADDCLIPBOARDFORMATLISTENERPROC g_fpAddClipboardFormatListener;
+extern REMOVECLIPBOARDFORMATLISTENERPROC g_fpRemoveClipboardFormatListener;
+
 /*
  * winclipboardwndproc.c
  */
diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c
index 50e1e8c..fa57ada 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -84,6 +84,10 @@ static pthread_t g_winClipboardProcThread;
 int xfixes_event_base;
 int xfixes_error_base;
 
+Bool g_fHasModernClipboardApi = FALSE;
+ADDCLIPBOARDFORMATLISTENERPROC g_fpAddClipboardFormatListener;
+REMOVECLIPBOARDFORMATLISTENERPROC g_fpRemoveClipboardFormatListener;
+
 /*
  * Local function prototypes
  */
@@ -138,6 +142,11 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
         ErrorF("winClipboardProc - Warning: Locale not supported by X.\n");
     }
 
+    g_fpAddClipboardFormatListener = (ADDCLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"AddClipboardFormatListener");
+    g_fpRemoveClipboardFormatListener = (REMOVECLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"RemoveClipboardFormatListener");
+    g_fHasModernClipboardApi = g_fpAddClipboardFormatListener && g_fpRemoveClipboardFormatListener;
+    ErrorF("OS maintains clipboard viewer chain: %s\n", g_fHasModernClipboardApi ? "yes" : "no");
+
     g_winClipboardProcThread = pthread_self();
 
     /* Set error handler */
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index d17cf2e..d289f77 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -58,6 +58,9 @@
 
 #define WIN_POLL_TIMEOUT	1
 
+#ifndef WM_CLIPBOARDUPDATE
+#define WM_CLIPBOARDUPDATE 0x031D
+#endif
 
 /*
  * Process X events up to specified timeout
@@ -151,8 +154,16 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     {
         winDebug("winClipboardWindowProc - WM_DESTROY\n");
 
-        /* Remove ourselves from the clipboard chain */
-        ChangeClipboardChain(hwnd, s_hwndNextViewer);
+        if (g_fHasModernClipboardApi)
+            {
+                /* Remove clipboard listener */
+                g_fpRemoveClipboardFormatListener(hwnd);
+            }
+        else
+            {
+                /* Remove ourselves from the clipboard chain */
+                ChangeClipboardChain(hwnd, s_hwndNextViewer);
+            }
 
         s_hwndNextViewer = NULL;
     }
@@ -168,8 +179,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
     case WM_CREATE:
     {
-        HWND first, next;
-        DWORD error_code = 0;
         ClipboardWindowCreationParams *cwcp = (ClipboardWindowCreationParams *)((CREATESTRUCT *)lParam)->lpCreateParams;
 
         winDebug("winClipboardWindowProc - WM_CREATE\n");
@@ -179,16 +188,26 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         atoms = cwcp->atoms;
         fRunning = TRUE;
 
-        first = GetClipboardViewer();   /* Get handle to first viewer in chain. */
-        if (first == hwnd)
-            return 0;           /* Make sure it's not us! */
-        /* Add ourselves to the clipboard viewer chain */
-        next = SetClipboardViewer(hwnd);
-        error_code = GetLastError();
-        if (SUCCEEDED(error_code) && (next == first))   /* SetClipboardViewer must have succeeded, and the handle */
-            s_hwndNextViewer = next;    /* it returned must have been the first window in the chain */
+        if (g_fHasModernClipboardApi)
+            {
+                g_fpAddClipboardFormatListener(hwnd);
+            }
         else
-            s_fCBCInitialized = FALSE;
+            {
+                HWND first, next;
+                DWORD error_code = 0;
+
+                first = GetClipboardViewer();   /* Get handle to first viewer in chain. */
+                if (first == hwnd)
+                    return 0;           /* Make sure it's not us! */
+                /* Add ourselves to the clipboard viewer chain */
+                next = SetClipboardViewer(hwnd);
+                error_code = GetLastError();
+                if (SUCCEEDED(error_code) && (next == first))   /* SetClipboardViewer must have succeeded, and the handle */
+                    s_hwndNextViewer = next;    /* it returned must have been the first window in the chain */
+                else
+                    s_fCBCInitialized = FALSE;
+            }
     }
         return 0;
 
@@ -233,6 +252,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         winDebug("winClipboardWindowProc - WM_WM_REINIT: Enter\n");
 
+        if (g_fHasModernClipboardApi)
+            {
+                return 0;
+            }
+
         first = GetClipboardViewer();   /* Get handle to first viewer in chain. */
         if (first == hwnd)
             return 0;           /* Make sure it's not us! */
@@ -257,38 +281,45 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         return 0;
 
     case WM_DRAWCLIPBOARD:
+    case WM_CLIPBOARDUPDATE:
     {
         static Bool s_fProcessingDrawClipboard = FALSE;
         int iReturn;
 
-        winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n");
+        if (message == WM_DRAWCLIPBOARD)
+            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n");
+        else
+            winDebug("winClipboardWindowProc -  WM_CLIPBOARDUPDATE: Enter\n");
 
-        /*
-         * We've occasionally seen a loop in the clipboard chain.
-         * Try and fix it on the first hint of recursion.
-         */
-        if (!s_fProcessingDrawClipboard) {
-            s_fProcessingDrawClipboard = TRUE;
-        }
-        else {
-            /* Attempt to break the nesting by getting out of the chain, twice?, and then fix and bail */
-            s_fCBCInitialized = FALSE;
-            ChangeClipboardChain(hwnd, s_hwndNextViewer);
-            winFixClipboardChain();
-            ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
-                   "Nested calls detected.  Re-initing.\n");
-            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
-            s_fProcessingDrawClipboard = FALSE;
-            return 0;
-        }
+        if (!g_fHasModernClipboardApi)
+            {
+                /*
+                 * We've occasionally seen a loop in the clipboard chain.
+                 * Try and fix it on the first hint of recursion.
+                 */
+                if (!s_fProcessingDrawClipboard) {
+                    s_fProcessingDrawClipboard = TRUE;
+                }
+                else {
+                    /* Attempt to break the nesting by getting out of the chain, twice?, and then fix and bail */
+                    s_fCBCInitialized = FALSE;
+                    ChangeClipboardChain(hwnd, s_hwndNextViewer);
+                    winFixClipboardChain();
+                    ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+                           "Nested calls detected.  Re-initing.\n");
+                    winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
+                    s_fProcessingDrawClipboard = FALSE;
+                    return 0;
+                }
 
-        /* Bail on first message */
-        if (!s_fCBCInitialized) {
-            s_fCBCInitialized = TRUE;
-            s_fProcessingDrawClipboard = FALSE;
-            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
-            return 0;
-        }
+                /* Bail on first message */
+                if (!s_fCBCInitialized) {
+                    s_fCBCInitialized = TRUE;
+                    s_fProcessingDrawClipboard = FALSE;
+                    winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
+                    return 0;
+                }
+            }
 
         /*
          * NOTE: We cannot bail out when NULL == GetClipboardOwner ()
commit 00199e8c822fcf6a933637410e44e08ac659f682
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Wed Jul 9 14:26:54 2014 +0100

    xwin: Check that window position is visible on non-rectangular virtual desktops
    
    Improve the check that window position is visible to work correctly for
    non-rectangular virtual desktops
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    (cherry picked from commit de7f1fd6f8f10f07b366ae5428a8c65a224bda98)

diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index f4de912..79ea108 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -503,15 +503,19 @@ winCreateWindowsWindow(WindowPtr pWin)
     iHeight = pWin->drawable.height;
 
     /* If it's an InputOutput window, and so is going to end up being made visible,
-       make sure the window actually ends up somewhere where it will be visible */
-    if (pWin->drawable.class != InputOnly) {
-        if ((iX < GetSystemMetrics(SM_XVIRTUALSCREEN)) ||
-            (iX > GetSystemMetrics(SM_CXVIRTUALSCREEN)))
-            iX = CW_USEDEFAULT;
+       make sure the window actually ends up somewhere where it will be visible
 
-        if ((iY < GetSystemMetrics(SM_YVIRTUALSCREEN)) ||
-            (iY > GetSystemMetrics(SM_CYVIRTUALSCREEN)))
-            iY = CW_USEDEFAULT;
+       To handle arrangements of monitors which form a non-rectangular virtual
+       desktop, check if the window will end up with it's top-left corner on any
+       monitor
+    */
+    if (pWin->drawable.class != InputOnly) {
+        POINT pt = { iX, iY };
+        if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) == NULL)
+            {
+                iX = CW_USEDEFAULT;
+                iY = CW_USEDEFAULT;
+            }
     }
 
     winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX,
commit 0fb47bd27919a7f1e47db3bd3f97fd9a07ccc517
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Thu May 8 11:40:39 2014 +0100

    xwin: Correctly interpret WM_HINTS, WM_NORMAL_HINTS properties on x86_64
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    (cherry picked from commit a9e73131b6453e0fa2da5360e84af7a2eae3b205)

diff --git a/hw/xwin/winmultiwindowclass.h b/hw/xwin/winmultiwindowclass.h
index 3244f78..37ee9fb 100644
--- a/hw/xwin/winmultiwindowclass.h
+++ b/hw/xwin/winmultiwindowclass.h
@@ -31,11 +31,24 @@
  */
 
 /*
+ * The next block of definitions are for window manager properties that
+ * clients and applications use for communication.
+ */
+
+/*
  * Structures
  */
 
+/*
+ * WM_HINTS structure
+ *
+ * NOTE: this structure represents the internal format stored in the property
+ * after it is marshalled by libX11, converting the flags field from an
+ * arch-dependent long to a 32-bit int.
+ */
+
 typedef struct {
-    long flags;                 /* marks which fields in this structure are defined */
+    int flags;                  /* marks which fields in this structure are defined */
     Bool input;                 /* does this application rely on the window manager to
                                    get keyboard input? */
     int initial_state;          /* see below */
@@ -59,11 +72,15 @@ typedef struct {
 #define	AllHints 	(InputHint|StateHint|IconPixmapHint|IconWindowHint|IconPositionHint|IconMaskHint|WindowGroupHint)
 
 /*
- * new version containing base_width, base_height, and win_gravity fields;
+ * ICCCM 1.0 version containing base_width, base_height, and win_gravity fields;
  * used with WM_NORMAL_HINTS.
+ *
+ * NOTE: this structure represents the internal format stored in the property
+ * after it is marshalled by libX11, converting the flags field from an
+ * arch-dependent long to a 32-bit int.
  */
 typedef struct {
-    long flags;                 /* marks which fields in this structure are defined */
+    int flags;                  /* marks which fields in this structure are defined */
     int x, y;                   /* obsolete for new window mgrs, but clients */
     int width, height;          /* should set so old wm's don't mess up */
     int min_width, min_height;
@@ -77,11 +94,6 @@ typedef struct {
     int win_gravity;            /* added by ICCCM version 1 */
 } WinXSizeHints;
 
-/*
- * The next block of definitions are for window manager properties that
- * clients and applications use for communication.
- */
-
 /* flags argument in size hints */
 #define USPosition      (1L << 0)       /* user specified x, y */
 #define USSize          (1L << 1)       /* user specified width, height */
commit 1e143cff16835dd69559ca5646f313dad3db75ab
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Thu Mar 13 18:04:17 2014 +0000

    xwin: Improve handling of no-decoration motif hint
    
    When motif decoration hint asks for no decoration, don't add sysmenu,
    mimimize or maximimize controls.
    
    (This fixes a problem with e.g. fbpanel having a minimize control, but
    gtk's panel_configure_event() doesn't like the state we put the window
    into when we minimize it, causing it to spin)
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    (cherry picked from commit d7cef6fbe23381b31c163468f349feee2f1b1eba)

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 3156e36..c010134 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -1738,7 +1738,7 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
         if (mwm_hint && nitems == PropMwmHintsElements &&
             (mwm_hint->flags & MwmHintsDecorations)) {
             if (!mwm_hint->decorations)
-                hint |= HINT_NOFRAME;
+                hint |= (HINT_NOFRAME | HINT_NOSYSMENU | HINT_NOMINIMIZE | HINT_NOMAXIMIZE);
             else if (!(mwm_hint->decorations & MwmDecorAll)) {
                 if (mwm_hint->decorations & MwmDecorBorder)
                     hint |= HINT_BORDER;
commit f0c2a3527797cf2bfbfa4697c294ae087c1e4423
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Fri Mar 28 16:57:48 2014 +0000

    xwin: XGetWMNormalHints() returns non-zero on success
    
    XGetWMNormalHints() doesn't actually return a Status value.  On success
    it returns a non-zero value, not Success.
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>
    (cherry picked from commit f75404be3ad94c8da493688397712c65ea66cb90)

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 1efe96a..3156e36 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -1785,8 +1785,7 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
         long supplied;
 
         if (normal_hint &&
-            (XGetWMNormalHints(pDisplay, iWindow, normal_hint, &supplied) ==
-             Success)) {
+            XGetWMNormalHints(pDisplay, iWindow, normal_hint, &supplied)) {
             if (normal_hint->flags & PMaxSize) {
                 /* Not maximizable if a maximum size is specified */
                 hint |= HINT_NOMAXIMIZE;
commit e457e93e5d33cbec387e40051fbabf6cf76d6af3
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Feb 24 16:52:59 2016 +0900

    present: Only requeue if target MSC is not reached after an unflip
    
    While present_pixmap decrements target_msc by 1 for present_queue_vblank,
    it leaves the original vblank->target_msc intact. So incrementing the
    latter for requeueing resulted in the requeued presentation being
    executed too late.
    
    Also, no need to requeue if the target MSC is already reached.
    
    This further reduces stutter when a popup menu appears on top of a
    flipping fullscreen window.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    (cherry picked from commit b4ac7b142fa3c536e9b283cfd34b94d82c03aac6)

diff --git a/present/present.c b/present/present.c
index 7f9fc17..62865be 100644
--- a/present/present.c
+++ b/present/present.c
@@ -582,10 +582,8 @@ present_check_flip_window (WindowPtr window)
     xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
         if (vblank->queued && vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, vblank->sync_flip, NULL, 0, 0)) {
             vblank->flip = FALSE;
-            if (vblank->sync_flip) {
+            if (vblank->sync_flip)
                 vblank->requeue = TRUE;
-                vblank->target_msc++;
-            }
         }
     }
 }
@@ -622,7 +620,8 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 
     if (vblank->requeue) {
         vblank->requeue = FALSE;
-        if (Success == present_queue_vblank(screen,
+        if (msc_is_after(vblank->target_msc, crtc_msc) &&
+            Success == present_queue_vblank(screen,
                                             vblank->crtc,
                                             vblank->event_id,
                                             vblank->target_msc))
commit eb5108b87017128f394ae31b5b7cd85dd8819bca
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Feb 24 16:52:58 2016 +0900

    present: Requeue if flip driver hook fails and target MSC not reached
    
    For flipping, we wait for the MSC before the target MSC and then call
    the driver flip hook. If the latter fails, we have to wait for the
    target MSC before falling back to a copy, or else it's executed too
    early.
    
    Fixes glxgears running at unbounded framerate (not synchronized to the
    refresh rate) in fullscreen if the driver flip hook fails.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    (cherry picked from commit e7a35b9e16aa12970908f5d55371bb1b862f8f24)

diff --git a/present/present.c b/present/present.c
index 17ec526..7f9fc17 100644
--- a/present/present.c
+++ b/present/present.c
@@ -712,6 +712,20 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             if (window == screen_priv->flip_window)
                 present_unflip(screen);
         }
+
+        /* If present_flip failed, we may have to requeue for the target MSC */
+        if (msc_is_after(vblank->target_msc, crtc_msc) &&
+            Success == present_queue_vblank(screen,
+                                            vblank->crtc,
+                                            vblank->event_id,
+                                            vblank->target_msc)) {
+            xorg_list_add(&vblank->event_queue, &present_exec_queue);
+            xorg_list_append(&vblank->window_list,
+                             &present_get_window_priv(window, TRUE)->vblank);
+            vblank->queued = TRUE;
+            return;
+        }
+
         present_copy_region(&window->drawable, vblank->pixmap, vblank->update, vblank->x_off, vblank->y_off);
 
         /* present_copy_region sticks the region into a scratch GC,
commit cf30b7cfd6d91da16c762332617fc165d82f17d2
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Feb 24 16:52:57 2016 +0900

    present: Move msc_is_(equal_or_)after to the top of present.c
    
    To make them usable from any other function in the file. No functional
    change.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    (cherry picked from commit 1a9f8c4623c4e6b6955cb6d5f44d29c244dfd32a)

diff --git a/present/present.c b/present/present.c
index 8cf3b6f..17ec526 100644
--- a/present/present.c
+++ b/present/present.c
@@ -46,6 +46,28 @@ static void
 present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
 
 /*
+ * Returns:
+ * TRUE if the first MSC value is after the second one
+ * FALSE if the first MSC value is equal to or before the second one
+ */
+static Bool
+msc_is_after(uint64_t test, uint64_t reference)
+{
+    return (int64_t)(test - reference) > 0;
+}
+
+/*
+ * Returns:
+ * TRUE if the first MSC value is equal to or after the second one
+ * FALSE if the first MSC value is before the second one
+ */
+static Bool
+msc_is_equal_or_after(uint64_t test, uint64_t reference)
+{
+    return (int64_t)(test - reference) >= 0;
+}
+
+/*
  * Copies the update region from a pixmap to the target drawable
  */
 static void
@@ -717,28 +739,6 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     present_vblank_destroy(vblank);
 }
 
-/*
- * Returns:
- * TRUE if the first MSC value is after the second one
- * FALSE if the first MSC value is equal to or before the second one
- */
-static Bool
-msc_is_after(uint64_t test, uint64_t reference)
-{
-    return (int64_t)(test - reference) > 0;
-}
-
-/*
- * Returns:
- * TRUE if the first MSC value is equal to or after the second one
- * FALSE if the first MSC value is before the second one
- */
-static Bool
-msc_is_equal_or_after(uint64_t test, uint64_t reference)
-{
-    return (int64_t)(test - reference) >= 0;
-}
-
 int
 present_pixmap(WindowPtr window,
                PixmapPtr pixmap,
commit 8869f45a965a7b12bb7fe03ba226167e1f821c1e
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Mon Feb 22 16:04:12 2016 -0300

    kdrive/evdev: update keyboard LEDs (#22302)
    
    Implement missing parts in kdrive evdev driver for
    correct update of evdev keyboard LEDs.
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=22302
    
    [ajax: Fixed deref-before-null-check bug]
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
    (cherry picked from commit 0461bca0cb2f7918c77ed45d2cbc756cf65021be)

diff --git a/hw/kdrive/linux/evdev.c b/hw/kdrive/linux/evdev.c
index 63e8409..7524894 100644
--- a/hw/kdrive/linux/evdev.c
+++ b/hw/kdrive/linux/evdev.c
@@ -440,10 +440,16 @@ EvdevKbdEnable(KdKeyboardInfo * ki)
 static void
 EvdevKbdLeds(KdKeyboardInfo * ki, int leds)
 {
-/*    struct input_event event;
+    struct input_event event;
     Kevdev             *ke;
 
-    ki->driverPrivate = ke;
+    if (!ki)
+        return;
+
+    ke = ki->driverPrivate;
+
+    if (!ke)
+        return;
 
     memset(&event, 0, sizeof(event));
 
@@ -466,7 +472,6 @@ EvdevKbdLeds(KdKeyboardInfo * ki, int leds)
     event.code = LED_COMPOSE;
     event.value = leds & (1 << 3) ? 1 : 0;
     write(ke->fd, (char *) &event, sizeof(event));
-*/
 }
 
 static void
commit 05f3cf659be44caf00e801a5bcd9362a1a87aa46
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Feb 22 16:20:00 2016 +0000

    Fix build on Cygwin by ensuring WIN32 check triggers only on MinGW
    
    The type of fd_mask was changed in Cygwin 2.4.0 headers from 'long' to
    'unsigned long'.  This exposes an existing problem with winauth.c, which
    includes Xwindows.h (which includes windows.h, which defines WIN32),
    before including osdep.h, which causes the now conflicting definition of
    fd_mask in osdep.h to be exposed:
    
    In file included from ../os/osdep.h:198:18: error: conflicting types for
    ‘fd_mask’ typedef long int fd_mask; /usr/include/sys/select.h:46:23:
    note: previous declaration of ‘fd_mask’ was here typedef unsigned long
    fd_mask;
    
    Adjust the include guards in osdep.h to make sure we only use WIN32
    guarded code when not compiling for Cygwin (i.e. WIN32 && !__CYGWIN__)
    
    This isn't a very elegant, but unfortunately appears to be the best
    solution, since it doesn't seem to be possible to write the test in a
    positive form.
    
    Future work: Should also audit of all the other uses of WIN32 in
    xserver, and make sure they are correct.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    (cherry picked from commit 30b7d7995ef70b7473e0fb170eb8ae23b8d1f4a7)

diff --git a/os/osdep.h b/os/osdep.h
index 86263a5..ff60943 100644
--- a/os/osdep.h
+++ b/os/osdep.h
@@ -72,7 +72,7 @@ SOFTWARE.
 #if defined(NOFILE) && !defined(NOFILES_MAX)
 #define OPEN_MAX NOFILE
 #else
-#if !defined(WIN32)
+#if !defined(WIN32) || defined(__CYGWIN__)
 #define OPEN_MAX NOFILES_MAX
 #else
 #define OPEN_MAX 512
@@ -171,7 +171,7 @@ extern fd_set ClientsWriteBlocked;
 extern fd_set OutputPending;
 extern fd_set IgnoredClientsWithInput;
 
-#ifndef WIN32
+#if !defined(WIN32) || defined(__CYGWIN__)
 extern int *ConnectionTranslation;
 #else
 extern int GetConnectionTranslation(int conn);
@@ -185,7 +185,7 @@ extern Bool AnyClientsWriteBlocked;
 extern WorkQueuePtr workQueue;
 
 /* in WaitFor.c */
-#ifdef WIN32
+#if defined(WIN32) && !defined(__CYGWIN__)
 typedef long int fd_mask;
 #endif
 #define ffs mffs
commit 10e46504711427ed5280fdeb974a08b888f47034
Author: Jonas Ådahl <jadahl at gmail.com>
Date:   Fri Feb 19 15:08:12 2016 +0800

    xwayland: Prefix shm tmp file names with xwayland
    
    Prefix the temporary file names used for allocating pixmaps with
    "xwayland-" instead of "weston-". This makes it less confusing while
    looking at the file names of the currently open fds of the Xwayland
    process.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
    (cherry picked from commit 544b4149268561d3d794aa540172831fa7550a20)

diff --git a/hw/xwayland/xwayland-shm.c b/hw/xwayland/xwayland-shm.c
index 1b388f0..1beade9 100644
--- a/hw/xwayland/xwayland-shm.c
+++ b/hw/xwayland/xwayland-shm.c
@@ -109,7 +109,7 @@ create_tmpfile_cloexec(char *tmpname)
 static int
 os_create_anonymous_file(off_t size)
 {
-    static const char template[] = "/weston-shared-XXXXXX";
+    static const char template[] = "/xwayland-shared-XXXXXX";
     const char *path;
     char *name;
     int fd;
commit de7f91c079d7168c107bb8b8dbe651eebd8e9a12
Author: Marc-Andre Lureau <marcandre.lureau at gmail.com>
Date:   Fri Feb 12 22:52:07 2016 +0100

    dri2: add virtio-gpu pci ids
    
    Add virtio-gpu legacy + 1.0 pci ids, allowing them to use
    modesetting + glamor with dri2.
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit 5627708e5f447d0e360bbc9eb8d1c4e58c5046d0)

diff --git a/hw/xfree86/dri2/pci_ids/Makefile.am b/hw/xfree86/dri2/pci_ids/Makefile.am
index c511108..69fe8c4 100644
--- a/hw/xfree86/dri2/pci_ids/Makefile.am
+++ b/hw/xfree86/dri2/pci_ids/Makefile.am
@@ -8,4 +8,5 @@ EXTRA_DIST = \
 	r600_pci_ids.h \
 	radeon_pci_ids.h \
 	radeonsi_pci_ids.h \
+	virtio_gpu_pci_ids.h \
 	vmwgfx_pci_ids.h
diff --git a/hw/xfree86/dri2/pci_ids/pci_id_driver_map.h b/hw/xfree86/dri2/pci_ids/pci_id_driver_map.h
index 8a97c6f..da7ea1c 100644
--- a/hw/xfree86/dri2/pci_ids/pci_id_driver_map.h
+++ b/hw/xfree86/dri2/pci_ids/pci_id_driver_map.h
@@ -51,6 +51,12 @@ static const int radeonsi_chip_ids[] = {
 #undef CHIPSET
 };
 
+static const int virtio_gpu_chip_ids[] = {
+#define CHIPSET(chip, name, family) chip,
+#include "pci_ids/virtio_gpu_pci_ids.h"
+#undef CHIPSET
+};
+
 static const int vmwgfx_chip_ids[] = {
 #define CHIPSET(chip, name, family) chip,
 #include "pci_ids/vmwgfx_pci_ids.h"
@@ -73,6 +79,7 @@ static const struct {
    { 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids) },
    { 0x1002, "radeonsi", radeonsi_chip_ids, ARRAY_SIZE(radeonsi_chip_ids) },
    { 0x10de, "nouveau", NULL, -1 },
+   { 0x1af4, "virtio_gpu", virtio_gpu_chip_ids, ARRAY_SIZE(virtio_gpu_chip_ids) },
    { 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids) },
    { 0x0000, NULL, NULL, 0 },
 };
diff --git a/hw/xfree86/dri2/pci_ids/virtio_gpu_pci_ids.h b/hw/xfree86/dri2/pci_ids/virtio_gpu_pci_ids.h
new file mode 100644
index 0000000..9232cd2
--- /dev/null
+++ b/hw/xfree86/dri2/pci_ids/virtio_gpu_pci_ids.h
@@ -0,0 +1,2 @@
+CHIPSET(0x0010, VIRTGL, VIRTGL)
+CHIPSET(0x1050, VIRTGL, VIRTGL)
commit 16573a4c35cb71f204b37ad1c3b3d115e84b2cd8
Author: Daniel Stone <daniels at collabora.com>
Date:   Fri Feb 12 16:36:59 2016 +0000

    dix: Add hybrid full-size/empty-clip mode to SetRootClip
    
    216bdbc735 removed the SetRootClip call in the XWayland output-hotplug
    handler when running rootless (e.g. as a part of Weston/Mutter), since
    the root window has no storage, so generating exposures will result in
    writes to invalid memory.
    
    Unfortunately, preventing the segfault also breaks sprite confinement.
    SetRootClip updates winSize and borderSize for the root window, which
    when combined with RRScreenSizeChanged calling ScreenRestructured,
    generates a new sprite-confinment area to update it to the whole screen.
    
    Removing this call results in the window geometry being reported
    correctly, but winSize/borderSize never changing from their values at
    startup, i.e. out of sync with the root window geometry / screen
    information in the connection info / XRandR.
    
    This patch introduces a hybrid mode, where we update winSize and
    borderSize for the root window, enabling sprite confinement to work
    correctly, but keep the clip emptied so exposures are never generated.
    
    Signed-off-by: Daniel Stone <daniels at collabora.com>
    Tested-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit e957a2e5dd288f515f3e93724823542c20333f6a)

diff --git a/dix/window.c b/dix/window.c
index 25d29ec..ead4dc2 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -3647,7 +3647,7 @@ WindowParentHasDeviceCursor(WindowPtr pWin,
  *	all of the windows
  */
 void
-SetRootClip(ScreenPtr pScreen, Bool enable)
+SetRootClip(ScreenPtr pScreen, int enable)
 {
     WindowPtr pWin = pScreen->root;
     WindowPtr pChild;
@@ -3655,6 +3655,7 @@ SetRootClip(ScreenPtr pScreen, Bool enable)
     Bool anyMarked = FALSE;
     WindowPtr pLayerWin;
     BoxRec box;
+    enum RootClipMode mode = enable;
 
     if (!pWin)
         return;
@@ -3679,23 +3680,32 @@ SetRootClip(ScreenPtr pScreen, Bool enable)
         }
     }
 
-    /*
-     * Use REGION_BREAK to avoid optimizations in ValidateTree
-     * that assume the root borderClip can't change well, normally
-     * it doesn't...)
-     */
-    if (enable) {
+    if (mode != ROOT_CLIP_NONE) {
+        pWin->drawable.width = pScreen->width;
+        pWin->drawable.height = pScreen->height;
+
         box.x1 = 0;
         box.y1 = 0;
         box.x2 = pScreen->width;
         box.y2 = pScreen->height;
+
         RegionInit(&pWin->winSize, &box, 1);
         RegionInit(&pWin->borderSize, &box, 1);
-        if (WasViewable)
-            RegionReset(&pWin->borderClip, &box);
-        pWin->drawable.width = pScreen->width;
-        pWin->drawable.height = pScreen->height;
+
+        /*
+         * Use REGION_BREAK to avoid optimizations in ValidateTree
+         * that assume the root borderClip can't change well, normally
+         * it doesn't...)
+         */
         RegionBreak(&pWin->clipList);
+
+	/* For INPUT_ONLY, empty the borderClip so no rendering will ever
+	 * be attempted to the screen pixmap (only redirected windows),
+	 * but we keep borderSize as full regardless. */
+        if (WasViewable && mode == ROOT_CLIP_FULL)
+            RegionReset(&pWin->borderClip, &box);
+        else
+            RegionEmpty(&pWin->borderClip);
     }
     else {
         RegionEmpty(&pWin->borderClip);
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index dddbe6e..582ff66 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -99,7 +99,7 @@ KdDisableScreen(ScreenPtr pScreen)
     if (!pScreenPriv->enabled)
         return;
     if (!pScreenPriv->closed)
-        SetRootClip(pScreen, FALSE);
+        SetRootClip(pScreen, ROOT_CLIP_NONE);
     KdDisableColormap(pScreen);
     if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->disableAccel)
         (*pScreenPriv->card->cfuncs->disableAccel) (pScreen);
@@ -182,7 +182,7 @@ KdEnableScreen(ScreenPtr pScreen)
     if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->enableAccel)
         (*pScreenPriv->card->cfuncs->enableAccel) (pScreen);
     KdEnableColormap(pScreen);
-    SetRootClip(pScreen, TRUE);
+    SetRootClip(pScreen, ROOT_CLIP_FULL);
     if (pScreenPriv->card->cfuncs->dpms)
         (*pScreenPriv->card->cfuncs->dpms) (pScreen, pScreenPriv->dpmsState);
     return TRUE;
diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index 9e8dd7a..01bb631 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -763,7 +763,7 @@ vfbRRScreenSetSize(ScreenPtr  pScreen,
                    CARD32     mmHeight)
 {
     // Prevent screen updates while we change things around
-    SetRootClip(pScreen, FALSE);
+    SetRootClip(pScreen, ROOT_CLIP_NONE);
 
     pScreen->width = width;
     pScreen->height = height;
@@ -771,7 +771,7 @@ vfbRRScreenSetSize(ScreenPtr  pScreen,
     pScreen->mmHeight = mmHeight;
 
     // Restore the ability to update screen, now with new dimensions
-    SetRootClip(pScreen, TRUE);
+    SetRootClip(pScreen, ROOT_CLIP_FULL);
 
     RRScreenSizeNotify (pScreen);
     RRTellChanged(pScreen);
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index c42e93e..3b01a49 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -1076,14 +1076,14 @@ xf86EnableDisableFBAccess(ScrnInfoPtr pScrnInfo, Bool enable)
          * Restore all of the clip lists on the screen
          */
         if (!xf86Resetting)
-            SetRootClip(pScreen, TRUE);
+            SetRootClip(pScreen, ROOT_CLIP_FULL);
 
     }
     else {
         /*
          * Empty all of the clip lists on the screen
          */
-        SetRootClip(pScreen, FALSE);
+        SetRootClip(pScreen, ROOT_CLIP_NONE);
     }
 }
 
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index eae7016..60d2254 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1848,13 +1848,13 @@ xf86RandR14ProviderSetOutputSource(ScreenPtr pScreen,
     if (provider->output_source == source_provider)
         return TRUE;
 
-    SetRootClip(source_provider->pScreen, FALSE);
+    SetRootClip(source_provider->pScreen, ROOT_CLIP_NONE);
 
     DetachUnboundGPU(pScreen);
     AttachOutputGPU(source_provider->pScreen, pScreen);
 
     provider->output_source = source_provider;
-    SetRootClip(source_provider->pScreen, TRUE);
+    SetRootClip(source_provider->pScreen, ROOT_CLIP_FULL);
     return TRUE;
 }
 
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 5577297..7f34e0c 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -275,7 +275,7 @@ DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr dev)
         break;
 
     case kXquartzSetRootClip:
-        QuartzSetRootClip((Bool)e->data[0]);
+        QuartzSetRootClip(e->data[0]);
         break;
 
     case kXquartzQuit:
diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index d3ec133..c8b6f96 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -485,7 +485,7 @@ QuartzHide(void)
  *  Enable or disable rendering to the X screen.
  */
 void
-QuartzSetRootClip(BOOL enable)
+QuartzSetRootClip(int mode)
 {
     int i;
 
@@ -494,7 +494,7 @@ QuartzSetRootClip(BOOL enable)
 
     for (i = 0; i < screenInfo.numScreens; i++) {
         if (screenInfo.screens[i]) {
-            SetRootClip(screenInfo.screens[i], enable);
+            SetRootClip(screenInfo.screens[i], mode);
         }
     }
 }
diff --git a/hw/xquartz/quartz.h b/hw/xquartz/quartz.h
index 47c4416..ddbf2e7 100644
--- a/hw/xquartz/quartz.h
+++ b/hw/xquartz/quartz.h
@@ -149,7 +149,7 @@ QuartzShow(void);
 void
 QuartzHide(void);
 void
-QuartzSetRootClip(BOOL enable);
+QuartzSetRootClip(int mode);
 void
 QuartzSpaceChanged(uint32_t space_id);
 
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 3557f30..40f22a3 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -236,7 +236,6 @@ xwl_glamor_create_screen_resources(ScreenPtr screen)
     if (xwl_screen->rootless) {
         screen->devPrivate =
             fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0);
-        SetRootClip(screen, FALSE);
     }
     else {
         screen->devPrivate =
@@ -247,6 +246,8 @@ xwl_glamor_create_screen_resources(ScreenPtr screen)
             glamor_set_screen_pixmap(screen->devPrivate, NULL);
     }
 
+    SetRootClip(screen, xwl_screen->root_clip_mode);
+
     return screen->devPrivate != NULL;
 }
 
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index e9ec190..5263cb3 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -164,8 +164,8 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height)
     struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
     double mmpd;
 
-    if (!xwl_screen->rootless)
-        SetRootClip(xwl_screen->screen, FALSE);
+    if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL)
+        SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE);
 
     xwl_screen->width = width;
     xwl_screen->height = height;
@@ -181,6 +181,8 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height)
         xwl_screen->screen->mmHeight = height * mmpd;
     }
 
+    SetRootClip(xwl_screen->screen, xwl_screen->root_clip_mode);
+
     if (xwl_screen->screen->root) {
         xwl_screen->screen->root->drawable.width = width;
         xwl_screen->screen->root->drawable.height = height;
@@ -188,9 +190,6 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height)
     }
 
     update_desktop_dimensions();
-
-    if (!xwl_screen->rootless)
-        SetRootClip(xwl_screen->screen, TRUE);
 }
 
 static void
diff --git a/hw/xwayland/xwayland-shm.c b/hw/xwayland/xwayland-shm.c
index 7072be4..1b388f0 100644
--- a/hw/xwayland/xwayland-shm.c
+++ b/hw/xwayland/xwayland-shm.c
@@ -279,16 +279,16 @@ xwl_shm_create_screen_resources(ScreenPtr screen)
     if (!ret)
         return ret;
 
-    if (xwl_screen->rootless) {
+    if (xwl_screen->rootless)
         screen->devPrivate =
             fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0);
-        SetRootClip(screen, FALSE);
-    }
     else
         screen->devPrivate =
             xwl_shm_create_pixmap(screen, screen->width, screen->height,
                                   screen->rootDepth,
                                   CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
 
+    SetRootClip(screen, xwl_screen->root_clip_mode);
+
     return screen->devPrivate != NULL;
 }
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 55bf6d0..86a7543 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -589,6 +589,13 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
         }
     }
 
+    /* In rootless mode, we don't have any screen storage, and the only
+     * rendering should be to redirected mode. */
+    if (xwl_screen->rootless)
+        xwl_screen->root_clip_mode = ROOT_CLIP_INPUT_ONLY;
+    else
+        xwl_screen->root_clip_mode = ROOT_CLIP_FULL;
+
     if (xwl_screen->listen_fd_count > 0) {
         if (xwl_screen->wm_fd >= 0)
             AddCallback(&SelectionCallback, wm_selection_callback, xwl_screen);
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index a7d7119..4fcdee5 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -49,6 +49,7 @@ struct xwl_screen {
     ScreenPtr screen;
     WindowPtr pointer_limbo_window;
     int expecting_event;
+    enum RootClipMode root_clip_mode;
 
     int wm_fd;
     int listen_fds[5];
diff --git a/hw/xwin/winrandr.c b/hw/xwin/winrandr.c
index f4ba054..c29d7b3 100644
--- a/hw/xwin/winrandr.c
+++ b/hw/xwin/winrandr.c
@@ -75,7 +75,7 @@ winDoRandRScreenSetSize(ScreenPtr pScreen,
     WindowPtr pRoot = pScreen->root;
 
     // Prevent screen updates while we change things around
-    SetRootClip(pScreen, FALSE);
+    SetRootClip(pScreen, ROOT_CLIP_NONE);
 
     /* Update the screen size as requested */
     pScreenInfo->dwWidth = width;
@@ -101,7 +101,7 @@ winDoRandRScreenSetSize(ScreenPtr pScreen,
     // does this emit a ConfigureNotify??
 
     // Restore the ability to update screen, now with new dimensions
-    SetRootClip(pScreen, TRUE);
+    SetRootClip(pScreen, ROOT_CLIP_FULL);
 
     // and arrange for it to be repainted
     pScreen->PaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND);
diff --git a/include/window.h b/include/window.h
index f13ed51..7a22feb 100644
--- a/include/window.h
+++ b/include/window.h
@@ -72,6 +72,12 @@ struct _Cursor;
 typedef struct _BackingStore *BackingStorePtr;
 typedef struct _Window *WindowPtr;
 
+enum RootClipMode {
+    ROOT_CLIP_NONE = 0, /**< resize the root window to 0x0 */
+    ROOT_CLIP_FULL = 1, /**< resize the root window to fit screen */
+    ROOT_CLIP_INPUT_ONLY = 2, /**< as above, but no rendering to screen */
+};
+
 typedef int (*VisitWindowProcPtr) (WindowPtr pWin,
                                    void *data);
 
@@ -221,7 +227,7 @@ extern _X_EXPORT RegionPtr CreateBoundingShape(WindowPtr /* pWin */ );
 
 extern _X_EXPORT RegionPtr CreateClipShape(WindowPtr /* pWin */ );
 
-extern _X_EXPORT void SetRootClip(ScreenPtr pScreen, Bool enable);
+extern _X_EXPORT void SetRootClip(ScreenPtr pScreen, int enable);
 extern _X_EXPORT void PrintWindowTree(void);
 extern _X_EXPORT void PrintPassiveGrabs(void);
 
commit 29d1c5a8e4127d5fd1a0d41f8e1474e9dfdb9638
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Feb 16 20:03:57 2016 -0800

    randr: Send ConfigNotify when manual monitor list changes
    
    This lets clients know that the layout of the monitors on the screen
    has changed so they can adapt appropriately.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit dbe8d03c42f01332b3dc41fe9290aed142f1436f)

diff --git a/randr/rrmonitor.c b/randr/rrmonitor.c
index 58041bb..ba310ea 100644
--- a/randr/rrmonitor.c
+++ b/randr/rrmonitor.c
@@ -721,7 +721,9 @@ ProcRRSetMonitor(ClientPtr client)
     monitor->geometry.mmHeight = stuff->monitor.heightInMillimeters;
 
     r = RRMonitorAdd(client, screen, monitor);
-    if (r != Success)
+    if (r == Success)
+        RRSendConfigNotify(screen);
+    else
         RRMonitorFree(monitor);
     return r;
 }
@@ -745,5 +747,8 @@ ProcRRDeleteMonitor(ClientPtr client)
         return BadAtom;
     }
 
-    return RRMonitorDelete(client, screen, stuff->name);
+    r = RRMonitorDelete(client, screen, stuff->name);
+    if (r == Success)
+        RRSendConfigNotify(screen);
+    return r;
 }
commit fc3eef6024355206ea429eb5e2d36001fa47a884
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Feb 10 11:13:04 2016 -0500

    dri2: Use the work queue to manage client sleeps
    
    In  commit e43abdce964f5ed9689cf908af8c305b39a5dd36
        Author: Chris Wilson <chris at chris-wilson.co.uk>
        Date:   Wed Feb 3 09:54:46 2016 +0000
    
            dri2: Unblock Clients on Drawable release
    
    we try to wake up any blocked clients at drawable destruction. But by
    the time we get there, CloseDownConnection has already torn down state
    that AttendClient wants to modify.
    
    Using ClientSleep instead of IgnoreClient puts a wakeup function on a
    workqueue, and the queue will be cleared for us in CloseDownClient
    before (non-neverretain) resource teardown.
    
    Tested-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit eddf848c44349c7ebc7da9957bffb3630f3faaa9)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index dfc2f49..f9d818c 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -260,8 +260,7 @@ DRI2SwapLimit(DrawablePtr pDraw, int swap_limit)
 
     if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
         if (pPriv->blockedClient) {
-            AttendClient(pPriv->blockedClient);
-            pPriv->blockedClient = NULL;
+            ClientSignal(pPriv->blockedClient);
         }
     }
 
@@ -414,7 +413,7 @@ DRI2DrawableGone(void *p, XID id)
     }
 
     if (pPriv->blockedClient)
-        AttendClient(pPriv->blockedClient);
+        ClientSignal(pPriv->blockedClient);
 
     free(pPriv);
 
@@ -690,6 +689,15 @@ DRI2InvalidateDrawable(DrawablePtr pDraw)
         ref->invalidate(pDraw, ref->priv, ref->id);
 }
 
+static Bool
+dri2ClientWake(ClientPtr client, void *closure)
+{
+    DRI2DrawablePtr pPriv = closure;
+    ClientWakeup(client);
+    pPriv->blockedClient = NULL;
+    return TRUE;
+}
+
 /*
  * In the direct rendered case, we throttle the clients that have more
  * than their share of outstanding swaps (and thus busy buffers) when a
@@ -710,7 +718,7 @@ DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw)
     if ((pPriv->swapsPending >= pPriv->swap_limit) && !pPriv->blockedClient) {
         ResetCurrentRequest(client);
         client->sequence--;
-        IgnoreClient(client);
+        ClientSleep(client, dri2ClientWake, pPriv);
         pPriv->blockedClient = client;
         return TRUE;
     }
@@ -722,7 +730,7 @@ static void
 __DRI2BlockClient(ClientPtr client, DRI2DrawablePtr pPriv)
 {
     if (pPriv->blockedClient == NULL) {
-        IgnoreClient(client);
+        ClientSleep(client, dri2ClientWake, pPriv);
         pPriv->blockedClient = client;
     }
 }
@@ -971,9 +979,8 @@ DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
                          frame, pPriv->swap_count);
 
     if (pPriv->blockedClient)
-        AttendClient(pPriv->blockedClient);
+        ClientSignal(pPriv->blockedClient);
 
-    pPriv->blockedClient = NULL;
     pPriv->blockedOnMsc = FALSE;
 }
 
@@ -1003,14 +1010,11 @@ DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
         ProcDRI2WaitMSCReply(client, ((CARD64) tv_sec * 1000000) + tv_usec,
                              frame, pPriv->swap_count);
         pPriv->target_sbc = -1;
-
-        AttendClient(pPriv->blockedClient);
-        pPriv->blockedClient = NULL;
+        ClientSignal(pPriv->blockedClient);
     }
     else if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
         if (pPriv->blockedClient) {
-            AttendClient(pPriv->blockedClient);
-            pPriv->blockedClient = NULL;
+            ClientSignal(pPriv->blockedClient);
         }
     }
 }
commit 9db37e05a96d1488b7cb30b7e1ccd4c73b38d915
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Feb 3 09:54:46 2016 +0000

    dri2: Unblock Clients on Drawable release
    
    If the Window is destroyed by another client, such as the window
    manager, the original client may be blocked by DRI2 awaiting a vblank
    event. When this happens, DRI2DrawableGone forgets to unblock that
    client and so the wait never completes.
    
    Note Present/xshmfence is also suspectible to this race.
    
    Testcase: dri2-race/manager
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
    Reviewed-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
    (cherry picked from commit e43abdce964f5ed9689cf908af8c305b39a5dd36)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index bbff11c..dfc2f49 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -413,6 +413,9 @@ DRI2DrawableGone(void *p, XID id)
         (*pDraw->pScreen->DestroyPixmap)(pPriv->redirectpixmap);
     }
 
+    if (pPriv->blockedClient)
+        AttendClient(pPriv->blockedClient);
+
     free(pPriv);
 
     return Success;
commit 7be0e08cd91ed4be18eefb04018be36dcf0f427e
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Dec 9 09:10:13 2015 -0500

    autogen: Set a default subject prefix for patches
    
    Per discussion at XDC2015, we want this so we can easily distinguish
    which module a patch is for. There's no way to set this in the
    server-side config, so setting a default at autogen time is about the
    best we can do.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit a722d617a092f08f69086630f5cfb598d4a21cc7)

diff --git a/autogen.sh b/autogen.sh
index aee4beb..4de97bf 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -9,6 +9,9 @@ cd "$srcdir"
 autoreconf --force -v --install || exit 1
 cd "$ORIGDIR" || exit $?
 
+git config --local --get format.subjectPrefix ||
+    git config --local format.subjectPrefix "PATCH xserver"
+
 if test -z "$NOCONFIGURE"; then
     exec "$srcdir"/configure "$@"
 fi
commit c388b2d52177eb7f66a63a8454cee1990b4813d9
Author: Jan Burgmeier <jan.burgmeier at unicon-software.com>
Date:   Thu Feb 4 14:06:43 2016 +0100

    Fix XineramaQueryScreens for reverse prime
    
    Make sure we account for slave CRTCs when building the monitor list,
    since that's what rrxinerama uses to fake Xinerama geometry.
    
    [ajax: Slightly more informative commit message.]
    
    Bugzilla: https://bugs.freedesktop.org/92313
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit 7bb64d8c1de9659f11da7917772919b071e9db82)

diff --git a/randr/rrmonitor.c b/randr/rrmonitor.c
index c37dcf8..58041bb 100644
--- a/randr/rrmonitor.c
+++ b/randr/rrmonitor.c
@@ -326,7 +326,7 @@ RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr *monitors_ret,
         RRMonitorSetFromClient(pScrPriv->monitors[list.client_primary], mon);
         mon++;
     } else if (list.server_primary >= 0) {
-        RRMonitorSetFromServer(pScrPriv->crtcs[list.server_primary], mon);
+        RRMonitorSetFromServer(list.server_crtc[list.server_primary], mon);
         mon++;
     }
 
@@ -354,8 +354,8 @@ RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr *monitors_ret,
 
     /* And finish with the list of crtc-inspired monitors
      */
-    for (c = 0; c < pScrPriv->numCrtcs; c++) {
-        RRCrtcPtr crtc = pScrPriv->crtcs[c];
+    for (c = 0; c < list.num_crtcs; c++) {
+        RRCrtcPtr crtc = list.server_crtc[c];
         if (c == list.server_primary && list.client_primary < 0)
             continue;
 
diff --git a/randr/rroutput.c b/randr/rroutput.c
index d12b9ba..686ae49 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -543,6 +543,7 @@ ProcRRSetOutputPrimary(ClientPtr client)
     WindowPtr pWin;
     rrScrPrivPtr pScrPriv;
     int ret;
+    ScreenPtr slave;
 
     REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq);
 
@@ -565,8 +566,19 @@ ProcRRSetOutputPrimary(ClientPtr client)
 
     pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
     if (pScrPriv)
+    {
         RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
 
+        xorg_list_for_each_entry(slave,
+                                 &pWin->drawable.pScreen->output_slave_list,
+                                 output_head) {
+            rrScrPrivPtr pSlavePriv;
+            pSlavePriv = rrGetScrPriv(slave);
+
+            RRSetPrimaryOutput(slave, pSlavePriv, output);
+        }
+    }
+
     return Success;
 }
 
commit 18155405875608f3a46db465aa9753d66b099f8e
Author: Rui Matos <tiagomatos at gmail.com>
Date:   Wed Feb 3 16:14:09 2016 +0100

    xwayland: Clear pending cursor frame callbacks on pointer enter
    
    The last cursor frame we commited before the pointer left one of our
    surfaces might not have been shown. In that case we'll have a cursor
    surface frame callback pending which we need to clear so that we can
    continue submitting new cursor frames.
    
    Signed-off-by: Rui Matos <tiagomatos at gmail.com>
    Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>
    Acked-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
    Reviewed-by: Daniel Stone <daniels at collabora.com>
    Reviewed-by: Jonas Ådahl <jadahl at gmail.com>
    (cherry picked from commit 87d5534f701242d7c23aa20545a6292a0779c89c)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 7494e63..23e138d 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -267,6 +267,16 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
     for (i = 0; i < dev->button->numButtons; i++)
         if (BitIsOn(dev->button->down, i))
             QueuePointerEvents(dev, ButtonRelease, i, 0, &mask);
+
+    /* The last cursor frame we commited before the pointer left one
+     * of our surfaces might not have been shown. In that case we'll
+     * have a cursor surface frame callback pending which we need to
+     * clear so that we can continue submitting new cursor frames. */
+    if (xwl_seat->cursor_frame_cb) {
+        wl_callback_destroy(xwl_seat->cursor_frame_cb);
+        xwl_seat->cursor_frame_cb = NULL;
+        xwl_seat_set_cursor(xwl_seat);
+    }
 }
 
 static void
commit eac170e469cb66a7e5a47d00c56ddc53c63cca85
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Feb 3 09:54:43 2016 +0000

    dri2: Only invalidate the immediate Window upon SetWindowPixmap
    
    All callers of SetWindowPixmap will themselves be traversing the Window
    heirarchy updating the backing Pixmap of each child and so we can forgo
    doing the identical traversal inside the DRI2SetWindowPixmap handler.
    
    Reported-by: Loïc Yhuel <loic.yhuel at gmail.com>
    Link: http://lists.x.org/archives/xorg-devel/2015-February/045638.html
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
    Reviewed-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
    (cherry picked from commit b7d392931a309d0fe754869efb456ccd0385f3aa)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 60ea6dd..bbff11c 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -1385,8 +1385,7 @@ DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
 static void
 DRI2SetWindowPixmap(WindowPtr pWin, PixmapPtr pPix)
 {
-    DrawablePtr pDraw = (DrawablePtr) pWin;
-    ScreenPtr pScreen = pDraw->pScreen;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
     DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
 
     pScreen->SetWindowPixmap = ds->SetWindowPixmap;
@@ -1394,7 +1393,7 @@ DRI2SetWindowPixmap(WindowPtr pWin, PixmapPtr pPix)
     ds->SetWindowPixmap = pScreen->SetWindowPixmap;
     pScreen->SetWindowPixmap = DRI2SetWindowPixmap;
 
-    DRI2InvalidateDrawableAll(pDraw);
+    DRI2InvalidateDrawable(&pWin->drawable);
 }
 
 #define MAX_PRIME DRI2DriverPrimeMask
commit 2fc1752ac39a9325dbc5f8e700fc566ea6f8240f
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan 27 11:26:16 2016 -0800

    glamor: Flip around conditionals in RepeatNone fixups.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 2c3e8768443caa66d78775ea79bb16a5faae3a3c)

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index da45920..73ac831 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -110,8 +110,8 @@ glamor_create_composite_fs(struct shader_key *key)
         "	if (repeat >= RepeatFix) {\n"
         "		tex = rel_tex_coord(tex, wh, repeat);\n"
         "		if (repeat == RepeatFix + RepeatNone) {\n"
-        "			if (!(tex.x >= 0.0 && tex.x < 1.0 && \n"
-        "			      tex.y >= 0.0 && tex.y < 1.0))\n"
+        "			if (tex.x < 0.0 || tex.x >= 1.0 || \n"
+        "			    tex.y < 0.0 || tex.y >= 1.0)\n"
         "				return vec4(0.0, 0.0, 0.0, 0.0);\n"
         "			tex = (fract(tex) / wh.xy);\n"
         "		}\n"
commit 4acebf257e37e075a14b3acecce27d050b18bba8
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan 27 11:21:05 2016 -0800

    glamor: Cut down a bunch of conditional handling for RepeatFix.
    
    For hardware that doesn't do actual jumps for conditionals (i915,
    current vc4 driver), this reduces the number of texture fetches
    performed (assuming the driver isn't really smart about noticing that
    the same sampler is used on each side of an if just with different
    coordinates).
    
    No performance difference on i965 with x11perf -magpixwin100 (n=40).
    Improves -magpixwin100 by 12.9174% +/- 0.405272% (n=5) on vc4.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit e82c8c81df80de487aa795d69e874a0811c537ea)

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index ed425f5..da45920 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -105,19 +105,18 @@ glamor_create_composite_fs(struct shader_key *key)
     /* The texture and the pixmap size is not match eaxctly, so can't sample it directly.
      * rel_sampler will recalculate the texture coords.*/
     const char *rel_sampler =
-        " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat, int set_alpha)\n"
+        " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat)\n"
         "{\n"
-        "	tex = rel_tex_coord(tex, wh, repeat);\n"
-        "	if (repeat == RepeatFix + RepeatNone) {\n"
-        "		if (!(tex.x >= 0.0 && tex.x < 1.0 \n"
-        "		    && tex.y >= 0.0 && tex.y < 1.0))\n"
-        "			return vec4(0.0, 0.0, 0.0, set_alpha);\n"
-        "		tex = (fract(tex) / wh.xy);\n"
+        "	if (repeat >= RepeatFix) {\n"
+        "		tex = rel_tex_coord(tex, wh, repeat);\n"
+        "		if (repeat == RepeatFix + RepeatNone) {\n"
+        "			if (!(tex.x >= 0.0 && tex.x < 1.0 && \n"
+        "			      tex.y >= 0.0 && tex.y < 1.0))\n"
+        "				return vec4(0.0, 0.0, 0.0, 0.0);\n"
+        "			tex = (fract(tex) / wh.xy);\n"
+        "		}\n"
         "	}\n"
-        "	if (set_alpha != 1)\n"
-        "		return texture2D(tex_image, tex);\n"
-        "	else\n"
-        "		return vec4(texture2D(tex_image, tex).rgb, 1.0);\n"
+        "	return texture2D(tex_image, tex);\n"
         "}\n";
 
     const char *source_solid_fetch =
@@ -132,11 +131,8 @@ glamor_create_composite_fs(struct shader_key *key)
         "uniform vec4 source_wh;"
         "vec4 get_source()\n"
         "{\n"
-        "	if (source_repeat_mode < RepeatFix)\n"
-        "		return texture2D(source_sampler, source_texture);\n"
-        "	else \n"
-        "		return rel_sampler(source_sampler, source_texture,\n"
-        "				   source_wh, source_repeat_mode, 0);\n"
+        "	return rel_sampler(source_sampler, source_texture,\n"
+        "			   source_wh, source_repeat_mode);\n"
         "}\n";
     const char *source_pixmap_fetch =
         "varying vec2 source_texture;\n"
@@ -144,11 +140,9 @@ glamor_create_composite_fs(struct shader_key *key)
         "uniform vec4 source_wh;\n"
         "vec4 get_source()\n"
         "{\n"
-        "	if (source_repeat_mode < RepeatFix) \n"
-        "		return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
-        "	else \n"
-        "		return rel_sampler(source_sampler, source_texture,\n"
-        "				   source_wh, source_repeat_mode, 1);\n"
+        "	return vec4(rel_sampler(source_sampler, source_texture,\n"
+        "				source_wh, source_repeat_mode).rgb,\n"
+        "				1.0);\n"
         "}\n";
     const char *mask_none =
         "vec4 get_mask()\n"
@@ -167,11 +161,8 @@ glamor_create_composite_fs(struct shader_key *key)
         "uniform vec4 mask_wh;\n"
         "vec4 get_mask()\n"
         "{\n"
-        "	if (mask_repeat_mode < RepeatFix) \n"
-        "		return texture2D(mask_sampler, mask_texture);\n"
-        "	else \n"
-        "		return rel_sampler(mask_sampler, mask_texture,\n"
-        "				   mask_wh, mask_repeat_mode, 0);\n"
+        "	return rel_sampler(mask_sampler, mask_texture,\n"
+        "			   mask_wh, mask_repeat_mode);\n"
         "}\n";
     const char *mask_pixmap_fetch =
         "varying vec2 mask_texture;\n"
@@ -179,11 +170,8 @@ glamor_create_composite_fs(struct shader_key *key)
         "uniform vec4 mask_wh;\n"
         "vec4 get_mask()\n"
         "{\n"
-        "	if (mask_repeat_mode < RepeatFix) \n"
-        "		return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
-        "	else \n"
-        "		return rel_sampler(mask_sampler, mask_texture,\n"
-        "				   mask_wh, mask_repeat_mode, 1);\n"
+        "	return vec4(rel_sampler(mask_sampler, mask_texture,\n"
+        "				mask_wh, mask_repeat_mode).rgb, 1.0);\n"
         "}\n";
 
     const char *dest_swizzle_default =
commit d1c0873228a115ee0ebf46afaf335b8b97a5bbdc
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan 27 11:15:27 2016 -0800

    glamor: Clarify how the repeat values being passed around work.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 2c3273861cdf874b165ce5a1953102187f71b48e)

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index a2a7f4a..ed425f5 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -76,11 +76,11 @@ glamor_create_composite_fs(struct shader_key *key)
         "{\n"
         "	vec2 rel_tex; \n"
         "	rel_tex = texture * wh.xy; \n"
-        "	if (repeat == RepeatNone)\n"
+        "	if (repeat == RepeatFix + RepeatNone)\n"
         "		return rel_tex; \n"
-        "	else if (repeat == RepeatNormal) \n"
+        "	else if (repeat == RepeatFix + RepeatNormal) \n"
         "		rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); \n"
-        "	else if (repeat == RepeatPad) { \n"
+        "	else if (repeat == RepeatFix + RepeatPad) { \n"
         "		if (rel_tex.x >= 1.0) \n"
         "			rel_tex.x = 1.0 - wh.z * wh.x / 2.; \n"
         "		else if (rel_tex.x < 0.0) \n"
@@ -90,7 +90,7 @@ glamor_create_composite_fs(struct shader_key *key)
         "		else if (rel_tex.y < 0.0) \n"
         "			rel_tex.y = 0.0; \n"
         "		rel_tex = rel_tex / wh.xy; \n"
-        "	} else if (repeat == RepeatReflect) {\n"
+        "	} else if (repeat == RepeatFix + RepeatReflect) {\n"
         "		if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n"
         "			rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x)) / wh.x;\n"
         "		else \n"
@@ -107,8 +107,8 @@ glamor_create_composite_fs(struct shader_key *key)
     const char *rel_sampler =
         " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat, int set_alpha)\n"
         "{\n"
-        "	tex = rel_tex_coord(tex, wh, repeat - RepeatFix);\n"
-        "	if (repeat == RepeatFix) {\n"
+        "	tex = rel_tex_coord(tex, wh, repeat);\n"
+        "	if (repeat == RepeatFix + RepeatNone) {\n"
         "		if (!(tex.x >= 0.0 && tex.x < 1.0 \n"
         "		    && tex.y >= 0.0 && tex.y < 1.0))\n"
         "			return vec4(0.0, 0.0, 0.0, set_alpha);\n"
commit b0b160aafc151b1fdf1840134bc344e3ce2f3e85
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan 27 11:10:14 2016 -0800

    glamor: Clean up formatting of RepeatFix shader code.
    
    All sorts of weird indentation, and some cuddled conditional
    statements deep in the if tree.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 990a8ee01324332ee9b4a4bb124ce8f73be24349)

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 4fbf842..a2a7f4a 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -74,30 +74,33 @@ glamor_create_composite_fs(struct shader_key *key)
     const char *relocate_texture =
         "vec2 rel_tex_coord(vec2 texture, vec4 wh, int repeat) \n"
         "{\n"
-        "   vec2 rel_tex; \n"
-        "   rel_tex = texture * wh.xy; \n"
+        "	vec2 rel_tex; \n"
+        "	rel_tex = texture * wh.xy; \n"
         "	if (repeat == RepeatNone)\n"
         "		return rel_tex; \n"
-        "   else if (repeat == RepeatNormal) \n"
-        "   	rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); 	\n"
-        "   else if(repeat == RepeatPad) { \n"
-        "           if (rel_tex.x >= 1.0) rel_tex.x = 1.0 - wh.z * wh.x / 2.;  	\n"
-        "		else if(rel_tex.x < 0.0) rel_tex.x = 0.0;	  	\n"
-        "           if (rel_tex.y >= 1.0) rel_tex.y = 1.0 - wh.w * wh.y / 2.;	\n"
-        "		else if(rel_tex.y < 0.0) rel_tex.y = 0.0;	\n"
-        "   	rel_tex = rel_tex / wh.xy; \n"
-        "    } \n"
-        "   else if(repeat == RepeatReflect) {\n"
+        "	else if (repeat == RepeatNormal) \n"
+        "		rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); \n"
+        "	else if (repeat == RepeatPad) { \n"
+        "		if (rel_tex.x >= 1.0) \n"
+        "			rel_tex.x = 1.0 - wh.z * wh.x / 2.; \n"
+        "		else if (rel_tex.x < 0.0) \n"
+        "			rel_tex.x = 0.0; \n"
+        "		if (rel_tex.y >= 1.0) \n"
+        "			rel_tex.y = 1.0 - wh.w * wh.y / 2.; \n"
+        "		else if (rel_tex.y < 0.0) \n"
+        "			rel_tex.y = 0.0; \n"
+        "		rel_tex = rel_tex / wh.xy; \n"
+        "	} else if (repeat == RepeatReflect) {\n"
         "		if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n"
-        "			rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x))/wh.x;\n"
+        "			rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x)) / wh.x;\n"
         "		else \n"
-        "			rel_tex.x = fract(rel_tex.x)/wh.x;\n"
+        "			rel_tex.x = fract(rel_tex.x) / wh.x;\n"
         "		if ((1.0 - mod(abs(floor(rel_tex.y)), 2.0)) < 0.001)\n"
-        "			rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y))/wh.y;\n"
+        "			rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y)) / wh.y;\n"
         "		else \n"
-        "			rel_tex.y = fract(rel_tex.y)/wh.y;\n"
-        "    } \n"
-        "   return rel_tex; \n"
+        "			rel_tex.y = fract(rel_tex.y) / wh.y;\n"
+        "	} \n"
+        "	return rel_tex; \n"
         "}\n";
     /* The texture and the pixmap size is not match eaxctly, so can't sample it directly.
      * rel_sampler will recalculate the texture coords.*/
@@ -105,7 +108,7 @@ glamor_create_composite_fs(struct shader_key *key)
         " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat, int set_alpha)\n"
         "{\n"
         "	tex = rel_tex_coord(tex, wh, repeat - RepeatFix);\n"
-        "   if (repeat == RepeatFix) {\n"
+        "	if (repeat == RepeatFix) {\n"
         "		if (!(tex.x >= 0.0 && tex.x < 1.0 \n"
         "		    && tex.y >= 0.0 && tex.y < 1.0))\n"
         "			return vec4(0.0, 0.0, 0.0, set_alpha);\n"
@@ -129,9 +132,9 @@ glamor_create_composite_fs(struct shader_key *key)
         "uniform vec4 source_wh;"
         "vec4 get_source()\n"
         "{\n"
-        "   if (source_repeat_mode < RepeatFix)\n"
+        "	if (source_repeat_mode < RepeatFix)\n"
         "		return texture2D(source_sampler, source_texture);\n"
-        "   else \n"
+        "	else \n"
         "		return rel_sampler(source_sampler, source_texture,\n"
         "				   source_wh, source_repeat_mode, 0);\n"
         "}\n";
@@ -141,7 +144,7 @@ glamor_create_composite_fs(struct shader_key *key)
         "uniform vec4 source_wh;\n"
         "vec4 get_source()\n"
         "{\n"
-        "   if (source_repeat_mode < RepeatFix) \n"
+        "	if (source_repeat_mode < RepeatFix) \n"
         "		return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
         "	else \n"
         "		return rel_sampler(source_sampler, source_texture,\n"
@@ -164,9 +167,9 @@ glamor_create_composite_fs(struct shader_key *key)
         "uniform vec4 mask_wh;\n"
         "vec4 get_mask()\n"
         "{\n"
-        "   if (mask_repeat_mode < RepeatFix) \n"
+        "	if (mask_repeat_mode < RepeatFix) \n"
         "		return texture2D(mask_sampler, mask_texture);\n"
-        "   else \n"
+        "	else \n"
         "		return rel_sampler(mask_sampler, mask_texture,\n"
         "				   mask_wh, mask_repeat_mode, 0);\n"
         "}\n";
@@ -176,9 +179,9 @@ glamor_create_composite_fs(struct shader_key *key)
         "uniform vec4 mask_wh;\n"
         "vec4 get_mask()\n"
         "{\n"
-        "   if (mask_repeat_mode < RepeatFix) \n"
-        "   	return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
-        "   else \n"
+        "	if (mask_repeat_mode < RepeatFix) \n"
+        "		return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
+        "	else \n"
         "		return rel_sampler(mask_sampler, mask_texture,\n"
         "				   mask_wh, mask_repeat_mode, 1);\n"
         "}\n";
commit 12e4e3ac31b05b501df74c4fa37274830e30662a
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan 27 10:24:17 2016 -0800

    glamor: Clarify some logic in RepeatFix handling.
    
    wh ratios are != 1.0 only when large, so with that we can simplify
    down how we end up with RepeatFix being used.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 20cb5b2d65ce63ea7934b77f1520387550c778a8)

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index ec757b3..4fbf842 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -565,22 +565,15 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
      *  GLES2 doesn't support RepeatNone. We need to fix it anyway.
      *
      **/
-    if (repeat_type != RepeatNone)
-        repeat_type += RepeatFix;
-    else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-             || glamor_pixmap_priv_is_large(pixmap_priv)) {
-        if (picture->transform)
-            repeat_type += RepeatFix;
-    }
-    if (repeat_type >= RepeatFix) {
+    if (glamor_pixmap_priv_is_large(pixmap_priv) ||
+        (glamor_priv->gl_flavor == GLAMOR_GL_ES2 && repeat_type == RepeatNone &&
+         picture->transform)) {
         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))
-            glUniform4fv(wh_location, 1, wh);
-        else
-            repeat_type -= RepeatFix;
+        glUniform4fv(wh_location, 1, wh);
+
+        repeat_type += RepeatFix;
     }
+
     glUniform1i(repeat_location, repeat_type);
 }
 
commit d5c9c541c5d325453ddb9ebcdcf36bc6ef0af4aa
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 26 17:29:48 2016 -0800

    glamor: Simplify the pixmap box looping.
    
    We had a double loop across h and w, and passed the current x and y
    out to callers who then used w to multiply/add to an index.  Instead,
    just single loop across w * h.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 07f0d90e4a8b05ef968b1ef47acda7c9f4580340)

diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c
index 2e4dfe2..f51ff6d 100644
--- a/glamor/glamor_composite_glyphs.c
+++ b/glamor/glamor_composite_glyphs.c
@@ -237,10 +237,10 @@ glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst,
     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);
+    glamor_pixmap_fbo *atlas_fbo = glamor_pixmap_fbo_at(atlas_priv, 0);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    int box_x, box_y;
+    int box_index;
     int off_x, off_y;
 
     glamor_put_vbo_space(drawable->pScreen);
@@ -255,11 +255,13 @@ glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst,
 
         glUniform1i(prog->atlas_uniform, 1);
 
-        glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+        glamor_pixmap_loop(pixmap_priv, box_index) {
             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);
+            glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE,
+                                            prog->matrix_uniform,
+                                            &off_x, &off_y);
 
             /* Run over the clip list, drawing the glyphs
              * in each box
diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index 1adfba0..5fed89f 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -307,7 +307,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
     glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
     glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap);
-    int src_box_x, src_box_y, dst_box_x, dst_box_y;
+    int src_box_index, dst_box_index;
     int dst_off_x, dst_off_y;
     int src_off_x, src_off_y;
     GLshort *v;
@@ -368,19 +368,20 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
 
     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);
+    glamor_pixmap_loop(src_priv, src_box_index) {
+        BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_index);
 
         args.dx = dx + src_off_x - src_box->x1;
         args.dy = dy + src_off_y - src_box->y1;
-        args.src = glamor_pixmap_fbo_at(src_priv, src_box_x, src_box_y);
+        args.src = glamor_pixmap_fbo_at(src_priv, src_box_index);
 
         if (!glamor_use_program(dst_pixmap, gc, prog, &args))
             goto bail_ctx;
 
-        glamor_pixmap_loop(dst_priv, dst_box_x, dst_box_y) {
-            glamor_set_destination_drawable(dst, dst_box_x, dst_box_y, FALSE, FALSE,
-                                            prog->matrix_uniform, &dst_off_x, &dst_off_y);
+        glamor_pixmap_loop(dst_priv, dst_box_index) {
+            glamor_set_destination_drawable(dst, dst_box_index, FALSE, FALSE,
+                                            prog->matrix_uniform,
+                                            &dst_off_x, &dst_off_y);
 
             glScissor(dst_off_x - args.dx,
                       dst_off_y - args.dy,
diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c
index 101228e..a6a11c1 100644
--- a/glamor/glamor_dash.c
+++ b/glamor/glamor_dash.c
@@ -205,16 +205,16 @@ glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog,
 {
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    int box_x, box_y;
+    int box_index;
     int off_x, off_y;
 
     glEnable(GL_SCISSOR_TEST);
 
-    glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+    glamor_pixmap_loop(pixmap_priv, box_index) {
         int nbox = RegionNumRects(gc->pCompositeClip);
         BoxPtr box = RegionRects(gc->pCompositeClip);
 
-        glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
+        glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE,
                                         prog->matrix_uniform, &off_x, &off_y);
 
         while (nbox--) {
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 1791f6d..b21aa06 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -48,7 +48,7 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
     glamor_pixmap_private *pixmap_priv;
     glamor_program *prog;
     RegionPtr clip = gc->pCompositeClip;
-    int box_x, box_y;
+    int box_index;
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -67,7 +67,7 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
     start_x += drawable->x;
     y += drawable->y;
 
-    glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+    glamor_pixmap_loop(pixmap_priv, box_index) {
         int x;
         int n;
         int num_points, max_points;
@@ -75,7 +75,7 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
         int off_x, off_y;
         char *vbo_offset;
 
-        glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE,
+        glamor_set_destination_drawable(drawable, box_index, FALSE, TRUE,
                                         prog->matrix_uniform, &off_x, &off_y);
 
         max_points = 500;
@@ -169,7 +169,7 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
     int bitmap_stride = bitmap->devKind;
     glamor_program *prog;
     RegionPtr clip = gc->pCompositeClip;
-    int box_x, box_y;
+    int box_index;
     int yy, xx;
     int num_points;
     INT16 *points = NULL;
@@ -220,8 +220,8 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
 
     glamor_put_vbo_space(screen);
 
-    glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
-        glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE,
+    glamor_pixmap_loop(pixmap_priv, box_index) {
+        glamor_set_destination_drawable(drawable, box_index, FALSE, TRUE,
                                         prog->matrix_uniform, NULL, NULL);
 
         glDrawArrays(GL_POINTS, 0, num_points);
diff --git a/glamor/glamor_lines.c b/glamor/glamor_lines.c
index 2dd9c07..a2c9b1f 100644
--- a/glamor/glamor_lines.c
+++ b/glamor/glamor_lines.c
@@ -44,7 +44,7 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
     int off_x, off_y;
     DDXPointPtr v;
     char *vbo_offset;
-    int box_x, box_y;
+    int box_index;
     int add_last;
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -99,11 +99,11 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
 
     glEnable(GL_SCISSOR_TEST);
 
-    glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+    glamor_pixmap_loop(pixmap_priv, box_index) {
         int nbox = RegionNumRects(gc->pCompositeClip);
         BoxPtr box = RegionRects(gc->pCompositeClip);
 
-        glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
+        glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE,
                                         prog->matrix_uniform, &off_x, &off_y);
 
         while (nbox--) {
diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c
index 3ba4a69..facfe82 100644
--- a/glamor/glamor_points.c
+++ b/glamor/glamor_points.c
@@ -46,7 +46,7 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
     int off_x, off_y;
     GLshort *vbo_ppt;
     char *vbo_offset;
-    int box_x, box_y;
+    int box_index;
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -86,11 +86,12 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
 
     glEnable(GL_SCISSOR_TEST);
 
-    glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+    glamor_pixmap_loop(pixmap_priv, box_index) {
         int nbox = RegionNumRects(gc->pCompositeClip);
         BoxPtr box = RegionRects(gc->pCompositeClip);
 
-        glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y);
+        glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE,
+                                        prog->matrix_uniform, &off_x, &off_y);
 
         while (nbox--) {
             glScissor(box->x1 + off_x,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 60b0a66..a70f10e 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -485,19 +485,17 @@ 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)
+glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int box)
 {
-    assert(x < priv->block_wcnt);
-    assert(y < priv->block_hcnt);
-    return priv->fbo_array[y * priv->block_wcnt + x];
+    assert(box < priv->block_wcnt * priv->block_hcnt);
+    return priv->fbo_array[box];
 }
 
 static inline BoxPtr
-glamor_pixmap_box_at(glamor_pixmap_private *priv, int x, int y)
+glamor_pixmap_box_at(glamor_pixmap_private *priv, int box)
 {
-    assert(x < priv->block_wcnt);
-    assert(y < priv->block_hcnt);
-    return &priv->box_array[y * priv->block_wcnt + x];
+    assert(box < priv->block_wcnt * priv->block_hcnt);
+    return &priv->box_array[box];
 }
 
 static inline int
@@ -512,9 +510,9 @@ glamor_pixmap_hcnt(glamor_pixmap_private *priv)
     return priv->block_hcnt;
 }
 
-#define glamor_pixmap_loop(priv, x, y)                  \
-    for (y = 0; y < glamor_pixmap_hcnt(priv); y++)      \
-        for (x = 0; x < glamor_pixmap_wcnt(priv); x++)
+#define glamor_pixmap_loop(priv, box_index)                            \
+    for (box_index = 0; box_index < glamor_pixmap_hcnt(priv) *         \
+             glamor_pixmap_wcnt(priv); box_index++)                    \
 
 /**
  * Pixmap upload status, used by glamor_render.c's support for
diff --git a/glamor/glamor_rects.c b/glamor/glamor_rects.c
index c378e4a..e447320 100644
--- a/glamor/glamor_rects.c
+++ b/glamor/glamor_rects.c
@@ -51,7 +51,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
     int off_x, off_y;
     GLshort *v;
     char *vbo_offset;
-    int box_x, box_y;
+    int box_index;
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -111,11 +111,12 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
 
     glEnable(GL_SCISSOR_TEST);
 
-    glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+    glamor_pixmap_loop(pixmap_priv, box_index) {
         int nbox = RegionNumRects(gc->pCompositeClip);
         BoxPtr box = RegionRects(gc->pCompositeClip);
 
-        glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y);
+        glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE,
+                                        prog->matrix_uniform, &off_x, &off_y);
 
         while (nbox--) {
             glScissor(box->x1 + off_x,
diff --git a/glamor/glamor_segs.c b/glamor/glamor_segs.c
index e167325..5fffa3b 100644
--- a/glamor/glamor_segs.c
+++ b/glamor/glamor_segs.c
@@ -44,7 +44,7 @@ glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc,
     int off_x, off_y;
     xSegment *v;
     char *vbo_offset;
-    int box_x, box_y;
+    int box_index;
     int add_last;
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -91,11 +91,11 @@ glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc,
 
     glEnable(GL_SCISSOR_TEST);
 
-    glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+    glamor_pixmap_loop(pixmap_priv, box_index) {
         int nbox = RegionNumRects(gc->pCompositeClip);
         BoxPtr box = RegionRects(gc->pCompositeClip);
 
-        glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
+        glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE,
                                         prog->matrix_uniform, &off_x, &off_y);
 
         while (nbox--) {
diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
index 58da3ed..89a9c51 100644
--- a/glamor/glamor_spans.c
+++ b/glamor/glamor_spans.c
@@ -55,7 +55,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
     GLshort *v;
     char *vbo_offset;
     int c;
-    int box_x, box_y;
+    int box_index;
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -119,11 +119,12 @@ glamor_fill_spans_gl(DrawablePtr drawable,
 
     glEnable(GL_SCISSOR_TEST);
 
-    glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+    glamor_pixmap_loop(pixmap_priv, box_index) {
         int nbox = RegionNumRects(gc->pCompositeClip);
         BoxPtr box = RegionRects(gc->pCompositeClip);
 
-        glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, FALSE, prog->matrix_uniform, &off_x, &off_y);
+        glamor_set_destination_drawable(drawable, box_index, FALSE, FALSE,
+                                        prog->matrix_uniform, &off_x, &off_y);
 
         while (nbox--) {
             glScissor(box->x1 + off_x,
@@ -180,7 +181,7 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv;
-    int box_x, box_y;
+    int box_index;
     int n;
     char *d;
     GLenum type;
@@ -197,9 +198,9 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
 
     glamor_make_current(glamor_priv);
 
-    glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
-        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);
+    glamor_pixmap_loop(pixmap_priv, box_index) {
+        BoxPtr                  box = glamor_pixmap_box_at(pixmap_priv, box_index);
+        glamor_pixmap_fbo       *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_index);
 
         glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
         glPixelStorei(GL_PACK_ALIGNMENT, 4);
@@ -265,7 +266,7 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv;
-    int box_x, box_y;
+    int box_index;
     int n;
     char *s;
     GLenum type;
@@ -289,9 +290,9 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
 
     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 
-    glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
-        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);
+    glamor_pixmap_loop(pixmap_priv, box_index) {
+        BoxPtr              box = glamor_pixmap_box_at(pixmap_priv, box_index);
+        glamor_pixmap_fbo  *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_index);
 
         glActiveTexture(GL_TEXTURE0);
         glBindTexture(GL_TEXTURE_2D, fbo->tex);
diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
index 429f53b..c305305 100644
--- a/glamor/glamor_text.c
+++ b/glamor/glamor_text.c
@@ -107,7 +107,7 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
     int firstCol = font->info.firstCol;
     int glyph_spacing_x = glamor_font->glyph_width_bytes * 8;
     int glyph_spacing_y = glamor_font->glyph_height;
-    int box_x, box_y;
+    int box_index;
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
 
@@ -188,11 +188,13 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
 
         glEnable(GL_SCISSOR_TEST);
 
-        glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+        glamor_pixmap_loop(pixmap_priv, box_index) {
             BoxPtr box = RegionRects(gc->pCompositeClip);
             int nbox = RegionNumRects(gc->pCompositeClip);
 
-            glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y);
+            glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE,
+                                            prog->matrix_uniform,
+                                            &off_x, &off_y);
 
             /* Run over the clip list, drawing the glyphs
              * in each box
diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
index 91e1747..ed81195 100644
--- a/glamor/glamor_transfer.c
+++ b/glamor/glamor_transfer.c
@@ -63,7 +63,7 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
     ScreenPtr                   screen = pixmap->drawable.pScreen;
     glamor_screen_private       *glamor_priv = glamor_get_screen_private(screen);
     glamor_pixmap_private       *priv = glamor_get_pixmap_private(pixmap);
-    int                         box_x, box_y;
+    int                         box_index;
     int                         bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
     GLenum                      type;
     GLenum                      format;
@@ -77,9 +77,9 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
     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);
-        glamor_pixmap_fbo       *fbo = glamor_pixmap_fbo_at(priv, box_x, box_y);
+    glamor_pixmap_loop(priv, box_index) {
+        BoxPtr                  box = glamor_pixmap_box_at(priv, box_index);
+        glamor_pixmap_fbo       *fbo = glamor_pixmap_fbo_at(priv, box_index);
         BoxPtr                  boxes = in_boxes;
         int                     nbox = in_nbox;
 
@@ -167,7 +167,7 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
     ScreenPtr screen = pixmap->drawable.pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
-    int box_x, box_y;
+    int box_index;
     int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
     GLenum type;
     GLenum format;
@@ -180,9 +180,9 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
     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);
-        glamor_pixmap_fbo       *fbo = glamor_pixmap_fbo_at(priv, box_x, box_y);
+    glamor_pixmap_loop(priv, box_index) {
+        BoxPtr                  box = glamor_pixmap_box_at(priv, box_index);
+        glamor_pixmap_fbo       *fbo = glamor_pixmap_fbo_at(priv, box_index);
         BoxPtr                  boxes = in_boxes;
         int                     nbox = in_nbox;
 
diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index 564a52d..17b1066 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -35,8 +35,7 @@
 
 void
 glamor_set_destination_drawable(DrawablePtr     drawable,
-                                int             box_x,
-                                int             box_y,
+                                int             box_index,
                                 Bool            do_drawable_translate,
                                 Bool            center_offset,
                                 GLint           matrix_uniform_location,
@@ -48,7 +47,7 @@ glamor_set_destination_drawable(DrawablePtr     drawable,
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     int off_x, off_y;
-    BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
+    BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index);
     int w = box->x2 - box->x1;
     int h = box->y2 - box->y1;
     float scale_x = 2.0f / (float) w;
@@ -95,7 +94,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_priv, glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y),
+    glamor_set_destination_pixmap_fbo(glamor_priv, glamor_pixmap_fbo_at(pixmap_priv, box_index),
                                       0, 0, w, h);
 }
 
diff --git a/glamor/glamor_transform.h b/glamor/glamor_transform.h
index dca6a26..ab7b2bc 100644
--- a/glamor/glamor_transform.h
+++ b/glamor/glamor_transform.h
@@ -25,8 +25,7 @@
 
 void
 glamor_set_destination_drawable(DrawablePtr     drawable,
-                                int             box_x,
-                                int             box_y,
+                                int             box_index,
                                 Bool            do_drawable_translate,
                                 Bool            center_offset,
                                 GLint           matrix_uniform_location,
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index e8c849d..9ac60af 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -258,7 +258,7 @@ glamor_xv_render(glamor_port_private *port_priv)
     GLint uloc;
     GLfloat *v;
     char *vbo_offset;
-    int dst_box_x, dst_box_y;
+    int dst_box_index;
 
     if (!glamor_priv->xv_prog.prog)
         glamor_init_xv_shader(screen);
@@ -368,11 +368,11 @@ glamor_xv_render(glamor_port_private *port_priv)
     glamor_put_vbo_space(screen);
 
     /* Now draw our big triangle, clipped to each of the clip boxes. */
-    glamor_pixmap_loop(pixmap_priv, dst_box_x, dst_box_y) {
+    glamor_pixmap_loop(pixmap_priv, dst_box_index) {
         int dst_off_x, dst_off_y;
 
         glamor_set_destination_drawable(port_priv->pDraw,
-                                        dst_box_x, dst_box_y,
+                                        dst_box_index,
                                         FALSE, FALSE,
                                         glamor_priv->xv_prog.matrix_uniform,
                                         &dst_off_x, &dst_off_y);
commit 68bd172432de069aa242d21b3af505867417ae45
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 26 15:56:27 2016 -0800

    glamor: Reuse the glamor_program_alpha_* enums for Render.
    
    This is a step toward using glamor_program.c for Render acceleration.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 0dbce65b08f4812dcaa4b77cd37aebac334c47a2)

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index b70533a..60b0a66 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -107,14 +107,6 @@ enum shader_mask {
     SHADER_MASK_COUNT,
 };
 
-enum shader_in {
-    SHADER_IN_NORMAL,
-    SHADER_IN_CA_SOURCE,
-    SHADER_IN_CA_ALPHA,
-    SHADER_IN_CA_DUAL_BLEND,
-    SHADER_IN_COUNT,
-};
-
 enum shader_dest_swizzle {
     SHADER_DEST_SWIZZLE_DEFAULT,
     SHADER_DEST_SWIZZLE_ALPHA_TO_RED,
@@ -124,7 +116,7 @@ enum shader_dest_swizzle {
 struct shader_key {
     enum shader_source source;
     enum shader_mask mask;
-    enum shader_in in;
+    glamor_program_alpha in;
     enum shader_dest_swizzle dest_swizzle;
 };
 
@@ -291,7 +283,7 @@ typedef struct glamor_screen_private {
     int render_nr_quads;
     glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
         [SHADER_MASK_COUNT]
-        [SHADER_IN_COUNT]
+        [glamor_program_alpha_count]
         [SHADER_DEST_SWIZZLE_COUNT];
 
     /* shaders to restore a texture to another texture. */
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index d1b7a15..ec757b3 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -278,16 +278,16 @@ glamor_create_composite_fs(struct shader_key *key)
 
     header = header_norm;
     switch (key->in) {
-    case SHADER_IN_NORMAL:
+    case glamor_program_alpha_normal:
         in = in_normal;
         break;
-    case SHADER_IN_CA_SOURCE:
+    case glamor_program_alpha_ca_first:
         in = in_ca_source;
         break;
-    case SHADER_IN_CA_ALPHA:
+    case glamor_program_alpha_ca_second:
         in = in_ca_alpha;
         break;
-    case SHADER_IN_CA_DUAL_BLEND:
+    case glamor_program_alpha_dual_blend:
         in = in_ca_dual_blend;
         header = header_ca_dual_blend;
         break;
@@ -368,7 +368,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
     glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
     glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
 
-    if (key->in == SHADER_IN_CA_DUAL_BLEND) {
+    if (key->in == glamor_program_alpha_dual_blend) {
         glBindFragDataLocationIndexed(prog, 0, 0, "color0");
         glBindFragDataLocationIndexed(prog, 0, 1, "color1");
     }
@@ -674,7 +674,7 @@ static const int pict_format_combine_tab[][3] = {
 
 static Bool
 combine_pict_format(PictFormatShort * des, const PictFormatShort src,
-                    const PictFormatShort mask, enum shader_in in_ca)
+                    const PictFormatShort mask, glamor_program_alpha in_ca)
 {
     PictFormatShort new_vis;
     int src_type, mask_type, src_bpp;
@@ -691,19 +691,19 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
     new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask);
 
     switch (in_ca) {
-    case SHADER_IN_NORMAL:
+    case glamor_program_alpha_normal:
         src_type = PICT_FORMAT_TYPE(src);
         mask_type = PICT_TYPE_A;
         break;
-    case SHADER_IN_CA_SOURCE:
+    case glamor_program_alpha_ca_first:
         src_type = PICT_FORMAT_TYPE(src);
         mask_type = PICT_FORMAT_TYPE(mask);
         break;
-    case SHADER_IN_CA_ALPHA:
+    case glamor_program_alpha_ca_second:
         src_type = PICT_TYPE_A;
         mask_type = PICT_FORMAT_TYPE(mask);
         break;
-    case SHADER_IN_CA_DUAL_BLEND:
+    case glamor_program_alpha_dual_blend:
         src_type = PICT_FORMAT_TYPE(src);
         mask_type = PICT_FORMAT_TYPE(mask);
         break;
@@ -867,19 +867,19 @@ glamor_composite_choose_shader(CARD8 op,
         }
 
         if (!mask->componentAlpha) {
-            key.in = SHADER_IN_NORMAL;
+            key.in = glamor_program_alpha_normal;
         }
         else {
             if (op == PictOpClear)
                 key.mask = SHADER_MASK_NONE;
             else if (glamor_priv->has_dual_blend)
-                key.in = SHADER_IN_CA_DUAL_BLEND;
+                key.in = glamor_program_alpha_dual_blend;
             else if (op == PictOpSrc || op == PictOpAdd
                      || op == PictOpIn || op == PictOpOut
                      || op == PictOpOverReverse)
-                key.in = SHADER_IN_CA_SOURCE;
+                key.in = glamor_program_alpha_ca_second;
             else if (op == PictOpOutReverse || op == PictOpInReverse) {
-                key.in = SHADER_IN_CA_ALPHA;
+                key.in = glamor_program_alpha_ca_first;
             }
             else {
                 glamor_fallback("Unsupported component alpha op: %d\n", op);
commit 6a71251b3985d6dd7c1ab1fa6e13f1edaa33a5c5
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 26 15:47:01 2016 -0800

    glamor: Drop extra SHADER_IN type for no mask present.
    
    We can just hand in a constant mask and the driver will optimize away
    the multiplication for us.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 9b676786de32f06aedf9d4c9535c10fda247335a)

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index d78db7f..b70533a 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -108,7 +108,6 @@ enum shader_mask {
 };
 
 enum shader_in {
-    SHADER_IN_SOURCE_ONLY,
     SHADER_IN_NORMAL,
     SHADER_IN_CA_SOURCE,
     SHADER_IN_CA_ALPHA,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 51718d1..d1b7a15 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -147,6 +147,11 @@ glamor_create_composite_fs(struct shader_key *key)
         "		return rel_sampler(source_sampler, source_texture,\n"
         "				   source_wh, source_repeat_mode, 1);\n"
         "}\n";
+    const char *mask_none =
+        "vec4 get_mask()\n"
+        "{\n"
+        "	return vec4(0.0, 0.0, 0.0, 1.0);\n"
+        "}\n";
     const char *mask_solid_fetch =
         "uniform vec4 mask;\n"
         "vec4 get_mask()\n"
@@ -190,11 +195,6 @@ glamor_create_composite_fs(struct shader_key *key)
         "	return vec4(color.a, undef, undef, undef);"
         "}";
 
-    const char *in_source_only =
-        "void main()\n"
-        "{\n"
-        "	gl_FragColor = dest_swizzle(get_source());\n"
-        "}\n";
     const char *in_normal =
         "void main()\n"
         "{\n"
@@ -246,6 +246,7 @@ glamor_create_composite_fs(struct shader_key *key)
 
     switch (key->mask) {
     case SHADER_MASK_NONE:
+        mask_fetch = mask_none;
         break;
     case SHADER_MASK_SOLID:
         mask_fetch = mask_solid_fetch;
@@ -277,9 +278,6 @@ glamor_create_composite_fs(struct shader_key *key)
 
     header = header_norm;
     switch (key->in) {
-    case SHADER_IN_SOURCE_ONLY:
-        in = in_source_only;
-        break;
     case SHADER_IN_NORMAL:
         in = in_normal;
         break;
@@ -693,8 +691,6 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
     new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask);
 
     switch (in_ca) {
-    case SHADER_IN_SOURCE_ONLY:
-        return TRUE;
     case SHADER_IN_NORMAL:
         src_type = PICT_FORMAT_TYPE(src);
         mask_type = PICT_TYPE_A;
@@ -893,7 +889,6 @@ glamor_composite_choose_shader(CARD8 op,
     }
     else {
         key.mask = SHADER_MASK_NONE;
-        key.in = SHADER_IN_SOURCE_ONLY;
     }
 
     if (dest_pixmap->drawable.bitsPerPixel <= 8 &&
commit 2db5bf7a1297a84e516ce87b24dd3982e7674bb2
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 26 15:19:50 2016 -0800

    glamor: Convert XV to using glamor_program.c.
    
    One less custom path!  By following the common glamor_program.c use
    pattern, we get the ability to handle large pixmaps as the
    destination.  It's also one less place where glamor_utils.h coordinate
    transformation happens.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 03f34f85563c81e1655626e10f75fd7e21393c92)

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index f1eed5b..d78db7f 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -318,7 +318,7 @@ typedef struct glamor_screen_private {
     Bool logged_any_fbo_allocation_failure;
 
     /* xv */
-    GLint xv_prog;
+    glamor_program xv_prog;
 
     struct glamor_context ctx;
 } glamor_screen_private;
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 2593d47..e8c849d 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -37,6 +37,7 @@
 #endif
 
 #include "glamor_priv.h"
+#include "glamor_transform.h"
 #include "glamor_transfer.h"
 
 #include <X11/extensions/Xv.h>
@@ -58,36 +59,36 @@ typedef struct tagREF_TRANSFORM {
 #define RTFContrast(a)   (1.0 + ((a)*1.0)/1000.0)
 #define RTFHue(a)   (((a)*3.1416)/1000.0)
 
-static const char *xv_vs = "attribute vec4 v_position;\n"
-    "attribute vec4 v_texcoord0;\n"
-    "varying vec2 tcs;\n"
-    "void main()\n"
-    "{\n"
-    "     gl_Position = v_position;\n"
-    "tcs = v_texcoord0.xy;\n"
-    "}\n";
-
-static const char *xv_ps = GLAMOR_DEFAULT_PRECISION
-    "uniform sampler2D y_sampler;\n"
-    "uniform sampler2D u_sampler;\n"
-    "uniform sampler2D v_sampler;\n"
-    "uniform vec4 offsetyco;\n"
-    "uniform vec4 ucogamma;\n"
-    "uniform vec4 vco;\n"
-    "varying vec2 tcs;\n"
-    "float sample;\n"
-    "vec4 temp1;\n"
-    "void main()\n"
-    "{\n"
-    "sample = texture2D(y_sampler, tcs).w;\n"
-    "temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n"
-    "sample = texture2D(u_sampler, tcs).w;\n"
-    "temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n"
-    "sample = texture2D(v_sampler, tcs).w;\n"
-    "temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n"
-    "temp1.w = 1.0;\n"
-    "gl_FragColor = temp1;\n"
-    "}\n";
+static const glamor_facet glamor_facet_xv_planar = {
+    .name = "xv_planar",
+
+    .source_name = "v_texcoord0",
+    .vs_vars = ("attribute vec2 position;\n"
+                "attribute vec2 v_texcoord0;\n"
+                "varying vec2 tcs;\n"),
+    .vs_exec = (GLAMOR_POS(gl_Position, position)
+                "        tcs = v_texcoord0;\n"),
+
+    .fs_vars = ("uniform sampler2D y_sampler;\n"
+                "uniform sampler2D u_sampler;\n"
+                "uniform sampler2D v_sampler;\n"
+                "uniform vec4 offsetyco;\n"
+                "uniform vec4 ucogamma;\n"
+                "uniform vec4 vco;\n"
+                "varying vec2 tcs;\n"),
+    .fs_exec = (
+                "        float sample;\n"
+                "        vec4 temp1;\n"
+                "        sample = texture2D(y_sampler, tcs).w;\n"
+                "        temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n"
+                "        sample = texture2D(u_sampler, tcs).w;\n"
+                "        temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n"
+                "        sample = texture2D(v_sampler, tcs).w;\n"
+                "        temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n"
+                "        temp1.w = 1.0;\n"
+                "        gl_FragColor = temp1;\n"
+                ),
+};
 
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
@@ -113,30 +114,19 @@ int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
 static void
 glamor_init_xv_shader(ScreenPtr screen)
 {
-    glamor_screen_private *glamor_priv;
-    GLint fs_prog, vs_prog, sampler_loc;
-
-    glamor_priv = glamor_get_screen_private(screen);
-    glamor_make_current(glamor_priv);
-    glamor_priv->xv_prog = glCreateProgram();
-
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xv_vs);
-    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xv_ps);
-    glAttachShader(glamor_priv->xv_prog, vs_prog);
-    glAttachShader(glamor_priv->xv_prog, fs_prog);
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    GLint sampler_loc;
 
-    glBindAttribLocation(glamor_priv->xv_prog,
-                         GLAMOR_VERTEX_POS, "v_position");
-    glBindAttribLocation(glamor_priv->xv_prog,
-                         GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-    glamor_link_glsl_prog(screen, glamor_priv->xv_prog, "xv");
+    glamor_build_program(screen,
+                         &glamor_priv->xv_prog,
+                         &glamor_facet_xv_planar, NULL, NULL, NULL);
 
-    glUseProgram(glamor_priv->xv_prog);
-    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "y_sampler");
+    glUseProgram(glamor_priv->xv_prog.prog);
+    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "y_sampler");
     glUniform1i(sampler_loc, 0);
-    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "u_sampler");
+    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "u_sampler");
     glUniform1i(sampler_loc, 1);
-    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "v_sampler");
+    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "v_sampler");
     glUniform1i(sampler_loc, 2);
 
 }
@@ -256,8 +246,6 @@ glamor_xv_render(glamor_port_private *port_priv)
     glamor_pixmap_private *src_pixmap_priv[3];
     BoxPtr box = REGION_RECTS(&port_priv->clip);
     int nBox = REGION_NUM_RECTS(&port_priv->clip);
-    int dst_x_off, dst_y_off;
-    GLfloat dst_xscale, dst_yscale;
     GLfloat src_xscale[3], src_yscale[3];
     int i;
     const float Loff = -0.0627;
@@ -270,8 +258,9 @@ glamor_xv_render(glamor_port_private *port_priv)
     GLint uloc;
     GLfloat *v;
     char *vbo_offset;
+    int dst_box_x, dst_box_y;
 
-    if (!glamor_priv->xv_prog)
+    if (!glamor_priv->xv_prog.prog)
         glamor_init_xv_shader(screen);
 
     cont = RTFContrast(port_priv->contrast);
@@ -293,10 +282,6 @@ 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, 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(glamor_priv, pixmap, pixmap_priv);
     glamor_set_alu(screen, GXcopy);
 
     for (i = 0; i < 3; i++) {
@@ -308,13 +293,13 @@ glamor_xv_render(glamor_port_private *port_priv)
         }
     }
     glamor_make_current(glamor_priv);
-    glUseProgram(glamor_priv->xv_prog);
+    glUseProgram(glamor_priv->xv_prog.prog);
 
-    uloc = glGetUniformLocation(glamor_priv->xv_prog, "offsetyco");
+    uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "offsetyco");
     glUniform4f(uloc, off[0], off[1], off[2], yco);
-    uloc = glGetUniformLocation(glamor_priv->xv_prog, "ucogamma");
+    uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "ucogamma");
     glUniform4f(uloc, uco[0], uco[1], uco[2], gamma);
-    uloc = glGetUniformLocation(glamor_priv->xv_prog, "vco");
+    uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "vco");
     glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
 
     glActiveTexture(GL_TEXTURE0);
@@ -352,16 +337,14 @@ glamor_xv_render(glamor_port_private *port_priv)
      * GL_QUAD.
      */
     i = 0;
-    v[i++] = v_from_x_coord_x(dst_xscale, port_priv->drw_x + dst_x_off);
-    v[i++] = v_from_x_coord_y(dst_yscale, port_priv->drw_y + dst_y_off);
+    v[i++] = port_priv->drw_x;
+    v[i++] = port_priv->drw_y;
 
-    v[i++] = v_from_x_coord_x(dst_xscale, port_priv->drw_x + dst_x_off +
-                              port_priv->dst_w * 2);
-    v[i++] = v_from_x_coord_y(dst_yscale, port_priv->drw_y + dst_y_off);
+    v[i++] = port_priv->drw_x + port_priv->dst_w * 2;
+    v[i++] = port_priv->drw_y;
 
-    v[i++] = v_from_x_coord_x(dst_xscale, port_priv->drw_x + dst_x_off);
-    v[i++] = v_from_x_coord_y(dst_yscale, port_priv->drw_y + dst_y_off +
-                              port_priv->dst_h * 2);
+    v[i++] = port_priv->drw_x;
+    v[i++] = port_priv->drw_y + port_priv->dst_h * 2;
 
     v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x);
     v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y);
@@ -385,16 +368,26 @@ glamor_xv_render(glamor_port_private *port_priv)
     glamor_put_vbo_space(screen);
 
     /* Now draw our big triangle, clipped to each of the clip boxes. */
-    for (i = 0; i < nBox; i++) {
-        int dstx, dsty, dstw, dsth;
+    glamor_pixmap_loop(pixmap_priv, dst_box_x, dst_box_y) {
+        int dst_off_x, dst_off_y;
+
+        glamor_set_destination_drawable(port_priv->pDraw,
+                                        dst_box_x, dst_box_y,
+                                        FALSE, FALSE,
+                                        glamor_priv->xv_prog.matrix_uniform,
+                                        &dst_off_x, &dst_off_y);
 
-        dstx = box[i].x1 + dst_x_off;
-        dsty = box[i].y1 + dst_y_off;
-        dstw = box[i].x2 - box[i].x1;
-        dsth = box[i].y2 - box[i].y1;
+        for (i = 0; i < nBox; i++) {
+            int dstx, dsty, dstw, dsth;
 
-        glScissor(dstx, dsty, dstw, dsth);
-        glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
+            dstx = box[i].x1 + dst_off_x;
+            dsty = box[i].y1 + dst_off_y;
+            dstw = box[i].x2 - box[i].x1;
+            dsth = box[i].y2 - box[i].y1;
+
+            glScissor(dstx, dsty, dstw, dsth);
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
+        }
     }
     glDisable(GL_SCISSOR_TEST);
 
commit 9be8478467fc4827ca8edc035f0a6d1cca78fbe0
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 26 14:52:08 2016 -0800

    glamor: Simplify XV vertex setup.
    
    We were clipping the drawn rectangle to each clip box, then expanding
    the box to a big triangle to avoid tearing, then drawing each triangle
    to the destination through a scissor.  If we're using a scissor for
    clipping, though, then we don't need to clip the drawn primitive on
    the CPU in the first place.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit f368a0ba3aa58e5260d839d11d2f3aef75feaeaf)

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 5d31fee..2593d47 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -343,45 +343,36 @@ glamor_xv_render(glamor_port_private *port_priv)
 
     glEnable(GL_SCISSOR_TEST);
 
-    v = glamor_get_vbo_space(screen, 16 * sizeof(GLfloat) * nBox, &vbo_offset);
+    v = glamor_get_vbo_space(screen, 3 * 4 * sizeof(GLfloat), &vbo_offset);
 
-    for (i = 0; i < nBox; i++) {
-        float off_x = box[i].x1 - port_priv->drw_x;
-        float off_y = box[i].y1 - port_priv->drw_y;
-        float diff_x = (float) port_priv->src_w / (float) port_priv->dst_w;
-        float diff_y = (float) port_priv->src_h / (float) port_priv->dst_h;
-        float srcx, srcy, srcw, srch;
-        int dstx, dsty, dstw, dsth;
-        GLfloat *vptr = v + (i * 8);
-        GLfloat *tptr = vptr + (8 * nBox);
+    /* Set up a single primitive covering the area being drawn.  We'll
+     * clip it to port_priv->clip using GL scissors instead of just
+     * emitting a GL_QUAD per box, because this way we hopefully avoid
+     * diagonal tearing between the two trangles used to rasterize a
+     * GL_QUAD.
+     */
+    i = 0;
+    v[i++] = v_from_x_coord_x(dst_xscale, port_priv->drw_x + dst_x_off);
+    v[i++] = v_from_x_coord_y(dst_yscale, port_priv->drw_y + dst_y_off);
 
-        dstx = box[i].x1 + dst_x_off;
-        dsty = box[i].y1 + dst_y_off;
-        dstw = box[i].x2 - box[i].x1;
-        dsth = box[i].y2 - box[i].y1;
+    v[i++] = v_from_x_coord_x(dst_xscale, port_priv->drw_x + dst_x_off +
+                              port_priv->dst_w * 2);
+    v[i++] = v_from_x_coord_y(dst_yscale, port_priv->drw_y + dst_y_off);
 
-        srcx = port_priv->src_x + off_x * diff_x;
-        srcy = port_priv->src_y + off_y * diff_y;
-        srcw = (port_priv->src_w * dstw) / (float) port_priv->dst_w;
-        srch = (port_priv->src_h * dsth) / (float) port_priv->dst_h;
-
-        glamor_set_normalize_vcoords(pixmap_priv,
-                                     dst_xscale, dst_yscale,
-                                     dstx - dstw,
-                                     dsty,
-                                     dstx + dstw,
-                                     dsty + dsth * 2,
-                                     vptr);
-
-        glamor_set_normalize_tcoords(src_pixmap_priv[0],
-                                     src_xscale[0],
-                                     src_yscale[0],
-                                     srcx - srcw,
-                                     srcy,
-                                     srcx + srcw,
-                                     srcy + srch * 2,
-                                     tptr);
-    }
+    v[i++] = v_from_x_coord_x(dst_xscale, port_priv->drw_x + dst_x_off);
+    v[i++] = v_from_x_coord_y(dst_yscale, port_priv->drw_y + dst_y_off +
+                              port_priv->dst_h * 2);
+
+    v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x);
+    v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y);
+
+    v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x +
+                              port_priv->src_w * 2);
+    v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y);
+
+    v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x);
+    v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y +
+                              port_priv->src_h * 2);
 
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2,
                           GL_FLOAT, GL_FALSE,
@@ -389,10 +380,11 @@ glamor_xv_render(glamor_port_private *port_priv)
 
     glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
                           GL_FLOAT, GL_FALSE,
-                          2 * sizeof(float), vbo_offset + (nBox * 8 * sizeof(GLfloat)));
+                          2 * sizeof(float), vbo_offset + 6 * sizeof(GLfloat));
 
     glamor_put_vbo_space(screen);
 
+    /* Now draw our big triangle, clipped to each of the clip boxes. */
     for (i = 0; i < nBox; i++) {
         int dstx, dsty, dstw, dsth;
 
@@ -402,7 +394,7 @@ glamor_xv_render(glamor_port_private *port_priv)
         dsth = box[i].y2 - box[i].y1;
 
         glScissor(dstx, dsty, dstw, dsth);
-        glDrawArrays(GL_TRIANGLE_FAN, i * 4, 3);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
     }
     glDisable(GL_SCISSOR_TEST);
 
commit d23fe3229c17cb0dfb4210041efbdc36fc365dad
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 26 14:18:48 2016 -0800

    glamor: Set up XV sampler uniforms once at program build time.
    
    No sense doing it on every draw.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 294e45b60d99cf7d11c657288bbe2670b56775f3)

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 6e1a588..5d31fee 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -114,7 +114,7 @@ static void
 glamor_init_xv_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    GLint fs_prog, vs_prog;
+    GLint fs_prog, vs_prog, sampler_loc;
 
     glamor_priv = glamor_get_screen_private(screen);
     glamor_make_current(glamor_priv);
@@ -130,6 +130,15 @@ glamor_init_xv_shader(ScreenPtr screen)
     glBindAttribLocation(glamor_priv->xv_prog,
                          GLAMOR_VERTEX_SOURCE, "v_texcoord0");
     glamor_link_glsl_prog(screen, glamor_priv->xv_prog, "xv");
+
+    glUseProgram(glamor_priv->xv_prog);
+    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "y_sampler");
+    glUniform1i(sampler_loc, 0);
+    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "u_sampler");
+    glUniform1i(sampler_loc, 1);
+    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "v_sampler");
+    glUniform1i(sampler_loc, 2);
+
 }
 
 #define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
@@ -258,7 +267,7 @@ glamor_xv_render(glamor_port_private *port_priv)
     float uco[3], vco[3], off[3];
     float bright, cont, gamma;
     int ref = port_priv->transform_index;
-    GLint uloc, sampler_loc;
+    GLint uloc;
     GLfloat *v;
     char *vbo_offset;
 
@@ -329,13 +338,6 @@ glamor_xv_render(glamor_port_private *port_priv)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "y_sampler");
-    glUniform1i(sampler_loc, 0);
-    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "u_sampler");
-    glUniform1i(sampler_loc, 1);
-    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "v_sampler");
-    glUniform1i(sampler_loc, 2);
-
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
commit ef993dbbed24f1fe68fd4c66f0035e6c74cde10d
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 26 13:39:18 2016 -0800

    glamor: Drop dead glamor_pict_format_is_compatible().
    
    This hasn't been used since 2f80c7791bb0b11f261cb1e3e0d89163dcdd0342
    (GLAMOR_SEPARATE_TEXTURE removal).
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 5d7bef2eedfd965359dd4eebb6ab806cdad5b83f)

diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 3adc687..5128a33 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -852,26 +852,6 @@ glamor_get_rgba_from_pixel(CARD32 pixel,
 }
 
 inline static Bool
-glamor_pict_format_is_compatible(PicturePtr picture)
-{
-    GLenum iformat;
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-
-    iformat = gl_iformat_for_pixmap(pixmap);
-    switch (iformat) {
-    case GL_RGBA:
-        return (picture->format == PICT_a8r8g8b8 ||
-                picture->format == PICT_x8r8g8b8);
-    case GL_ALPHA:
-    case GL_RED:
-    case GL_LUMINANCE:
-        return (picture->format == PICT_a8);
-    default:
-        return FALSE;
-    }
-}
-
-inline static Bool
 glamor_is_large_pixmap(PixmapPtr pixmap)
 {
     glamor_pixmap_private *priv;
commit f031c5edbf36a029800d0f8574aea226a4b5b82f
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 26 15:08:17 2016 -0800

    glamor: Drop comment about dead yInverted flag.
    
    Wait long enough, and you don't need to think about it at all.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 4494a450405cf539743cbcfe6907bf5bdd2d80cb)

diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index ad06943..564a52d 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -77,8 +77,6 @@ glamor_set_destination_drawable(DrawablePtr     drawable,
      *  gl_x = (render_x + drawable->x + off_x) * 2 / width - 1
      *
      *  gl_x = (render_x) * 2 / width + (drawable->x + off_x) * 2 / width - 1
-     *
-     * I'll think about yInverted later, when I have some way to test
      */
 
     if (do_drawable_translate) {
commit f1a03379c44c467b92753748165380e33e2e28c8
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 26 13:34:00 2016 -0800

    glamor: Rename the *y_inverted helpers to not say "inverted".
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit f7c24e6ac345aab91df5fc959f239a33f37113b1)

diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 875c935..3adc687 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -36,9 +36,9 @@
 #include "mipict.h"
 
 #define v_from_x_coord_x(_xscale_, _x_)          ( 2 * (_x_) * (_xscale_) - 1.0)
-#define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0)
+#define v_from_x_coord_y(_yscale_, _y_)          (2 * (_y_) * (_yscale_) - 1.0)
 #define t_from_x_coord_x(_xscale_, _x_)          ((_x_) * (_xscale_))
-#define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
+#define t_from_x_coord_y(_yscale_, _y_)          ((_y_) * (_yscale_))
 
 #define pixmap_priv_get_dest_scale(pixmap, _pixmap_priv_, _pxscale_, _pyscale_) \
   do {                                                                   \
@@ -311,7 +311,7 @@
 				     texcoord)                          \
   do {									\
 	(texcoord)[0] = t_from_x_coord_x(xscale, _tx_);			\
-        (texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_);        \
+        (texcoord)[1] = t_from_x_coord_y(yscale, _ty_);                 \
         DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0],	\
 		(texcoord)[1]);						\
   } while(0)
@@ -330,7 +330,7 @@
     tx += fbo_x_off;							\
     ty += fbo_y_off;							\
     (texcoord)[0] = t_from_x_coord_x(xscale, tx);			\
-    (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty);		\
+    (texcoord)[1] = t_from_x_coord_y(yscale, ty);                       \
     DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]);	\
   } while(0)
 
@@ -482,8 +482,8 @@
     (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2);	\
     (vertices)[2 * stride] = _t2_;					\
     (vertices)[3 * stride] = _t0_;					\
-    (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1);	\
-    (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2); \
+    (vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1);               \
+    (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2);  \
     (vertices)[1 * stride + 1] = _t1_;					\
     (vertices)[3 * stride + 1] = _t5_;					\
   } while(0)
@@ -562,8 +562,8 @@
 	(vertices)[2] = t_from_x_coord_x(xscale, x2);			\
 	(vertices)[6] = (vertices)[2];					\
 	(vertices)[4] = (vertices)[0];					\
-        (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1);          \
-        (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2);          \
+        (vertices)[1] = t_from_x_coord_y(yscale, y1);                   \
+        (vertices)[7] = t_from_x_coord_y(yscale, y2);                   \
 	(vertices)[3] = (vertices)[1];					\
 	(vertices)[5] = (vertices)[7];					\
     } while(0)
@@ -596,7 +596,7 @@
 					vertices)                       \
     do {								\
 	(vertices)[0] = v_from_x_coord_x(xscale, x);			\
-        (vertices)[1] = v_from_x_coord_y_inverted(yscale, y);           \
+        (vertices)[1] = v_from_x_coord_y(yscale, y);                    \
     } while(0)
 
 #define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx,		\
@@ -639,11 +639,9 @@
 					x2 + fbo_x_off);		\
     (vertices)[2 * stride] = _t2_;					\
     (vertices)[3 * stride] = _t0_;					\
-    (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale,		\
-                                                     y1 + fbo_y_off);   \
+    (vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off);    \
     (vertices)[2 * stride + 1] = _t5_ =                                 \
-        v_from_x_coord_y_inverted(yscale,                               \
-                                  y2 + fbo_y_off);                      \
+        v_from_x_coord_y(yscale, y2 + fbo_y_off);                       \
     (vertices)[1 * stride + 1] = _t1_;					\
     (vertices)[3 * stride + 1] = _t5_;					\
   } while(0)
@@ -675,8 +673,8 @@
 	(vertices)[2] = v_from_x_coord_x(xscale, x2);			\
 	(vertices)[6] = (vertices)[2];					\
 	(vertices)[4] = (vertices)[0];					\
-        (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1);          \
-        (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2);          \
+        (vertices)[1] = v_from_x_coord_y(yscale, y1);                   \
+        (vertices)[7] = v_from_x_coord_y(yscale, y2);                   \
 	(vertices)[3] = (vertices)[1];					\
 	(vertices)[5] = (vertices)[7];					\
     } while(0)
@@ -685,7 +683,7 @@
                                 pt)				\
     do {							\
         (pt)[0] = t_from_x_coord_x(xscale, x);			\
-        (pt)[1] = t_from_x_coord_y_inverted(yscale, y);         \
+        (pt)[1] = t_from_x_coord_y(yscale, y);                  \
     } while(0)
 
 #define glamor_set_circle_centre(width, height, x, y,	\
commit 83395e6a99c0665490948c92da9bd768954f8c9e
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 26 13:31:59 2016 -0800

    glamor: Drop dead *_from_x_coord_y() functions.
    
    They've been dead since the yInverted removal
    (e310387f443b6333edf02c8980daa303505382b4).
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 1fcb6f4cbf3d6514716435a0e79c0e6d53c31a3a)

diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index d4366c1..875c935 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -36,10 +36,8 @@
 #include "mipict.h"
 
 #define v_from_x_coord_x(_xscale_, _x_)          ( 2 * (_x_) * (_xscale_) - 1.0)
-#define v_from_x_coord_y(_yscale_, _y_)          (-2 * (_y_) * (_yscale_) + 1.0)
 #define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0)
 #define t_from_x_coord_x(_xscale_, _x_)          ((_x_) * (_xscale_))
-#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, _pixmap_priv_, _pxscale_, _pyscale_) \
commit 558ea399664b767c3f9c1acc18f4b2d341d6929c
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jan 21 16:01:14 2016 -0800

    glamor: Clarify when Render fallbacks happen due to an unsupported op.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 9ef11f13af7f552dadb4a90c248e525a257e0a2c)

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 5712cf8..51718d1 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1577,8 +1577,10 @@ glamor_composite(CARD8 op,
     if (!glamor_pixmap_has_fbo(dest_pixmap))
         goto fail;
 
-    if (op >= ARRAY_SIZE(composite_op_info))
+    if (op >= ARRAY_SIZE(composite_op_info)) {
+        glamor_fallback("Unsupported composite op %x\n", op);
         goto fail;
+    }
 
     if (mask && mask->componentAlpha && !glamor_priv->has_dual_blend) {
         if (op == PictOpAtop
commit 7c63e80e3f9de3d1b8132a40be6f932e772e0d69
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan 27 11:35:03 2016 -0800

    glamor: Label programs before linking them.
    
    i965 does most of its compiling at link time, so our debug output for
    its shaders didn't have the name on.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit b8229cc5f5298a37a4735dd002b0e0ebfc8bc75a)

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 0104b88..b9948b5 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -87,6 +87,17 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
     GLint ok;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
+    if (glamor_priv->has_khr_debug) {
+        char *label;
+        va_list va;
+
+        va_start(va, format);
+        XNFvasprintf(&label, format, va);
+        glObjectLabel(GL_PROGRAM, prog, -1, label);
+        free(label);
+        va_end(va);
+    }
+
     glLinkProgram(prog);
     glGetProgramiv(prog, GL_LINK_STATUS, &ok);
     if (!ok) {
@@ -100,17 +111,6 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
         ErrorF("Failed to link: %s\n", info);
         FatalError("GLSL link failure\n");
     }
-
-    if (glamor_priv->has_khr_debug) {
-        char *label;
-        va_list va;
-
-        va_start(va, format);
-        XNFvasprintf(&label, format, va);
-        glObjectLabel(GL_PROGRAM, prog, -1, label);
-        free(label);
-        va_end(va);
-    }
 }
 
 /*
commit 14e2b6f9d87921b39c0874e1a74dff2f9e396f78
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan 27 16:11:17 2016 -0800

    ephyr: Make sure we have GLX_ARB_create_context before calling it.
    
    This should fix aborts()s from epoxy on old software stacks.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 68f236ebd4b268a9e525d623986999d230feb453)

diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c
index 0981144..636150d 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -330,20 +330,26 @@ ephyr_glamor_glx_screen_init(xcb_window_t win)
                        "GLX_EXT_create_context_es2_profile\n");
         }
     } else {
-        static const int context_attribs[] = {
-            GLX_CONTEXT_PROFILE_MASK_ARB,
-            GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
-            GLX_CONTEXT_MAJOR_VERSION_ARB,
-            GLAMOR_GL_CORE_VER_MAJOR,
-            GLX_CONTEXT_MINOR_VERSION_ARB,
-            GLAMOR_GL_CORE_VER_MINOR,
-            0,
-        };
-        oldErrorHandler = XSetErrorHandler(ephyr_glx_error_handler);
-        ctx = glXCreateContextAttribsARB(dpy, fb_config, NULL, True,
-                                         context_attribs);
-        XSync(dpy, False);
-        XSetErrorHandler(oldErrorHandler);
+        if (epoxy_has_glx_extension(dpy, DefaultScreen(dpy),
+                                    "GLX_ARB_create_context")) {
+            static const int context_attribs[] = {
+                GLX_CONTEXT_PROFILE_MASK_ARB,
+                GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+                GLX_CONTEXT_MAJOR_VERSION_ARB,
+                GLAMOR_GL_CORE_VER_MAJOR,
+                GLX_CONTEXT_MINOR_VERSION_ARB,
+                GLAMOR_GL_CORE_VER_MINOR,
+                0,
+            };
+            oldErrorHandler = XSetErrorHandler(ephyr_glx_error_handler);
+            ctx = glXCreateContextAttribsARB(dpy, fb_config, NULL, True,
+                                             context_attribs);
+            XSync(dpy, False);
+            XSetErrorHandler(oldErrorHandler);
+        } else {
+            ctx = NULL;
+        }
+
         if (!ctx)
             ctx = glXCreateContext(dpy, visual_info, NULL, True);
     }
commit cd9ae6d1a259f3229df4c110903658d1bede8554
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 8 17:41:37 2015 -0500

    xfree86: Build parser for DRI config file subsection unconditionally
    
    This applies regardless of which DRI you're asking for. Worse, leaving
    it out means breaking the config file syntax in a pointless way, since
    non-DRI servers can safely just parse it and ignore it.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit 953b71270cf12c59c8a836c9be403d07fb01fa22)

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index d2c3225..0c067c0 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -46,10 +46,8 @@
 #include <xorg-config.h>
 #endif
 
-#ifdef XF86DRI
 #include <sys/types.h>
 #include <grp.h>
-#endif
 
 #include "xf86.h"
 #include "xf86Modes.h"
@@ -132,9 +130,7 @@ static Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input,
 static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
 static Bool addDefaultModes(MonPtr monitorp);
 
-#ifdef XF86DRI
 static void configDRI(XF86ConfDRIPtr drip);
-#endif
 static void configExtensions(XF86ConfExtensionsPtr conf_ext);
 
 /*
@@ -2218,7 +2214,6 @@ configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active, Bool g
     return TRUE;
 }
 
-#ifdef XF86DRI
 static void
 configDRI(XF86ConfDRIPtr drip)
 {
@@ -2239,7 +2234,6 @@ configDRI(XF86ConfDRIPtr drip)
         xf86ConfigDRI.mode = drip->dri_mode;
     }
 }
-#endif
 
 static void
 configExtensions(XF86ConfExtensionsPtr conf_ext)
@@ -2532,9 +2526,7 @@ xf86HandleConfigFile(Bool autoconfig)
     configServerFlags(xf86configptr->conf_flags, xf86ConfigLayout.options);
     configFiles(xf86configptr->conf_files);
     configExtensions(xf86configptr->conf_extensions);
-#ifdef XF86DRI
     configDRI(xf86configptr->conf_dri);
-#endif
 
     checkInput(&xf86ConfigLayout, implicit_layout);
 
commit 3da08902dd5961ea6f70431fce813f294d0f8547
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jan 27 16:46:06 2016 -0800

    ephyr: catch X errors if we try to create a core context and fail.
    
    This stops Xephyr failing on GLXBadFBConfig.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit d8ecbe563991cc689e95a8cb9d510e920eaceea0)

diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c
index b9fe8d1..0981144 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -280,9 +280,16 @@ ephyr_glamor_process_event(xcb_generic_event_t *xev)
     XUnlockDisplay(dpy);
 }
 
+static int
+ephyr_glx_error_handler(Display * _dpy, XErrorEvent * ev)
+{
+    return 0;
+}
+
 struct ephyr_glamor *
 ephyr_glamor_glx_screen_init(xcb_window_t win)
 {
+    int (*oldErrorHandler) (Display *, XErrorEvent *);
     static const float position[] = {
         -1, -1,
          1, -1,
@@ -332,8 +339,11 @@ ephyr_glamor_glx_screen_init(xcb_window_t win)
             GLAMOR_GL_CORE_VER_MINOR,
             0,
         };
+        oldErrorHandler = XSetErrorHandler(ephyr_glx_error_handler);
         ctx = glXCreateContextAttribsARB(dpy, fb_config, NULL, True,
                                          context_attribs);
+        XSync(dpy, False);
+        XSetErrorHandler(oldErrorHandler);
         if (!ctx)
             ctx = glXCreateContext(dpy, visual_info, NULL, True);
     }
commit 4c6ca0aae5a301140eadc97313be954bd6a5fe18
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Jan 19 08:06:25 2016 +1000

    xwayland: add support for use core profile for glamor. (v2)
    
    This adds support to Xwayland to try and use OpenGL core
    profile for glamor first.
    
    v1.1: use version defines.
    v2: let glamor work out core profile itself.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    (cherry picked from commit 6978c8ee666a9224213173e7680e2d71b1094bab)

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index cb1851b..3557f30 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -270,6 +270,15 @@ xwl_drm_init_egl(struct xwl_screen *xwl_screen)
 {
     EGLint major, minor;
     const char *version;
+    static const EGLint config_attribs_core[] = {
+        EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,
+        EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
+        EGL_CONTEXT_MAJOR_VERSION_KHR,
+        GLAMOR_GL_CORE_VER_MAJOR,
+        EGL_CONTEXT_MINOR_VERSION_KHR,
+        GLAMOR_GL_CORE_VER_MINOR,
+        EGL_NONE
+    };
 
     if (xwl_screen->egl_display)
         return;
@@ -298,7 +307,11 @@ xwl_drm_init_egl(struct xwl_screen *xwl_screen)
     ErrorF("glamor: EGL version %s:\n", version);
 
     xwl_screen->egl_context = eglCreateContext(xwl_screen->egl_display,
-                                               NULL, EGL_NO_CONTEXT, NULL);
+                                               NULL, EGL_NO_CONTEXT, config_attribs_core);
+    if (!xwl_screen->egl_context)
+        xwl_screen->egl_context = eglCreateContext(xwl_screen->egl_display,
+                                                   NULL, EGL_NO_CONTEXT, NULL);
+
     if (xwl_screen->egl_context == EGL_NO_CONTEXT) {
         ErrorF("Failed to create EGL context\n");
         return;
commit b0fa782081f933e84f068228ca35fa5c25c9a4b3
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Jan 19 07:59:59 2016 +1000

    glamor: add core profile support to EGL glamor. (v2)
    
    v1.1: use version defines.
    v2: let glamor work it out itself
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    (cherry picked from commit 79c3925532bc0d098c9a4da6d5117bdada56e0af)

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index c33cae1..80a97f7 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -791,6 +791,15 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 #endif
         EGL_NONE
     };
+    static const EGLint config_attribs_core[] = {
+        EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,
+        EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
+        EGL_CONTEXT_MAJOR_VERSION_KHR,
+        GLAMOR_GL_CORE_VER_MAJOR,
+        EGL_CONTEXT_MINOR_VERSION_KHR,
+        GLAMOR_GL_CORE_VER_MINOR,
+        EGL_NONE
+    };
 
     glamor_identify(0);
     glamor_egl = calloc(sizeof(*glamor_egl), 1);
@@ -851,12 +860,21 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
                                 KHR_surfaceless_opengl);
 #endif
 
+#ifndef GLAMOR_GLES2
     glamor_egl->context = eglCreateContext(glamor_egl->display,
                                            NULL, EGL_NO_CONTEXT,
-                                           config_attribs);
-    if (glamor_egl->context == EGL_NO_CONTEXT) {
-        xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create EGL context\n");
-        goto error;
+                                           config_attribs_core);
+#else
+    glamor_egl->context = NULL;
+#endif
+    if (!glamor_egl->context) {
+        glamor_egl->context = eglCreateContext(glamor_egl->display,
+                                               NULL, EGL_NO_CONTEXT,
+                                               config_attribs);
+        if (glamor_egl->context == EGL_NO_CONTEXT) {
+            xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create EGL context\n");
+            goto error;
+        }
     }
 
     if (!eglMakeCurrent(glamor_egl->display,
commit 181ea41e71934a0c575322a8be9234f2e64ef8db
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Sep 10 19:05:08 2014 -0700

    ephyr: Create 3.1 core profile context if possible (v3)
    
    On desktop GL, ask for a 3.1 core profile context if that's available,
    otherwise create a generic context.
    
    v2: tell glamor the profile is a core one.
    v2.1: add/use GL version defines
    v3: let glamor work out core itself
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    (cherry picked from commit 98c3504dcfcec227b9c7798a0bd287941cec0691)

diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c
index 30c5245..b9fe8d1 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -41,6 +41,10 @@
 #include "os.h"
 #include <X11/Xproto.h>
 
+/* until we need geometry shaders GL3.1 should suffice. */
+/* Xephyr has it's own copy of this for build reasons */
+#define GLAMOR_GL_CORE_VER_MAJOR 3
+#define GLAMOR_GL_CORE_VER_MINOR 1
 /** @{
  *
  * global state for Xephyr with glamor.
@@ -319,7 +323,19 @@ ephyr_glamor_glx_screen_init(xcb_window_t win)
                        "GLX_EXT_create_context_es2_profile\n");
         }
     } else {
-        ctx = glXCreateContext(dpy, visual_info, NULL, True);
+        static const int context_attribs[] = {
+            GLX_CONTEXT_PROFILE_MASK_ARB,
+            GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+            GLX_CONTEXT_MAJOR_VERSION_ARB,
+            GLAMOR_GL_CORE_VER_MAJOR,
+            GLX_CONTEXT_MINOR_VERSION_ARB,
+            GLAMOR_GL_CORE_VER_MINOR,
+            0,
+        };
+        ctx = glXCreateContextAttribsARB(dpy, fb_config, NULL, True,
+                                         context_attribs);
+        if (!ctx)
+            ctx = glXCreateContext(dpy, visual_info, NULL, True);
     }
     if (ctx == NULL)
         FatalError("glXCreateContext failed\n");
commit d7f03d57454de989025de2a2ef644d43eead9ddf
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Jan 11 14:00:35 2016 +1000

    glamor: add core profile support. (v2)
    
    Glamor works out from the profile if it is
    core.
    
    This flag is used to disable quads for rendering.
    
    v1.1: split long line + make whitespace conform (Michel)
    v1.2: add GL 3.1 version defines
    v2: move to having glamor work out the profile.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    (cherry picked from commit 564d9f0f8c17bb3c13aa3ca36da7825454dc5de3)

diff --git a/glamor/glamor.c b/glamor/glamor.c
index ea77fc9..9c6a0d1 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -584,9 +584,15 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_priv->has_dual_blend =
         epoxy_has_gl_extension("GL_ARB_blend_func_extended");
 
+    /* assume a core profile if we are GL 3.1 and don't have ARB_compatibility */
+    glamor_priv->is_core_profile =
+        gl_version >= 31 && !epoxy_has_gl_extension("GL_ARB_compatibility");
+
     glamor_setup_debug_output(screen);
 
-    glamor_priv->use_quads = (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
+    glamor_priv->use_quads = (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) &&
+                             !glamor_priv->is_core_profile;
+
     /* Driver-specific hack: Avoid using GL_QUADS on VC4, where
      * they'll be emulated more expensively than we can with our
      * cached IB.
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 4be8800..0aa6d56 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -64,6 +64,10 @@ typedef enum glamor_pixmap_type {
 #define GLAMOR_VALID_FLAGS      (GLAMOR_USE_EGL_SCREEN                \
                                  | GLAMOR_NO_DRI3)
 
+/* until we need geometry shaders GL3.1 should suffice. */
+#define GLAMOR_GL_CORE_VER_MAJOR 3
+#define GLAMOR_GL_CORE_VER_MINOR 1
+
 /* @glamor_init: Initialize glamor internal data structure.
  *
  * @screen: Current screen pointer.
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index d2ef266..f1eed5b 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -217,6 +217,7 @@ typedef struct glamor_screen_private {
     Bool use_quads;
     Bool has_vertex_array_object;
     Bool has_dual_blend;
+    Bool is_core_profile;
     int max_fbo_size;
 
     GLuint one_channel_format;
commit 0cd5b9525a8f661c6b2545c21ce1ba21577c009e
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Sep 10 19:02:55 2014 -0700

    glamor: Use GL_RED instead of GL_ALPHA if we have texture_swizzle (v3)
    
    GL_RED is supported by core profiles while GL_ALPHA is not; use GL_RED
    for one channel objects (depth 1 to 8), and then swizzle them into the
    alpha channel when used as a mask.
    
    [airlied: updated to master, add swizzle to composited glyphs and xv paths]
    
    v2: consolidate setting swizzle into the texture creation code, it
        should work fine there. Handle swizzle when setting color as well.
    v3: Fix drawing to a8 with Render (changes by anholt, reviewed by airlied).
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    (cherry picked from commit e6754dcb59ee21abb42421a28f4e467295584f67)

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 74692e0..ea77fc9 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -604,6 +604,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_priv->max_fbo_size = MAX_FBO_SIZE;
 #endif
 
+    glamor_priv->one_channel_format = GL_ALPHA;
+    if (epoxy_has_gl_extension("GL_ARB_texture_rg") && epoxy_has_gl_extension("GL_ARB_texture_swizzle"))
+        glamor_priv->one_channel_format = GL_RED;
+
     glamor_set_debug_level(&glamor_debug_level);
 
     glamor_priv->saved_procs.create_screen_resources =
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index b1b584d..5bfffe5 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -75,6 +75,8 @@ cache_format(GLenum format)
 {
     switch (format) {
     case GL_ALPHA:
+    case GL_LUMINANCE:
+    case GL_RED:
         return 2;
     case GL_RGB:
         return 1;
@@ -338,6 +340,8 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
     glBindTexture(GL_TEXTURE_2D, tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    if (format == glamor_priv->one_channel_format && format == GL_RED)
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
     glamor_priv->suppress_gl_out_of_memory_logging = true;
     glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
                  format, GL_UNSIGNED_BYTE, NULL);
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 352858f..b069ce5 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -41,19 +41,21 @@
  * Return 0 if find a matched texture type. Otherwise return -1.
  **/
 static int
-glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format,
+glamor_get_tex_format_type_from_pictformat_gl(ScreenPtr pScreen,
+                                              PictFormatShort format,
                                               GLenum *tex_format,
                                               GLenum *tex_type,
                                               int *no_alpha,
                                               int *revert,
                                               int *swap_rb, int is_upload)
 {
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
     *no_alpha = 0;
     *revert = REVERT_NONE;
     *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
     switch (format) {
     case PICT_a1:
-        *tex_format = GL_ALPHA;
+        *tex_format = glamor_priv->one_channel_format;
         *tex_type = GL_UNSIGNED_BYTE;
         *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
         break;
@@ -111,7 +113,7 @@ glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format,
         *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
         break;
     case PICT_a8:
-        *tex_format = GL_ALPHA;
+        *tex_format = glamor_priv->one_channel_format;
         *tex_type = GL_UNSIGNED_BYTE;
         break;
     case PICT_x4r4g4b4:
@@ -137,13 +139,15 @@ glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format,
 #define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
 
 static int
-glamor_get_tex_format_type_from_pictformat_gles2(PictFormatShort format,
+glamor_get_tex_format_type_from_pictformat_gles2(ScreenPtr pScreen,
+                                                 PictFormatShort format,
                                                  GLenum *tex_format,
                                                  GLenum *tex_type,
                                                  int *no_alpha,
                                                  int *revert,
                                                  int *swap_rb, int is_upload)
 {
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
     int need_swap_rb = 0;
 
     *no_alpha = 0;
@@ -264,13 +268,13 @@ glamor_get_tex_format_type_from_pictformat_gles2(PictFormatShort format,
         break;
 
     case PICT_a1:
-        *tex_format = GL_ALPHA;
+        *tex_format = glamor_priv->one_channel_format;
         *tex_type = GL_UNSIGNED_BYTE;
         *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
         break;
 
     case PICT_a8:
-        *tex_format = GL_ALPHA;
+        *tex_format = glamor_priv->one_channel_format;
         *tex_type = GL_UNSIGNED_BYTE;
         *revert = REVERT_NONE;
         break;
@@ -317,14 +321,16 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
         glamor_get_screen_private(pixmap->drawable.pScreen);
 
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-        return glamor_get_tex_format_type_from_pictformat_gl(pict_format,
+        return glamor_get_tex_format_type_from_pictformat_gl(pixmap->drawable.pScreen,
+                                                             pict_format,
                                                              format, type,
                                                              no_alpha,
                                                              revert,
                                                              swap_rb,
                                                              is_upload);
     } else {
-        return glamor_get_tex_format_type_from_pictformat_gles2(pict_format,
+        return glamor_get_tex_format_type_from_pictformat_gles2(pixmap->drawable.pScreen,
+                                                                pict_format,
                                                                 format, type,
                                                                 no_alpha,
                                                                 revert,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index e49aee5..d2ef266 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -116,10 +116,17 @@ enum shader_in {
     SHADER_IN_COUNT,
 };
 
+enum shader_dest_swizzle {
+    SHADER_DEST_SWIZZLE_DEFAULT,
+    SHADER_DEST_SWIZZLE_ALPHA_TO_RED,
+    SHADER_DEST_SWIZZLE_COUNT,
+};
+
 struct shader_key {
     enum shader_source source;
     enum shader_mask mask;
     enum shader_in in;
+    enum shader_dest_swizzle dest_swizzle;
 };
 
 struct blendinfo {
@@ -212,6 +219,8 @@ typedef struct glamor_screen_private {
     Bool has_dual_blend;
     int max_fbo_size;
 
+    GLuint one_channel_format;
+
     struct xorg_list
         fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
     unsigned long fbo_cache_watermark;
@@ -282,7 +291,8 @@ typedef struct glamor_screen_private {
     int render_nr_quads;
     glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
         [SHADER_MASK_COUNT]
-        [SHADER_IN_COUNT];
+        [SHADER_IN_COUNT]
+        [SHADER_DEST_SWIZZLE_COUNT];
 
     /* shaders to restore a texture to another texture. */
     GLint finish_access_prog[2];
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 4e66f6d..5712cf8 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -177,33 +177,46 @@ glamor_create_composite_fs(struct shader_key *key)
         "		return rel_sampler(mask_sampler, mask_texture,\n"
         "				   mask_wh, mask_repeat_mode, 1);\n"
         "}\n";
+
+    const char *dest_swizzle_default =
+        "vec4 dest_swizzle(vec4 color)\n"
+        "{"
+        "	return color;"
+        "}";
+    const char *dest_swizzle_alpha_to_red =
+        "vec4 dest_swizzle(vec4 color)\n"
+        "{"
+        "	float undef;\n"
+        "	return vec4(color.a, undef, undef, undef);"
+        "}";
+
     const char *in_source_only =
         "void main()\n"
         "{\n"
-        "	gl_FragColor = get_source();\n"
+        "	gl_FragColor = dest_swizzle(get_source());\n"
         "}\n";
     const char *in_normal =
         "void main()\n"
         "{\n"
-        "	gl_FragColor = get_source() * get_mask().a;\n"
+        "	gl_FragColor = dest_swizzle(get_source() * get_mask().a);\n"
         "}\n";
     const char *in_ca_source =
         "void main()\n"
         "{\n"
-        "	gl_FragColor = get_source() * get_mask();\n"
+        "	gl_FragColor = dest_swizzle(get_source() * get_mask());\n"
         "}\n";
     const char *in_ca_alpha =
         "void main()\n"
         "{\n"
-        "	gl_FragColor = get_source().a * get_mask();\n"
+        "	gl_FragColor = dest_swizzle(get_source().a * get_mask());\n"
         "}\n";
     const char *in_ca_dual_blend =
         "out vec4 color0;\n"
         "out vec4 color1;\n"
         "void main()\n"
         "{\n"
-        "	color0 = get_source() * get_mask();\n"
-        "	color1 = get_source().a * get_mask();\n"
+        "	color0 = dest_swizzle(get_source() * get_mask());\n"
+        "	color1 = dest_swizzle(get_source().a * get_mask());\n"
         "}\n";
     const char *header_ca_dual_blend =
         "#version 130\n";
@@ -214,6 +227,7 @@ glamor_create_composite_fs(struct shader_key *key)
     const char *in;
     const char *header;
     const char *header_norm = "";
+    const char *dest_swizzle;
     GLuint prog;
 
     switch (key->source) {
@@ -246,6 +260,21 @@ glamor_create_composite_fs(struct shader_key *key)
         FatalError("Bad composite shader mask");
     }
 
+    /* If we're storing to an a8 texture but our texture format is
+     * GL_RED because of a core context, then we need to make sure to
+     * put the alpha into the red channel.
+     */
+    switch (key->dest_swizzle) {
+    case SHADER_DEST_SWIZZLE_DEFAULT:
+        dest_swizzle = dest_swizzle_default;
+        break;
+    case SHADER_DEST_SWIZZLE_ALPHA_TO_RED:
+        dest_swizzle = dest_swizzle_alpha_to_red;
+        break;
+    default:
+        FatalError("Bad composite shader dest swizzle");
+    }
+
     header = header_norm;
     switch (key->in) {
     case SHADER_IN_SOURCE_ONLY:
@@ -271,8 +300,8 @@ glamor_create_composite_fs(struct shader_key *key)
     XNFasprintf(&source,
                 "%s"
                 GLAMOR_DEFAULT_PRECISION
-                "%s%s%s%s%s%s", header, repeat_define, relocate_texture,
-                rel_sampler, source_fetch, mask_fetch, in);
+                "%s%s%s%s%s%s%s", header, repeat_define, relocate_texture,
+                rel_sampler, source_fetch, mask_fetch, dest_swizzle, in);
 
     prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
     free(source);
@@ -386,18 +415,36 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     glamor_composite_shader *shader;
 
-    shader = &glamor_priv->composite_shader[key->source][key->mask][key->in];
+    shader = &glamor_priv->composite_shader[key->source][key->mask][key->in][key->dest_swizzle];
     if (shader->prog == 0)
         glamor_create_composite_shader(screen, key, shader);
 
     return shader;
 }
 
+static GLenum
+glamor_translate_blend_alpha_to_red(GLenum blend)
+{
+    switch (blend) {
+    case GL_SRC_ALPHA:
+        return GL_SRC_COLOR;
+    case GL_DST_ALPHA:
+        return GL_DST_COLOR;
+    case GL_ONE_MINUS_SRC_ALPHA:
+        return GL_ONE_MINUS_SRC_COLOR;
+    case GL_ONE_MINUS_DST_ALPHA:
+        return GL_ONE_MINUS_DST_COLOR;
+    default:
+        return blend;
+    }
+}
+
 static Bool
 glamor_set_composite_op(ScreenPtr screen,
                         CARD8 op, struct blendinfo *op_info_result,
                         PicturePtr dest, PicturePtr mask,
-                        enum ca_state ca_state)
+                        enum ca_state ca_state,
+                        struct shader_key *key)
 {
     GLenum source_blend, dest_blend;
     struct blendinfo *op_info;
@@ -444,6 +491,14 @@ glamor_set_composite_op(ScreenPtr screen,
         }
     }
 
+    /* If we're outputting our alpha to the red channel, then any
+     * reads of alpha for blending need to come from the red channel.
+     */
+    if (key->dest_swizzle == SHADER_DEST_SWIZZLE_ALPHA_TO_RED) {
+        source_blend = glamor_translate_blend_alpha_to_red(source_blend);
+        dest_blend = glamor_translate_blend_alpha_to_red(dest_blend);
+    }
+
     op_info_result->source_blend = source_blend;
     op_info_result->dest_blend = dest_blend;
     op_info_result->source_alpha = op_info->source_alpha;
@@ -841,6 +896,13 @@ glamor_composite_choose_shader(CARD8 op,
         key.in = SHADER_IN_SOURCE_ONLY;
     }
 
+    if (dest_pixmap->drawable.bitsPerPixel <= 8 &&
+        glamor_priv->one_channel_format == GL_RED) {
+        key.dest_swizzle = SHADER_DEST_SWIZZLE_ALPHA_TO_RED;
+    } else {
+        key.dest_swizzle = SHADER_DEST_SWIZZLE_DEFAULT;
+    }
+
     if (source && source->alphaMap) {
         glamor_fallback("source alphaMap\n");
         goto fail;
@@ -970,8 +1032,10 @@ glamor_composite_choose_shader(CARD8 op,
         goto fail;
     }
 
-    if (!glamor_set_composite_op(screen, op, op_info, dest, mask, ca_state))
+    if (!glamor_set_composite_op(screen, op, op_info, dest, mask, ca_state,
+                                 &key)) {
         goto fail;
+    }
 
     *shader = glamor_lookup_composite_shader(screen, &key);
     if ((*shader)->prog == 0) {
diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
index 155d7e0..91e1747 100644
--- a/glamor/glamor_transfer.c
+++ b/glamor/glamor_transfer.c
@@ -42,7 +42,7 @@ glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type)
         *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
         break;
     case 8:
-        *format = GL_ALPHA;
+        *format = glamor_get_screen_private(pixmap->drawable.pScreen)->one_channel_format;
         *type = GL_UNSIGNED_BYTE;
         break;
     default:
diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index f476a99..ad06943 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -111,12 +111,18 @@ glamor_set_color(PixmapPtr      pixmap,
                  CARD32         pixel,
                  GLint          uniform)
 {
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private((pixmap)->drawable.pScreen);
     float       color[4];
 
     glamor_get_rgba_from_pixel(pixel,
                                &color[0], &color[1], &color[2], &color[3],
                                format_for_pixmap(pixmap));
 
+    if ((pixmap->drawable.depth == 1 || pixmap->drawable.depth == 8) &&
+	glamor_priv->one_channel_format == GL_RED)
+      color[0] = color[3];
+
     glUniform4fv(uniform, 1, color);
 }
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index e648af2..d4366c1 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -757,7 +757,7 @@ gl_iformat_for_pixmap(PixmapPtr pixmap)
 
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
         ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) {
-        return GL_ALPHA;
+        return glamor_priv->one_channel_format;
     } else {
         return GL_RGBA;
     }
@@ -867,6 +867,8 @@ glamor_pict_format_is_compatible(PicturePtr picture)
         return (picture->format == PICT_a8r8g8b8 ||
                 picture->format == PICT_x8r8g8b8);
     case GL_ALPHA:
+    case GL_RED:
+    case GL_LUMINANCE:
         return (picture->format == PICT_a8);
     default:
         return FALSE;
commit 7bd0f79c38cac71d433b1ec7e56a6ff7c2550bcc
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jun 18 11:14:41 2015 -0700

    glamor: Delay making pixmaps shareable until we need to.
    
    If a pixmap isn't getting exported as a dmabuf, then we don't need to
    make an EGLImage/GBM bo for it.  This should reduce normal pixmap
    allocation overhead, and also lets the driver choose non-scanout
    formats which may be much higher performance.
    
    On Raspberry Pi, where scanout isn't usable as a texture source, this
    improves x11perf -copypixwin100 from about 4300/sec to 5780/sec under
    xcompmgr -a, because we no longer need to upload our x11perf window to
    a tiled temporary in order to render it to the screen.
    
    v2: Just use pixmap->usage_hint instead of a new field.  Drop the
        changes that started storing gbm_bos in the pixmap priv due to
        lifetime issues.
    v3: Fix a missing gbm_bo_destroy() on the pixmap-from-fd success path.
    
    [ajax: Restore glamor_egl_create_argb8888_based_texture for ABI reasons.
    I'm not aware of any driver using it directly, but.]
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    (cherry picked from commit 51984dddfcc7133ed3c1f20d03514aa98c9a7831)

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 3fe4d47..c33cae1 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -395,79 +395,92 @@ glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name)
 }
 #endif
 
-#ifdef GLAMOR_HAS_GBM
-static void *
-_get_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, unsigned int tex)
+static Bool
+glamor_make_pixmap_exportable(PixmapPtr pixmap)
 {
+#ifdef GLAMOR_HAS_GBM
+    ScreenPtr screen = pixmap->drawable.pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
     struct glamor_pixmap_private *pixmap_priv =
         glamor_get_pixmap_private(pixmap);
-    struct glamor_screen_private *glamor_priv =
-        glamor_get_screen_private(screen);
-    struct glamor_egl_screen_private *glamor_egl;
-    EGLImageKHR image;
+    unsigned width = pixmap->drawable.width;
+    unsigned height = pixmap->drawable.height;
     struct gbm_bo *bo;
+    PixmapPtr exported;
+    GCPtr scratch_gc;
 
-    EGLint attribs[] = {
-        EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
-        EGL_GL_TEXTURE_LEVEL_KHR, 0,
-        EGL_NONE
-    };
+    if (pixmap_priv->image)
+        return TRUE;
 
-    glamor_egl = glamor_egl_get_screen_private(scrn);
+    if (pixmap->drawable.bitsPerPixel != 32) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                   "Failed to make %dbpp pixmap exportable\n",
+                   pixmap->drawable.bitsPerPixel);
+        return FALSE;
+    }
 
-    glamor_make_current(glamor_priv);
+    bo = gbm_bo_create(glamor_egl->gbm, width, height,
+                       GBM_FORMAT_ARGB8888,
+#ifdef GLAMOR_HAS_GBM_LINEAR
+                       (pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ?
+                        GBM_BO_USE_LINEAR : 0) |
+#endif
+                       GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+    if (!bo) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                   "Failed to make %dx%dx%dbpp GBM bo\n",
+                   width, height, pixmap->drawable.bitsPerPixel);
+        return FALSE;
+    }
 
-    image = pixmap_priv->image;
-    if (!image) {
-        image = eglCreateImageKHR(glamor_egl->display,
-                                  glamor_egl->context,
-                                  EGL_GL_TEXTURE_2D_KHR,
-                                  (EGLClientBuffer) (uintptr_t)
-                                  tex, attribs);
-        if (image == EGL_NO_IMAGE_KHR)
-            return NULL;
-
-        glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
-        glamor_egl_set_pixmap_image(pixmap, image);
+    exported = screen->CreatePixmap(screen, 0, 0, pixmap->drawable.depth, 0);
+    screen->ModifyPixmapHeader(exported, width, height, 0, 0,
+                               gbm_bo_get_stride(bo), NULL);
+    if (!glamor_egl_create_textured_pixmap_from_gbm_bo(exported, bo)) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                   "Failed to make %dx%dx%dbpp pixmap from GBM bo\n",
+                   width, height, pixmap->drawable.bitsPerPixel);
+        screen->DestroyPixmap(exported);
+        gbm_bo_destroy(bo);
+        return FALSE;
     }
+    gbm_bo_destroy(bo);
 
-    bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
-    if (!bo)
-        return NULL;
+    scratch_gc = GetScratchGC(pixmap->drawable.depth, screen);
+    ValidateGC(&pixmap->drawable, scratch_gc);
+    scratch_gc->ops->CopyArea(&pixmap->drawable, &exported->drawable,
+                              scratch_gc,
+                              0, 0, width, height, 0, 0);
+    FreeScratchGC(scratch_gc);
 
-    pixmap->devKind = gbm_bo_get_stride(bo);
+    /* Now, swap the tex/gbm/EGLImage/etc. of the exported pixmap into
+     * the original pixmap struct.
+     */
+    glamor_egl_exchange_buffers(pixmap, exported);
 
-    return bo;
-}
+    screen->DestroyPixmap(exported);
+
+    return TRUE;
+#else
+    return FALSE;
 #endif
+}
 
 void *
 glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap)
 {
-#ifdef GLAMOR_HAS_GBM
-    glamor_screen_private *glamor_priv =
-        glamor_get_screen_private(pixmap->drawable.pScreen);
-    glamor_pixmap_private *pixmap_priv =
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
+    struct glamor_pixmap_private *pixmap_priv =
         glamor_get_pixmap_private(pixmap);
 
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-    if (!glamor_priv->dri3_enabled)
+    if (!glamor_make_pixmap_exportable(pixmap))
         return NULL;
-    switch (pixmap_priv->type) {
-    case GLAMOR_TEXTURE_DRM:
-    case GLAMOR_TEXTURE_ONLY:
-        if (!glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0))
-            return NULL;
-        return _get_gbm_bo_from_pixmap(screen, pixmap,
-                                       pixmap_priv->fbo->tex);
-    default:
-        break;
-    }
-    return NULL;
-#else
-    return NULL;
-#endif
+
+    return gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE,
+                         pixmap_priv->image, 0);
 }
 
 int
@@ -483,7 +496,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
 
     glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
 
-    bo = _get_gbm_bo_from_pixmap(screen, pixmap, tex);
+    bo = glamor_gbm_bo_from_pixmap(screen, pixmap);
     if (!bo)
         goto failure;
 
@@ -520,8 +533,8 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     struct glamor_egl_screen_private *glamor_egl;
     struct gbm_bo *bo;
-    Bool ret = FALSE;
     struct gbm_import_fd_data import_data = { 0 };
+    Bool ret;
 
     glamor_egl = glamor_egl_get_screen_private(scrn);
 
@@ -544,10 +557,7 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
 
     ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo);
     gbm_bo_destroy(bo);
-
-    if (ret)
-        return TRUE;
-    return FALSE;
+    return ret;
 #else
     return FALSE;
 #endif
diff --git a/glamor/glamor_egl_stubs.c b/glamor/glamor_egl_stubs.c
index c11e6d5..5dbbfe4 100644
--- a/glamor/glamor_egl_stubs.c
+++ b/glamor/glamor_egl_stubs.c
@@ -48,9 +48,3 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
 {
     return 0;
 }
-
-unsigned int
-glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear)
-{
-    return 0;
-}
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 545f89f..b1b584d 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -329,30 +329,19 @@ glamor_destroy_fbo(glamor_screen_private *glamor_priv,
 
 static int
 _glamor_create_tex(glamor_screen_private *glamor_priv,
-                   int w, int h, GLenum format, Bool linear)
+                   int w, int h, GLenum format)
 {
-    unsigned int tex = 0;
-
-    /* With dri3, we want to allocate ARGB8888 pixmaps only.
-     * Depending on the implementation, GL_RGBA might not
-     * give us ARGB8888. We ask glamor_egl to use get
-     * an ARGB8888 based texture for us. */
-    if (glamor_priv->dri3_enabled && format == GL_RGBA) {
-        tex = glamor_egl_create_argb8888_based_texture(glamor_priv->screen,
-                                                       w, h, linear);
-    }
-    if (!tex) {
-        glamor_make_current(glamor_priv);
-        glGenTextures(1, &tex);
-        glBindTexture(GL_TEXTURE_2D, tex);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
-        glamor_priv->suppress_gl_out_of_memory_logging = true;
-        glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
-                     format, GL_UNSIGNED_BYTE, NULL);
-        glamor_priv->suppress_gl_out_of_memory_logging = false;
-    }
+    unsigned int tex;
+
+    glamor_make_current(glamor_priv);
+    glGenTextures(1, &tex);
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glamor_priv->suppress_gl_out_of_memory_logging = true;
+    glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
+                 format, GL_UNSIGNED_BYTE, NULL);
+    glamor_priv->suppress_gl_out_of_memory_logging = false;
 
     if (glGetError() == GL_OUT_OF_MEMORY) {
         if (!glamor_priv->logged_any_fbo_allocation_failure) {
@@ -383,7 +372,7 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
     if (fbo)
         return fbo;
  new_fbo:
-    tex = _glamor_create_tex(glamor_priv, w, h, format, flag == CREATE_PIXMAP_USAGE_SHARED);
+    tex = _glamor_create_tex(glamor_priv, w, h, format);
     if (!tex)
         return NULL;
     fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
@@ -548,7 +537,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
         if (!pixmap_priv->fbo->tex)
             pixmap_priv->fbo->tex =
                 _glamor_create_tex(glamor_priv, pixmap->drawable.width,
-                                   pixmap->drawable.height, format, FALSE);
+                                   pixmap->drawable.height, format);
 
         if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0)
             if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->fbo) != 0)
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index dd41577..cb1851b 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -416,12 +416,6 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
     return 0;
 }
 
-unsigned int
-glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear)
-{
-    return 0;
-}
-
 struct xwl_auth_state {
     int fd;
     ClientPtr client;
commit ec9b79c8d497522f87697e434f55086f185e65e7
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jun 18 11:26:46 2015 -0700

    glamor: Simplify DRI3 pixmap-from-fd, using GBM.
    
    This GBM import path was introduced in 10.2, which we already require.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    (cherry picked from commit 6be33fd044949330e0b2b4185882c9664d2f90b4)

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index cc16b0a..3fe4d47 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -520,18 +520,8 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     struct glamor_egl_screen_private *glamor_egl;
     struct gbm_bo *bo;
-    EGLImageKHR image;
     Bool ret = FALSE;
-
-    EGLint attribs[] = {
-        EGL_WIDTH, 0,
-        EGL_HEIGHT, 0,
-        EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
-        EGL_DMA_BUF_PLANE0_FD_EXT, 0,
-        EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
-        EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
-        EGL_NONE
-    };
+    struct gbm_import_fd_data import_data = { 0 };
 
     glamor_egl = glamor_egl_get_screen_private(scrn);
 
@@ -541,23 +531,12 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
     if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0)
         return FALSE;
 
-    attribs[1] = width;
-    attribs[3] = height;
-    attribs[7] = fd;
-    attribs[11] = stride;
-    image = eglCreateImageKHR(glamor_egl->display,
-                              EGL_NO_CONTEXT,
-                              EGL_LINUX_DMA_BUF_EXT,
-                              NULL, attribs);
-
-    if (image == EGL_NO_IMAGE_KHR)
-        return FALSE;
-
-    /* EGL_EXT_image_dma_buf_import can impose restrictions on the
-     * usage of the image. Use gbm_bo to bypass the limitations. */
-    bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
-    eglDestroyImageKHR(glamor_egl->display, image);
-
+    import_data.fd = fd;
+    import_data.width = width;
+    import_data.height = height;
+    import_data.stride = stride;
+    import_data.format = GBM_FORMAT_ARGB8888;
+    bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD, &import_data, 0);
     if (!bo)
         return FALSE;
 
@@ -879,8 +858,6 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 #ifdef GLAMOR_HAS_GBM
     if (epoxy_has_egl_extension(glamor_egl->display,
                                 "EGL_KHR_gl_texture_2D_image") &&
-        epoxy_has_egl_extension(glamor_egl->display,
-                                "EGL_EXT_image_dma_buf_import") &&
         epoxy_has_gl_extension("GL_OES_EGL_image"))
         glamor_egl->dri3_capable = TRUE;
 #endif
commit fba0d8a3c9deff557f8a9735fc907556e4e861aa
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan 20 12:33:25 2016 -0800

    glamor: Drop duplicated GLAMOR_DEFAULT_PRECISIONs in render accel.
    
    We only need it once at the top of the shader, so just put it
    there.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit 5042b0652b9fe5fed57a233880c3429ba390d86d)

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index e563e40..4e66f6d 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -72,7 +72,6 @@ glamor_create_composite_fs(struct shader_key *key)
         "uniform int 			source_repeat_mode;\n"
         "uniform int 			mask_repeat_mode;\n";
     const char *relocate_texture =
-        GLAMOR_DEFAULT_PRECISION
         "vec2 rel_tex_coord(vec2 texture, vec4 wh, int repeat) \n"
         "{\n"
         "   vec2 rel_tex; \n"
@@ -119,14 +118,12 @@ glamor_create_composite_fs(struct shader_key *key)
         "}\n";
 
     const char *source_solid_fetch =
-        GLAMOR_DEFAULT_PRECISION
         "uniform vec4 source;\n"
         "vec4 get_source()\n"
         "{\n"
         "	return source;\n"
         "}\n";
     const char *source_alpha_pixmap_fetch =
-        GLAMOR_DEFAULT_PRECISION
         "varying vec2 source_texture;\n"
         "uniform sampler2D source_sampler;\n"
         "uniform vec4 source_wh;"
@@ -139,7 +136,6 @@ glamor_create_composite_fs(struct shader_key *key)
         "				   source_wh, source_repeat_mode, 0);\n"
         "}\n";
     const char *source_pixmap_fetch =
-        GLAMOR_DEFAULT_PRECISION
         "varying vec2 source_texture;\n"
         "uniform sampler2D source_sampler;\n"
         "uniform vec4 source_wh;\n"
@@ -152,14 +148,12 @@ glamor_create_composite_fs(struct shader_key *key)
         "				   source_wh, source_repeat_mode, 1);\n"
         "}\n";
     const char *mask_solid_fetch =
-        GLAMOR_DEFAULT_PRECISION
         "uniform vec4 mask;\n"
         "vec4 get_mask()\n"
         "{\n"
         "	return mask;\n"
         "}\n";
     const char *mask_alpha_pixmap_fetch =
-        GLAMOR_DEFAULT_PRECISION
         "varying vec2 mask_texture;\n"
         "uniform sampler2D mask_sampler;\n"
         "uniform vec4 mask_wh;\n"
@@ -172,7 +166,6 @@ glamor_create_composite_fs(struct shader_key *key)
         "				   mask_wh, mask_repeat_mode, 0);\n"
         "}\n";
     const char *mask_pixmap_fetch =
-        GLAMOR_DEFAULT_PRECISION
         "varying vec2 mask_texture;\n"
         "uniform sampler2D mask_sampler;\n"
         "uniform vec4 mask_wh;\n"
@@ -185,31 +178,26 @@ glamor_create_composite_fs(struct shader_key *key)
         "				   mask_wh, mask_repeat_mode, 1);\n"
         "}\n";
     const char *in_source_only =
-        GLAMOR_DEFAULT_PRECISION
         "void main()\n"
         "{\n"
         "	gl_FragColor = get_source();\n"
         "}\n";
     const char *in_normal =
-        GLAMOR_DEFAULT_PRECISION
         "void main()\n"
         "{\n"
         "	gl_FragColor = get_source() * get_mask().a;\n"
         "}\n";
     const char *in_ca_source =
-        GLAMOR_DEFAULT_PRECISION
         "void main()\n"
         "{\n"
         "	gl_FragColor = get_source() * get_mask();\n"
         "}\n";
     const char *in_ca_alpha =
-        GLAMOR_DEFAULT_PRECISION
         "void main()\n"
         "{\n"
         "	gl_FragColor = get_source().a * get_mask();\n"
         "}\n";
     const char *in_ca_dual_blend =
-        GLAMOR_DEFAULT_PRECISION
         "out vec4 color0;\n"
         "out vec4 color1;\n"
         "void main()\n"
@@ -280,7 +268,10 @@ glamor_create_composite_fs(struct shader_key *key)
         FatalError("Bad composite IN type");
     }
 
-    XNFasprintf(&source, "%s%s%s%s%s%s%s", header, repeat_define, relocate_texture,
+    XNFasprintf(&source,
+                "%s"
+                GLAMOR_DEFAULT_PRECISION
+                "%s%s%s%s%s%s", header, repeat_define, relocate_texture,
                 rel_sampler, source_fetch, mask_fetch, in);
 
     prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
commit 389761e592184d78969469914d1aba5d281824fd
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Jan 12 18:13:46 2016 +1000

    glamor: Add support for CA rendering in a single pass.
    
    It's been on the list to add dual source blending support to avoid the
    two pass componentAlpha code.  Radeon has done this for a while in
    EXA, so let's add support to bring glamor up to using it.
    
    This adds dual blend to both render and composite glyphs paths.
    
    Initial results show close to doubling of speed of x11perf -rgb10text.
    
    v2: Fix breakage of all of CA acceleration for systems without
        GL_ARB_blend_func_extended.  Add CA support for all the ops we
        support in non-CA mode when blend_func_extended is present.  Clean
        up some comments and formatting.  (changes by anholt)
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    (cherry picked from commit e7308b6c77561df44c04f81509f8ada678705d94)

diff --git a/glamor/glamor.c b/glamor/glamor.c
index c097732..74692e0 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -581,6 +581,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         epoxy_has_gl_extension("GL_NV_pack_subimage");
     glamor_priv->has_vertex_array_object =
         epoxy_has_gl_extension("GL_ARB_vertex_array_object");
+    glamor_priv->has_dual_blend =
+        epoxy_has_gl_extension("GL_ARB_blend_func_extended");
 
     glamor_setup_debug_output(screen);
 
diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c
index 8692904..2e4dfe2 100644
--- a/glamor/glamor_composite_glyphs.c
+++ b/glamor/glamor_composite_glyphs.c
@@ -186,7 +186,9 @@ static const glamor_facet glamor_facet_composite_glyphs_130 = {
     .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_vars = ("varying vec2 glyph_pos;\n"
+                "out vec4 color0;\n"
+                "out vec4 color1;\n"),
     .fs_exec = ("       vec4 mask = texture2D(atlas, glyph_pos);\n"),
     .source_name = "source",
     .locations = glamor_program_location_atlas,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 8ed53e7..e49aee5 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -86,6 +86,12 @@ typedef struct glamor_composite_shader {
     };
 } glamor_composite_shader;
 
+enum ca_state {
+    CA_NONE,
+    CA_TWO_PASS,
+    CA_DUAL_BLEND,
+};
+
 enum shader_source {
     SHADER_SOURCE_SOLID,
     SHADER_SOURCE_TEXTURE,
@@ -106,6 +112,7 @@ enum shader_in {
     SHADER_IN_NORMAL,
     SHADER_IN_CA_SOURCE,
     SHADER_IN_CA_ALPHA,
+    SHADER_IN_CA_DUAL_BLEND,
     SHADER_IN_COUNT,
 };
 
@@ -202,6 +209,7 @@ typedef struct glamor_screen_private {
     Bool has_rw_pbo;
     Bool use_quads;
     Bool has_vertex_array_object;
+    Bool has_dual_blend;
     int max_fbo_size;
 
     struct xorg_list
diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index 416c54a..ddab16f 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -344,6 +344,10 @@ glamor_build_program(ScreenPtr          screen,
 #endif
         glBindAttribLocation(prog->prog, GLAMOR_VERTEX_SOURCE, prim->source_name);
     }
+    if (prog->alpha == glamor_program_alpha_dual_blend) {
+        glBindFragDataLocationIndexed(prog->prog, 0, 0, "color0");
+        glBindFragDataLocationIndexed(prog->prog, 0, 1, "color1");
+    }
 
     glamor_link_glsl_prog(screen, prog->prog, "%s_%s", prim->name, fill->name);
 
@@ -474,11 +478,24 @@ glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst)
     }
 
     /* 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)
+    if (alpha == glamor_program_alpha_dual_blend) {
+        switch (dst_blend) {
+        case GL_SRC_ALPHA:
+            dst_blend = GL_SRC1_COLOR;
+            break;
+        case GL_ONE_MINUS_SRC_ALPHA:
+            dst_blend = GL_ONE_MINUS_SRC1_COLOR;
+            break;
+        }
+    } else if (alpha != glamor_program_alpha_normal) {
+        switch (dst_blend) {
+        case GL_SRC_ALPHA:
             dst_blend = GL_SRC_COLOR;
-        else if (dst_blend == GL_ONE_MINUS_SRC_ALPHA)
+            break;
+        case GL_ONE_MINUS_SRC_ALPHA:
             dst_blend = GL_ONE_MINUS_SRC_COLOR;
+            break;
+        }
     }
 
     glEnable(GL_BLEND);
@@ -547,7 +564,9 @@ static const glamor_facet *glamor_facet_source[glamor_program_source_count] = {
 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"
+    [glamor_program_alpha_ca_second] = "       gl_FragColor = source * mask;\n",
+    [glamor_program_alpha_dual_blend] = "      color0 = source * mask;\n"
+                                        "      color1 = source.a * mask;\n"
 };
 
 static Bool
@@ -567,9 +586,9 @@ glamor_setup_one_program_render(ScreenPtr               screen,
         if (!fill)
             return FALSE;
 
+        prog->alpha = alpha;
         if (!glamor_build_program(screen, prog, prim, fill, glamor_combine[alpha], defines))
             return FALSE;
-        prog->alpha = alpha;
     }
 
     return TRUE;
@@ -585,6 +604,7 @@ glamor_setup_program_render(CARD8                 op,
                             const char            *defines)
 {
     ScreenPtr                   screen = dst->pDrawable->pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     glamor_program_alpha        alpha;
     glamor_program_source       source_type;
     glamor_program              *prog;
@@ -593,10 +613,15 @@ glamor_setup_program_render(CARD8                 op,
         return NULL;
 
     if (glamor_is_component_alpha(mask)) {
-        /* This only works for PictOpOver */
-        if (op != PictOpOver)
-            return NULL;
-        alpha = glamor_program_alpha_ca_first;
+        if (glamor_priv->has_dual_blend) {
+            alpha = glamor_program_alpha_dual_blend;
+        } else {
+            /* This only works for PictOpOver */
+            if (op != PictOpOver)
+                return NULL;
+
+            alpha = glamor_program_alpha_ca_first;
+        }
     } else
         alpha = glamor_program_alpha_normal;
 
diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h
index 9e561cd..ab6e46f 100644
--- a/glamor/glamor_program.h
+++ b/glamor/glamor_program.h
@@ -43,6 +43,7 @@ typedef enum {
     glamor_program_alpha_normal,
     glamor_program_alpha_ca_first,
     glamor_program_alpha_ca_second,
+    glamor_program_alpha_dual_blend,
     glamor_program_alpha_count
 } glamor_program_alpha;
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 1b226aa..e563e40 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -208,10 +208,24 @@ glamor_create_composite_fs(struct shader_key *key)
         "{\n"
         "	gl_FragColor = get_source().a * get_mask();\n"
         "}\n";
+    const char *in_ca_dual_blend =
+        GLAMOR_DEFAULT_PRECISION
+        "out vec4 color0;\n"
+        "out vec4 color1;\n"
+        "void main()\n"
+        "{\n"
+        "	color0 = get_source() * get_mask();\n"
+        "	color1 = get_source().a * get_mask();\n"
+        "}\n";
+    const char *header_ca_dual_blend =
+        "#version 130\n";
+
     char *source;
     const char *source_fetch;
     const char *mask_fetch = "";
     const char *in;
+    const char *header;
+    const char *header_norm = "";
     GLuint prog;
 
     switch (key->source) {
@@ -244,6 +258,7 @@ glamor_create_composite_fs(struct shader_key *key)
         FatalError("Bad composite shader mask");
     }
 
+    header = header_norm;
     switch (key->in) {
     case SHADER_IN_SOURCE_ONLY:
         in = in_source_only;
@@ -257,11 +272,15 @@ glamor_create_composite_fs(struct shader_key *key)
     case SHADER_IN_CA_ALPHA:
         in = in_ca_alpha;
         break;
+    case SHADER_IN_CA_DUAL_BLEND:
+        in = in_ca_dual_blend;
+        header = header_ca_dual_blend;
+        break;
     default:
         FatalError("Bad composite IN type");
     }
 
-    XNFasprintf(&source, "%s%s%s%s%s%s", repeat_define, relocate_texture,
+    XNFasprintf(&source, "%s%s%s%s%s%s%s", header, repeat_define, relocate_texture,
                 rel_sampler, source_fetch, mask_fetch, in);
 
     prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
@@ -331,6 +350,10 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
     glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
     glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
 
+    if (key->in == SHADER_IN_CA_DUAL_BLEND) {
+        glBindFragDataLocationIndexed(prog, 0, 0, "color0");
+        glBindFragDataLocationIndexed(prog, 0, 1, "color1");
+    }
     glamor_link_glsl_prog(screen, prog, "composite");
 
     shader->prog = prog;
@@ -382,7 +405,8 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct
 static Bool
 glamor_set_composite_op(ScreenPtr screen,
                         CARD8 op, struct blendinfo *op_info_result,
-                        PicturePtr dest, PicturePtr mask)
+                        PicturePtr dest, PicturePtr mask,
+                        enum ca_state ca_state)
 {
     GLenum source_blend, dest_blend;
     struct blendinfo *op_info;
@@ -391,6 +415,7 @@ glamor_set_composite_op(ScreenPtr screen,
         glamor_fallback("unsupported render op %d \n", op);
         return GL_FALSE;
     }
+
     op_info = &composite_op_info[op];
 
     source_blend = op_info->source_blend;
@@ -407,12 +432,25 @@ glamor_set_composite_op(ScreenPtr screen,
     }
 
     /* Set up the source alpha value for blending in component alpha mode. */
-    if (mask && mask->componentAlpha
-        && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha) {
-        if (dest_blend == GL_SRC_ALPHA)
+    if (ca_state == CA_DUAL_BLEND) {
+        switch (dest_blend) {
+        case GL_SRC_ALPHA:
+            dest_blend = GL_SRC1_COLOR;
+            break;
+        case GL_ONE_MINUS_SRC_ALPHA:
+            dest_blend = GL_ONE_MINUS_SRC1_COLOR;
+            break;
+        }
+    } else if (mask && mask->componentAlpha
+               && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha) {
+        switch (dest_blend) {
+        case GL_SRC_ALPHA:
             dest_blend = GL_SRC_COLOR;
-        else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA)
+            break;
+        case GL_ONE_MINUS_SRC_ALPHA:
             dest_blend = GL_ONE_MINUS_SRC_COLOR;
+            break;
+        }
     }
 
     op_info_result->source_blend = source_blend;
@@ -623,6 +661,10 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
         src_type = PICT_TYPE_A;
         mask_type = PICT_FORMAT_TYPE(mask);
         break;
+    case SHADER_IN_CA_DUAL_BLEND:
+        src_type = PICT_FORMAT_TYPE(src);
+        mask_type = PICT_FORMAT_TYPE(mask);
+        break;
     default:
         return FALSE;
     }
@@ -715,9 +757,11 @@ glamor_composite_choose_shader(CARD8 op,
                                struct shader_key *s_key,
                                glamor_composite_shader ** shader,
                                struct blendinfo *op_info,
-                               PictFormatShort *psaved_source_format)
+                               PictFormatShort *psaved_source_format,
+                               enum ca_state ca_state)
 {
     ScreenPtr screen = dest->pDrawable->pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     enum glamor_pixmap_status source_status = GLAMOR_NONE;
     enum glamor_pixmap_status mask_status = GLAMOR_NONE;
     PictFormatShort saved_source_format = 0;
@@ -786,6 +830,8 @@ glamor_composite_choose_shader(CARD8 op,
         else {
             if (op == PictOpClear)
                 key.mask = SHADER_MASK_NONE;
+            else if (glamor_priv->has_dual_blend)
+                key.in = SHADER_IN_CA_DUAL_BLEND;
             else if (op == PictOpSrc || op == PictOpAdd
                      || op == PictOpIn || op == PictOpOut
                      || op == PictOpOverReverse)
@@ -933,7 +979,7 @@ glamor_composite_choose_shader(CARD8 op,
         goto fail;
     }
 
-    if (!glamor_set_composite_op(screen, op, op_info, dest, mask))
+    if (!glamor_set_composite_op(screen, op, op_info, dest, mask, ca_state))
         goto fail;
 
     *shader = glamor_lookup_composite_shader(screen, &key);
@@ -1025,7 +1071,7 @@ glamor_composite_with_shader(CARD8 op,
                              glamor_pixmap_private *mask_pixmap_priv,
                              glamor_pixmap_private *dest_pixmap_priv,
                              int nrect, glamor_composite_rect_t *rects,
-                             Bool two_pass_ca)
+                             enum ca_state ca_state)
 {
     ScreenPtr screen = dest->pDrawable->pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
@@ -1048,17 +1094,17 @@ glamor_composite_with_shader(CARD8 op,
                                         source_pixmap_priv, mask_pixmap_priv,
                                         dest_pixmap_priv,
                                         &key, &shader, &op_info,
-                                        &saved_source_format)) {
+                                        &saved_source_format, ca_state)) {
         glamor_fallback("glamor_composite_choose_shader failed\n");
         return ret;
     }
-    if (two_pass_ca) {
+    if (ca_state == CA_TWO_PASS) {
         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,
-                                            &saved_source_format)) {
+                                            &saved_source_format, ca_state)) {
             glamor_fallback("glamor_composite_choose_shader failed\n");
             return ret;
         }
@@ -1173,7 +1219,7 @@ glamor_composite_with_shader(CARD8 op,
         glamor_put_vbo_space(screen);
         glamor_flush_composite_rects(screen);
         nrect -= rect_processed;
-        if (two_pass_ca) {
+        if (ca_state == CA_TWO_PASS) {
             glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv,
                                               &key_ca, shader_ca, &op_info_ca);
             glamor_flush_composite_rects(screen);
@@ -1278,6 +1324,7 @@ glamor_composite_clipped_region(CARD8 op,
     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_screen_private *glamor_priv = glamor_get_screen_private(dest_pixmap->drawable.pScreen);
     ScreenPtr screen = dest->pDrawable->pScreen;
     PicturePtr temp_src = source, temp_mask = mask;
     PixmapPtr temp_src_pixmap = source_pixmap;
@@ -1295,7 +1342,7 @@ glamor_composite_clipped_region(CARD8 op,
     int height;
     BoxPtr box;
     int nbox;
-    Bool two_pass_ca = FALSE;
+    enum ca_state ca_state = CA_NONE;
 
     extent = RegionExtents(region);
     box = RegionRects(region);
@@ -1357,14 +1404,15 @@ glamor_composite_clipped_region(CARD8 op,
         x_temp_mask = -extent->x1 + x_dest + dest->pDrawable->x;
         y_temp_mask = -extent->y1 + y_dest + dest->pDrawable->y;
     }
-    /* Do two-pass PictOpOver componentAlpha, until we enable
-     * dual source color blending.
-     */
 
     if (mask && mask->componentAlpha) {
-        if (op == PictOpOver) {
-            two_pass_ca = TRUE;
-            op = PictOpOutReverse;
+        if (glamor_priv->has_dual_blend) {
+            ca_state = CA_DUAL_BLEND;
+        } else {
+            if (op == PictOpOver) {
+                ca_state = CA_TWO_PASS;
+                op = PictOpOutReverse;
+            }
         }
     }
 
@@ -1416,7 +1464,7 @@ glamor_composite_clipped_region(CARD8 op,
                                           temp_src_pixmap, temp_mask_pixmap, dest_pixmap,
                                           temp_src_priv, temp_mask_priv,
                                           dest_pixmap_priv,
-                                          box_cnt, prect, two_pass_ca);
+                                          box_cnt, prect, ca_state);
         if (!ok)
             break;
         nbox -= box_cnt;
@@ -1477,7 +1525,7 @@ glamor_composite(CARD8 op,
     if (op >= ARRAY_SIZE(composite_op_info))
         goto fail;
 
-    if (mask && mask->componentAlpha) {
+    if (mask && mask->componentAlpha && !glamor_priv->has_dual_blend) {
         if (op == PictOpAtop
             || op == PictOpAtopReverse
             || op == PictOpXor || op >= PictOpSaturate) {
commit 2e79da2dce15b25534ea83eb453cb9b762a2e29f
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jan 21 12:01:02 2016 -0800

    glamor: Drop the composite_with_copy path entirely.
    
    I originally inherited this from the EXA code, without determining
    whether it was really needed.  Regular composite should end up doing
    the same thing, since it's all just shaders anyway.  To the extent
    that it doesn't, we should fix composite.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit cab14a9a08ff06bc4cbef79c7be8f1d07c07ebf9)

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 92b6b0c..1b226aa 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -508,41 +508,6 @@ glamor_set_composite_solid(float *color, GLint uniform_location)
     glUniform4fv(uniform_location, 1, color);
 }
 
-static int
-compatible_formats(CARD8 op, PicturePtr dst, PicturePtr src)
-{
-    if (op == PictOpSrc) {
-        /* We can't do direct copies between different depths at 16bpp
-         * because r,g,b are allocated to different bits.
-         */
-        if (dst->pDrawable->bitsPerPixel == 16 &&
-            dst->pDrawable->depth != src->pDrawable->depth) {
-            return 0;
-        }
-
-        if (src->format == dst->format)
-            return 1;
-
-        if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8)
-            return 1;
-
-        if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8)
-            return 1;
-    }
-    else if (op == PictOpOver) {
-        if (src->alphaMap || dst->alphaMap)
-            return 0;
-
-        if (src->format != dst->format)
-            return 0;
-
-        if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8)
-            return 1;
-    }
-
-    return 0;
-}
-
 static char
 glamor_get_picture_location(PicturePtr picture)
 {
@@ -564,54 +529,6 @@ glamor_get_picture_location(PicturePtr picture)
     return glamor_get_drawable_location(picture->pDrawable);
 }
 
-static Bool
-glamor_composite_with_copy(CARD8 op,
-                           PicturePtr source,
-                           PicturePtr dest,
-                           INT16 x_source,
-                           INT16 y_source,
-                           INT16 x_dest, INT16 y_dest, RegionPtr region)
-{
-    int ret = FALSE;
-
-    if (!source->pDrawable)
-        return FALSE;
-
-    if (!compatible_formats(op, dest, source))
-        return FALSE;
-
-    if (source->repeat || source->transform) {
-        return FALSE;
-    }
-
-    x_dest += dest->pDrawable->x;
-    y_dest += dest->pDrawable->y;
-    x_source += source->pDrawable->x;
-    y_source += source->pDrawable->y;
-    if (PICT_FORMAT_A(source->format) == 0) {
-        /* Fallback if we sample outside the source so that we
-         * swizzle the correct clear color for out-of-bounds texels.
-         */
-        if (region->extents.x1 + x_source - x_dest < 0)
-            goto cleanup_region;
-        if (region->extents.x2 + x_source - x_dest > source->pDrawable->width)
-            goto cleanup_region;
-
-        if (region->extents.y1 + y_source - y_dest < 0)
-            goto cleanup_region;
-        if (region->extents.y2 + y_source - y_dest > source->pDrawable->height)
-            goto cleanup_region;
-    }
-    glamor_copy(source->pDrawable,
-                dest->pDrawable, NULL,
-                RegionRects(region), RegionNumRects(region),
-                x_source - x_dest, y_source - y_dest,
-                FALSE, FALSE, 0, NULL);
-    ret = TRUE;
- cleanup_region:
-    return ret;
-}
-
 static void *
 glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 {
@@ -1451,15 +1368,6 @@ glamor_composite_clipped_region(CARD8 op,
         }
     }
 
-    if (!mask && temp_src) {
-        if (glamor_composite_with_copy(op, temp_src, dest,
-                                       x_temp_src, y_temp_src,
-                                       x_dest, y_dest, region)) {
-            ok = TRUE;
-            goto out;
-        }
-    }
-
     if (temp_src_pixmap == dest_pixmap) {
         glamor_fallback("source and dest pixmaps are the same\n");
         goto out;
commit aad8e4714a2bdeada5c7ae42d2047cf6a4720d19
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Sep 10 16:17:52 2014 -0700

    glamor: Use vertex array objects
    
    Core contexts require the use of vertex array objects, so switch both glamor
    and ephyr/glamor over.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit 49aa5e3ea4eecea0562c05a4e52962985a56e510)

diff --git a/glamor/glamor.c b/glamor/glamor.c
index f2aec46..c097732 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -579,6 +579,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP ||
         epoxy_gl_version() >= 30 ||
         epoxy_has_gl_extension("GL_NV_pack_subimage");
+    glamor_priv->has_vertex_array_object =
+        epoxy_has_gl_extension("GL_ARB_vertex_array_object");
 
     glamor_setup_debug_output(screen);
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index a190e67..8ed53e7 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -201,6 +201,7 @@ typedef struct glamor_screen_private {
     Bool has_unpack_subimage;
     Bool has_rw_pbo;
     Bool use_quads;
+    Bool has_vertex_array_object;
     int max_fbo_size;
 
     struct xorg_list
@@ -247,6 +248,7 @@ typedef struct glamor_screen_private {
     char                        *glyph_defines;
 
     /** Vertex buffer for all GPU rendering. */
+    GLuint vao;
     GLuint vbo;
     /** Next offset within the VBO that glamor_get_vbo_space() will use. */
     int vbo_offset;
diff --git a/glamor/glamor_vbo.c b/glamor/glamor_vbo.c
index ba60ce6..b8db009 100644
--- a/glamor/glamor_vbo.c
+++ b/glamor/glamor_vbo.c
@@ -174,6 +174,11 @@ glamor_init_vbo(ScreenPtr screen)
     glamor_make_current(glamor_priv);
 
     glGenBuffers(1, &glamor_priv->vbo);
+    if (glamor_priv->has_vertex_array_object) {
+        glGenVertexArrays(1, &glamor_priv->vao);
+        glBindVertexArray(glamor_priv->vao);
+    } else
+        glamor_priv->vao = 0;
 }
 
 void
@@ -183,6 +188,10 @@ glamor_fini_vbo(ScreenPtr screen)
 
     glamor_make_current(glamor_priv);
 
+    if (glamor_priv->vao != 0) {
+        glDeleteVertexArrays(1, &glamor_priv->vao);
+        glamor_priv->vao = 0;
+    }
     if (!glamor_priv->has_map_buffer_range)
         free(glamor_priv->vb);
 }
diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c
index 582e3af..30c5245 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -71,6 +71,8 @@ struct ephyr_glamor {
 
     /* Size of the window that we're rendering to. */
     unsigned width, height;
+
+    GLuint vao, vbo;
 };
 
 static GLint
@@ -189,47 +191,53 @@ ephyr_glamor_set_texture(struct ephyr_glamor *glamor, uint32_t tex)
     glamor->tex = tex;
 }
 
+static void
+ephyr_glamor_set_vertices(struct ephyr_glamor *glamor)
+{
+    glVertexAttribPointer(glamor->texture_shader_position_loc,
+                          2, GL_FLOAT, FALSE, 0, (void *) 0);
+    glVertexAttribPointer(glamor->texture_shader_texcoord_loc,
+                          2, GL_FLOAT, FALSE, 0, (void *) (sizeof (float) * 8));
+
+    glEnableVertexAttribArray(glamor->texture_shader_position_loc);
+    glEnableVertexAttribArray(glamor->texture_shader_texcoord_loc);
+}
+
+static void
+ephyr_glamor_clear_vertices(struct ephyr_glamor *glamor)
+{
+    glDisableVertexAttribArray(glamor->texture_shader_position_loc);
+    glDisableVertexAttribArray(glamor->texture_shader_texcoord_loc);
+}
+
 void
 ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
                               struct pixman_region16 *damage)
 {
-    /* Redraw the whole screen, since glXSwapBuffers leaves the back
-     * buffer undefined.
-     */
-    static const float position[] = {
-        -1, -1,
-         1, -1,
-         1,  1,
-        -1,  1,
-    };
-    static const float texcoords[] = {
-        0, 1,
-        1, 1,
-        1, 0,
-        0, 0,
-    };
+    GLint old_vao;
 
     glXMakeCurrent(dpy, glamor->glx_win, glamor->ctx);
 
+    if (glamor->vao) {
+        glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao);
+        glBindVertexArray(glamor->vao);
+    } else
+        ephyr_glamor_set_vertices(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);
-    glVertexAttribPointer(glamor->texture_shader_texcoord_loc,
-                          2, GL_FLOAT, FALSE, 0, texcoords);
-    glEnableVertexAttribArray(glamor->texture_shader_position_loc);
-    glEnableVertexAttribArray(glamor->texture_shader_texcoord_loc);
-
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, glamor->tex);
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
-    glDisableVertexAttribArray(glamor->texture_shader_position_loc);
-    glDisableVertexAttribArray(glamor->texture_shader_texcoord_loc);
+    if (glamor->vao)
+        glBindVertexArray(old_vao);
+    else
+        ephyr_glamor_clear_vertices(glamor);
 
     glXSwapBuffers(dpy, glamor->glx_win);
 }
@@ -271,6 +279,18 @@ ephyr_glamor_process_event(xcb_generic_event_t *xev)
 struct ephyr_glamor *
 ephyr_glamor_glx_screen_init(xcb_window_t win)
 {
+    static const float position[] = {
+        -1, -1,
+         1, -1,
+         1,  1,
+        -1,  1,
+        0, 1,
+        1, 1,
+        1, 0,
+        0, 0,
+    };
+    GLint old_vao;
+
     GLXContext ctx;
     struct ephyr_glamor *glamor;
     GLXWindow glx_win;
@@ -312,6 +332,24 @@ ephyr_glamor_glx_screen_init(xcb_window_t win)
     glamor->glx_win = glx_win;
     ephyr_glamor_setup_texturing_shader(glamor);
 
+    if (epoxy_has_gl_extension("GL_ARB_vertex_array_object")) {
+        glGenVertexArrays(1, &glamor->vao);
+        glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao);
+        glBindVertexArray(glamor->vao);
+    } else
+        glamor->vao = 0;
+
+    glGenBuffers(1, &glamor->vbo);
+
+    glBindBuffer(GL_ARRAY_BUFFER, glamor->vbo);
+    glBufferData(GL_ARRAY_BUFFER, sizeof (position), position, GL_STATIC_DRAW);
+
+    if (glamor->vao) {
+        ephyr_glamor_set_vertices(glamor);
+        glBindVertexArray(old_vao);
+    } else
+        glBindBuffer(GL_ARRAY_BUFFER, 0);
+
     return glamor;
 }
 
commit 6691f523332a5993d3e90e16d8edff7f3b85c4ae
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Jan 19 10:34:14 2016 +1000

    glamor/xv: add vbo support (v2.1)
    
    This converts the Xv code to using VBOs instead of
    client ptrs. This is necessary to move towards using
    the core profile later.
    
    v2: put all boxes into single vbo, use draw arrays
    to offset things. (Eric)
    v2.1: brown paper bag with releasing vbo.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit d99204fb5e09ce7be36485d4226f7ad6d6eb24cc)

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 85e6528..6e1a588 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -245,7 +245,6 @@ glamor_xv_render(glamor_port_private *port_priv)
     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);
     int nBox = REGION_NUM_RECTS(&port_priv->clip);
     int dst_x_off, dst_y_off;
@@ -260,6 +259,8 @@ glamor_xv_render(glamor_port_private *port_priv)
     float bright, cont, gamma;
     int ref = port_priv->transform_index;
     GLint uloc, sampler_loc;
+    GLfloat *v;
+    char *vbo_offset;
 
     if (!glamor_priv->xv_prog)
         glamor_init_xv_shader(screen);
@@ -335,16 +336,13 @@ glamor_xv_render(glamor_port_private *port_priv)
     sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "v_sampler");
     glUniform1i(sampler_loc, 2);
 
-    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
-                          GL_FLOAT, GL_FALSE,
-                          2 * sizeof(float), texcoords);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                          GL_FALSE, 2 * sizeof(float), vertices);
-
-    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
     glEnable(GL_SCISSOR_TEST);
+
+    v = glamor_get_vbo_space(screen, 16 * sizeof(GLfloat) * nBox, &vbo_offset);
+
     for (i = 0; i < nBox; i++) {
         float off_x = box[i].x1 - port_priv->drw_x;
         float off_y = box[i].y1 - port_priv->drw_y;
@@ -352,6 +350,8 @@ glamor_xv_render(glamor_port_private *port_priv)
         float diff_y = (float) port_priv->src_h / (float) port_priv->dst_h;
         float srcx, srcy, srcw, srch;
         int dstx, dsty, dstw, dsth;
+        GLfloat *vptr = v + (i * 8);
+        GLfloat *tptr = vptr + (8 * nBox);
 
         dstx = box[i].x1 + dst_x_off;
         dsty = box[i].y1 + dst_y_off;
@@ -369,7 +369,7 @@ glamor_xv_render(glamor_port_private *port_priv)
                                      dsty,
                                      dstx + dstw,
                                      dsty + dsth * 2,
-                                     vertices);
+                                     vptr);
 
         glamor_set_normalize_tcoords(src_pixmap_priv[0],
                                      src_xscale[0],
@@ -378,10 +378,29 @@ glamor_xv_render(glamor_port_private *port_priv)
                                      srcy,
                                      srcx + srcw,
                                      srcy + srch * 2,
-                                     texcoords);
+                                     tptr);
+    }
+
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2,
+                          GL_FLOAT, GL_FALSE,
+                          2 * sizeof(float), vbo_offset);
+
+    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+                          GL_FLOAT, GL_FALSE,
+                          2 * sizeof(float), vbo_offset + (nBox * 8 * sizeof(GLfloat)));
+
+    glamor_put_vbo_space(screen);
+
+    for (i = 0; i < nBox; i++) {
+        int dstx, dsty, dstw, dsth;
+
+        dstx = box[i].x1 + dst_x_off;
+        dsty = box[i].y1 + dst_y_off;
+        dstw = box[i].x2 - box[i].x1;
+        dsth = box[i].y2 - box[i].y1;
 
         glScissor(dstx, dsty, dstw, dsth);
-        glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
+        glDrawArrays(GL_TRIANGLE_FAN, i * 4, 3);
     }
     glDisable(GL_SCISSOR_TEST);
 
commit eabe0e0b3685b5ab38c3597f238e92a3e4598441
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Jan 11 14:00:04 2016 +1000

    glamor: use vbos in gradient/picture code.
    
    This converts two client arrays users to using vbos,
    this is necessary to move to using core profile later.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit 5582ad1b9b29934498cf3fef305d3a988130cd52)

diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 30c29f6..c50542a 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -647,12 +647,12 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
                                         PicturePtr dst_picture,
                                         GLfloat *xscale, GLfloat *yscale,
                                         int x_source, int y_source,
-                                        float vertices[8],
-                                        float tex_vertices[8],
                                         int tex_normalize)
 {
     glamor_pixmap_private *pixmap_priv;
     PixmapPtr pixmap = NULL;
+    GLfloat *v;
+    char *vbo_offset;
 
     pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable);
     pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -670,13 +670,15 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
            *xscale, *yscale, x_source, y_source,
            dst_picture->pDrawable->width, dst_picture->pDrawable->height);
 
+    v = glamor_get_vbo_space(screen, 16 * sizeof(GLfloat), &vbo_offset);
+
     glamor_set_normalize_vcoords_tri_strip(*xscale, *yscale,
                                            0, 0,
                                            (INT16) (dst_picture->pDrawable->
                                                     width),
                                            (INT16) (dst_picture->pDrawable->
                                                     height),
-                                           vertices);
+                                           v);
 
     if (tex_normalize) {
         glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale,
@@ -687,7 +689,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
                                                 (INT16) (dst_picture->
                                                          pDrawable->height +
                                                          y_source),
-                                                tex_vertices);
+                                                &v[8]);
     }
     else {
         glamor_set_tcoords_tri_strip(x_source, y_source,
@@ -695,28 +697,29 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
                                      x_source,
                                      (INT16) (dst_picture->pDrawable->height) +
                                      y_source,
-                                     tex_vertices);
+                                     &v[8]);
     }
 
     DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
            "rightbottom: %f X %f, leftbottom : %f X %f\n",
-           vertices[0], vertices[1], vertices[2], vertices[3],
-           vertices[4], vertices[5], vertices[6], vertices[7]);
+           v[0], v[1], v[2], v[3],
+           v[4], v[5], v[6], v[7]);
     DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
            "rightbottom: %f X %f, leftbottom : %f X %f\n",
-           tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
-           tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
+           v[8], v[9], v[10], v[11],
+           v[12], v[13], v[14], v[15]);
 
     glamor_make_current(glamor_priv);
 
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                          GL_FALSE, 0, vertices);
+                          GL_FALSE, 0, vbo_offset);
     glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-                          GL_FALSE, 0, tex_vertices);
+                          GL_FALSE, 0, vbo_offset + 8 * sizeof(GLfloat));
 
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
+    glamor_put_vbo_space(screen);
     return 1;
 }
 
@@ -812,13 +815,11 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
     PixmapPtr pixmap = NULL;
     GLint gradient_prog = 0;
     int error;
-    float tex_vertices[8];
     int stops_count = 0;
     int count = 0;
     GLfloat *stop_colors = NULL;
     GLfloat *n_stops = NULL;
     GLfloat xscale, yscale;
-    float vertices[8];
     float transform_mat[3][3];
     static const float identity_mat[3][3] = { {1.0, 0.0, 0.0},
     {0.0, 1.0, 0.0},
@@ -969,7 +970,7 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
 
     if (!_glamor_gradient_set_pixmap_destination
         (screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source,
-         vertices, tex_vertices, 0))
+         0))
         goto GRADIENT_FAIL;
 
     glamor_set_alu(screen, GXcopy);
@@ -1123,7 +1124,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
     float pt_distance;
     float p1_distance;
     GLfloat cos_val;
-    float tex_vertices[8];
     int stops_count = 0;
     GLfloat *stop_colors = NULL;
     GLfloat *n_stops = NULL;
@@ -1131,7 +1131,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
     float slope;
     GLfloat xscale, yscale;
     GLfloat pt1[2], pt2[2];
-    float vertices[8];
     float transform_mat[3][3];
     static const float identity_mat[3][3] = { {1.0, 0.0, 0.0},
     {0.0, 1.0, 0.0},
@@ -1287,7 +1286,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
 
     if (!_glamor_gradient_set_pixmap_destination
         (screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source,
-         vertices, tex_vertices, 1))
+         1))
         goto GRADIENT_FAIL;
 
     glamor_set_alu(screen, GXcopy);
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index d6f37cf..352858f 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -597,14 +597,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(pixmap->drawable.pScreen);
-    static float vertices[8];
-
-    static float texcoords_inv[8] = { 0, 0,
-        1, 0,
-        1, 1,
-        0, 1
-    };
-    float *ptexcoords;
     float dst_xscale, dst_yscale;
     GLuint tex = 0;
     int need_free_bits = 0;
@@ -666,14 +658,22 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
             return FALSE;
         }
     } else {
-        ptexcoords = texcoords_inv;
+        static const float texcoords_inv[8] = { 0, 0,
+                                                1, 0,
+                                                1, 1,
+                                                0, 1
+        };
+        GLfloat *v;
+        char *vbo_offset;
+
+        v = glamor_get_vbo_space(screen, 16 * sizeof(GLfloat), &vbo_offset);
 
         pixmap_priv_get_dest_scale(pixmap, pixmap_priv, &dst_xscale, &dst_yscale);
         glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
                                      dst_yscale,
                                      x, y,
                                      x + w, y + h,
-                                     vertices);
+                                     v);
         /* Slow path, we need to flip y or wire alpha to 1. */
         glamor_make_current(glamor_priv);
 
@@ -685,13 +685,16 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
             return FALSE;
         }
 
+        memcpy(&v[8], texcoords_inv, 8 * sizeof(GLfloat));
+
         glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                              GL_FALSE, 2 * sizeof(float), vertices);
+                              GL_FALSE, 2 * sizeof(float), vbo_offset);
         glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
         glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-                              GL_FALSE, 2 * sizeof(float), ptexcoords);
+                              GL_FALSE, 2 * sizeof(float), vbo_offset + 8 * sizeof(GLfloat));
         glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
+        glamor_put_vbo_space(screen);
         glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
         glamor_set_alu(screen, GXcopy);
         glActiveTexture(GL_TEXTURE0);


More information about the xorg-commit mailing list