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

Jeremy Huddleston jeremyhu at freedesktop.org
Wed May 4 00:15:05 PDT 2016


 Xext/Makefile.am                                 |    7 
 Xext/panoramiXprocs.c                            |    4 
 Xext/saver.c                                     |    2 
 Xext/security.c                                  |    2 
 Xext/sync.c                                      |   21 
 Xext/vidmode.c                                   | 2151 ++++++++++++++++++++
 Xext/xace.h                                      |    2 
 Xext/xselinux_hooks.c                            |   18 
 Xext/xvmain.c                                    |   11 
 Xext/xvmc.c                                      |   17 
 Xi/exevents.c                                    |    7 
 autogen.sh                                       |    3 
 config/dbus-core.c                               |   16 
 config/hal.c                                     |    4 
 config/udev.c                                    |   53 
 config/wscons.c                                  |    2 
 configure.ac                                     |   84 
 dix/devices.c                                    |    3 
 dix/dispatch.c                                   |   17 
 dix/dixfonts.c                                   |    2 
 dix/dixutils.c                                   |   22 
 dix/getevents.c                                  |   29 
 dix/inpututils.c                                 |    4 
 dix/main.c                                       |    6 
 dix/pixmap.c                                     |   21 
 dix/property.c                                   |    8 
 dix/ptrveloc.c                                   |   48 
 dix/window.c                                     |  158 +
 dri3/dri3_request.c                              |    8 
 dri3/dri3int.h                                   |   26 
 exa/Makefile.am                                  |    4 
 glamor/Makefile.am                               |    6 
 glamor/glamor.c                                  |   60 
 glamor/glamor.h                                  |   25 
 glamor/glamor_composite_glyphs.c                 |   23 
 glamor/glamor_compositerects.c                   |   18 
 glamor/glamor_copy.c                             |   18 
 glamor/glamor_core.c                             |  190 -
 glamor/glamor_dash.c                             |    6 
 glamor/glamor_egl.c                              |  306 +-
 glamor/glamor_egl_stubs.c                        |   11 
 glamor/glamor_fbo.c                              |   66 
 glamor/glamor_font.c                             |   35 
 glamor/glamor_font.h                             |    2 
 glamor/glamor_glyphblt.c                         |   12 
 glamor/glamor_gradient.c                         |   33 
 glamor/glamor_lines.c                            |    6 
 glamor/glamor_picture.c                          |  979 ++-------
 glamor/glamor_points.c                           |    7 
 glamor/glamor_priv.h                             |   81 
 glamor/glamor_program.c                          |   49 
 glamor/glamor_program.h                          |    1 
 glamor/glamor_rects.c                            |    7 
 glamor/glamor_render.c                           |  470 ++--
 glamor/glamor_segs.c                             |    6 
 glamor/glamor_spans.c                            |   23 
 glamor/glamor_text.c                             |   18 
 glamor/glamor_transfer.c                         |   18 
 glamor/glamor_transform.c                        |   23 
 glamor/glamor_transform.h                        |   15 
 glamor/glamor_utils.h                            |   63 
 glamor/glamor_vbo.c                              |   25 
 glamor/glamor_xv.c                               |  224 +-
 glx/createcontext.c                              |   31 
 glx/extension_string.c                           |    8 
 glx/extension_string.h                           |    4 
 glx/glxcmds.c                                    |   81 
 glx/glxdri2.c                                    |   91 
 glx/glxdriswrast.c                               |   42 
 glx/glxext.c                                     |    2 
 glx/glxscreens.c                                 |   44 
 glx/glxscreens.h                                 |   16 
 hw/dmx/config/dmxcompat.c                        |    2 
 hw/dmx/config/dmxconfig.c                        |    2 
 hw/dmx/config/dmxparse.h                         |    2 
 hw/dmx/config/dmxtodmx.c                         |    1 
 hw/dmx/config/parser.y                           |    1 
 hw/dmx/config/scanner.l                          |    6 
 hw/dmx/config/xdmxconfig.c                       |    1 
 hw/dmx/doxygen/doxygen.conf.in                   | 2429 +++++++++++++++--------
 hw/dmx/glxProxy/glxcmds.c                        |    5 
 hw/dmx/glxProxy/glxsingle.c                      |    5 
 hw/dmx/glxProxy/render2swap.c                    |   34 
 hw/dmx/glxProxy/renderpixswap.c                  |    3 
 hw/kdrive/ephyr/Makefile.am                      |   14 
 hw/kdrive/ephyr/ephyr.c                          |  110 -
 hw/kdrive/ephyr/ephyr.h                          |    3 
 hw/kdrive/ephyr/ephyr_glamor_glx.c               |  122 -
 hw/kdrive/ephyr/ephyrdri.c                       |  356 ---
 hw/kdrive/ephyr/ephyrdri.h                       |   70 
 hw/kdrive/ephyr/ephyrdriext.c                    | 1376 -------------
 hw/kdrive/ephyr/ephyrdriext.h                    |   40 
 hw/kdrive/ephyr/ephyrglxext.c                    |  854 --------
 hw/kdrive/ephyr/ephyrglxext.h                    |   34 
 hw/kdrive/ephyr/ephyrhostglx.c                   |  490 ----
 hw/kdrive/ephyr/ephyrhostglx.h                   |   75 
 hw/kdrive/ephyr/ephyrinit.c                      |   58 
 hw/kdrive/ephyr/hostx.c                          |  215 +-
 hw/kdrive/ephyr/hostx.h                          |   23 
 hw/kdrive/ephyr/os.c                             |    1 
 hw/kdrive/linux/evdev.c                          |   17 
 hw/kdrive/linux/keyboard.c                       |  441 ----
 hw/kdrive/linux/linux.c                          |   17 
 hw/kdrive/src/Makefile.am                        |    8 
 hw/kdrive/src/kdrive.c                           |  100 
 hw/kdrive/src/kinfo.c                            |    4 
 hw/kdrive/src/kinput.c                           |  313 ++
 hw/vfb/InitOutput.c                              |  123 +
 hw/vfb/Makefile.am                               |    1 
 hw/xfree86/Makefile.am                           |    6 
 hw/xfree86/common/Makefile.am                    |    5 
 hw/xfree86/common/vidmodeproc.h                  |   83 
 hw/xfree86/common/xf86.h                         |    9 
 hw/xfree86/common/xf86AutoConfig.c               |   10 
 hw/xfree86/common/xf86Config.c                   |    8 
 hw/xfree86/common/xf86Configure.c                |    2 
 hw/xfree86/common/xf86Events.c                   |    7 
 hw/xfree86/common/xf86Extensions.c               |    3 
 hw/xfree86/common/xf86Globals.c                  |    3 
 hw/xfree86/common/xf86Helper.c                   |   85 
 hw/xfree86/common/xf86Init.c                     |  159 -
 hw/xfree86/common/xf86Module.h                   |    5 
 hw/xfree86/common/xf86Priv.h                     |    4 
 hw/xfree86/common/xf86Privstr.h                  |   22 
 hw/xfree86/common/xf86VidMode.c                  |  582 +----
 hw/xfree86/common/xf86Xinput.c                   |   47 
 hw/xfree86/common/xf86cmap.c                     |    2 
 hw/xfree86/common/xf86str.h                      |   92 
 hw/xfree86/common/xf86vmode.c                    | 2165 --------------------
 hw/xfree86/ddc/ddcProperty.c                     |   55 
 hw/xfree86/ddc/edid.h                            |    1 
 hw/xfree86/dixmods/xkbPrivate.c                  |    2 
 hw/xfree86/doc/Makefile.am                       |    1 
 hw/xfree86/doc/README.DRIcomp                    |  551 -----
 hw/xfree86/doc/ddxDesign.xml                     |   18 
 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/i915_pci_ids.h           |    4 
 hw/xfree86/dri2/pci_ids/i965_pci_ids.h           |   56 
 hw/xfree86/dri2/pci_ids/pci_id_driver_map.h      |    7 
 hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h       |   38 
 hw/xfree86/dri2/pci_ids/virtio_gpu_pci_ids.h     |    2 
 hw/xfree86/drivers/modesetting/dri2.c            |    4 
 hw/xfree86/drivers/modesetting/driver.c          |  104 
 hw/xfree86/drivers/modesetting/driver.h          |    5 
 hw/xfree86/drivers/modesetting/drmmode_display.c |  156 +
 hw/xfree86/drivers/modesetting/drmmode_display.h |    6 
 hw/xfree86/drivers/modesetting/present.c         |    6 
 hw/xfree86/drivers/modesetting/vblank.c          |   16 
 hw/xfree86/exa/Makefile.am                       |    3 
 hw/xfree86/int10/xf86x86emu.c                    |    2 
 hw/xfree86/loader/Makefile.am                    |    2 
 hw/xfree86/loader/loader.c                       |    1 
 hw/xfree86/loader/loadmod.c                      |    3 
 hw/xfree86/loader/os.c                           |    2 
 hw/xfree86/man/Xorg.man                          |   60 
 hw/xfree86/man/xorg.conf.man                     |   23 
 hw/xfree86/modes/xf86Crtc.c                      |   12 
 hw/xfree86/modes/xf86Cursors.c                   |   21 
 hw/xfree86/modes/xf86RandR12.c                   |    4 
 hw/xfree86/os-support/bus/Sbus.c                 |    4 
 hw/xfree86/os-support/linux/systemd-logind.c     |    3 
 hw/xfree86/os-support/xf86_OSlib.h               |   22 
 hw/xfree86/parser/DRI.c                          |    2 
 hw/xfree86/parser/Device.c                       |    3 
 hw/xfree86/parser/Extensions.c                   |    2 
 hw/xfree86/parser/Files.c                        |    2 
 hw/xfree86/parser/Flags.c                        |    2 
 hw/xfree86/parser/Input.c                        |    3 
 hw/xfree86/parser/InputClass.c                   |   95 
 hw/xfree86/parser/Layout.c                       |    4 
 hw/xfree86/parser/Module.c                       |    4 
 hw/xfree86/parser/Monitor.c                      |    8 
 hw/xfree86/parser/OutputClass.c                  |    3 
 hw/xfree86/parser/Pointer.c                      |    4 
 hw/xfree86/parser/Screen.c                       |    4 
 hw/xfree86/parser/Vendor.c                       |    4 
 hw/xfree86/parser/Video.c                        |    4 
 hw/xfree86/parser/configProcs.h                  |    6 
 hw/xfree86/parser/read.c                         |    2 
 hw/xfree86/parser/scan.c                         |   42 
 hw/xfree86/parser/write.c                        |   31 
 hw/xfree86/parser/xf86Parser.h                   |    2 
 hw/xfree86/parser/xf86tokens.h                   |   13 
 hw/xfree86/ramdac/xf86Cursor.c                   |   24 
 hw/xfree86/ramdac/xf86Cursor.h                   |    1 
 hw/xfree86/vbe/vbe.c                             |    2 
 hw/xfree86/x86emu/ops.c                          |  192 +
 hw/xfree86/x86emu/x86emu/regs.h                  |    8 
 hw/xfree86/xorg-wrapper.c                        |    1 
 hw/xnest/Keyboard.c                              |    5 
 hw/xquartz/GL/indirect.c                         |   40 
 hw/xquartz/bundle/Info.plist.cpp                 |   23 
 hw/xquartz/bundle/Makefile.am                    |    6 
 hw/xquartz/darwinEvents.c                        |    2 
 hw/xquartz/quartz.c                              |    4 
 hw/xquartz/quartz.h                              |    2 
 hw/xwayland/Makefile.am                          |    9 
 hw/xwayland/xwayland-cvt.c                       |    4 
 hw/xwayland/xwayland-glamor-xv.c                 |  412 +++
 hw/xwayland/xwayland-glamor.c                    |   36 
 hw/xwayland/xwayland-input.c                     |   38 
 hw/xwayland/xwayland-output.c                    |   95 
 hw/xwayland/xwayland-shm.c                       |   18 
 hw/xwayland/xwayland-vidmode.c                   |  419 +++
 hw/xwayland/xwayland.c                           |   69 
 hw/xwayland/xwayland.h                           |   10 
 hw/xwin/InitOutput.c                             |   87 
 hw/xwin/glx/indirect.c                           |  108 -
 hw/xwin/man/XWin.man                             |    7 
 hw/xwin/win.h                                    |   27 
 hw/xwin/winallpriv.c                             |    7 
 hw/xwin/winauth.c                                |   42 
 hw/xwin/winclipboard/internal.h                  |    8 
 hw/xwin/winclipboard/thread.c                    |    9 
 hw/xwin/winclipboard/wndproc.c                   |  109 -
 hw/xwin/winconfig.c                              |   79 
 hw/xwin/winengine.c                              |    2 
 hw/xwin/winglobals.c                             |    1 
 hw/xwin/winglobals.h                             |    1 
 hw/xwin/winlayouts.h                             |    5 
 hw/xwin/winmsg.c                                 |   33 
 hw/xwin/winmsg.h                                 |   17 
 hw/xwin/winmultiwindowclass.h                    |   28 
 hw/xwin/winmultiwindowicons.c                    |  151 -
 hw/xwin/winmultiwindowicons.h                    |    4 
 hw/xwin/winmultiwindowwindow.c                   |   86 
 hw/xwin/winmultiwindowwm.c                       | 1345 +++++-------
 hw/xwin/winprefs.c                               |    1 
 hw/xwin/winprocarg.c                             |   13 
 hw/xwin/winrandr.c                               |   96 
 hw/xwin/winscrinit.c                             |   10 
 hw/xwin/winshadddnl.c                            |    6 
 hw/xwin/winshadgdi.c                             |   12 
 hw/xwin/winwin32rootless.c                       |   68 
 hw/xwin/winwin32rootlesswindow.c                 |   15 
 hw/xwin/winwin32rootlesswndproc.c                |  239 --
 hw/xwin/winwindow.h                              |   24 
 hw/xwin/winwindowswm.c                           |    2 
 hw/xwin/winwndproc.c                             |   46 
 include/Makefile.am                              |    2 
 include/displaymode.h                            |  102 
 include/dix-config.h.in                          |    6 
 include/dix.h                                    |   10 
 include/dixstruct.h                              |    6 
 include/eventstr.h                               |   10 
 include/input.h                                  |    2 
 include/inpututils.h                             |    4 
 include/list.h                                   |    8 
 include/os.h                                     |   18 
 include/property.h                               |    9 
 include/vidmodestr.h                             |  142 +
 include/window.h                                 |    9 
 man/Xserver.man                                  |   13 
 os/WaitFor.c                                     |   51 
 os/access.c                                      |   68 
 os/backtrace.c                                   |    2 
 os/connection.c                                  |  231 +-
 os/io.c                                          |   23 
 os/log.c                                         |  126 -
 os/osdep.h                                       |   16 
 os/osinit.c                                      |    1 
 os/rpcauth.c                                     |    2 
 os/utils.c                                       |   42 
 os/xdmauth.c                                     |    2 
 os/xdmcp.c                                       |  158 -
 present/present.c                                |  154 +
 present/present_priv.h                           |    2 
 randr/rrcrtc.c                                   |   89 
 randr/rrmonitor.c                                |   15 
 randr/rroutput.c                                 |   12 
 record/record.c                                  |    1 
 render/animcur.c                                 |   57 
 render/picture.c                                 |    3 
 test/Makefile.am                                 |    4 
 xfixes/cursor.c                                  |    4 
 xkb/xkbAccessX.c                                 |    7 
 xkb/xkbActions.c                                 |  170 -
 xkb/xkbEvents.c                                  |    2 
 xkb/xkbInit.c                                    |    2 
 281 files changed, 10514 insertions(+), 13312 deletions(-)

New commits:
commit 059d5ef30490233f410ca87084c7697b87e5b05e
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue May 3 23:43:06 2016 -0700

    XQuartz: Update copyright years
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/bundle/Info.plist.cpp b/hw/xquartz/bundle/Info.plist.cpp
index f6a72af..3742353 100644
--- a/hw/xquartz/bundle/Info.plist.cpp
+++ b/hw/xquartz/bundle/Info.plist.cpp
@@ -39,9 +39,9 @@
 	<key>LSApplicationCategoryType</key>
 		<string>public.app-category.utilities</string>
 	<key>NSHumanReadableCopyright</key>
-		<string>© 2003-2013 Apple Inc.
+		<string>© 2003-2016 Apple Inc.
 © 2003 XFree86 Project, Inc.
-© 2003-2013 X.org Foundation, Inc.
+© 2003-2016 X.org Foundation, Inc.
 </string>
 	<key>NSMainNibFile</key>
 		<string>main</string>
commit d6ba4f2c52da150a9a92bdb00efe7902d17033bd
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue May 3 23:42:34 2016 -0700

    XQuartz: Add --with-bundle-version and --with-bundle-version-string configure options
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/configure.ac b/configure.ac
index 61af401..2633f4e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -559,6 +559,16 @@ AC_ARG_WITH(bundle-id-prefix,  AS_HELP_STRING([--with-bundle-id-prefix=RDNS_PREF
                                [ BUNDLE_ID_PREFIX="${withval}" ])
 AC_SUBST([BUNDLE_ID_PREFIX])
 AC_DEFINE_UNQUOTED(BUNDLE_ID_PREFIX, "$BUNDLE_ID_PREFIX", [Prefix to use for bundle identifiers])
+DEFAULT_BUNDLE_VERSION=`echo ${PACKAGE_VERSION} | cut -f1-3 -d.`
+m4_define(DEFAULT_BUNDLE_VERSION, m4_esyscmd([echo ]AC_PACKAGE_VERSION[ | cut -f1-3 -d.]))
+AC_ARG_WITH(bundle-version,    AS_HELP_STRING([--with-bundle-version=VERSION], [Version to use for X11.app's CFBundleVersion (default: ]DEFAULT_BUNDLE_VERSION[)]),
+                               [ BUNDLE_VERSION="${withval}" ],
+                               [ BUNDLE_VERSION="${DEFAULT_BUNDLE_VERSION}" ])
+AC_SUBST([BUNDLE_VERSION])
+AC_ARG_WITH(bundle-version-string, AS_HELP_STRING([--with-bundle-version-string=VERSION], [Version to use for X11.app's CFBundleShortVersionString (default: ]AC_PACKAGE_VERSION[)]),
+                               [ BUNDLE_VERSION_STRING="${withval}" ],
+                               [ BUNDLE_VERSION_STRING="${PACKAGE_VERSION}" ])
+AC_SUBST([BUNDLE_VERSION_STRING])
 AC_ARG_ENABLE(sparkle,AS_HELP_STRING([--enable-sparkle], [Enable updating of X11.app using the Sparkle Framework (default: disabled)]),
 				[ XQUARTZ_SPARKLE="${enableval}" ],
 				[ XQUARTZ_SPARKLE="no" ])
diff --git a/hw/xquartz/bundle/Info.plist.cpp b/hw/xquartz/bundle/Info.plist.cpp
index 8d543a1..f6a72af 100644
--- a/hw/xquartz/bundle/Info.plist.cpp
+++ b/hw/xquartz/bundle/Info.plist.cpp
@@ -19,9 +19,9 @@
 	<key>CFBundlePackageType</key>
 		<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-		<string>2.7.7</string>
+		<string>BUNDLE_VERSION_STRING</string>
 	<key>CFBundleVersion</key>
-		<string>2.7.7</string>
+		<string>BUNDLE_VERSION</string>
 	<key>CFBundleSignature</key>
 		<string>x11a</string>
 	<key>CSResourcesFileMapped</key>
diff --git a/hw/xquartz/bundle/Makefile.am b/hw/xquartz/bundle/Makefile.am
index ac293db..424a747 100644
--- a/hw/xquartz/bundle/Makefile.am
+++ b/hw/xquartz/bundle/Makefile.am
@@ -1,8 +1,10 @@
 include cpprules.in
 
 CPP_FILES_FLAGS = \
+	-DAPPLE_APPLICATION_NAME="$(APPLE_APPLICATION_NAME)" \
 	-DBUNDLE_ID_PREFIX="$(BUNDLE_ID_PREFIX)" \
-	-DAPPLE_APPLICATION_NAME="$(APPLE_APPLICATION_NAME)"
+	-DBUNDLE_VERSION="$(BUNDLE_VERSION)" \
+	-DBUNDLE_VERSION_STRING="$(BUNDLE_VERSION_STRING)"
 
 if XQUARTZ_SPARKLE
 CPP_FILES_FLAGS += -DXQUARTZ_SPARKLE -DXQUARTZ_SPARKLE_FEED_URL="$(XQUARTZ_SPARKLE_FEED_URL)"
commit c1614928c10a8f8400f99acfd1b7f96d503af7ec
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue May 3 23:21:38 2016 -0700

    XQuartz: Add --with-sparkle-feed-url configure option
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/configure.ac b/configure.ac
index 4779cf5..61af401 100644
--- a/configure.ac
+++ b/configure.ac
@@ -563,6 +563,10 @@ AC_ARG_ENABLE(sparkle,AS_HELP_STRING([--enable-sparkle], [Enable updating of X11
 				[ XQUARTZ_SPARKLE="${enableval}" ],
 				[ XQUARTZ_SPARKLE="no" ])
 AC_SUBST([XQUARTZ_SPARKLE])
+AC_ARG_WITH(sparkle-feed-url,  AS_HELP_STRING([--with-sparkle-feed-url=URL], [URL for the Sparkle feed (default: https://www.xquartz.org/releases/sparkle/release.xml)]),
+                               [ XQUARTZ_SPARKLE_FEED_URL="${withval}" ],
+                               [ XQUARTZ_SPARKLE_FEED_URL="https://www.xquartz.org/releases/sparkle/release.xml" ])
+AC_SUBST([XQUARTZ_SPARKLE_FEED_URL])
 AC_ARG_ENABLE(visibility,     AS_HELP_STRING([--enable-visibility], [Enable symbol visibility (default: auto)]),
 				[SYMBOL_VISIBILITY=$enableval],
 				[SYMBOL_VISIBILITY=auto])
diff --git a/hw/xquartz/bundle/Info.plist.cpp b/hw/xquartz/bundle/Info.plist.cpp
index d98eaa6..8d543a1 100644
--- a/hw/xquartz/bundle/Info.plist.cpp
+++ b/hw/xquartz/bundle/Info.plist.cpp
@@ -34,7 +34,7 @@
 	<key>SUPublicDSAKeyFile</key>
 		<string>sparkle.pem</string>
         <key>SUFeedURL</key>
-                <string>https://www.xquartz.org/releases/sparkle/release.xml</string>
+                <string>XQUARTZ_SPARKLE_FEED_URL</string>
 #endif
 	<key>LSApplicationCategoryType</key>
 		<string>public.app-category.utilities</string>
diff --git a/hw/xquartz/bundle/Makefile.am b/hw/xquartz/bundle/Makefile.am
index 0740752..ac293db 100644
--- a/hw/xquartz/bundle/Makefile.am
+++ b/hw/xquartz/bundle/Makefile.am
@@ -5,7 +5,7 @@ CPP_FILES_FLAGS = \
 	-DAPPLE_APPLICATION_NAME="$(APPLE_APPLICATION_NAME)"
 
 if XQUARTZ_SPARKLE
-CPP_FILES_FLAGS += -DXQUARTZ_SPARKLE
+CPP_FILES_FLAGS += -DXQUARTZ_SPARKLE -DXQUARTZ_SPARKLE_FEED_URL="$(XQUARTZ_SPARKLE_FEED_URL)"
 endif
 
 install-data-hook:
commit 299b01eabf827a7435b5d6004d50637ac710bbc7
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue May 3 23:14:24 2016 -0700

    XQuartz: Update release feed URL to use new https URL
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/bundle/Info.plist.cpp b/hw/xquartz/bundle/Info.plist.cpp
index 06e33f8..d98eaa6 100644
--- a/hw/xquartz/bundle/Info.plist.cpp
+++ b/hw/xquartz/bundle/Info.plist.cpp
@@ -34,20 +34,7 @@
 	<key>SUPublicDSAKeyFile</key>
 		<string>sparkle.pem</string>
         <key>SUFeedURL</key>
-                <string>http://xquartz.macosforge.org/downloads/sparkle/release.xml</string>
-	<key>NSAppTransportSecurity</key>
-	<dict>
-		<key>NSExceptionDomains</key>
-		<dict>
-			<key>macosforge.org</key>
-			<dict>
-				<key>NSIncludesSubdomains</key>
-				<true/>
-				<key>NSExceptionAllowsInsecureHTTPLoads</key>
-				<true/>
-			</dict>
-		</dict>
-	</dict>
+                <string>https://www.xquartz.org/releases/sparkle/release.xml</string>
 #endif
 	<key>LSApplicationCategoryType</key>
 		<string>public.app-category.utilities</string>
commit 16d6733c63727d910eb516d7f6950f4675281f2d
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue May 3 23:24:44 2016 -0700

    XQuartz: Fix the help text for --with-bundle-id-prefix
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/configure.ac b/configure.ac
index 8467e59..4779cf5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -555,7 +555,7 @@ AC_ARG_WITH(apple-application-name,AS_HELP_STRING([--with-apple-application-name
 				[ APPLE_APPLICATION_NAME="${withval}" ],
 				[ APPLE_APPLICATION_NAME="X11" ])
 AC_SUBST([APPLE_APPLICATION_NAME])
-AC_ARG_WITH(bundle-id-prefix,  AS_HELP_STRING([--with-bundle-id-prefix=PATH], [Prefix to use for bundle identifiers (default: org.x)]),
+AC_ARG_WITH(bundle-id-prefix,  AS_HELP_STRING([--with-bundle-id-prefix=RDNS_PREFIX], [Prefix to use for bundle identifiers (default: org.x)]),
                                [ BUNDLE_ID_PREFIX="${withval}" ])
 AC_SUBST([BUNDLE_ID_PREFIX])
 AC_DEFINE_UNQUOTED(BUNDLE_ID_PREFIX, "$BUNDLE_ID_PREFIX", [Prefix to use for bundle identifiers])
commit 214a66b661dcb56ebb9776e34049753f65c7510a
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue May 3 23:16:46 2016 -0700

    XQuartz: Remove --with-launchd-id-prefix
    
    It's been deprecated for years.
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/configure.ac b/configure.ac
index db87ff9..8467e59 100644
--- a/configure.ac
+++ b/configure.ac
@@ -555,9 +555,6 @@ AC_ARG_WITH(apple-application-name,AS_HELP_STRING([--with-apple-application-name
 				[ APPLE_APPLICATION_NAME="${withval}" ],
 				[ APPLE_APPLICATION_NAME="X11" ])
 AC_SUBST([APPLE_APPLICATION_NAME])
-AC_ARG_WITH(launchd-id-prefix,  AS_HELP_STRING([--with-launchd-id-prefix=PATH], [Deprecated: Use --with-bundle-id-prefix.]),
-                                [ BUNDLE_ID_PREFIX="${withval}" ],
-                                [ BUNDLE_ID_PREFIX="org.x" ])
 AC_ARG_WITH(bundle-id-prefix,  AS_HELP_STRING([--with-bundle-id-prefix=PATH], [Prefix to use for bundle identifiers (default: org.x)]),
                                [ BUNDLE_ID_PREFIX="${withval}" ])
 AC_SUBST([BUNDLE_ID_PREFIX])
commit 2285fe78c04714561a0d1a164a41a38c48263f89
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Apr 22 15:04:37 2016 +1000

    xfree86: add support for MatchIsTabletPad
    
    The tablet pads have been separate kernel devices for a while now and
    libwacom has labelled them with the udev ID_INPUT_TABLET_PAD for over a year
    now. Add a new MatchIsTabletPad directive to apply configuration options
    specifically to the Pad part of a tablet.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/config/hal.c b/config/hal.c
index c76eced..e33e333 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -177,6 +177,8 @@ device_added(LibHalContext * hal_ctx, const char *udi)
         attrs.flags |= ATTR_JOYSTICK;
     if (libhal_device_query_capability(hal_ctx, udi, "input.tablet", NULL))
         attrs.flags |= ATTR_TABLET;
+    if (libhal_device_query_capability(hal_ctx, udi, "input.tablet_pad", NULL))
+        attrs.flags |= ATTR_TABLET_PAD;
     if (libhal_device_query_capability(hal_ctx, udi, "input.touchpad", NULL))
         attrs.flags |= ATTR_TOUCHPAD;
     if (libhal_device_query_capability(hal_ctx, udi, "input.touchscreen", NULL))
diff --git a/config/udev.c b/config/udev.c
index 1a6e82a..23b795f 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -258,6 +258,10 @@ device_added(struct udev_device *udev_device)
             LOG_PROPERTY(path, key, value);
             attrs.flags |= ATTR_TABLET;
         }
+        else if (!strcmp(key, "ID_INPUT_TABLET_PAD")) {
+            LOG_PROPERTY(path, key, value);
+            attrs.flags |= ATTR_TABLET_PAD;
+        }
         else if (!strcmp(key, "ID_INPUT_TOUCHPAD")) {
             LOG_PROPERTY(path, key, value);
             attrs.flags |= ATTR_TOUCHPAD;
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 4f2e6c8..b02a162 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -646,6 +646,9 @@ InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
     if (iclass->is_tablet.set &&
         iclass->is_tablet.val != ! !(attrs->flags & ATTR_TABLET))
         return FALSE;
+    if (iclass->is_tablet_pad.set &&
+        iclass->is_tablet_pad.val != ! !(attrs->flags & ATTR_TABLET_PAD))
+        return FALSE;
     if (iclass->is_touchpad.set &&
         iclass->is_touchpad.val != ! !(attrs->flags & ATTR_TOUCHPAD))
         return FALSE;
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
index 8c4aeb5..65c411e 100644
--- a/hw/xfree86/man/xorg.conf.man
+++ b/hw/xfree86/man/xorg.conf.man
@@ -1188,6 +1188,8 @@ entries.
 .TP 7
 .BI "MatchIsTablet       \*q" bool \*q
 .TP 7
+.BI "MatchIsTabletPad    \*q" bool \*q
+.TP 7
 .BI "MatchIsTouchpad     \*q" bool \*q
 .TP 7
 .BI "MatchIsTouchscreen  \*q" bool \*q
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index 392aa28..7281659 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -52,6 +52,7 @@ static const xf86ConfigSymTabRec InputClassTab[] = {
     {MATCH_IS_POINTER, "matchispointer"},
     {MATCH_IS_JOYSTICK, "matchisjoystick"},
     {MATCH_IS_TABLET, "matchistablet"},
+    {MATCH_IS_TABLET_PAD, "matchistabletpad"},
     {MATCH_IS_TOUCHPAD, "matchistouchpad"},
     {MATCH_IS_TOUCHSCREEN, "matchistouchscreen"},
     {NOMATCH_PRODUCT, "nomatchproduct"},
@@ -346,6 +347,14 @@ xf86parseInputClassSection(void)
             if (!ptr->is_tablet.set)
                 Error(BOOL_MSG, "MatchIsTablet");
             break;
+        case MATCH_IS_TABLET_PAD:
+            if (xf86getSubToken(&(ptr->comment)) != STRING)
+                Error(QUOTE_MSG, "MatchIsTabletPad");
+            ptr->is_tablet_pad.set = xf86getBoolValue(&ptr->is_tablet_pad.val, xf86_lex_val.str);
+            free(xf86_lex_val.str);
+            if (!ptr->is_tablet_pad.set)
+                Error(BOOL_MSG, "MatchIsTabletPad");
+            break;
         case MATCH_IS_TOUCHPAD:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchIsTouchpad");
@@ -474,6 +483,9 @@ xf86printInputClassSection(FILE * cf, XF86ConfInputClassPtr ptr)
         if (ptr->is_tablet.set)
             fprintf(cf, "\tIsTablet        \"%s\"\n",
                     ptr->is_tablet.val ? "yes" : "no");
+        if (ptr->is_tablet_pad.set)
+            fprintf(cf, "\tIsTabletPad     \"%s\"\n",
+                    ptr->is_tablet_pad.val ? "yes" : "no");
         if (ptr->is_touchpad.set)
             fprintf(cf, "\tIsTouchpad      \"%s\"\n",
                     ptr->is_touchpad.val ? "yes" : "no");
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index a038f9e..ff35846 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -326,6 +326,7 @@ typedef struct {
     xf86TriState is_pointer;
     xf86TriState is_joystick;
     xf86TriState is_tablet;
+    xf86TriState is_tablet_pad;
     xf86TriState is_touchpad;
     xf86TriState is_touchscreen;
     XF86OptionPtr option_lst;
diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
index f955af0..15792c6 100644
--- a/hw/xfree86/parser/xf86tokens.h
+++ b/hw/xfree86/parser/xf86tokens.h
@@ -285,6 +285,7 @@ typedef enum {
     MATCH_IS_POINTER,
     MATCH_IS_JOYSTICK,
     MATCH_IS_TABLET,
+    MATCH_IS_TABLET_PAD,
     MATCH_IS_TOUCHPAD,
     MATCH_IS_TOUCHSCREEN,
 
diff --git a/include/input.h b/include/input.h
index 9662123..cfdea2a 100644
--- a/include/input.h
+++ b/include/input.h
@@ -237,6 +237,7 @@ typedef struct _InputAttributes {
 #define ATTR_TOUCHPAD (1<<4)
 #define ATTR_TOUCHSCREEN (1<<5)
 #define ATTR_KEY (1<<6)
+#define ATTR_TABLET_PAD (1<<7)
 
 /* Key/Button has been run through all input processing and events sent to clients. */
 #define KEY_PROCESSED 1
commit fa02b05645080c285da5972262a8d37403e39d7e
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue May 3 06:54:57 2016 +1000

    modesetting: port clean start code from amdgpu. (v2)
    
    Both radeon and amdgpu don't set the mode until the first blockhandler,
    this means everything should be rendered on the screen correctly by
    then.
    
    This ports this code, it also removes the tail call of EnterVT from
    ScreenInit, it really isn't necessary and causes us to set a dirty mode
    with -modesetting always anyways.
    
    v2: reorder set desired modes vs block handler as done for amdgpu.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 6c4bac3..fe5d5e1 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -614,6 +614,17 @@ msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask)
 }
 
 static void
+msBlockHandler_oneshot(ScreenPtr pScreen, void *pTimeout, void *pReadmask)
+{
+    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    modesettingPtr ms = modesettingPTR(pScrn);
+
+    msBlockHandler(pScreen, pTimeout, pReadmask);
+
+    drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE);
+}
+
+static void
 FreeRec(ScrnInfoPtr pScrn)
 {
     modesettingPtr ms;
@@ -972,7 +983,7 @@ CreateScreenResources(ScreenPtr pScreen)
     ret = pScreen->CreateScreenResources(pScreen);
     pScreen->CreateScreenResources = CreateScreenResources;
 
-    if (!drmmode_set_desired_modes(pScrn, &ms->drmmode))
+    if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, pScrn->is_gpu))
         return FALSE;
 
     if (!drmmode_glamor_handle_new_screen_pixmap(&ms->drmmode))
@@ -1235,7 +1246,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
     pScreen->CloseScreen = CloseScreen;
 
     ms->BlockHandler = pScreen->BlockHandler;
-    pScreen->BlockHandler = msBlockHandler;
+    pScreen->BlockHandler = msBlockHandler_oneshot;
 
     pScreen->SharePixmapBacking = msSharePixmapBacking;
     pScreen->SetSharedPixmapBacking = msSetSharedPixmapBacking;
@@ -1289,7 +1300,9 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
     }
 #endif
 
-    return EnterVT(pScrn);
+    pScrn->vtSema = TRUE;
+
+    return TRUE;
 }
 
 static void
@@ -1336,7 +1349,7 @@ EnterVT(ScrnInfoPtr pScrn)
 
     SetMaster(pScrn);
 
-    if (!drmmode_set_desired_modes(pScrn, &ms->drmmode))
+    if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE))
         return FALSE;
 
     return TRUE;
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index e0d624f..546673b 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1853,7 +1853,7 @@ drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y)
 }
 
 Bool
-drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
+drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw)
 {
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
     int c;
@@ -1866,8 +1866,10 @@ drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 
         /* Skip disabled CRTCs */
         if (!crtc->enabled) {
-            drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-                           0, 0, 0, NULL, 0, NULL);
+            if (set_hw) {
+                drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+                               0, 0, 0, NULL, 0, NULL);
+            }
             continue;
         }
 
@@ -1898,10 +1900,19 @@ drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
             crtc->desiredY = 0;
         }
 
-        if (!crtc->funcs->
-            set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation,
-                           crtc->desiredX, crtc->desiredY))
-            return FALSE;
+        if (set_hw) {
+            if (!crtc->funcs->
+                set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation,
+                               crtc->desiredX, crtc->desiredY))
+                return FALSE;
+        } else {
+            crtc->mode = crtc->desiredMode;
+            crtc->rotation = crtc->desiredRotation;
+            crtc->x = crtc->desiredX;
+            crtc->y = crtc->desiredY;
+            if (!xf86CrtcRotate(crtc))
+                return FALSE;
+        }
     }
     return TRUE;
 }
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index a648d89..6b94641 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -163,7 +163,7 @@ Bool drmmode_SetSlaveBO(PixmapPtr ppix,
 
 extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
 void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
-extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
+extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw);
 extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
 
 extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
commit caabc4e85540dcd4225f2780b5616f7d870fbb06
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue May 3 06:54:56 2016 +1000

    modesetting: add support for background none.
    
    This adds support using glamor for background None.
    
    loosely based off the amdgpu code. relies on the glamor_finish code.
    
    Acked-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 8f60eae..6c4bac3 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1098,6 +1098,25 @@ SetMaster(ScrnInfoPtr pScrn)
     return ret == 0;
 }
 
+/* When the root window is created, initialize the screen contents from
+ * console if -background none was specified on the command line
+ */
+static Bool
+CreateWindow_oneshot(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    modesettingPtr ms = modesettingPTR(pScrn);
+    Bool ret;
+
+    pScreen->CreateWindow = ms->CreateWindow;
+    ret = pScreen->CreateWindow(pWin);
+
+    if (ret)
+        drmmode_copy_fb(pScrn, &ms->drmmode);
+    return ret;
+}
+
 static Bool
 ScreenInit(ScreenPtr pScreen, int argc, char **argv)
 {
@@ -1206,6 +1225,11 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
      * later memory should be bound when allocating, e.g rotate_mem */
     pScrn->vtSema = TRUE;
 
+    if (serverGeneration == 1 && bgNoneRoot && ms->drmmode.glamor) {
+        ms->CreateWindow = pScreen->CreateWindow;
+        pScreen->CreateWindow = CreateWindow_oneshot;
+    }
+
     pScreen->SaveScreen = xf86SaveScreen;
     ms->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = CloseScreen;
diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index 5e1c5d9..3a60449 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -97,7 +97,7 @@ typedef struct _modesettingRec {
 
     Bool noAccel;
     CloseScreenProcPtr CloseScreen;
-
+    CreateWindowProcPtr CreateWindow;
     unsigned int SaveGeneration;
 
     CreateScreenResourcesProcPtr createScreenResources;
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 262e015..e0d624f 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -51,7 +51,9 @@
 #include "driver.h"
 
 static Bool drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height);
-
+static PixmapPtr drmmode_create_pixmap_header(ScreenPtr pScreen, int width, int height,
+                                              int depth, int bitsPerPixel, int devKind,
+                                              void *pPixData);
 static Bool
 drmmode_zaphod_string_matches(ScrnInfoPtr scrn, const char *s, char *output_name)
 {
@@ -285,49 +287,101 @@ drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
     drmmode_crtc->dpms_mode = mode;
 }
 
-#if 0
 static PixmapPtr
-create_pixmap_for_fbcon(drmmode_ptr drmmode, ScrnInfoPtr pScrn, int crtc_id)
+create_pixmap_for_fbcon(drmmode_ptr drmmode, ScrnInfoPtr pScrn, int fbcon_id)
 {
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    drmmode_crtc_private_ptr drmmode_crtc;
-    ScreenPtr pScreen = pScrn->pScreen;
-    PixmapPtr pixmap;
-    struct radeon_bo *bo;
+    PixmapPtr pixmap = drmmode->fbcon_pixmap;
     drmModeFBPtr fbcon;
     struct drm_gem_flink flink;
+    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
+    Bool ret;
 
-    drmmode_crtc = xf86_config->crtc[crtc_id]->driver_private;
+    if (pixmap)
+        return pixmap;
 
-    fbcon = drmModeGetFB(drmmode->fd, drmmode_crtc->mode_crtc->buffer_id);
+    fbcon = drmModeGetFB(drmmode->fd, fbcon_id);
     if (fbcon == NULL)
         return NULL;
 
+    if (fbcon->depth != pScrn->depth ||
+        fbcon->width != pScrn->virtualX ||
+        fbcon->height != pScrn->virtualY)
+        goto out_free_fb;
+
     flink.handle = fbcon->handle;
     if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't flink fbcon handle\n");
-        return NULL;
-    }
-
-    bo = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0);
-    if (bo == NULL) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "Couldn't allocate bo for fbcon handle\n");
-        return NULL;
+        goto out_free_fb;
     }
 
-    pixmap = drmmode_create_bo_pixmap(pScreen, fbcon->width, fbcon->height,
-                                      fbcon->depth, fbcon->bpp,
-                                      fbcon->pitch, bo);
+    pixmap = drmmode_create_pixmap_header(pScreen, fbcon->width,
+                                          fbcon->height, fbcon->depth,
+                                          fbcon->bpp, fbcon->pitch, NULL);
     if (!pixmap)
-        return NULL;
+        goto out_free_fb;
+
+    ret = glamor_egl_create_textured_pixmap(pixmap, fbcon->handle, fbcon->pitch);
+    if (!ret) {
+      FreePixmap(pixmap);
+      pixmap = NULL;
+    }
 
-    radeon_bo_unref(bo);
+    drmmode->fbcon_pixmap = pixmap;
+out_free_fb:
     drmModeFreeFB(fbcon);
     return pixmap;
 }
 
-#endif
+void
+drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
+{
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
+    PixmapPtr src, dst;
+    int fbcon_id = 0;
+    GCPtr gc;
+    int i;
+
+    for (i = 0; i < xf86_config->num_crtc; i++) {
+        drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[i]->driver_private;
+        if (drmmode_crtc->mode_crtc->buffer_id)
+            fbcon_id = drmmode_crtc->mode_crtc->buffer_id;
+    }
+
+    if (!fbcon_id)
+        return;
+
+    if (fbcon_id == drmmode->fb_id) {
+        /* in some rare case there might be no fbcon and we might already
+         * be the one with the current fb to avoid a false deadlck in
+         * kernel ttm code just do nothing as anyway there is nothing
+         * to do
+         */
+        return;
+    }
+
+    src = create_pixmap_for_fbcon(drmmode, pScrn, fbcon_id);
+    if (!src)
+        return;
+
+    dst = pScreen->GetScreenPixmap(pScreen);
+
+    gc = GetScratchGC(pScrn->depth, pScreen);
+    ValidateGC(&dst->drawable, gc);
+
+    (*gc->ops->CopyArea)(&src->drawable, &dst->drawable, gc, 0, 0,
+                         pScrn->virtualX, pScrn->virtualY, 0, 0);
+
+    FreeScratchGC(gc);
+
+    glamor_finish(pScreen);
+
+    pScreen->canDoBGNoneRoot = TRUE;
+
+    if (drmmode->fbcon_pixmap)
+        pScrn->pScreen->DestroyPixmap(drmmode->fbcon_pixmap);
+    drmmode->fbcon_pixmap = NULL;
+}
 
 static Bool
 drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index fca68a6..a648d89 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -87,6 +87,8 @@ typedef struct {
     Bool reverse_prime_offload_mode;
 
     Bool is_secondary;
+
+    PixmapPtr fbcon_pixmap;
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
@@ -174,7 +176,7 @@ void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode,
                              int *depth, int *bpp);
 
-
+void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 #ifndef DRM_CAP_DUMB_PREFERRED_DEPTH
 #define DRM_CAP_DUMB_PREFERRED_DEPTH 3
 #endif
commit c33250945b45adc447154239f0cf48fb9b2d7335
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Apr 8 11:26:36 2016 -0400

    kdrive: Nuke a bunch of dead code
    
    gcc6 says:
    
    keyboard.c:46:21: warning: ‘linux_to_x’ defined but not used
    
    Only referenced by a bunch of long if-0'd code, so chuck it all out.
    
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/kdrive/linux/keyboard.c b/hw/kdrive/linux/keyboard.c
index 9a6ee2d..5d31b7d 100644
--- a/hw/kdrive/linux/keyboard.c
+++ b/hw/kdrive/linux/keyboard.c
@@ -43,445 +43,6 @@
 
 extern int LinuxConsoleFd;
 
-static const KeySym linux_to_x[256] = {
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    XK_BackSpace, XK_Tab, XK_Linefeed, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, XK_Escape,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    XK_space, XK_exclam, XK_quotedbl, XK_numbersign,
-    XK_dollar, XK_percent, XK_ampersand, XK_apostrophe,
-    XK_parenleft, XK_parenright, XK_asterisk, XK_plus,
-    XK_comma, XK_minus, XK_period, XK_slash,
-    XK_0, XK_1, XK_2, XK_3,
-    XK_4, XK_5, XK_6, XK_7,
-    XK_8, XK_9, XK_colon, XK_semicolon,
-    XK_less, XK_equal, XK_greater, XK_question,
-    XK_at, XK_A, XK_B, XK_C,
-    XK_D, XK_E, XK_F, XK_G,
-    XK_H, XK_I, XK_J, XK_K,
-    XK_L, XK_M, XK_N, XK_O,
-    XK_P, XK_Q, XK_R, XK_S,
-    XK_T, XK_U, XK_V, XK_W,
-    XK_X, XK_Y, XK_Z, XK_bracketleft,
-    XK_backslash, XK_bracketright, XK_asciicircum, XK_underscore,
-    XK_grave, XK_a, XK_b, XK_c,
-    XK_d, XK_e, XK_f, XK_g,
-    XK_h, XK_i, XK_j, XK_k,
-    XK_l, XK_m, XK_n, XK_o,
-    XK_p, XK_q, XK_r, XK_s,
-    XK_t, XK_u, XK_v, XK_w,
-    XK_x, XK_y, XK_z, XK_braceleft,
-    XK_bar, XK_braceright, XK_asciitilde, XK_BackSpace,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    NoSymbol, NoSymbol, NoSymbol, NoSymbol,
-    XK_nobreakspace, XK_exclamdown, XK_cent, XK_sterling,
-    XK_currency, XK_yen, XK_brokenbar, XK_section,
-    XK_diaeresis, XK_copyright, XK_ordfeminine, XK_guillemotleft,
-    XK_notsign, XK_hyphen, XK_registered, XK_macron,
-    XK_degree, XK_plusminus, XK_twosuperior, XK_threesuperior,
-    XK_acute, XK_mu, XK_paragraph, XK_periodcentered,
-    XK_cedilla, XK_onesuperior, XK_masculine, XK_guillemotright,
-    XK_onequarter, XK_onehalf, XK_threequarters, XK_questiondown,
-    XK_Agrave, XK_Aacute, XK_Acircumflex, XK_Atilde,
-    XK_Adiaeresis, XK_Aring, XK_AE, XK_Ccedilla,
-    XK_Egrave, XK_Eacute, XK_Ecircumflex, XK_Ediaeresis,
-    XK_Igrave, XK_Iacute, XK_Icircumflex, XK_Idiaeresis,
-    XK_ETH, XK_Ntilde, XK_Ograve, XK_Oacute,
-    XK_Ocircumflex, XK_Otilde, XK_Odiaeresis, XK_multiply,
-    XK_Ooblique, XK_Ugrave, XK_Uacute, XK_Ucircumflex,
-    XK_Udiaeresis, XK_Yacute, XK_THORN, XK_ssharp,
-    XK_agrave, XK_aacute, XK_acircumflex, XK_atilde,
-    XK_adiaeresis, XK_aring, XK_ae, XK_ccedilla,
-    XK_egrave, XK_eacute, XK_ecircumflex, XK_ediaeresis,
-    XK_igrave, XK_iacute, XK_icircumflex, XK_idiaeresis,
-    XK_eth, XK_ntilde, XK_ograve, XK_oacute,
-    XK_ocircumflex, XK_otilde, XK_odiaeresis, XK_division,
-    XK_oslash, XK_ugrave, XK_uacute, XK_ucircumflex,
-    XK_udiaeresis, XK_yacute, XK_thorn, XK_ydiaeresis
-};
-
-/*
- * Getting a keycode from scancode
- *
- * With XKB
- * --------
- *
- * We have to enqueue keyboard events using standard X keycodes which correspond
- * to AT scancode + 8; this means that we need to translate the Linux scancode
- * provided by the kernel to an AT scancode -- this translation is not linear
- * and requires that we use a LUT.
- *
- *
- * Without XKB
- * -----------
- *
- * We can use custom keycodes, which makes things simpler; we define our custom
- * keycodes as Linux scancodes + KD_KEY_OFFSET
-*/
-
-/*
-   This LUT translates AT scancodes into Linux ones -- the keymap we create
-   for the core X keyboard protocol has to be AT-scancode based so that it
-   corresponds to the Xkb keymap.
-*/
-#if 0
-static unsigned char at2lnx[] = {
-    0x0,                        /* no valid scancode */
-    0x01, /* KEY_Escape */ 0x02,        /* KEY_1 */
-    0x03, /* KEY_2 */ 0x04,     /* KEY_3 */
-    0x05, /* KEY_4 */ 0x06,     /* KEY_5 */
-    0x07, /* KEY_6 */ 0x08,     /* KEY_7 */
-    0x09, /* KEY_8 */ 0x0a,     /* KEY_9 */
-    0x0b, /* KEY_0 */ 0x0c,     /* KEY_Minus */
-    0x0d, /* KEY_Equal */ 0x0e, /* KEY_BackSpace */
-    0x0f, /* KEY_Tab */ 0x10,   /* KEY_Q */
-    0x11, /* KEY_W */ 0x12,     /* KEY_E */
-    0x13, /* KEY_R */ 0x14,     /* KEY_T */
-    0x15, /* KEY_Y */ 0x16,     /* KEY_U */
-    0x17, /* KEY_I */ 0x18,     /* KEY_O */
-    0x19, /* KEY_P */ 0x1a,     /* KEY_LBrace */
-    0x1b, /* KEY_RBrace */ 0x1c,        /* KEY_Enter */
-    0x1d, /* KEY_LCtrl */ 0x1e, /* KEY_A */
-    0x1f, /* KEY_S */ 0x20,     /* KEY_D */
-    0x21, /* KEY_F */ 0x22,     /* KEY_G */
-    0x23, /* KEY_H */ 0x24,     /* KEY_J */
-    0x25, /* KEY_K */ 0x26,     /* KEY_L */
-    0x27, /* KEY_SemiColon */ 0x28,     /* KEY_Quote */
-    0x29, /* KEY_Tilde */ 0x2a, /* KEY_ShiftL */
-    0x2b, /* KEY_BSlash */ 0x2c,        /* KEY_Z */
-    0x2d, /* KEY_X */ 0x2e,     /* KEY_C */
-    0x2f, /* KEY_V */ 0x30,     /* KEY_B */
-    0x31, /* KEY_N */ 0x32,     /* KEY_M */
-    0x33, /* KEY_Comma */ 0x34, /* KEY_Period */
-    0x35, /* KEY_Slash */ 0x36, /* KEY_ShiftR */
-    0x37, /* KEY_KP_Multiply */ 0x38,   /* KEY_Alt */
-    0x39, /* KEY_Space */ 0x3a, /* KEY_CapsLock */
-    0x3b, /* KEY_F1 */ 0x3c,    /* KEY_F2 */
-    0x3d, /* KEY_F3 */ 0x3e,    /* KEY_F4 */
-    0x3f, /* KEY_F5 */ 0x40,    /* KEY_F6 */
-    0x41, /* KEY_F7 */ 0x42,    /* KEY_F8 */
-    0x43, /* KEY_F9 */ 0x44,    /* KEY_F10 */
-    0x45, /* KEY_NumLock */ 0x46,       /* KEY_ScrollLock */
-    0x47, /* KEY_KP_7 */ 0x48,  /* KEY_KP_8 */
-    0x49, /* KEY_KP_9 */ 0x4a,  /* KEY_KP_Minus */
-    0x4b, /* KEY_KP_4 */ 0x4c,  /* KEY_KP_5 */
-    0x4d, /* KEY_KP_6 */ 0x4e,  /* KEY_KP_Plus */
-    0x4f, /* KEY_KP_1 */ 0x50,  /* KEY_KP_2 */
-    0x51, /* KEY_KP_3 */ 0x52,  /* KEY_KP_0 */
-    0x53, /* KEY_KP_Decimal */ 0x54,    /* KEY_SysReqest */
-    0x00, /* 0x55 */ 0x56,      /* KEY_Less */
-    0x57, /* KEY_F11 */ 0x58,   /* KEY_F12 */
-    0x66, /* KEY_Home */ 0x67,  /* KEY_Up */
-    0x68, /* KEY_PgUp */ 0x69,  /* KEY_Left */
-    0x5d, /* KEY_Begin */ 0x6a, /* KEY_Right */
-    0x6b, /* KEY_End */ 0x6c,   /* KEY_Down */
-    0x6d, /* KEY_PgDown */ 0x6e,        /* KEY_Insert */
-    0x6f, /* KEY_Delete */ 0x60,        /* KEY_KP_Enter */
-    0x61, /* KEY_RCtrl */ 0x77, /* KEY_Pause */
-    0x63, /* KEY_Print */ 0x62, /* KEY_KP_Divide */
-    0x64, /* KEY_AltLang */ 0x65,       /* KEY_Break */
-    0x00, /* KEY_LMeta */ 0x00, /* KEY_RMeta */
-    0x7A, /* KEY_Menu/FOCUS_PF11 */ 0x00,       /* 0x6e */
-    0x7B, /* FOCUS_PF12 */ 0x00,        /* 0x70 */
-    0x00, /* 0x71 */ 0x00,      /* 0x72 */
-    0x59, /* FOCUS_PF2 */ 0x78, /* FOCUS_PF9 */
-    0x00, /* 0x75 */ 0x00,      /* 0x76 */
-    0x5A, /* FOCUS_PF3 */ 0x5B, /* FOCUS_PF4 */
-    0x5C, /* FOCUS_PF5 */ 0x5D, /* FOCUS_PF6 */
-    0x5E, /* FOCUS_PF7 */ 0x5F, /* FOCUS_PF8 */
-    0x7C, /* JAP_86 */ 0x79,    /* FOCUS_PF10 */
-    0x00,                       /* 0x7f */
-};
-
-#define NUM_AT_KEYS (sizeof(at2lnx)/sizeof(at2lnx[0]))
-#define LNX_KEY_INDEX(n) n < NUM_AT_KEYS ? at2lnx[n] : 0
-
-static unsigned char tbl[KD_MAX_WIDTH] = {
-    0,
-    1 << KG_SHIFT,
-    (1 << KG_ALTGR),
-    (1 << KG_ALTGR) | (1 << KG_SHIFT)
-};
-#endif
-
-static void
-readKernelMapping(KdKeyboardInfo * ki)
-{
-#if 0
-    KeySym *k;
-    int i, j;
-    struct kbentry kbe;
-    int minKeyCode, maxKeyCode;
-    int row;
-    int fd;
-
-    if (!ki)
-        return;
-
-    fd = LinuxConsoleFd;
-
-    minKeyCode = NR_KEYS;
-    maxKeyCode = 0;
-    row = 0;
-    ki->keySyms.mapWidth = KD_MAX_WIDTH;
-    for (i = 0; i < NR_KEYS && row < KD_MAX_LENGTH; ++i) {
-        kbe.kb_index = LNX_KEY_INDEX(i);
-
-        k = ki->keySyms.map + row * ki->keySyms.mapWidth;
-
-        for (j = 0; j < ki->keySyms.mapWidth; ++j) {
-            unsigned short kval;
-
-            k[j] = NoSymbol;
-
-            kbe.kb_table = tbl[j];
-            kbe.kb_value = 0;
-            if (ioctl(fd, KDGKBENT, &kbe))
-                continue;
-
-            kval = KVAL(kbe.kb_value);
-            switch (KTYP(kbe.kb_value)) {
-            case KT_LATIN:
-            case KT_LETTER:
-                k[j] = linux_to_x[kval];
-                break;
-
-            case KT_FN:
-                if (kval <= 19)
-                    k[j] = XK_F1 + kval;
-                else
-                    switch (kbe.kb_value) {
-                    case K_FIND:
-                        k[j] = XK_Home; /* or XK_Find */
-                        break;
-                    case K_INSERT:
-                        k[j] = XK_Insert;
-                        break;
-                    case K_REMOVE:
-                        k[j] = XK_Delete;
-                        break;
-                    case K_SELECT:
-                        k[j] = XK_End;  /* or XK_Select */
-                        break;
-                    case K_PGUP:
-                        k[j] = XK_Prior;
-                        break;
-                    case K_PGDN:
-                        k[j] = XK_Next;
-                        break;
-                    case K_HELP:
-                        k[j] = XK_Help;
-                        break;
-                    case K_DO:
-                        k[j] = XK_Execute;
-                        break;
-                    case K_PAUSE:
-                        k[j] = XK_Pause;
-                        break;
-                    case K_MACRO:
-                        k[j] = XK_Menu;
-                        break;
-                    default:
-                        break;
-                    }
-                break;
-
-            case KT_SPEC:
-                switch (kbe.kb_value) {
-                case K_ENTER:
-                    k[j] = XK_Return;
-                    break;
-                case K_BREAK:
-                    k[j] = XK_Break;
-                    break;
-                case K_CAPS:
-                    k[j] = XK_Caps_Lock;
-                    break;
-                case K_NUM:
-                    k[j] = XK_Num_Lock;
-                    break;
-                case K_HOLD:
-                    k[j] = XK_Scroll_Lock;
-                    break;
-                case K_COMPOSE:
-                    k[j] = XK_Multi_key;
-                    break;
-                default:
-                    break;
-                }
-                break;
-
-            case KT_PAD:
-                switch (kbe.kb_value) {
-                case K_PPLUS:
-                    k[j] = XK_KP_Add;
-                    break;
-                case K_PMINUS:
-                    k[j] = XK_KP_Subtract;
-                    break;
-                case K_PSTAR:
-                    k[j] = XK_KP_Multiply;
-                    break;
-                case K_PSLASH:
-                    k[j] = XK_KP_Divide;
-                    break;
-                case K_PENTER:
-                    k[j] = XK_KP_Enter;
-                    break;
-                case K_PCOMMA:
-                    k[j] = XK_KP_Separator;
-                    break;
-                case K_PDOT:
-                    k[j] = XK_KP_Decimal;
-                    break;
-                case K_PPLUSMINUS:
-                    k[j] = XK_KP_Subtract;
-                    break;
-                default:
-                    if (kval <= 9)
-                        k[j] = XK_KP_0 + kval;
-                    break;
-                }
-                break;
-
-                /*
-                 * KT_DEAD keys are for accelerated diacritical creation.
-                 */
-            case KT_DEAD:
-                switch (kbe.kb_value) {
-                case K_DGRAVE:
-                    k[j] = XK_dead_grave;
-                    break;
-                case K_DACUTE:
-                    k[j] = XK_dead_acute;
-                    break;
-                case K_DCIRCM:
-                    k[j] = XK_dead_circumflex;
-                    break;
-                case K_DTILDE:
-                    k[j] = XK_dead_tilde;
-                    break;
-                case K_DDIERE:
-                    k[j] = XK_dead_diaeresis;
-                    break;
-                }
-                break;
-
-            case KT_CUR:
-                switch (kbe.kb_value) {
-                case K_DOWN:
-                    k[j] = XK_Down;
-                    break;
-                case K_LEFT:
-                    k[j] = XK_Left;
-                    break;
-                case K_RIGHT:
-                    k[j] = XK_Right;
-                    break;
-                case K_UP:
-                    k[j] = XK_Up;
-                    break;
-                }
-                break;
-
-            case KT_SHIFT:
-                switch (kbe.kb_value) {
-                case K_ALTGR:
-                    k[j] = XK_Mode_switch;
-                    break;
-                case K_ALT:
-                    k[j] = (kbe.kb_index == 0x64 ? XK_Alt_R : XK_Alt_L);
-                    break;
-                case K_CTRL:
-                    k[j] = (kbe.kb_index == 0x61 ? XK_Control_R : XK_Control_L);
-                    break;
-                case K_CTRLL:
-                    k[j] = XK_Control_L;
-                    break;
-                case K_CTRLR:
-                    k[j] = XK_Control_R;
-                    break;
-                case K_SHIFT:
-                    k[j] = (kbe.kb_index == 0x36 ? XK_Shift_R : XK_Shift_L);
-                    break;
-                case K_SHIFTL:
-                    k[j] = XK_Shift_L;
-                    break;
-                case K_SHIFTR:
-                    k[j] = XK_Shift_R;
-                    break;
-                default:
-                    break;
-                }
-                break;
-
-                /*
-                 * KT_ASCII keys accumulate a 3 digit decimal number that gets
-                 * emitted when the shift state changes. We can't emulate that.
-                 */
-            case KT_ASCII:
-                break;
-
-            case KT_LOCK:
-                if (kbe.kb_value == K_SHIFTLOCK)
-                    k[j] = XK_Shift_Lock;
-                break;
-
-#ifdef KT_X
-            case KT_X:
-                /* depends on new keyboard symbols in file linux/keyboard.h */
-                if (kbe.kb_value == K_XMENU)
-                    k[j] = XK_Menu;
-                if (kbe.kb_value == K_XTELEPHONE)
-                    k[j] = XK_telephone;
-                break;
-#endif
-#ifdef KT_XF
-            case KT_XF:
-                /* special linux keysyms which map directly to XF86 keysyms */
-                k[j] = (kbe.kb_value & 0xFF) + 0x1008FF00;
-                break;
-#endif
-
-            default:
-                break;
-            }
-            if (i < minKeyCode)
-                minKeyCode = i;
-            if (i > maxKeyCode)
-                maxKeyCode = i;
-        }
-
-        if (minKeyCode == NR_KEYS)
-            continue;
-
-        if (k[3] == k[2])
-            k[3] = NoSymbol;
-        if (k[2] == k[1])
-            k[2] = NoSymbol;
-        if (k[1] == k[0])
-            k[1] = NoSymbol;
-        if (k[0] == k[2] && k[1] == k[3])
-            k[2] = k[3] = NoSymbol;
-        if (k[3] == k[0] && k[2] == k[1] && k[2] == NoSymbol)
-            k[3] = NoSymbol;
-        row++;
-    }
-    ki->minScanCode = minKeyCode;
-    ki->maxScanCode = maxKeyCode;
-#endif
-}
-
 /*
  * We need these to handle extended scancodes correctly (I could just use the
  * numbers below, but this makes the code more readable
@@ -759,8 +320,6 @@ LinuxKeyboardInit(KdKeyboardInfo * ki)
     free(ki->name);
     ki->name = strdup("Linux console keyboard");
 
-    readKernelMapping(ki);
-
     return Success;
 }
 
commit a5dd7b890f4f3a5245639591c73303c5a087b38a
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Apr 8 11:24:50 2016 -0400

    dix: Squash some new gcc6 warnings
    
    -Wlogical-op now tells us:
    
        devices.c:1685:23: warning: logical ‘and’ of equal expressions
    
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c
index 9eb29bd..18f3ac7 100644
--- a/Xext/panoramiXprocs.c
+++ b/Xext/panoramiXprocs.c
@@ -106,7 +106,7 @@ PanoramiXCreateWindow(ClientPtr client)
     if ((Mask) stuff->mask & CWColormap) {
         cmap_offset = Ones((Mask) stuff->mask & (CWColormap - 1));
         tmp = *((CARD32 *) &stuff[1] + cmap_offset);
-        if ((tmp != CopyFromParent) && (tmp != None)) {
+        if (tmp != CopyFromParent) {
             result = dixLookupResourceByType((void **) &cmap, tmp,
                                              XRT_COLORMAP, client,
                                              DixReadAccess);
@@ -210,7 +210,7 @@ PanoramiXChangeWindowAttributes(ClientPtr client)
     if ((Mask) stuff->valueMask & CWColormap) {
         cmap_offset = Ones((Mask) stuff->valueMask & (CWColormap - 1));
         tmp = *((CARD32 *) &stuff[1] + cmap_offset);
-        if ((tmp != CopyFromParent) && (tmp != None)) {
+        if (tmp != CopyFromParent) {
             result = dixLookupResourceByType((void **) &cmap, tmp,
                                              XRT_COLORMAP, client,
                                              DixReadAccess);
diff --git a/Xext/saver.c b/Xext/saver.c
index 0e20467..750b8b9 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -1143,7 +1143,7 @@ ProcScreenSaverSetAttributes(ClientPtr client)
         if ((Mask) stuff->mask & CWColormap) {
             cmap_offset = Ones((Mask) stuff->mask & (CWColormap - 1));
             tmp = *((CARD32 *) &stuff[1] + cmap_offset);
-            if ((tmp != CopyFromParent) && (tmp != None)) {
+            if (tmp != CopyFromParent) {
                 status = dixLookupResourceByType((void **) &cmap, tmp,
                                                  XRT_COLORMAP, client,
                                                  DixReadAccess);
diff --git a/dix/devices.c b/dix/devices.c
index 9b0c7d2..a532dcf 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1682,8 +1682,7 @@ ProcSetModifierMapping(ClientPtr client)
                        stuff->numKeyPerModifier);
     if (rc == MappingFailed || rc == -1)
         return BadValue;
-    if (rc != Success && rc != MappingSuccess && rc != MappingFailed &&
-        rc != MappingBusy)
+    if (rc != MappingSuccess && rc != MappingFailed && rc != MappingBusy)
         return rc;
 
     rep.success = rc;
diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c
index 1271010..59d275e 100644
--- a/hw/xfree86/common/xf86Configure.c
+++ b/hw/xfree86/common/xf86Configure.c
@@ -264,7 +264,7 @@ configureDeviceSection(int screennum)
     ptr->dev_busid = DevToConfig[screennum].GDev.busID;
     ptr->dev_driver = DevToConfig[screennum].GDev.driver;
     ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
-    for (i = 0; (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS); i++)
+    for (i = 0; i < MAXDACSPEEDS; i++)
         ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
     ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
     ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase;
diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c
index 0dbbd6c..0bbd661 100644
--- a/xkb/xkbEvents.c
+++ b/xkb/xkbEvents.c
@@ -505,7 +505,7 @@ XkbHandleBell(BOOL force,
     if ((!interest) || (force))
         return;
 
-    if ((class == 0) || (class == KbdFeedbackClass)) {
+    if (class == KbdFeedbackClass) {
         KeybdCtrl *pKeyCtrl = (KeybdCtrl *) pCtrl;
 
         id = pKeyCtrl->id;
commit 23dfa017298ceceac818f83779858e490c7757b6
Author: Andreas Schwab <schwab at suse.de>
Date:   Thu Apr 28 14:47:33 2016 +0200

    x86emu: Change include order to avoid conflict with system header
    
    R_SP is also defined in <sys/ucontext.h> on m68k.  Also remove duplicate
    definitions.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Andreas Schwab <schwab at suse.de>

diff --git a/hw/xfree86/int10/xf86x86emu.c b/hw/xfree86/int10/xf86x86emu.c
index 4b0a130..1dc695d 100644
--- a/hw/xfree86/int10/xf86x86emu.c
+++ b/hw/xfree86/int10/xf86x86emu.c
@@ -7,13 +7,13 @@
 #include <xorg-config.h>
 #endif
 
-#include <x86emu.h>
 #include "xf86.h"
 #include "xf86_OSproc.h"
 #include "xf86Pci.h"
 #define _INT10_PRIVATE
 #include "xf86int10.h"
 #include "int10Defines.h"
+#include <x86emu.h>
 
 #define M _X86EMU_env
 
diff --git a/hw/xfree86/x86emu/x86emu/regs.h b/hw/xfree86/x86emu/x86emu/regs.h
index c040259..3c9469f 100644
--- a/hw/xfree86/x86emu/x86emu/regs.h
+++ b/hw/xfree86/x86emu/x86emu/regs.h
@@ -158,14 +158,6 @@ struct i386_segment_regs {
 #define R_FLG spc.FLAGS
 
 /* special registers */
-#define R_SP  spc.SP.I16_reg.x_reg
-#define R_BP  spc.BP.I16_reg.x_reg
-#define R_SI  spc.SI.I16_reg.x_reg
-#define R_DI  spc.DI.I16_reg.x_reg
-#define R_IP  spc.IP.I16_reg.x_reg
-#define R_FLG spc.FLAGS
-
-/* special registers */
 #define R_ESP  spc.SP.I32_reg.e_reg
 #define R_EBP  spc.BP.I32_reg.e_reg
 #define R_ESI  spc.SI.I32_reg.e_reg
commit aa4e757130010dd3202f10ec6cb0c306c1dbcfbc
Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Mar 11 09:22:00 2016 +1000

    glamor: add glamor_finish API
    
    Some drivers are calling glFinish, they really should be doing this.
    
    This also is needed for some reverse prime scenarios.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index efe5953..477bc0e 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -813,3 +813,12 @@ glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
     }
     return -1;
 }
+
+void
+glamor_finish(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    glamor_make_current(glamor_priv);
+    glFinish();
+}
diff --git a/glamor/glamor.h b/glamor/glamor.h
index a73e9ef..e27033a 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -336,6 +336,7 @@ extern _X_EXPORT void glamor_destroy_gc(GCPtr gc);
 extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region);
 
+extern _X_EXPORT void glamor_finish(ScreenPtr screen);
 #define HAS_GLAMOR_TEXT 1
 
 #ifdef GLAMOR_FOR_XORG
commit f48b0534f110397246809d279225afedb28aa233
Author: Marek Chalupa <mchqwerty at gmail.com>
Date:   Mon Apr 25 11:33:00 2016 +0200

    xwayland-shm: fortify fallocate against EINTR
    
    If posix_fallocate or ftruncate is interrupted by signal while working,
    we return -1 as fd and the allocation process returns BadAlloc error.
    That causes xwayland clients to abort with 'BadAlloc (insufficient
    resources for operation)' even when there's a lot of resources
    available.
    
    Fix it by trying again when we get EINTR.
    
    Signed-off-by: Marek Chalupa <mchqwerty at gmail.com>
    Reviewed-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

diff --git a/hw/xwayland/xwayland-shm.c b/hw/xwayland/xwayland-shm.c
index e8545b3..c199e5e 100644
--- a/hw/xwayland/xwayland-shm.c
+++ b/hw/xwayland/xwayland-shm.c
@@ -140,14 +140,20 @@ os_create_anonymous_file(off_t size)
         return -1;
 
 #ifdef HAVE_POSIX_FALLOCATE
-    ret = posix_fallocate(fd, 0, size);
+    do {
+        ret = posix_fallocate(fd, 0, size);
+    } while (ret == EINTR);
+
     if (ret != 0) {
         close(fd);
         errno = ret;
         return -1;
     }
 #else
-    ret = ftruncate(fd, size);
+    do {
+        ret = ftruncate(fd, size);
+    } while (ret == -1 && errno == EINTR);
+
     if (ret < 0) {
         close(fd);
         return -1;
commit 4cc32880737c2d3e568fdb4867b2dba10fb3998a
Author: Alexandre Courbot <acourbot at nvidia.com>
Date:   Wed Mar 23 13:47:37 2016 +0900

    configure.ac: Keep environment CFLAGS when testing
    
    DRI2 detection could fail if configure is invoked with a sysroot passed
    as CFLAGS. Ideally configure should invoke gcc with the sysroot argument
    passed to the configure script, but for some reason this is not done by
    AC_COMPILE_IFELSE.
    
    Fix this by ensuring CFLAGS are preserved when checking for stuff.
    
    Signed-off-by: Alexandre Courbot <acourbot at nvidia.com>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>

diff --git a/configure.ac b/configure.ac
index 06b6a08..db87ff9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -880,7 +880,7 @@ if test "x$CONFIG_UDEV" = xyes; then
 	fi
 	SAVE_LIBS=$LIBS
 	SAVE_CFLAGS=$CFLAGS
-	CFLAGS=$UDEV_CFLAGS
+	CFLAGS="$CFLAGS $UDEV_CFLAGS"
 	LIBS=$UDEV_LIBS
 	AC_CHECK_FUNCS([udev_monitor_filter_add_match_tag])
 	AC_CHECK_FUNCS([udev_enumerate_add_match_tag])
@@ -1293,7 +1293,7 @@ fi
 
 if test "x$DRI2" = xyes; then
 	save_CFLAGS=$CFLAGS
-	CFLAGS="$GL_CFLAGS $LIBDRM_CFLAGS"
+	CFLAGS="$CFLAGS $GL_CFLAGS $LIBDRM_CFLAGS"
 	AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <GL/gl.h>
 #include <GL/internal/dri_interface.h>
 #ifndef __DRI_DRI2
commit 16e4bce9e5257c50c80c66efee0d07c2483619e1
Author: Simon Thum <simon.thum at gmx.de>
Date:   Fri Apr 8 13:24:39 2016 +0200

    dix/ptraccel: Remove float literals
    
    This was fine back when valuators were integer. Device
    properties are float (not double), so some instances remain.
    
    Signed-off-by: Simon Thum <simon.thum at gmx.de>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 050c12a..727602e 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -794,12 +794,12 @@ ComputeAcceleration(DeviceIntPtr dev,
             BasicComputeAcceleration(dev, vel, vel->last_velocity, threshold,
                                      acc);
         result +=
-            4.0f * BasicComputeAcceleration(dev, vel,
+            4.0 * BasicComputeAcceleration(dev, vel,
                                             (vel->last_velocity +
                                              vel->velocity) / 2,
                                             threshold,
                                             acc);
-        result /= 6.0f;
+        result /= 6.0;
         DebugAccelF("profile average [%.2f ... %.2f] is %.3f\n",
                     vel->velocity, vel->last_velocity, result);
     }
@@ -860,7 +860,7 @@ PowerProfile(DeviceIntPtr dev,
 {
     double vel_dist;
 
-    acc = (acc - 1.0) * 0.1f + 1.0;     /* without this, acc of 2 is unuseable */
+    acc = (acc - 1.0) * 0.1 + 1.0;     /* without this, acc of 2 is unuseable */
 
     if (velocity <= threshold)
         return vel->min_acceleration;
@@ -878,9 +878,9 @@ PowerProfile(DeviceIntPtr dev,
 static inline double
 CalcPenumbralGradient(double x)
 {
-    x *= 2.0f;
-    x -= 1.0f;
-    return 0.5f + (x * sqrt(1.0 - x * x) + asin(x)) / M_PI;
+    x *= 2.0;
+    x -= 1.0;
+    return 0.5 + (x * sqrt(1.0 - x * x) + asin(x)) / M_PI;
 }
 
 /**
@@ -916,23 +916,23 @@ SmoothLinearProfile(DeviceIntPtr dev,
 {
     double res, nv;
 
-    if (acc > 1.0f)
-        acc -= 1.0f;            /*this is so acc = 1 is no acceleration */
+    if (acc > 1.0)
+        acc -= 1.0;            /*this is so acc = 1 is no acceleration */
     else
-        return 1.0f;
+        return 1.0;
 
-    nv = (velocity - threshold) * acc * 0.5f;
+    nv = (velocity - threshold) * acc * 0.5;
 
     if (nv < 0) {
         res = 0;
     }
     else if (nv < 2) {
-        res = CalcPenumbralGradient(nv * 0.25f) * 2.0f;
+        res = CalcPenumbralGradient(nv * 0.25) * 2.0;
     }
     else {
-        nv -= 2.0f;
-        res = nv * 2.0f / M_PI  /* steepness of gradient at 0.5 */
-            + 1.0f;             /* gradient crosses 2|1 */
+        nv -= 2.0;
+        res = nv * 2.0 / M_PI  /* steepness of gradient at 0.5 */
+            + 1.0;             /* gradient crosses 2|1 */
     }
     res += vel->min_acceleration;
     return res;
@@ -949,7 +949,7 @@ SmoothLimitedProfile(DeviceIntPtr dev,
 {
     double res;
 
-    if (velocity >= threshold || threshold == 0.0f)
+    if (velocity >= threshold || threshold == 0.0)
         return acc;
 
     velocity /= threshold;      /* should be [0..1[ now */
@@ -971,7 +971,7 @@ static double
 NoProfile(DeviceIntPtr dev,
           DeviceVelocityPtr vel, double velocity, double threshold, double acc)
 {
-    return 1.0f;
+    return 1.0;
 }
 
 static PointerAccelerationProfileFunc
@@ -1091,7 +1091,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
         return;
 
     if (velocitydata->statistics.profile_number == AccelProfileNone &&
-        velocitydata->const_acceleration == 1.0f) {
+        velocitydata->const_acceleration == 1.0) {
         return;                 /*we're inactive anyway, so skip the whole thing. */
     }
 
@@ -1119,8 +1119,8 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
                                        (double) dev->ptrfeed->ctrl.den);
 
             DebugAccelF("mult is %f\n", mult);
-            if (mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
-                if (mult > 1.0f && soften)
+            if (mult != 1.0 || velocitydata->const_acceleration != 1.0) {
+                if (mult > 1.0 && soften)
                     ApplySoftening(velocitydata, &dx, &dy);
                 ApplyConstantDeceleration(velocitydata, &dx, &dy);
 
commit c8e5fc30575a309c25970fc68b9184c07bb74df4
Author: Simon Thum <simon.thum at gmx.de>
Date:   Tue Apr 5 14:29:47 2016 +0200

    dix/ptraccel: Fix memory leak in InitPredictableAccelerationScheme
    
    This was quite unlikely except in situations where a proper startup
    would have been impossible anyway, but since automated checks don't
    grade likelyhood just fix it.
    
    Detected by Jeremy Huddleston's clang checks.
    
    Signed-off-by: Simon Thum <simon.thum at gmx.de>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index e75300a..050c12a 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -134,13 +134,19 @@ InitPredictableAccelerationScheme(DeviceIntPtr dev,
     scheme = *protoScheme;
     vel = calloc(1, sizeof(DeviceVelocityRec));
     schemeData = calloc(1, sizeof(PredictableAccelSchemeRec));
-    if (!vel || !schemeData)
+    if (!vel || !schemeData) {
+        free(vel);
+        free(schemeData);
         return FALSE;
+    }
     InitVelocityData(vel);
     schemeData->vel = vel;
     scheme.accelData = schemeData;
-    if (!InitializePredictableAccelerationProperties(dev, vel, schemeData))
+    if (!InitializePredictableAccelerationProperties(dev, vel, schemeData)) {
+        free(vel);
+        free(schemeData);
         return FALSE;
+    }
     /* all fine, assign scheme to device */
     dev->valuator->accelScheme = scheme;
     return TRUE;
commit f641ae412287ecb7a3437987e2ba1646a8443aa4
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Mar 9 10:45:48 2016 +1000

    Xi: don't deliver emulated motion events for non-emulating touches
    
    The touchpoint knows whether it should be emulating or not and we have a check
    for that later. Check for this before we generate the event and try to deliver
    it, lest we trigger a bug warning.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1282252
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 74e49ed..5a0b68d 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1379,6 +1379,9 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
     if (!TouchResourceIsOwner(ti, listener->listener))
         return !Success;
 
+    if (!ti->emulate_pointer)
+        return !Success;
+
     nevents = TouchConvertToPointerEvent(ev, &motion, &button);
     BUG_RETURN_VAL(nevents == 0, BadValue);
 
commit 577bebe2067293bb154068e99a2ef085b066cb67
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Sun Apr 17 20:30:46 2016 +0100

    xfree86/parser: simplify #ifdef ladder
    
    Rather than 'hacking' around symbol names and providing macros such as
    'Local' just fold things and make the code more readable.
    
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/hw/xfree86/parser/write.c b/hw/xfree86/parser/write.c
index 8792783..9a24dd6 100644
--- a/hw/xfree86/parser/write.c
+++ b/hw/xfree86/parser/write.c
@@ -73,14 +73,7 @@
 #define HAS_NO_UIDS
 #endif
 
-#ifdef HAS_NO_UIDS
-#define doWriteConfigFile xf86writeConfigFile
-#define Local /**/
-#else
-#define Local static
-#endif
-
-Local int
+static int
 doWriteConfigFile(const char *filename, XF86ConfigPtr cptr)
 {
     FILE *cf;
@@ -134,24 +127,19 @@ doWriteConfigFile(const char *filename, XF86ConfigPtr cptr)
     return 1;
 }
 
-#ifndef HAS_NO_UIDS
-
 int
 xf86writeConfigFile(const char *filename, XF86ConfigPtr cptr)
 {
+#ifndef HAS_NO_UIDS
     int ret;
 
-#if !defined(HAS_SAVED_IDS_AND_SETEUID)
-    int pid, p;
-    int status;
-    void (*csig) (int);
-#else
-    int ruid, euid;
-#endif
-
     if (getuid() != geteuid()) {
 
 #if !defined(HAS_SAVED_IDS_AND_SETEUID)
+        int pid, p;
+        int status;
+        void (*csig) (int);
+
         /* Need to fork to change ruid without loosing euid */
         csig = signal(SIGCHLD, SIG_DFL);
         switch ((pid = fork())) {
@@ -178,6 +166,7 @@ xf86writeConfigFile(const char *filename, XF86ConfigPtr cptr)
             return 0;
 
 #else                           /* HAS_SAVED_IDS_AND_SETEUID */
+        int ruid, euid;
 
         ruid = getuid();
         euid = geteuid();
@@ -198,9 +187,7 @@ xf86writeConfigFile(const char *filename, XF86ConfigPtr cptr)
 #endif                          /* HAS_SAVED_IDS_AND_SETEUID */
 
     }
-    else {
+    else
+#endif                          /* !HAS_NO_UIDS */
         return doWriteConfigFile(filename, cptr);
-    }
 }
-
-#endif                          /* !HAS_NO_UIDS */
commit 537276a5b86b7341169ea4eb36d479a503ba5d84
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Sun Apr 17 20:30:45 2016 +0100

    xfree86/parser: reuse StringToToken() in xf86getToken()
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>

diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c
index 5c2e4ae..81a454b 100644
--- a/hw/xfree86/parser/scan.c
+++ b/hw/xfree86/parser/scan.c
@@ -441,14 +441,8 @@ xf86getToken(const xf86ConfigSymTabRec * tab)
     /*
      * Joop, at last we have to lookup the token ...
      */
-    if (tab) {
-        i = 0;
-        while (tab[i].token != -1)
-            if (xf86nameCompare(configRBuf, tab[i].name) == 0)
-                return tab[i].token;
-            else
-                i++;
-    }
+    if (tab)
+        return StringToToken(configRBuf, tab);
 
     return ERROR_TOKEN;         /* Error catcher */
 }
commit 944ea03d5be2ffe22a3f1c4c287760261c31235f
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Sun Apr 17 20:30:44 2016 +0100

    xfree86/parser: move StringToToken() definition further up
    
    ... so that we can use it without the forward declaration. Plus we're
    doing to reuse it in the next commit ;-)
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>

diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c
index 2760439..5c2e4ae 100644
--- a/hw/xfree86/parser/scan.c
+++ b/hw/xfree86/parser/scan.c
@@ -87,8 +87,6 @@
 #define CONFIG_BUF_LEN     1024
 #define CONFIG_MAX_FILES   64
 
-static int StringToToken(const char *, const xf86ConfigSymTabRec *);
-
 static struct {
     FILE *file;
     char *path;
@@ -241,6 +239,18 @@ xf86getNextLine(void)
     return ret;
 }
 
+static int
+StringToToken(const char *str, const xf86ConfigSymTabRec * tab)
+{
+    int i;
+
+    for (i = 0; tab[i].token != -1; i++) {
+        if (!xf86nameCompare(tab[i].name, str))
+            return tab[i].token;
+    }
+    return ERROR_TOKEN;
+}
+
 /*
  * xf86getToken --
  *      Read next Token from the config file. Handle the global variable
@@ -1028,18 +1038,6 @@ xf86getStringToken(const xf86ConfigSymTabRec * tab)
     return StringToToken(xf86_lex_val.str, tab);
 }
 
-static int
-StringToToken(const char *str, const xf86ConfigSymTabRec * tab)
-{
-    int i;
-
-    for (i = 0; tab[i].token != -1; i++) {
-        if (!xf86nameCompare(tab[i].name, str))
-            return tab[i].token;
-    }
-    return ERROR_TOKEN;
-}
-
 /*
  * Compare two names.  The characters '_', ' ', and '\t' are ignored
  * in the comparison.
commit b93be14b7d339e4e46d941729dad853452fae8c0
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Sun Apr 17 20:30:43 2016 +0100

    xfree86/parser: annotate xf86ConfigSymTabRec as constant data
    
    Add the const notation to all the static storage as well as the
    functions that use it - xf86getToken(), xf86getSubTokenWithTab(),
    StringToToken() and xf86getStringToken().
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>

diff --git a/hw/xfree86/parser/DRI.c b/hw/xfree86/parser/DRI.c
index 9ed5b9e..31f447d 100644
--- a/hw/xfree86/parser/DRI.c
+++ b/hw/xfree86/parser/DRI.c
@@ -37,7 +37,7 @@
 #include "Configint.h"
 
 
-static xf86ConfigSymTabRec DRITab[] = {
+static const xf86ConfigSymTabRec DRITab[] = {
     {ENDSECTION, "endsection"},
     {GROUP, "group"},
     {MODE, "mode"},
diff --git a/hw/xfree86/parser/Device.c b/hw/xfree86/parser/Device.c
index 7e49843..353d48c 100644
--- a/hw/xfree86/parser/Device.c
+++ b/hw/xfree86/parser/Device.c
@@ -61,8 +61,7 @@
 #include "Configint.h"
 
 
-static
-xf86ConfigSymTabRec DeviceTab[] = {
+static const xf86ConfigSymTabRec DeviceTab[] = {
     {ENDSECTION, "endsection"},
     {IDENTIFIER, "identifier"},
     {VENDOR, "vendorname"},
diff --git a/hw/xfree86/parser/Extensions.c b/hw/xfree86/parser/Extensions.c
index a6fcb56..3a21959 100644
--- a/hw/xfree86/parser/Extensions.c
+++ b/hw/xfree86/parser/Extensions.c
@@ -41,7 +41,7 @@
 #include "Configint.h"
 
 
-static xf86ConfigSymTabRec ExtensionsTab[] = {
+static const xf86ConfigSymTabRec ExtensionsTab[] = {
     {ENDSECTION, "endsection"},
     {OPTION, "option"},
     {-1, ""},
diff --git a/hw/xfree86/parser/Files.c b/hw/xfree86/parser/Files.c
index 849bf92..c86ac7a 100644
--- a/hw/xfree86/parser/Files.c
+++ b/hw/xfree86/parser/Files.c
@@ -61,7 +61,7 @@
 #include "Configint.h"
 
 
-static xf86ConfigSymTabRec FilesTab[] = {
+static const xf86ConfigSymTabRec FilesTab[] = {
     {ENDSECTION, "endsection"},
     {FONTPATH, "fontpath"},
     {MODULEPATH, "modulepath"},
diff --git a/hw/xfree86/parser/Flags.c b/hw/xfree86/parser/Flags.c
index 5169665..0f69734 100644
--- a/hw/xfree86/parser/Flags.c
+++ b/hw/xfree86/parser/Flags.c
@@ -63,7 +63,7 @@
 #include "optionstr.h"
 
 
-static xf86ConfigSymTabRec ServerFlagsTab[] = {
+static const xf86ConfigSymTabRec ServerFlagsTab[] = {
     {ENDSECTION, "endsection"},
     {NOTRAPSIGNALS, "notrapsignals"},
     {DONTZAP, "dontzap"},
diff --git a/hw/xfree86/parser/Input.c b/hw/xfree86/parser/Input.c
index cfacd4e..88d19b6 100644
--- a/hw/xfree86/parser/Input.c
+++ b/hw/xfree86/parser/Input.c
@@ -62,8 +62,7 @@
 #include "Configint.h"
 
 
-static
-xf86ConfigSymTabRec InputTab[] = {
+static const xf86ConfigSymTabRec InputTab[] = {
     {ENDSECTION, "endsection"},
     {IDENTIFIER, "identifier"},
     {OPTION, "option"},
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index 5d3b59c..392aa28 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -34,8 +34,7 @@
 #include "Configint.h"
 
 
-static
-xf86ConfigSymTabRec InputClassTab[] = {
+static const xf86ConfigSymTabRec InputClassTab[] = {
     {ENDSECTION, "endsection"},
     {IDENTIFIER, "identifier"},
     {OPTION, "option"},
diff --git a/hw/xfree86/parser/Layout.c b/hw/xfree86/parser/Layout.c
index 0ace5da..2c829f4 100644
--- a/hw/xfree86/parser/Layout.c
+++ b/hw/xfree86/parser/Layout.c
@@ -66,7 +66,7 @@
 extern int xf86CheckBoolOption(void *optlist, const char *name, int deflt);
 
 
-static xf86ConfigSymTabRec LayoutTab[] = {
+static const xf86ConfigSymTabRec LayoutTab[] = {
     {ENDSECTION, "endsection"},
     {SCREEN, "screen"},
     {IDENTIFIER, "identifier"},
@@ -77,7 +77,7 @@ static xf86ConfigSymTabRec LayoutTab[] = {
     {-1, ""},
 };
 
-static xf86ConfigSymTabRec AdjTab[] = {
+static const xf86ConfigSymTabRec AdjTab[] = {
     {RIGHTOF, "rightof"},
     {LEFTOF, "leftof"},
     {ABOVE, "above"},
diff --git a/hw/xfree86/parser/Module.c b/hw/xfree86/parser/Module.c
index 0dcf4ba..38bf777 100644
--- a/hw/xfree86/parser/Module.c
+++ b/hw/xfree86/parser/Module.c
@@ -61,13 +61,13 @@
 #include "Configint.h"
 
 
-static xf86ConfigSymTabRec SubModuleTab[] = {
+static const xf86ConfigSymTabRec SubModuleTab[] = {
     {ENDSUBSECTION, "endsubsection"},
     {OPTION, "option"},
     {-1, ""},
 };
 
-static xf86ConfigSymTabRec ModuleTab[] = {
+static const xf86ConfigSymTabRec ModuleTab[] = {
     {ENDSECTION, "endsection"},
     {LOAD, "load"},
     {DISABLE, "disable"},
diff --git a/hw/xfree86/parser/Monitor.c b/hw/xfree86/parser/Monitor.c
index 0a8c081..a33c968 100644
--- a/hw/xfree86/parser/Monitor.c
+++ b/hw/xfree86/parser/Monitor.c
@@ -61,7 +61,7 @@
 #include "Configint.h"
 
 
-static xf86ConfigSymTabRec MonitorTab[] = {
+static const xf86ConfigSymTabRec MonitorTab[] = {
     {ENDSECTION, "endsection"},
     {IDENTIFIER, "identifier"},
     {VENDOR, "vendorname"},
@@ -77,7 +77,7 @@ static xf86ConfigSymTabRec MonitorTab[] = {
     {-1, ""},
 };
 
-static xf86ConfigSymTabRec ModesTab[] = {
+static const xf86ConfigSymTabRec ModesTab[] = {
     {ENDSECTION, "endsection"},
     {IDENTIFIER, "identifier"},
     {MODELINE, "modeline"},
@@ -85,7 +85,7 @@ static xf86ConfigSymTabRec ModesTab[] = {
     {-1, ""},
 };
 
-static xf86ConfigSymTabRec TimingTab[] = {
+static const xf86ConfigSymTabRec TimingTab[] = {
     {TT_INTERLACE, "interlace"},
     {TT_PHSYNC, "+hsync"},
     {TT_NHSYNC, "-hsync"},
@@ -101,7 +101,7 @@ static xf86ConfigSymTabRec TimingTab[] = {
     {-1, ""},
 };
 
-static xf86ConfigSymTabRec ModeTab[] = {
+static const xf86ConfigSymTabRec ModeTab[] = {
     {DOTCLOCK, "dotclock"},
     {HTIMINGS, "htimings"},
     {VTIMINGS, "vtimings"},
diff --git a/hw/xfree86/parser/OutputClass.c b/hw/xfree86/parser/OutputClass.c
index 3f2082e..8064e0c 100644
--- a/hw/xfree86/parser/OutputClass.c
+++ b/hw/xfree86/parser/OutputClass.c
@@ -32,8 +32,7 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-static
-xf86ConfigSymTabRec OutputClassTab[] = {
+static const xf86ConfigSymTabRec OutputClassTab[] = {
     {ENDSECTION, "endsection"},
     {IDENTIFIER, "identifier"},
     {DRIVER, "driver"},
diff --git a/hw/xfree86/parser/Pointer.c b/hw/xfree86/parser/Pointer.c
index 2f9d505..ff63deb 100644
--- a/hw/xfree86/parser/Pointer.c
+++ b/hw/xfree86/parser/Pointer.c
@@ -62,7 +62,7 @@
 #include "Xprintf.h"
 
 
-static xf86ConfigSymTabRec PointerTab[] = {
+static const xf86ConfigSymTabRec PointerTab[] = {
     {PROTOCOL, "protocol"},
     {EMULATE3, "emulate3buttons"},
     {EM3TIMEOUT, "emulate3timeout"},
@@ -83,7 +83,7 @@ static xf86ConfigSymTabRec PointerTab[] = {
     {-1, ""},
 };
 
-static xf86ConfigSymTabRec ZMapTab[] = {
+static const xf86ConfigSymTabRec ZMapTab[] = {
     {XAXIS, "x"},
     {YAXIS, "y"},
     {-1, ""},
diff --git a/hw/xfree86/parser/Screen.c b/hw/xfree86/parser/Screen.c
index 4731970..a831c30 100644
--- a/hw/xfree86/parser/Screen.c
+++ b/hw/xfree86/parser/Screen.c
@@ -61,7 +61,7 @@
 #include "Configint.h"
 
 
-static xf86ConfigSymTabRec DisplayTab[] = {
+static const xf86ConfigSymTabRec DisplayTab[] = {
     {ENDSUBSECTION, "endsubsection"},
     {MODES, "modes"},
     {VIEWPORT, "viewport"},
@@ -222,7 +222,7 @@ xf86parseDisplaySubSection(void)
 
 #undef CLEANUP
 
-static xf86ConfigSymTabRec ScreenTab[] = {
+static const xf86ConfigSymTabRec ScreenTab[] = {
     {ENDSECTION, "endsection"},
     {IDENTIFIER, "identifier"},
     {MATCHSEAT, "matchseat"},
diff --git a/hw/xfree86/parser/Vendor.c b/hw/xfree86/parser/Vendor.c
index f137a4e..50ea689 100644
--- a/hw/xfree86/parser/Vendor.c
+++ b/hw/xfree86/parser/Vendor.c
@@ -61,7 +61,7 @@
 #include "Configint.h"
 
 
-static xf86ConfigSymTabRec VendorSubTab[] = {
+static const xf86ConfigSymTabRec VendorSubTab[] = {
     {ENDSUBSECTION, "endsubsection"},
     {IDENTIFIER, "identifier"},
     {OPTION, "option"},
@@ -129,7 +129,7 @@ xf86parseVendorSubSection(void)
 
 #undef CLEANUP
 
-static xf86ConfigSymTabRec VendorTab[] = {
+static const xf86ConfigSymTabRec VendorTab[] = {
     {ENDSECTION, "endsection"},
     {IDENTIFIER, "identifier"},
     {OPTION, "option"},
diff --git a/hw/xfree86/parser/Video.c b/hw/xfree86/parser/Video.c
index 666b0ab..4e8526f 100644
--- a/hw/xfree86/parser/Video.c
+++ b/hw/xfree86/parser/Video.c
@@ -61,7 +61,7 @@
 #include "Configint.h"
 
 
-static xf86ConfigSymTabRec VideoPortTab[] = {
+static const xf86ConfigSymTabRec VideoPortTab[] = {
     {ENDSUBSECTION, "endsubsection"},
     {IDENTIFIER, "identifier"},
     {OPTION, "option"},
@@ -128,7 +128,7 @@ xf86parseVideoPortSubSection(void)
 
 #undef CLEANUP
 
-static xf86ConfigSymTabRec VideoAdaptorTab[] = {
+static const xf86ConfigSymTabRec VideoAdaptorTab[] = {
     {ENDSECTION, "endsection"},
     {IDENTIFIER, "identifier"},
     {VENDOR, "vendorname"},
diff --git a/hw/xfree86/parser/configProcs.h b/hw/xfree86/parser/configProcs.h
index 171f8e8..7a46e01 100644
--- a/hw/xfree86/parser/configProcs.h
+++ b/hw/xfree86/parser/configProcs.h
@@ -102,9 +102,9 @@ void xf86printVideoAdaptorSection(FILE * cf, XF86ConfVideoAdaptorPtr ptr);
 void xf86freeVideoAdaptorList(XF86ConfVideoAdaptorPtr ptr);
 
 /* scan.c */
-int xf86getToken(xf86ConfigSymTabRec * tab);
+int xf86getToken(const xf86ConfigSymTabRec * tab);
 int xf86getSubToken(char **comment);
-int xf86getSubTokenWithTab(char **comment, xf86ConfigSymTabRec * tab);
+int xf86getSubTokenWithTab(char **comment, const xf86ConfigSymTabRec * tab);
 void xf86unGetToken(int token);
 char *xf86tokenString(void);
 void
@@ -116,7 +116,7 @@ _X_ATTRIBUTE_PRINTF(1, 2);
 void
 xf86setSection(const char *section);
 int
-xf86getStringToken(xf86ConfigSymTabRec * tab);
+xf86getStringToken(const xf86ConfigSymTabRec * tab);
 
 /* write.c */
 /* DRI.c */
diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c
index 327c02a..ec038ae 100644
--- a/hw/xfree86/parser/read.c
+++ b/hw/xfree86/parser/read.c
@@ -61,7 +61,7 @@
 #include "Configint.h"
 
 
-static xf86ConfigSymTabRec TopLevelTab[] = {
+static const xf86ConfigSymTabRec TopLevelTab[] = {
     {SECTION, "section"},
     {-1, ""},
 };
diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c
index b8a08cf..2760439 100644
--- a/hw/xfree86/parser/scan.c
+++ b/hw/xfree86/parser/scan.c
@@ -87,7 +87,7 @@
 #define CONFIG_BUF_LEN     1024
 #define CONFIG_MAX_FILES   64
 
-static int StringToToken(const char *, xf86ConfigSymTabRec *);
+static int StringToToken(const char *, const xf86ConfigSymTabRec *);
 
 static struct {
     FILE *file;
@@ -247,7 +247,7 @@ xf86getNextLine(void)
  *      pushToken.
  */
 int
-xf86getToken(xf86ConfigSymTabRec * tab)
+xf86getToken(const xf86ConfigSymTabRec * tab)
 {
     int c, i;
 
@@ -460,7 +460,7 @@ xf86getSubToken(char **comment)
  /*NOTREACHED*/}
 
 int
-xf86getSubTokenWithTab(char **comment, xf86ConfigSymTabRec * tab)
+xf86getSubTokenWithTab(char **comment, const xf86ConfigSymTabRec * tab)
 {
     int token;
 
@@ -1023,13 +1023,13 @@ xf86setSection(const char *section)
  *  Lookup a string if it is actually a token in disguise.
  */
 int
-xf86getStringToken(xf86ConfigSymTabRec * tab)
+xf86getStringToken(const xf86ConfigSymTabRec * tab)
 {
     return StringToToken(xf86_lex_val.str, tab);
 }
 
 static int
-StringToToken(const char *str, xf86ConfigSymTabRec * tab)
+StringToToken(const char *str, const xf86ConfigSymTabRec * tab)
 {
     int i;
 
commit 3981dcdd489b60fbf356534a509ca93dcbedf769
Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Sun Apr 17 20:34:43 2016 +0100

    dri3: remove unused file dri3int.h
    
    Copied during the prototyping stage and never used.
    
    Cc: Keith Packard <keithp at keithp.com>
    Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/dri3/dri3int.h b/dri3/dri3int.h
deleted file mode 100644
index 7f53eba..0000000
--- a/dri3/dri3int.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright © 2011 Daniel Stone
- *
- * 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.
- *
- * Author: Daniel Stone <daniel at fooishbar.org>
- */
-
-extern Bool DRI2ModuleSetup(void);
commit a1b13cda6169a98d694451fec75e63352e9d90bd
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Jan 6 09:09:21 2016 -0500

    xfree86: Remove xf86RegisterRootWindowProperty
    
    All consumers have been ported to the root window callback, so this can
    all be nuked.
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index 38b901f..adb5601 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -61,10 +61,6 @@ extern _X_EXPORT DevPrivateKeyRec xf86ScreenKeyRec;
 
 #define xf86ScreenKey (&xf86ScreenKeyRec)
 
-extern _X_EXPORT DevPrivateKeyRec xf86CreateRootWindowKeyRec;
-
-#define xf86CreateRootWindowKey (&xf86CreateRootWindowKeyRec)
-
 extern _X_EXPORT ScrnInfoPtr *xf86Screens;      /* List of pointers to ScrnInfoRecs */
 extern _X_EXPORT const unsigned char byte_reversed[256];
 extern _X_EXPORT Bool fbSlotClaimed;
@@ -351,9 +347,6 @@ xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag,
 
 extern _X_EXPORT Bool
 xf86IsScreenPrimary(ScrnInfoPtr pScrn);
-extern _X_EXPORT int
-xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
-                               int format, unsigned long len, void *value);
 extern _X_EXPORT Bool
 xf86IsUnblank(int mode);
 
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index 86bf15d..07cfabf 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -201,5 +201,4 @@ Bool xf86AllowMouseOpenFail = FALSE;
 Bool xf86VidModeDisabled = FALSE;
 Bool xf86VidModeAllowNonLocal = FALSE;
 #endif
-RootWinPropPtr *xf86RegisteredPropertiesTable = NULL;
 Bool xorgHWAccess = FALSE;
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index e6dd4a6..1d4b431 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -1817,81 +1817,6 @@ xf86IsScreenPrimary(ScrnInfoPtr pScrn)
     return FALSE;
 }
 
-int
-xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
-                               int format, unsigned long len, void *value)
-{
-    RootWinPropPtr pNewProp = NULL, pRegProp;
-    Bool existing = FALSE;
-
-    DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
-           ScrnIndex, (long)property, (long)type, format, len, value);
-
-    if (ScrnIndex < 0 || ScrnIndex >= xf86NumScreens) {
-        return BadMatch;
-    }
-
-    if (xf86RegisteredPropertiesTable &&
-        xf86RegisteredPropertiesTable[ScrnIndex]) {
-        for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex];
-             pNewProp; pNewProp = pNewProp->next) {
-            if (strcmp(pNewProp->name, NameForAtom(property)) == 0)
-                break;
-        }
-    }
-
-    if (!pNewProp) {
-        if ((pNewProp = (RootWinPropPtr) malloc(sizeof(RootWinProp))) == NULL) {
-            return BadAlloc;
-        }
-        /*
-         * We will put this property at the end of the list so that
-         * the changes are made in the order they were requested.
-         */
-        pNewProp->next = NULL;
-    }
-    else {
-        free((void *) pNewProp->name);
-        existing = TRUE;
-    }
-
-    pNewProp->name = xnfstrdup(NameForAtom(property));
-    pNewProp->type = type;
-    pNewProp->format = format;
-    pNewProp->size = len;
-    pNewProp->data = value;
-
-    DebugF("new property filled\n");
-
-    if (xf86RegisteredPropertiesTable == NULL) {
-        DebugF("creating xf86RegisteredPropertiesTable[] size %d\n",
-               xf86NumScreens);
-        xf86RegisteredPropertiesTable =
-            xnfcalloc(sizeof(RootWinProp), xf86NumScreens);
-    }
-
-    DebugF("xf86RegisteredPropertiesTable %p\n",
-           (void *) xf86RegisteredPropertiesTable);
-    DebugF("xf86RegisteredPropertiesTable[%d] %p\n",
-           ScrnIndex, (void *) xf86RegisteredPropertiesTable[ScrnIndex]);
-
-    if (!existing) {
-        if (xf86RegisteredPropertiesTable[ScrnIndex] == NULL) {
-            xf86RegisteredPropertiesTable[ScrnIndex] = pNewProp;
-        }
-        else {
-            pRegProp = xf86RegisteredPropertiesTable[ScrnIndex];
-            while (pRegProp->next != NULL) {
-                DebugF("- next %p\n", (void *) pRegProp);
-                pRegProp = pRegProp->next;
-            }
-            pRegProp->next = pNewProp;
-        }
-    }
-    DebugF("xf86RegisterRootWindowProperty succeeded\n");
-    return Success;
-}
-
 Bool
 xf86IsUnblank(int mode)
 {
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 744af7c..46976c1 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -297,50 +297,6 @@ xf86PrivsElevated(void)
     return privsElevated;
 }
 
-static Bool
-xf86CreateRootWindow(WindowPtr pWin)
-{
-    int ret = TRUE;
-    int err = Success;
-    ScreenPtr pScreen = pWin->drawable.pScreen;
-    RootWinPropPtr pProp;
-    CreateWindowProcPtr create_window = (CreateWindowProcPtr)
-        dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
-
-    DebugF("xf86CreateRootWindow(%p)\n", pWin);
-
-    /* Unhook this function ... */
-    pScreen->CreateWindow = create_window;
-    dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
-
-    /* ... and call the previous CreateWindow fuction, if any */
-    if (NULL != pScreen->CreateWindow) {
-        ret = (*pScreen->CreateWindow) (pWin);
-    }
-
-    /* Now do our stuff */
-    if (xf86RegisteredPropertiesTable != NULL) {
-        if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
-            for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
-                 pProp != NULL && err == Success; pProp = pProp->next) {
-                Atom prop;
-
-                prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
-                err = dixChangeWindowProperty(serverClient, pWin,
-                                              prop, pProp->type,
-                                              pProp->format, PropModeReplace,
-                                              pProp->size, pProp->data, FALSE);
-            }
-
-            /* Look at err */
-            ret &= (err == Success);
-
-        }
-    }
-
-    return ret;
-}
-
 static void
 InstallSignalHandlers(void)
 {
@@ -815,8 +771,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
         if (!xf86ColormapAllocatePrivates(xf86Screens[i]))
             FatalError("Cannot register DDX private keys");
 
-    if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0) ||
-        !dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
+    if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0))
         FatalError("Cannot register DDX private keys");
 
     for (i = 0; i < xf86NumGPUScreens; i++) {
@@ -887,11 +842,6 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
         DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
                i, xf86Screens[i]->pScreen->CreateWindow);
 
-        dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
-                      xf86CreateRootWindowKey,
-                      xf86Screens[i]->pScreen->CreateWindow);
-        xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
-
         if (PictureGetSubpixelOrder(xf86Screens[i]->pScreen) == SubPixelUnknown) {
             xf86MonPtr DDC = (xf86MonPtr) (xf86Screens[i]->monitor->DDC);
 
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index ad3f2b9..81f7294 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -92,8 +92,6 @@ extern _X_EXPORT const char *xf86VisualNames[];
 extern _X_EXPORT int xf86Verbose;       /* verbosity level */
 extern _X_EXPORT int xf86LogVerbose;    /* log file verbosity level */
 
-extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable;
-
 extern ScrnInfoPtr *xf86GPUScreens;      /* List of pointers to ScrnInfoRecs */
 extern int xf86NumGPUScreens;
 #ifndef DEFAULT_VERBOSE
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index 4830fb3..ad86138 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -115,16 +115,6 @@ typedef struct {
 } DPMSRec, *DPMSPtr;
 #endif
 
-/* Information for root window properties. */
-typedef struct _RootWinProp {
-    struct _RootWinProp *next;
-    const char *name;
-    Atom type;
-    short format;
-    long size;
-    void *data;
-} RootWinProp, *RootWinPropPtr;
-
 /* ISC's cc can't handle ~ of UL constants, so explicitly type cast them. */
 #define XLED1   ((unsigned long) 0x00000001)
 #define XLED2   ((unsigned long) 0x00000002)
commit e89c7f1c2a0ea3480b21446e413073c1427285ae
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Jan 6 09:04:15 2016 -0500

    xfree86: Create EDID atom from the root window callback (v2)
    
    v2: Fix swapped callback args
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/ddc/ddcProperty.c b/hw/xfree86/ddc/ddcProperty.c
index 53446b8..e68672e 100644
--- a/hw/xfree86/ddc/ddcProperty.c
+++ b/hw/xfree86/ddc/ddcProperty.c
@@ -57,29 +57,13 @@ setRootWindowEDID(ScreenPtr pScreen, xf86MonPtr DDC)
 }
 
 static void
-edidMakeAtom(int i, const char *name, xf86MonPtr DDC)
+addEDIDProp(CallbackListPtr *pcbl, void *scrn, void *screen)
 {
-    Atom atom;
-    unsigned char *atom_data;
-    int size = edidSize(DDC);
+    ScreenPtr pScreen = screen;
+    ScrnInfoPtr pScrn = scrn;
 
-    if (!(atom_data = malloc(size * sizeof(CARD8))))
-        return;
-
-    atom = MakeAtom(name, strlen(name), TRUE);
-    memcpy(atom_data, DDC->rawData, size);
-    xf86RegisterRootWindowProperty(i, atom, XA_INTEGER, 8, size, atom_data);
-}
-
-static void
-addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
-{
-    int scrnIndex = pScrn->scrnIndex;
-
-    if (xf86Initialising)
-        edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC);
-    else
-        setRootWindowEDID(pScrn->pScreen, DDC);
+    if (xf86ScreenToScrn(pScreen) == pScrn)
+        setRootWindowEDID(pScreen, pScrn->monitor->DDC);
 }
 
 Bool
@@ -90,7 +74,10 @@ xf86SetDDCproperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
 
     xf86EdidMonitorSet(pScrn->scrnIndex, pScrn->monitor, DDC);
 
-    addRootWindowProperties(pScrn, DDC);
+    if (xf86Initialising)
+        AddCallback(&RootWindowFinalizeCallback, addEDIDProp, pScrn);
+    else
+        setRootWindowEDID(pScrn->pScreen, DDC);
 
     return TRUE;
 }
commit 8e3010d7d8e8c49c8859b576de1808ae7b2859be
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Jan 6 08:54:47 2016 -0500

    xfree86: Remove a never-hit diagnostic message
    
    Practically speaking, the EDID major version is never not 1.
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/ddc/ddcProperty.c b/hw/xfree86/ddc/ddcProperty.c
index e1b37db..53446b8 100644
--- a/hw/xfree86/ddc/ddcProperty.c
+++ b/hw/xfree86/ddc/ddcProperty.c
@@ -76,17 +76,10 @@ addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
 {
     int scrnIndex = pScrn->scrnIndex;
 
-    if (DDC->ver.version == 1) {
-        if (xf86Initialising)
-            edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC);
-        else
-            setRootWindowEDID(pScrn->pScreen, DDC);
-    }
-    else {
-        xf86DrvMsg(scrnIndex, X_PROBED, "unexpected EDID version %d.%d\n",
-                   DDC->ver.version, DDC->ver.revision);
-        return;
-    }
+    if (xf86Initialising)
+        edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC);
+    else
+        setRootWindowEDID(pScrn->pScreen, DDC);
 }
 
 Bool
commit 7961377567f15dfad9d96c5c0a0992b38013d973
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Jan 6 08:47:37 2016 -0500

    xfree86: Make xf86SetDDCproperties work more than once (v2)
    
    We can call this more than once via xf86OutputSetEDID since hotplug is
    actually a thing in RANDR 1.2, but xf86RegisterRootWindowProperty merely
    adds the data to a list to be applied to the root at CreateWindow time,
    so calls past the first (for a given screen) would have no effect until
    server regen.
    
    Once we've initialised pScrn->pScreen is filled in, so we can just set
    the property directly.
    
    v2: Removed pointless version check, deobfuscate math (Walter Harms)
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/ddc/ddcProperty.c b/hw/xfree86/ddc/ddcProperty.c
index c51c3e6..e1b37db 100644
--- a/hw/xfree86/ddc/ddcProperty.c
+++ b/hw/xfree86/ddc/ddcProperty.c
@@ -27,6 +27,7 @@
 
 #include "xf86.h"
 #include "xf86DDC.h"
+#include "xf86Priv.h"
 #include <X11/Xatom.h>
 #include "property.h"
 #include "propertyst.h"
@@ -34,17 +35,39 @@
 
 #define EDID1_ATOM_NAME         "XFree86_DDC_EDID1_RAWDATA"
 
+static int
+edidSize(const xf86MonPtr DDC)
+{
+    int ret = 128;
+
+    if (DDC->flags & EDID_COMPLETE_RAWDATA)
+       ret += DDC->no_sections * 128;
+
+    return ret;
+}
+
 static void
-edidMakeAtom(int i, const char *name, CARD8 *data, int size)
+setRootWindowEDID(ScreenPtr pScreen, xf86MonPtr DDC)
+{
+    Atom atom = MakeAtom(EDID1_ATOM_NAME, strlen(EDID1_ATOM_NAME), TRUE);
+
+    dixChangeWindowProperty(serverClient, pScreen->root, atom, XA_INTEGER,
+                            8, PropModeReplace, edidSize(DDC), DDC->rawData,
+                            FALSE);
+}
+
+static void
+edidMakeAtom(int i, const char *name, xf86MonPtr DDC)
 {
     Atom atom;
     unsigned char *atom_data;
+    int size = edidSize(DDC);
 
     if (!(atom_data = malloc(size * sizeof(CARD8))))
         return;
 
     atom = MakeAtom(name, strlen(name), TRUE);
-    memcpy(atom_data, data, size);
+    memcpy(atom_data, DDC->rawData, size);
     xf86RegisterRootWindowProperty(i, atom, XA_INTEGER, 8, size, atom_data);
 }
 
@@ -54,10 +77,10 @@ addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
     int scrnIndex = pScrn->scrnIndex;
 
     if (DDC->ver.version == 1) {
-        int size = 128 +
-            (DDC->flags & EDID_COMPLETE_RAWDATA ? DDC->no_sections * 128 : 0);
-
-        edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC->rawData, size);
+        if (xf86Initialising)
+            edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC);
+        else
+            setRootWindowEDID(pScrn->pScreen, DDC);
     }
     else {
         xf86DrvMsg(scrnIndex, X_PROBED, "unexpected EDID version %d.%d\n",
commit 8be83fff04a009109a956837ca983a96fd279711
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Jan 6 08:35:43 2016 -0500

    xfree86: Remove some leftovers from DisplayID support
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/ddc/ddcProperty.c b/hw/xfree86/ddc/ddcProperty.c
index fc63f0e..c51c3e6 100644
--- a/hw/xfree86/ddc/ddcProperty.c
+++ b/hw/xfree86/ddc/ddcProperty.c
@@ -53,11 +53,7 @@ addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
 {
     int scrnIndex = pScrn->scrnIndex;
 
-    if (DDC->flags & MONITOR_DISPLAYID) {
-        /* Don't bother, use RANDR already */
-        return;
-    }
-    else if (DDC->ver.version == 1) {
+    if (DDC->ver.version == 1) {
         int size = 128 +
             (DDC->flags & EDID_COMPLETE_RAWDATA ? DDC->no_sections * 128 : 0);
 
@@ -76,9 +72,7 @@ xf86SetDDCproperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
     if (!pScrn || !pScrn->monitor || !DDC)
         return FALSE;
 
-    if (DDC->flags & MONITOR_DISPLAYID);
-    else
-        xf86EdidMonitorSet(pScrn->scrnIndex, pScrn->monitor, DDC);
+    xf86EdidMonitorSet(pScrn->scrnIndex, pScrn->monitor, DDC);
 
     addRootWindowProperties(pScrn, DDC);
 
diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h
index 4c2da51..750e427 100644
--- a/hw/xfree86/ddc/edid.h
+++ b/hw/xfree86/ddc/edid.h
@@ -537,7 +537,6 @@ struct detailed_monitor_section {
 #define MONITOR_EDID_COMPLETE_RAWDATA	0x01
 /* old, don't use */
 #define EDID_COMPLETE_RAWDATA		0x01
-#define MONITOR_DISPLAYID		0x02
 
 /*
  * For DisplayID devices, only the scrnIndex, flags, and rawData fields
commit 0cd2a24b61ef1583fc6b3fec7d01c7481cc97d52
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Jan 6 08:30:07 2016 -0500

    xfree86: Unexport xf86Initialising, remove xf86ServerIsInitialising
    
    Neither of these are used from outside the server.
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index 1cde478..38b901f 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -306,8 +306,6 @@ xf86ServerIsExiting(void);
 extern _X_EXPORT Bool
 xf86ServerIsResetting(void);
 extern _X_EXPORT Bool
-xf86ServerIsInitialising(void);
-extern _X_EXPORT Bool
 xf86ServerIsOnlyDetecting(void);
 extern _X_EXPORT Bool
 xf86CaughtSignal(void);
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index 3b01a49..e6dd4a6 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -1516,12 +1516,6 @@ xf86ServerIsResetting(void)
 }
 
 Bool
-xf86ServerIsInitialising(void)
-{
-    return xf86Initialising;
-}
-
-Bool
 xf86ServerIsOnlyDetecting(void)
 {
     return xf86DoConfigure;
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index 6e374eb..ad3f2b9 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -86,7 +86,7 @@ extern _X_EXPORT serverLayoutRec xf86ConfigLayout;
 extern _X_EXPORT DriverPtr *xf86DriverList;
 extern _X_EXPORT int xf86NumDrivers;
 extern _X_EXPORT Bool xf86Resetting;
-extern _X_EXPORT Bool xf86Initialising;
+extern Bool xf86Initialising;
 extern _X_EXPORT int xf86NumScreens;
 extern _X_EXPORT const char *xf86VisualNames[];
 extern _X_EXPORT int xf86Verbose;       /* verbosity level */
diff --git a/hw/xfree86/doc/ddxDesign.xml b/hw/xfree86/doc/ddxDesign.xml
index 53647d0..f7d6628 100644
--- a/hw/xfree86/doc/ddxDesign.xml
+++ b/hw/xfree86/doc/ddxDesign.xml
@@ -2054,18 +2054,6 @@ functions is as follows:
 
       <blockquote><para>
 	  <programlisting>
-    Bool xf86ServerIsInitialising();
-	  </programlisting>
-	  <blockquote><para>
-      Returns <constant>TRUE</constant> if the server is at the beginning of
-      a generation and is in the process of initialising, and
-      <constant>FALSE</constant> otherwise.
-	    </para></blockquote>
-
-	</para></blockquote>
-
-      <blockquote><para>
-	  <programlisting>
     Bool xf86ServerIsOnlyProbing();
 	  </programlisting>
 	  <blockquote><para>
commit e70ee11a39b957141fbc565d79d128a46fac5f34
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Jan 5 16:27:41 2016 -0500

    xfree86: Create VT atoms from the root window callback (v2)
    
    v2: Fix swapped callback args
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index f5f407e..744af7c 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -381,10 +381,28 @@ AddSeatId(CallbackListPtr *pcbl, void *data, void *screen)
                    "Failed to register seat property\n");
 }
 
-/* The memory storing the initial value of the XFree86_has_VT root window
- * property.  This has to remain available until server start-up, so we just
- * use a global. */
-static CARD32 HasVTValue = 1;
+static void
+AddVTAtoms(CallbackListPtr *pcbl, void *data, void *screen)
+{
+#define VT_ATOM_NAME         "XFree86_VT"
+    int err, HasVT = 1;
+    ScreenPtr pScreen = screen;
+    Atom VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
+    Atom HasVTAtom = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1,
+                              TRUE);
+
+    err = dixChangeWindowProperty(serverClient, pScreen->root, VTAtom,
+                                  XA_INTEGER, 32, PropModeReplace, 1,
+                                  &xf86Info.vtno, FALSE);
+
+    err |= dixChangeWindowProperty(serverClient, pScreen->root, HasVTAtom,
+                                   XA_INTEGER, 32, PropModeReplace, 1,
+                                   &HasVT, FALSE);
+
+    if (err != Success)
+        xf86DrvMsg(pScreen->myNum, X_WARNING,
+                   "Failed to register VT properties\n");
+}
 
 /*
  * InitOutput --
@@ -727,44 +745,6 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
         }
         formatsDone = TRUE;
 
-        if (xf86Info.vtno >= 0) {
-#define VT_ATOM_NAME         "XFree86_VT"
-            Atom VTAtom = -1;
-            Atom HasVTAtom = -1;
-            CARD32 *VT = NULL;
-            CARD32 *HasVT = &HasVTValue;
-            int ret;
-
-            /* This memory needs to stay available until the screen has been
-               initialized, and we can create the property for real.
-             */
-            if ((VT = malloc(sizeof(CARD32))) == NULL) {
-                FatalError
-                    ("Unable to make VT property - out of memory. Exiting...\n");
-            }
-            *VT = xf86Info.vtno;
-
-            VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
-            HasVTAtom = MakeAtom(HAS_VT_ATOM_NAME,
-                                 sizeof(HAS_VT_ATOM_NAME) - 1, TRUE);
-
-            for (i = 0, ret = Success; i < xf86NumScreens && ret == Success;
-                 i++) {
-                ret =
-                    xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
-                                                   VTAtom, XA_INTEGER, 32, 1,
-                                                   VT);
-                if (ret == Success)
-                    ret = xf86RegisterRootWindowProperty(xf86Screens[i]
-                                                             ->scrnIndex,
-                                                         HasVTAtom, XA_INTEGER,
-                                                         32, 1, HasVT);
-                if (ret != Success)
-                    xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
-                               "Failed to register VT properties\n");
-            }
-        }
-
         /* If a screen uses depth 24, show what the pixmap format is */
         for (i = 0; i < xf86NumScreens; i++) {
             if (xf86Screens[i]->depth == 24) {
@@ -798,6 +778,9 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
             xf86EnableIO();
     }
 
+    if (xf86Info.vtno >= 0)
+        AddCallback(&RootWindowFinalizeCallback, AddVTAtoms, NULL);
+
     if (SeatId)
         AddCallback(&RootWindowFinalizeCallback, AddSeatId, SeatId);
 
commit da9ee1eddd65d00788cef8a3becfad948c0a2168
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Jan 5 16:11:42 2016 -0500

    xfree86: Create seat atom from the root window callback (v2)
    
    v2: Fix swapped callback args
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index de51497..f5f407e 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -365,6 +365,22 @@ InstallSignalHandlers(void)
     }
 }
 
+static void
+AddSeatId(CallbackListPtr *pcbl, void *data, void *screen)
+{
+    ScreenPtr pScreen = screen;
+    Atom SeatAtom = MakeAtom(SEAT_ATOM_NAME, sizeof(SEAT_ATOM_NAME) - 1, TRUE);
+    int err;
+
+    err = dixChangeWindowProperty(serverClient, pScreen->root, SeatAtom,
+                                  XA_STRING, 8, PropModeReplace,
+                                  strlen(data) + 1, data, FALSE);
+
+    if (err != Success)
+        xf86DrvMsg(pScreen->myNum, X_WARNING,
+                   "Failed to register seat property\n");
+}
+
 /* The memory storing the initial value of the XFree86_has_VT root window
  * property.  This has to remain available until server start-up, so we just
  * use a global. */
@@ -749,26 +765,6 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
             }
         }
 
-        if (SeatId) {
-            Atom SeatAtom;
-
-            SeatAtom =
-                MakeAtom(SEAT_ATOM_NAME, sizeof(SEAT_ATOM_NAME) - 1, TRUE);
-
-            for (i = 0; i < xf86NumScreens; i++) {
-                int ret;
-
-                ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
-                                                     SeatAtom, XA_STRING, 8,
-                                                     strlen(SeatId) + 1,
-                                                     SeatId);
-                if (ret != Success) {
-                    xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
-                               "Failed to register seat property\n");
-                }
-            }
-        }
-
         /* If a screen uses depth 24, show what the pixmap format is */
         for (i = 0; i < xf86NumScreens; i++) {
             if (xf86Screens[i]->depth == 24) {
@@ -802,6 +798,9 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
             xf86EnableIO();
     }
 
+    if (SeatId)
+        AddCallback(&RootWindowFinalizeCallback, AddSeatId, SeatId);
+
     /*
      * Use the previously collected parts to setup pScreenInfo
      */
commit 2c3a3afb5104714b637c1c4aea195df73e0fa918
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Jan 5 15:56:42 2016 -0500

    dix: Add RootWindowFinalizeCallback
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/dix/main.c b/dix/main.c
index 661ab03..77e0f2e 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -129,6 +129,8 @@ pthread_cond_t serverRunningCond = PTHREAD_COND_INITIALIZER;
 
 #endif
 
+CallbackListPtr RootWindowFinalizeCallback = NULL;
+
 int
 dix_main(int argc, char *argv[], char *envp[])
 {
@@ -230,6 +232,7 @@ dix_main(int argc, char *argv[], char *envp[])
                 FatalError("failed to create default stipple");
             if (!CreateRootWindow(pScreen))
                 FatalError("failed to create root window");
+            CallCallbacks(&RootWindowFinalizeCallback, pScreen);
         }
 
         if (SetDefaultFontPath(defaultFontPath) != Success) {
diff --git a/include/dix.h b/include/dix.h
index d49d055..f63606a 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -594,6 +594,8 @@ typedef struct {
     DeviceIntPtr device;
 } DeviceEventInfoRec;
 
+extern _X_EXPORT CallbackListPtr RootWindowFinalizeCallback;
+
 extern int
 XItoCoreType(int xi_type);
 extern Bool
commit 8437955515ad59b0bfcd6598248e7f0ffc706370
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Mar 17 09:53:58 2016 +0100

    glamor: fix wrong offset on composite rectangles
    
    When using PictOpSrc, the destination is wrongly shifted back to (0, 0).
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94568
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
index 885a6c0..199e627 100644
--- a/glamor/glamor_compositerects.c
+++ b/glamor/glamor_compositerects.c
@@ -107,7 +107,6 @@ glamor_composite_rectangles(CARD8 op,
     struct glamor_pixmap_private *priv;
     pixman_region16_t region;
     pixman_box16_t *boxes;
-    int dst_x, dst_y;
     int num_boxes;
     PicturePtr source = NULL;
     Bool need_free_region = FALSE;
@@ -225,17 +224,18 @@ glamor_composite_rectangles(CARD8 op,
            RegionExtents(&region)->x2, RegionExtents(&region)->y2,
            RegionNumRects(&region));
 
-    glamor_get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
-    pixman_region_translate(&region, dst_x, dst_y);
-
-    DEBUGF("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n",
-           __FUNCTION__, dst_x, dst_y,
-           RegionExtents(&region)->x1, RegionExtents(&region)->y1,
-           RegionExtents(&region)->x2, RegionExtents(&region)->y2);
-
     boxes = pixman_region_rectangles(&region, &num_boxes);
     if (op == PictOpSrc || op == PictOpClear) {
         CARD32 pixel;
+        int dst_x, dst_y;
+
+        glamor_get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
+        pixman_region_translate(&region, dst_x, dst_y);
+
+        DEBUGF("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n",
+               __FUNCTION__, dst_x, dst_y,
+               RegionExtents(&region)->x1, RegionExtents(&region)->y1,
+               RegionExtents(&region)->x2, RegionExtents(&region)->y2);
 
         if (op == PictOpClear)
             pixel = 0;
commit e8e5d839968e22cf42a6e1982a07b02c6f4a4562
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Apr 1 13:38:11 2016 +0200

    xwayland: Fix compiler warning in GLAMOR Xv
    
    XvWindowMask is defined as 0x00020000 and cannot fit in the XvAdaptor
    type which is defined as an unsigned char, thus causing a compiler
    warning:
    
      xwayland-glamor-xv.c: In function ‘xwl_glamor_xv_add_adaptors’:
      xwayland-glamor-xv.c:339:16: warning: large integer implicitly
      truncated to unsigned type [-Woverflow]
    
    This XvWindowMask value is actually not used for XvAdaptor itself but by
    the server in its xf86xv implementation, so we don't even need that mask
    in our xwayland-glamor-xv implementation.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-glamor-xv.c b/hw/xwayland/xwayland-glamor-xv.c
index c99418d..65f93c6 100644
--- a/hw/xwayland/xwayland-glamor-xv.c
+++ b/hw/xwayland/xwayland-glamor-xv.c
@@ -336,7 +336,7 @@ xwl_glamor_xv_add_adaptors(ScreenPtr pScreen)
 
     pa = xnfcalloc(1, sizeof(XvAdaptorRec));
     pa->pScreen = pScreen;
-    pa->type = (unsigned int) (XvWindowMask | XvInputMask | XvImageMask);
+    pa->type = (unsigned char) (XvInputMask | XvImageMask);
     pa->ddStopVideo = xwl_glamor_xv_stop_video;
     pa->ddPutImage = xwl_glamor_xv_put_image;
     pa->ddSetPortAttribute = xwl_glamor_xv_set_port_attribute;
commit f9b5bbaa3a7fce1a4efb2084b8d9d82b98d4ee83
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Mar 8 15:42:42 2016 +1000

    xkb: fix SlowKeys release/reject beeps
    
    Wrong use of the mask here caused a beep whenever a key was rejected but
    also when it was released after being accepted. Fix the mask to check
    for the correct enabled controls.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Daniel Stone <daniels at collabora.com>

diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index 02e820b..892cb30 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -618,6 +618,7 @@ AccessXFilterReleaseEvent(DeviceEvent *event, DeviceIntPtr keybd)
     if (ctrls->enabled_ctrls & XkbSlowKeysMask) {
         xkbAccessXNotify ev;
         unsigned beep_type;
+        unsigned mask;
 
         ev.keycode = key;
         ev.slowKeysDelay = ctrls->slow_keys_delay;
@@ -625,14 +626,16 @@ AccessXFilterReleaseEvent(DeviceEvent *event, DeviceIntPtr keybd)
         if (BitIsOn(keybd->key->down, key) || (xkbi->mouseKey == key)) {
             ev.detail = XkbAXN_SKRelease;
             beep_type = _BEEP_SLOW_RELEASE;
+            mask = XkbAX_SKReleaseFBMask;
         }
         else {
             ev.detail = XkbAXN_SKReject;
             beep_type = _BEEP_SLOW_REJECT;
+            mask = XkbAX_SKRejectFBMask;
             ignoreKeyEvent = TRUE;
         }
         XkbSendAccessXNotify(keybd, &ev);
-        if (XkbAX_NeedFeedback(ctrls, XkbAX_SKRejectFBMask)) {
+        if (XkbAX_NeedFeedback(ctrls, mask)) {
             XkbDDXAccessXBeep(keybd, beep_type, XkbSlowKeysMask);
         }
         if (xkbi->slowKey == key)
commit a6288f0954cf97499e78849a87847062ee962c17
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Tue Nov 3 19:07:43 2015 +0000

    hw/xwin: xcbify internal window manager
    
    Convert the code for the multiwindow mode internal window manager to xcb
    
    xcb conversion avoids xlib/xserver namespace collision and _XSERVER64 type
    sizing issues
    
    v2: Various fixes
    v3: Don't include X11/extensions/windowswmstr.h, which uses the Display type
    and thus depends on Xlib.h, just for _WINDOWSWM_NATIVE_HWND
    v4: Fix indentation, add some error handling.
    Fix a bug with ConfigureNotify handling
    v5: Fix a bug which prevented WM_NORMAL_HINTS from being checked
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/configure.ac b/configure.ac
index 1e78b7d..06b6a08 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2150,7 +2150,7 @@ if test "x$XWIN" = xyes; then
 	AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
 	AC_CHECK_TOOL(WINDRES, windres)
 
-	PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfixes x11-xcb xcb-image xcb-icccm])
+	PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfixes x11-xcb xcb-aux xcb-image xcb-ewmh xcb-icccm])
 
 	if test "x$WINDOWSWM" = xauto; then
 		PKG_CHECK_EXISTS($WINDOWSWMPROTO, [WINDOWSWM=yes], [WINDOWSWM=no])
diff --git a/hw/xwin/winauth.c b/hw/xwin/winauth.c
index 7be7dca..e863439 100644
--- a/hw/xwin/winauth.c
+++ b/hw/xwin/winauth.c
@@ -38,6 +38,16 @@
 #include "securitysrv.h"
 #include "os/osdep.h"
 
+#include <xcb/xcb.h>
+
+/* Need to get this from Xlib.h */
+extern void XSetAuthorization(
+    const char *                /* name */,
+    int                         /* namelen */,
+    const char *                /* data */,
+    int                         /* datalen */
+);
+
 /*
  * Constants
  */
@@ -51,6 +61,7 @@
 static XID g_authId = 0;
 static unsigned int g_uiAuthDataLen = 0;
 static char *g_pAuthData = NULL;
+static xcb_auth_info_t auth_info;
 
 /*
  * Code to generate a MIT-MAGIC-COOKIE-1, copied from under XCSECURITY
@@ -131,6 +142,11 @@ winGenerateAuthorization(void)
                  g_uiAuthDataLen, g_pAuthData);
     }
 
+    auth_info.name = AUTH_NAME;
+    auth_info.namelen = strlen(AUTH_NAME);
+    auth_info.data = g_pAuthData;
+    auth_info.datalen = g_uiAuthDataLen;
+
 #ifdef XCSECURITY
     /* Allocate structure for additional auth information */
     pAuth = (SecurityAuthorizationPtr)
@@ -168,3 +184,12 @@ winSetAuthorization(void)
     XSetAuthorization(AUTH_NAME,
                       strlen(AUTH_NAME), g_pAuthData, g_uiAuthDataLen);
 }
+
+xcb_auth_info_t *
+winGetXcbAuthInfo(void)
+{
+    if (g_pAuthData)
+        return &auth_info;
+
+    return NULL;
+}
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 80bb483..e23913e 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -45,17 +45,15 @@
 #define HANDLE void *
 #include <pthread.h>
 #undef HANDLE
-#include <X11/X.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xlib-xcb.h>
-#include <X11/Xlocale.h>
-#include <X11/Xproto.h>
-#include <X11/Xutil.h>
-#include <X11/cursorfont.h>
+#include <xcb/xcb.h>
+#include <xcb/xcb_icccm.h>
+#include <xcb/xcb_ewmh.h>
+#include <xcb/xcb_aux.h>
+
 #include <X11/Xwindows.h>
 
 /* Local headers */
+#include "X11/Xdefs.h" // for Bool type
 #include "winwindow.h"
 #include "winprefs.h"
 #include "window.h"
@@ -65,13 +63,9 @@
 #include "windisplay.h"
 #include "winmultiwindowicons.h"
 
-#ifdef XWIN_MULTIWINDOWEXTWM
-#include <X11/extensions/windowswmstr.h>
-#else
 /* We need the native HWND atom for intWM, so for consistency use the
-   same name as extWM would if we were building with enabled... */
+   same name as extWM does */
 #define WINDOWSWM_NATIVE_HWND "_WINDOWSWM_NATIVE_HWND"
-#endif
 
 #ifndef HOST_NAME_MAX
 #define HOST_NAME_MAX 255
@@ -80,6 +74,7 @@
 extern void winDebug(const char *format, ...);
 extern void winReshapeMultiWindow(WindowPtr pWin);
 extern void winUpdateRgnMultiWindow(WindowPtr pWin);
+extern xcb_auth_info_t *winGetXcbAuthInfo(void);
 
 #ifndef CYGDEBUG
 #define CYGDEBUG NO
@@ -94,8 +89,6 @@ extern void winUpdateRgnMultiWindow(WindowPtr pWin);
 #ifdef HAS_DEVWINDOWS
 #define WIN_MSG_QUEUE_FNAME	"/dev/windows"
 #endif
-#define WIN_JMP_OKAY		0
-#define WIN_JMP_ERROR_IO	2
 
 /*
  * Local structures
@@ -114,12 +107,14 @@ typedef struct _WMMsgQueueRec {
 } WMMsgQueueRec, *WMMsgQueuePtr;
 
 typedef struct _WMInfo {
-    Display *pDisplay;
+    xcb_connection_t *conn;
     WMMsgQueueRec wmMsgQueue;
-    Atom atmWmProtos;
-    Atom atmWmDelete;
-    Atom atmWmTakeFocus;
-    Atom atmPrivMap;
+    xcb_atom_t atmWmProtos;
+    xcb_atom_t atmWmDelete;
+    xcb_atom_t atmWmTakeFocus;
+    xcb_atom_t atmPrivMap;
+    xcb_atom_t atmUtf8String;
+    xcb_ewmh_connection_t ewmh;
 } WMInfoRec, *WMInfoPtr;
 
 typedef struct _WMProcArgRec {
@@ -129,7 +124,7 @@ typedef struct _WMProcArgRec {
 } WMProcArgRec, *WMProcArgPtr;
 
 typedef struct _XMsgProcArgRec {
-    Display *pDisplay;
+    xcb_connection_t *conn;
     DWORD dwScreen;
     WMInfoPtr pWMInfo;
     pthread_mutex_t *ppmServerStarted;
@@ -149,46 +144,31 @@ static Bool
  InitQueue(WMMsgQueuePtr pQueue);
 
 static void
- GetWindowName(Display * pDpy, Window iWin, char **ppWindowName);
+ GetWindowName(WMInfoPtr pWMInfo, xcb_window_t iWin, char **ppWindowName);
 
-static int
- SendXMessage(Display * pDisplay, Window iWin, Atom atmType, long nData);
+static void
+ SendXMessage(xcb_connection_t *conn, xcb_window_t iWin, xcb_atom_t atmType, long nData);
 
 static void
- UpdateName(WMInfoPtr pWMInfo, Window iWindow);
+ UpdateName(WMInfoPtr pWMInfo, xcb_window_t iWindow);
 
 static void *winMultiWindowWMProc(void *pArg);
 
-static int
- winMultiWindowWMErrorHandler(Display * pDisplay, XErrorEvent * pErr);
-
-static int
- winMultiWindowWMIOErrorHandler(Display * pDisplay);
-
 static void *winMultiWindowXMsgProc(void *pArg);
 
-static int
- winMultiWindowXMsgProcErrorHandler(Display * pDisplay, XErrorEvent * pErr);
-
-static int
- winMultiWindowXMsgProcIOErrorHandler(Display * pDisplay);
-
-static int
- winRedirectErrorHandler(Display * pDisplay, XErrorEvent * pErr);
-
 static void
  winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg);
 
 #if 0
 static void
- PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction);
+ PreserveWin32Stack(WMInfoPtr pWMInfo, xcb_window_t iWindow, UINT direction);
 #endif
 
 static Bool
-CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen);
+CheckAnotherWindowManager(xcb_connection_t *conn, DWORD dwScreen);
 
 static void
- winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle);
+ winApplyHints(WMInfoPtr pWMInfo, xcb_window_t iWindow, HWND hWnd, HWND * zstyle);
 
 void
  winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
@@ -197,14 +177,7 @@ void
  * Local globals
  */
 
-static jmp_buf g_jmpWMEntry;
-static XIOErrorHandler g_winMultiWindowWMOldIOErrorHandler;
-static pthread_t g_winMultiWindowWMThread;
-static jmp_buf g_jmpXMsgProcEntry;
-static XIOErrorHandler g_winMultiWindowXMsgProcOldIOErrorHandler;
-static pthread_t g_winMultiWindowXMsgProcThread;
 static Bool g_shutdown = FALSE;
-static Bool redirectError = FALSE;
 
 /*
  * Translate msg id to text, for debug purposes
@@ -328,7 +301,7 @@ PopMessage(WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo)
  */
 
 static Bool
-HaveMessage(WMMsgQueuePtr pQueue, UINT msg, Window iWindow)
+HaveMessage(WMMsgQueuePtr pQueue, UINT msg, xcb_window_t iWindow)
 {
     WMMsgNodePtr pNode;
 
@@ -376,29 +349,20 @@ InitQueue(WMMsgQueuePtr pQueue)
 
 static
 char *
-Xutf8TextPropertyToString(Display * pDisplay, XTextProperty * xtp)
+Xutf8TextPropertyToString(WMInfoPtr pWMInfo, xcb_icccm_get_text_property_reply_t *xtp)
 {
-    int nNum;
-    char **ppList;
     char *pszReturnData;
 
-    if (Xutf8TextPropertyToTextList(pDisplay, xtp, &ppList, &nNum) >= Success &&
-        nNum > 0 && *ppList) {
-        int i;
-        int iLen = 0;
-
-        for (i = 0; i < nNum; i++)
-            iLen += strlen(ppList[i]);
-        pszReturnData = malloc(iLen + 1);
-        pszReturnData[0] = '\0';
-        for (i = 0; i < nNum; i++)
-            strcat(pszReturnData, ppList[i]);
-        if (ppList)
-            XFreeStringList(ppList);
+    if ((xtp->encoding == XCB_ATOM_STRING) ||        // Latin1 ISO 8859-1
+        (xtp->encoding == pWMInfo->atmUtf8String)) { // UTF-8  ISO 10646
+        pszReturnData = strndup(xtp->name, xtp->name_len);
     }
     else {
-        pszReturnData = malloc(1);
-        pszReturnData[0] = '\0';
+        // Converting from COMPOUND_TEXT to UTF-8 properly is complex to
+        // implement, and not very much use unless you have an old
+        // application which isn't UTF-8 aware.
+        ErrorF("Xutf8TextPropertyToString: text encoding %d is not implemented\n", xtp->encoding);
+        pszReturnData = strdup("");
     }
 
     return pszReturnData;
@@ -409,11 +373,11 @@ Xutf8TextPropertyToString(Display * pDisplay, XTextProperty * xtp)
  */
 
 static void
-GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName)
+GetWindowName(WMInfoPtr pWMInfo, xcb_window_t iWin, char **ppWindowName)
 {
-    int nResult;
-    XTextProperty xtpWindowName;
-    XTextProperty xtpClientMachine;
+    xcb_connection_t *conn = pWMInfo->conn;
+    xcb_get_property_cookie_t cookie;
+    xcb_icccm_get_text_property_reply_t reply;
     char *pszWindowName;
     char *pszClientMachine;
     char hostname[HOST_NAME_MAX + 1];
@@ -426,24 +390,21 @@ GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName)
     *ppWindowName = NULL;
 
     /* Try to get window name */
-    nResult = XGetWMName(pDisplay, iWin, &xtpWindowName);
-    if (!nResult || !xtpWindowName.value || !xtpWindowName.nitems) {
-#if CYGMULTIWINDOW_DEBUG
-        ErrorF("GetWindowName - XGetWMName failed.  No name.\n");
-#endif
+    cookie = xcb_icccm_get_wm_name(conn, iWin);
+    if (!xcb_icccm_get_wm_name_reply(conn, cookie, &reply, NULL)) {
+        ErrorF("GetWindowName - xcb_icccm_get_wm_name_reply failed.  No name.\n");
         return;
     }
 
-    pszWindowName = Xutf8TextPropertyToString(pDisplay, &xtpWindowName);
-    XFree(xtpWindowName.value);
+    pszWindowName = Xutf8TextPropertyToString(pWMInfo, &reply);
+    xcb_icccm_get_text_property_reply_wipe(&reply);
 
     if (g_fHostInTitle) {
         /* Try to get client machine name */
-        nResult = XGetWMClientMachine(pDisplay, iWin, &xtpClientMachine);
-        if (nResult && xtpClientMachine.value && xtpClientMachine.nitems) {
-            pszClientMachine =
-                Xutf8TextPropertyToString(pDisplay, &xtpClientMachine);
-            XFree(xtpClientMachine.value);
+        cookie = xcb_icccm_get_wm_client_machine(conn, iWin);
+        if (xcb_icccm_get_wm_client_machine_reply(conn, cookie, &reply, NULL)) {
+            pszClientMachine = Xutf8TextPropertyToString(pWMInfo, &reply);
+            xcb_icccm_get_text_property_reply_wipe(&reply);
 
             /*
                If we have a client machine name
@@ -479,17 +440,21 @@ GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName)
  */
 
 static Bool
-IsWmProtocolAvailable(Display * pDisplay, Window iWindow, Atom atmProtocol)
+IsWmProtocolAvailable(WMInfoPtr pWMInfo, xcb_window_t iWindow, xcb_atom_t atmProtocol)
 {
-  int i, n, found = 0;
-  Atom *protocols;
-
-  if (XGetWMProtocols(pDisplay, iWindow, &protocols, &n)) {
-    for (i = 0; i < n; ++i)
-      if (protocols[i] == atmProtocol)
-        ++found;
-
-    XFree(protocols);
+  int i, found = 0;
+  xcb_get_property_cookie_t cookie;
+  xcb_icccm_get_wm_protocols_reply_t reply;
+  xcb_connection_t *conn = pWMInfo->conn;
+
+  cookie = xcb_icccm_get_wm_protocols(conn, iWindow, pWMInfo->ewmh.WM_PROTOCOLS);
+  if (xcb_icccm_get_wm_protocols_reply(conn, cookie, &reply, NULL)) {
+    for (i = 0; i < reply.atoms_len; ++i)
+      if (reply.atoms[i] == atmProtocol) {
+              ++found;
+              break;
+      }
+    xcb_icccm_get_wm_protocols_reply_wipe(&reply);
   }
 
   return found > 0;
@@ -499,49 +464,46 @@ IsWmProtocolAvailable(Display * pDisplay, Window iWindow, Atom atmProtocol)
  * Send a message to the X server from the WM thread
  */
 
-static int
-SendXMessage(Display * pDisplay, Window iWin, Atom atmType, long nData)
+static void
+SendXMessage(xcb_connection_t *conn, xcb_window_t iWin, xcb_atom_t atmType, long nData)
 {
-    XEvent e;
+    xcb_client_message_event_t e;
 
     /* Prepare the X event structure */
-    e.type = ClientMessage;
-    e.xclient.window = iWin;
-    e.xclient.message_type = atmType;
-    e.xclient.format = 32;
-    e.xclient.data.l[0] = nData;
-    e.xclient.data.l[1] = CurrentTime;
+    memset(&e, 0, sizeof(e));
+    e.response_type = XCB_CLIENT_MESSAGE;
+    e.window = iWin;
+    e.type = atmType;
+    e.format = 32;
+    e.data.data32[0] = nData;
+    e.data.data32[1] = XCB_CURRENT_TIME;
 
     /* Send the event to X */
-    return XSendEvent(pDisplay, iWin, False, NoEventMask, &e);
+    xcb_send_event(conn, FALSE, iWin, XCB_EVENT_MASK_NO_EVENT, (const char *)&e);
 }
 
 /*
  * See if we can get the stored HWND for this window...
  */
 static HWND
-getHwnd(WMInfoPtr pWMInfo, Window iWindow)
+getHwnd(WMInfoPtr pWMInfo, xcb_window_t iWindow)
 {
-    Atom atmType;
-    int fmtRet;
-    unsigned long items, remain;
-    HWND *retHwnd, hWnd = NULL;
-
-    if (XGetWindowProperty(pWMInfo->pDisplay,
-                           iWindow,
-                           pWMInfo->atmPrivMap,
-                           0,
-                           sizeof(HWND)/4,
-                           False,
-                           XA_INTEGER,
-                           &atmType,
-                           &fmtRet,
-                           &items,
-                           &remain, (unsigned char **) &retHwnd) == Success) {
-        if (retHwnd) {
-            hWnd = *retHwnd;
-            XFree(retHwnd);
+    HWND hWnd = NULL;
+    xcb_get_property_cookie_t cookie;
+    xcb_get_property_reply_t *reply;
+
+    cookie = xcb_get_property(pWMInfo->conn, FALSE, iWindow, pWMInfo->atmPrivMap,
+                              XCB_ATOM_INTEGER, 0L, sizeof(HWND)/4L);
+    reply = xcb_get_property_reply(pWMInfo->conn, cookie, NULL);
+
+    if (reply) {
+        int length = xcb_get_property_value_length(reply);
+        HWND *value = xcb_get_property_value(reply);
+
+        if (value && (length == sizeof(HWND))) {
+            hWnd = *value;
         }
+        free(reply);
     }
 
     /* Some sanity checks */
@@ -554,26 +516,81 @@ getHwnd(WMInfoPtr pWMInfo, Window iWindow)
 }
 
 /*
+ * Helper function to check for override-redirect
+ */
+static Bool
+IsOverrideRedirect(xcb_connection_t *conn, xcb_window_t iWin)
+{
+    Bool result = FALSE;
+    xcb_get_window_attributes_reply_t *reply;
+    xcb_get_window_attributes_cookie_t cookie;
+
+    cookie = xcb_get_window_attributes(conn, iWin);
+    reply = xcb_get_window_attributes_reply(conn, cookie, NULL);
+    if (reply) {
+        result = (reply->override_redirect != 0);
+        free(reply);
+    }
+    else {
+        ErrorF("IsOverrideRedirect: Failed to get window attributes\n");
+    }
+
+    return result;
+}
+
+/*
+ * Helper function to get class and window names
+*/
+static void
+GetClassNames(WMInfoPtr pWMInfo, xcb_window_t iWindow, char **res_name,
+              char **res_class, char **window_name)
+{
+    xcb_get_property_cookie_t cookie1;
+    xcb_icccm_get_wm_class_reply_t reply1;
+    xcb_get_property_cookie_t cookie2;
+    xcb_icccm_get_text_property_reply_t reply2;
+
+    cookie1 = xcb_icccm_get_wm_class(pWMInfo->conn, iWindow);
+    if (xcb_icccm_get_wm_class_reply(pWMInfo->conn, cookie1, &reply1,
+                                     NULL)) {
+        *res_name = strdup(reply1.instance_name);
+        *res_class = strdup(reply1.class_name);
+        xcb_icccm_get_wm_class_reply_wipe(&reply1);
+    }
+    else {
+        *res_name = strdup("");
+        *res_class = strdup("");
+    }
+
+    cookie2 = xcb_icccm_get_wm_name(pWMInfo->conn, iWindow);
+    if (xcb_icccm_get_wm_name_reply(pWMInfo->conn, cookie2, &reply2, NULL)) {
+        *window_name = strndup(reply2.name, reply2.name_len);
+        xcb_icccm_get_text_property_reply_wipe(&reply2);
+    }
+    else {
+        *window_name = strdup("");
+    }
+}
+
+/*
  * Updates the name of a HWND according to its X WM_NAME property
  */
 
 static void
-UpdateName(WMInfoPtr pWMInfo, Window iWindow)
+UpdateName(WMInfoPtr pWMInfo, xcb_window_t iWindow)
 {
     HWND hWnd;
-    XWindowAttributes attr;
 
     hWnd = getHwnd(pWMInfo, iWindow);
     if (!hWnd)
         return;
 
     /* If window isn't override-redirect */
-    XGetWindowAttributes(pWMInfo->pDisplay, iWindow, &attr);
-    if (!attr.override_redirect) {
+    if (!IsOverrideRedirect(pWMInfo->conn, iWindow)) {
         char *pszWindowName;
 
         /* Get the X windows window name */
-        GetWindowName(pWMInfo->pDisplay, iWindow, &pszWindowName);
+        GetWindowName(pWMInfo, iWindow, &pszWindowName);
 
         if (pszWindowName) {
             /* Convert from UTF-8 to wide char */
@@ -598,39 +615,30 @@ UpdateName(WMInfoPtr pWMInfo, Window iWindow)
  */
 
 static void
-UpdateIcon(WMInfoPtr pWMInfo, Window iWindow)
+UpdateIcon(WMInfoPtr pWMInfo, xcb_window_t iWindow)
 {
     HWND hWnd;
     HICON hIconNew = NULL;
-    XWindowAttributes attr;
 
     hWnd = getHwnd(pWMInfo, iWindow);
     if (!hWnd)
         return;
 
     /* If window isn't override-redirect */
-    XGetWindowAttributes(pWMInfo->pDisplay, iWindow, &attr);
-    if (!attr.override_redirect) {
-        XClassHint class_hint = { 0, 0 };
+    if (!IsOverrideRedirect(pWMInfo->conn, iWindow)) {
         char *window_name = 0;
+        char *res_name = 0;
+        char *res_class = 0;
 
-        if (XGetClassHint(pWMInfo->pDisplay, iWindow, &class_hint)) {
-            XFetchName(pWMInfo->pDisplay, iWindow, &window_name);
+        GetClassNames(pWMInfo, iWindow, &res_name, &res_class, &window_name);
 
-            hIconNew =
-                (HICON) winOverrideIcon(class_hint.res_name,
-                                        class_hint.res_class, window_name);
+        hIconNew = winOverrideIcon(res_name, res_class, window_name);
 
-            if (class_hint.res_name)
-                XFree(class_hint.res_name);
-            if (class_hint.res_class)
-                XFree(class_hint.res_class);
-            if (window_name)
-                XFree(window_name);
-        }
+        free(res_name);
+        free(res_class);
+        free(window_name);
+        winUpdateIcon(hWnd, pWMInfo->conn, iWindow, hIconNew);
     }
-
-    winUpdateIcon(hWnd, XGetXCBConnection(pWMInfo->pDisplay), iWindow, hIconNew);
 }
 
 /*
@@ -638,7 +646,7 @@ UpdateIcon(WMInfoPtr pWMInfo, Window iWindow)
  */
 
 static void
-UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
+UpdateStyle(WMInfoPtr pWMInfo, xcb_window_t iWindow)
 {
     HWND hWnd;
     HWND zstyle = HWND_NOTOPMOST;
@@ -649,7 +657,7 @@ UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
         return;
 
     /* Determine the Window style, which determines borders and clipping region... */
-    winApplyHints(pWMInfo->pDisplay, iWindow, hWnd, &zstyle);
+    winApplyHints(pWMInfo, iWindow, hWnd, &zstyle);
     winUpdateWindowPosition(hWnd, &zstyle);
 
     /* Apply the updated window style, without changing it's show or activation state */
@@ -678,7 +686,7 @@ UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
  */
 
 static void
-UpdateState(WMInfoPtr pWMInfo, Window iWindow)
+UpdateState(WMInfoPtr pWMInfo, xcb_window_t iWindow)
 {
     HWND hWnd;
 
@@ -697,11 +705,11 @@ UpdateState(WMInfoPtr pWMInfo, Window iWindow)
  * starting at the window passed in
  */
 static void
-PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction)
+PreserveWin32Stack(WMInfoPtr pWMInfo, xcb_window_t iWindow, UINT direction)
 {
     HWND hWnd;
     DWORD myWinProcID, winProcID;
-    Window xWindow;
+    xcb_window_t xWindow;
     WINDOWPLACEMENT wndPlace;
 
     hWnd = getHwnd(pWMInfo, iWindow);
@@ -779,7 +787,12 @@ winMultiWindowWMProc(void *pArg)
 
         case WM_WM_RAISE:
             /* Raise the window */
-            XRaiseWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
+            {
+                const static uint32_t values[] = { XCB_STACK_MODE_ABOVE };
+                xcb_configure_window(pWMInfo->conn, pNode->msg.iWindow,
+                                     XCB_CONFIG_WINDOW_STACK_MODE, values);
+            }
+
 #if 0
             PreserveWin32Stack(pWMInfo, pNode->msg.iWindow, GW_HWNDPREV);
 #endif
@@ -787,22 +800,29 @@ winMultiWindowWMProc(void *pArg)
 
         case WM_WM_LOWER:
             /* Lower the window */
-            XLowerWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
+            {
+                const static uint32_t values[] = { XCB_STACK_MODE_BELOW };
+                xcb_configure_window(pWMInfo->conn, pNode->msg.iWindow,
+                                     XCB_CONFIG_WINDOW_STACK_MODE, values);
+            }
             break;
 
         case WM_WM_MAP2:
-            XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER,
-                            32,
-                            PropModeReplace,
-                            (unsigned char *) &(pNode->msg.hwndWindow), sizeof(HWND)/4);
+            /* Put a note as to the HWND associated with this Window */
+            xcb_change_property(pWMInfo->conn, XCB_PROP_MODE_REPLACE,
+                                pNode->msg.iWindow, pWMInfo->atmPrivMap,
+                                XCB_ATOM_INTEGER, 32,
+                                sizeof(HWND)/4, &(pNode->msg.hwndWindow));
+
             break;
 
         case WM_WM_MAP3:
             /* Put a note as to the HWND associated with this Window */
-            XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER,
-                            32,
-                            PropModeReplace,
-                            (unsigned char *) &(pNode->msg.hwndWindow), sizeof(HWND)/4);
+            xcb_change_property(pWMInfo->conn, XCB_PROP_MODE_REPLACE,
+                                pNode->msg.iWindow, pWMInfo->atmPrivMap,
+                                XCB_ATOM_INTEGER, 32,
+                                sizeof(HWND)/4, &(pNode->msg.hwndWindow));
+
             UpdateName(pWMInfo, pNode->msg.iWindow);
             UpdateIcon(pWMInfo, pNode->msg.iWindow);
             UpdateStyle(pWMInfo, pNode->msg.iWindow);
@@ -823,20 +843,20 @@ winMultiWindowWMProc(void *pArg)
         case WM_WM_UNMAP:
 
             /* Unmap the window */
-            XUnmapWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
+            xcb_unmap_window(pWMInfo->conn, pNode->msg.iWindow);
             break;
 
         case WM_WM_KILL:
             {
                 /* --- */
-                if (IsWmProtocolAvailable(pWMInfo->pDisplay,
+                if (IsWmProtocolAvailable(pWMInfo,
                                           pNode->msg.iWindow,
                                           pWMInfo->atmWmDelete))
-                    SendXMessage(pWMInfo->pDisplay,
+                    SendXMessage(pWMInfo->conn,
                                  pNode->msg.iWindow,
                                  pWMInfo->atmWmProtos, pWMInfo->atmWmDelete);
                 else
-                    XKillClient(pWMInfo->pDisplay, pNode->msg.iWindow);
+                    xcb_kill_client(pWMInfo->conn, pNode->msg.iWindow);
             }
             break;
 
@@ -853,23 +873,24 @@ winMultiWindowWMProc(void *pArg)
             */
             {
               Bool neverFocus = FALSE;
-              XWMHints *hints = XGetWMHints(pWMInfo->pDisplay, pNode->msg.iWindow);
-
-              if (hints) {
-                if (hints->flags & InputHint)
-                  neverFocus = !hints->input;
-                XFree(hints);
+              xcb_get_property_cookie_t cookie;
+              xcb_icccm_wm_hints_t hints;
+
+              cookie = xcb_icccm_get_wm_hints(pWMInfo->conn, pNode->msg.iWindow);
+              if (xcb_icccm_get_wm_hints_reply(pWMInfo->conn, cookie, &hints,
+                                               NULL)) {
+                if (hints.flags & XCB_ICCCM_WM_HINT_INPUT)
+                  neverFocus = !hints.input;
               }
 
               if (!neverFocus)
-                XSetInputFocus(pWMInfo->pDisplay,
-                               pNode->msg.iWindow,
-                               RevertToPointerRoot, CurrentTime);
+                xcb_set_input_focus(pWMInfo->conn, XCB_INPUT_FOCUS_POINTER_ROOT,
+                                    pNode->msg.iWindow, XCB_CURRENT_TIME);
 
-              if (IsWmProtocolAvailable(pWMInfo->pDisplay,
+              if (IsWmProtocolAvailable(pWMInfo,
                                         pNode->msg.iWindow,
                                         pWMInfo->atmWmTakeFocus))
-                SendXMessage(pWMInfo->pDisplay,
+                SendXMessage(pWMInfo->conn,
                              pNode->msg.iWindow,
                              pWMInfo->atmWmProtos, pWMInfo->atmWmTakeFocus);
 
@@ -886,11 +907,8 @@ winMultiWindowWMProc(void *pArg)
 
         case WM_WM_HINTS_EVENT:
             {
-            XWindowAttributes attr;
-
             /* Don't do anything if this is an override-redirect window */
-            XGetWindowAttributes (pWMInfo->pDisplay, pNode->msg.iWindow, &attr);
-            if (attr.override_redirect)
+            if (IsOverrideRedirect(pWMInfo->conn, pNode->msg.iWindow))
               break;
 
             UpdateStyle(pWMInfo, pNode->msg.iWindow);
@@ -911,7 +929,30 @@ winMultiWindowWMProc(void *pArg)
         free(pNode);
 
         /* Flush any pending events on our display */
-        XFlush(pWMInfo->pDisplay);
+        xcb_flush(pWMInfo->conn);
+
+        /* This is just laziness rather than making sure we used _checked everywhere */
+        {
+            xcb_generic_event_t *event = xcb_poll_for_event(pWMInfo->conn);
+            if (event) {
+                if ((event->response_type & ~0x80) == 0) {
+                    xcb_generic_error_t *err = (xcb_generic_error_t *)event;
+                    ErrorF("winMultiWindowWMProc - Error code: %i, ID: 0x%08x, "
+                           "Major opcode: %i, Minor opcode: %i\n",
+                           err->error_code, err->resource_id,
+                           err->major_code, err->minor_code);
+                }
+            }
+        }
+
+        /* I/O errors etc. */
+        {
+            int e = xcb_connection_has_error(pWMInfo->conn);
+            if (e) {
+                ErrorF("winMultiWindowWMProc - Fatal error %d on xcb connection\n", e);
+                break;
+            }
+        }
     }
 
     /* Free the condition variable */
@@ -929,6 +970,22 @@ winMultiWindowWMProc(void *pArg)
     return NULL;
 }
 
+static xcb_atom_t
+intern_atom(xcb_connection_t *conn, const char *atomName)
+{
+  xcb_intern_atom_reply_t *atom_reply;
+  xcb_intern_atom_cookie_t atom_cookie;
+  xcb_atom_t atom = XCB_ATOM_NONE;
+
+  atom_cookie = xcb_intern_atom(conn, 0, strlen(atomName), atomName);
+  atom_reply = xcb_intern_atom_reply(conn, atom_cookie, NULL);
+  if (atom_reply) {
+    atom = atom_reply->atom;
+    free(atom_reply);
+  }
+  return atom;
+}
+
 /*
  * X message procedure
  */
@@ -940,14 +997,13 @@ winMultiWindowXMsgProc(void *pArg)
     XMsgProcArgPtr pProcArg = (XMsgProcArgPtr) pArg;
     char pszDisplay[512];
     int iRetries;
-    XEvent event;
-    Atom atmWmName;
-    Atom atmWmHints;
-    Atom atmWmChange;
-    Atom atmNetWmIcon;
-    Atom atmWindowState, atmMotifWmHints, atmWindowType, atmNormalHints;
+    xcb_atom_t atmWmName;
+    xcb_atom_t atmWmHints;
+    xcb_atom_t atmWmChange;
+    xcb_atom_t atmNetWmIcon;
+    xcb_atom_t atmWindowState, atmMotifWmHints, atmWindowType, atmNormalHints;
     int iReturn;
-    XIconSize *xis;
+    xcb_auth_info_t *auth_info;
 
     winDebug("winMultiWindowXMsgProc - Hello\n");
 
@@ -969,43 +1025,11 @@ winMultiWindowXMsgProc(void *pArg)
 
     ErrorF("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n");
 
-    /* Allow multiple threads to access Xlib */
-    if (XInitThreads() == 0) {
-        ErrorF("winMultiWindowXMsgProc - XInitThreads () failed.  Exiting.\n");
-        pthread_exit(NULL);
-    }
-
-    /* See if X supports the current locale */
-    if (XSupportsLocale() == False) {
-        ErrorF("winMultiWindowXMsgProc - Warning: locale not supported by X\n");
-    }
-
     /* Release the server started mutex */
     pthread_mutex_unlock(pProcArg->ppmServerStarted);
 
     ErrorF("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n");
 
-    /* Install our error handler */
-    XSetErrorHandler(winMultiWindowXMsgProcErrorHandler);
-    g_winMultiWindowXMsgProcThread = pthread_self();
-    g_winMultiWindowXMsgProcOldIOErrorHandler =
-        XSetIOErrorHandler(winMultiWindowXMsgProcIOErrorHandler);
-
-    /* Set jump point for IO Error exits */
-    iReturn = setjmp(g_jmpXMsgProcEntry);
-
-    /* Check if we should continue operations */
-    if (iReturn != WIN_JMP_ERROR_IO && iReturn != WIN_JMP_OKAY) {
-        /* setjmp returned an unknown value, exit */
-        ErrorF("winInitMultiWindowXMsgProc - setjmp returned: %d.  Exiting.\n",
-               iReturn);
-        pthread_exit(NULL);
-    }
-    else if (iReturn == WIN_JMP_ERROR_IO) {
-        ErrorF("winInitMultiWindowXMsgProc - Caught IO Error.  Exiting.\n");
-        pthread_exit(NULL);
-    }
-
     /* Setup the display connection string x */
     winGetDisplayName(pszDisplay, (int) pProcArg->dwScreen);
 
@@ -1013,7 +1037,7 @@ winMultiWindowXMsgProc(void *pArg)
     ErrorF("winMultiWindowXMsgProc - DISPLAY=%s\n", pszDisplay);
 
     /* Use our generated cookie for authentication */
-    winSetAuthorization();
+    auth_info = winGetXcbAuthInfo();
 
     /* Initialize retry count */
     iRetries = 0;
@@ -1021,8 +1045,9 @@ winMultiWindowXMsgProc(void *pArg)
     /* Open the X display */
     do {
         /* Try to open the display */
-        pProcArg->pDisplay = XOpenDisplay(pszDisplay);
-        if (pProcArg->pDisplay == NULL) {
+        pProcArg->conn = xcb_connect_to_display_with_auth_info(pszDisplay,
+                                                               auth_info, NULL);
+        if (xcb_connection_has_error(pProcArg->conn)) {
             ErrorF("winMultiWindowXMsgProc - Could not open display, try: %d, "
                    "sleeping: %d\n", iRetries + 1, WIN_CONNECT_DELAY);
             ++iRetries;
@@ -1032,45 +1057,55 @@ winMultiWindowXMsgProc(void *pArg)
         else
             break;
     }
-    while (pProcArg->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
+    while (xcb_connection_has_error(pProcArg->conn) && iRetries < WIN_CONNECT_RETRIES);
 
     /* Make sure that the display opened */
-    if (pProcArg->pDisplay == NULL) {
+    if (xcb_connection_has_error(pProcArg->conn)) {
         ErrorF("winMultiWindowXMsgProc - Failed opening the display.  "
                "Exiting.\n");
         pthread_exit(NULL);
     }
 
-    ErrorF("winMultiWindowXMsgProc - XOpenDisplay () returned and "
+    ErrorF("winMultiWindowXMsgProc - xcb_connect() returned and "
            "successfully opened the display.\n");
 
     /* Check if another window manager is already running */
-    if (CheckAnotherWindowManager(pProcArg->pDisplay, pProcArg->dwScreen)) {
+    if (CheckAnotherWindowManager(pProcArg->conn, pProcArg->dwScreen)) {
         ErrorF("winMultiWindowXMsgProc - "
                "another window manager is running.  Exiting.\n");
         pthread_exit(NULL);
     }
 
-    /* Set up the supported icon sizes */
-    xis = XAllocIconSize();
-    if (xis) {
-        xis->min_width = xis->min_height = 16;
-        xis->max_width = xis->max_height = 48;
-        xis->width_inc = xis->height_inc = 16;
-        XSetIconSizes(pProcArg->pDisplay,
-                      RootWindow(pProcArg->pDisplay, pProcArg->dwScreen),
-                      xis, 1);
-        XFree(xis);
+    {
+        /* Get root window id */
+        xcb_screen_t *root_screen = xcb_aux_get_screen(pProcArg->conn, pProcArg->dwScreen);
+        xcb_window_t root_window_id = root_screen->root;
+
+        /* Set WM_ICON_SIZE property indicating desired icon sizes */
+        typedef struct {
+            uint32_t min_width, min_height;
+            uint32_t max_width, max_height;
+            int32_t width_inc, height_inc;
+        } xcb_wm_icon_size_hints_hints_t;
+
+        xcb_wm_icon_size_hints_hints_t xis;
+        xis.min_width = xis.min_height = 16;
+        xis.max_width = xis.max_height = 48;
+        xis.width_inc = xis.height_inc = 16;
+
+        xcb_change_property(pProcArg->conn, XCB_PROP_MODE_REPLACE, root_window_id,
+                            XCB_ATOM_WM_ICON_SIZE, XCB_ATOM_WM_ICON_SIZE, 32,
+                            sizeof(xis)/4, &xis);
     }
 
-    atmWmName = XInternAtom(pProcArg->pDisplay, "WM_NAME", False);
-    atmWmHints = XInternAtom(pProcArg->pDisplay, "WM_HINTS", False);
-    atmWmChange = XInternAtom(pProcArg->pDisplay, "WM_CHANGE_STATE", False);
-    atmNetWmIcon = XInternAtom(pProcArg->pDisplay, "_NET_WM_ICON", False);
-    atmWindowState = XInternAtom(pProcArg->pDisplay, "_NET_WM_STATE", False);
-    atmMotifWmHints = XInternAtom(pProcArg->pDisplay, "_MOTIF_WM_HINTS", False);
-    atmWindowType = XInternAtom(pProcArg->pDisplay, "_NET_WM_WINDOW_TYPE", False);
-    atmNormalHints = XInternAtom(pProcArg->pDisplay, "WM_NORMAL_HINTS", False);
+    atmWmName = intern_atom(pProcArg->conn, "WM_NAME");
+    atmWmHints = intern_atom(pProcArg->conn, "WM_HINTS");
+    atmWmChange = intern_atom(pProcArg->conn, "WM_CHANGE_STATE");
+    atmNetWmIcon = intern_atom(pProcArg->conn, "_NET_WM_ICON");
+    atmWindowState = intern_atom(pProcArg->conn, "_NET_WM_STATE");
+    atmMotifWmHints = intern_atom(pProcArg->conn, "_MOTIF_WM_HINTS");
+    atmWindowType = intern_atom(pProcArg->conn, "_NET_WM_WINDOW_TYPE");
+    atmNormalHints = intern_atom(pProcArg->conn, "WM_NORMAL_HINTS");
 
     /*
        iiimxcf had a bug until 2009-04-27, assuming that the
@@ -1080,32 +1115,54 @@ winMultiWindowXMsgProc(void *pArg)
        Since this is on in the default Solaris 10 install,
        workaround this by making sure it does exist...
      */
-    XInternAtom(pProcArg->pDisplay, "WM_STATE", 0);
+    intern_atom(pProcArg->conn, "WM_STATE");
 
     /* Loop until we explicitly break out */
     while (1) {
+        xcb_generic_event_t *event;
+        uint8_t type;
+        Bool send_event;
+
         if (g_shutdown)
             break;
 
         /* Fetch next event */
-        XNextEvent(pProcArg->pDisplay, &event);
-
-        /* Branch on event type */
-        if (event.type == CreateNotify) {
-            XWindowAttributes attr;
+        event = xcb_wait_for_event(pProcArg->conn);
+        if (!event) { // returns NULL on I/O error
+            int e = xcb_connection_has_error(pProcArg->conn);
+            ErrorF("winMultiWindowXMsgProc - Fatal error %d on xcb connection\n", e);
+            break;
+        }
 
-            XSelectInput(pProcArg->pDisplay,
-                         event.xcreatewindow.window, PropertyChangeMask);
+        type = event->response_type & ~0x80;
+        send_event = event->response_type & 0x80;
 
-            /* Get the window attributes */
-            XGetWindowAttributes(pProcArg->pDisplay,
-                                 event.xcreatewindow.window, &attr);
+        winDebug("winMultiWindowXMsgProc - event %d\n", type);
 
-            if (!attr.override_redirect)
-                XSetWindowBorderWidth(pProcArg->pDisplay,
-                                      event.xcreatewindow.window, 0);
+        /* Branch on event type */
+        if (type == 0) {
+            xcb_generic_error_t *err = (xcb_generic_error_t *)event;
+            ErrorF("winMultiWindowXMsgProc - Error code: %i, ID: 0x%08x, "
+                   "Major opcode: %i, Minor opcode: %i\n",
+                   err->error_code, err->resource_id,
+                   err->major_code, err->minor_code);
+            }
+        else if (type == XCB_CREATE_NOTIFY) {
+            xcb_create_notify_event_t *notify = (xcb_create_notify_event_t *)event;
+
+            /* Request property change events */
+            const static uint32_t mask_value[] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
+            xcb_change_window_attributes (pProcArg->conn, notify->window,
+                                          XCB_CW_EVENT_MASK, mask_value);
+
+            /* If it's not override-redirect, set the border-width to 0 */
+            if (!IsOverrideRedirect(pProcArg->conn, notify->window)) {
+                const static uint32_t width_value[] = { 0 };
+                xcb_configure_window(pProcArg->conn, notify->window,
+                                     XCB_CONFIG_WINDOW_BORDER_WIDTH, width_value);
+            }
         }
-        else if (event.type == MapNotify) {
+        else if (type == XCB_MAP_NOTIFY) {
             /* Fake a reparentNotify event as SWT/Motif expects a
                Window Manager to reparent a top-level window when
                it is mapped and waits until they do.
@@ -1121,43 +1178,44 @@ winMultiWindowXMsgProc(void *pArg)
                See sourceware bugzilla #9848
              */
 
-            XWindowAttributes attr;
-            Window root;
-            Window parent;
-            Window *children;
-            unsigned int nchildren;
-
-            if (XGetWindowAttributes(event.xmap.display,
-                                     event.xmap.window,
-                                     &attr) &&
-                XQueryTree(event.xmap.display,
-                           event.xmap.window,
-                           &root, &parent, &children, &nchildren)) {
-                if (children)
-                    XFree(children);
+            xcb_map_notify_event_t *notify = (xcb_map_notify_event_t *)event;
+
+            xcb_get_geometry_cookie_t cookie;
+            xcb_get_geometry_reply_t *reply;
+            xcb_query_tree_cookie_t cookie_qt;
+            xcb_query_tree_reply_t *reply_qt;
+
+            cookie = xcb_get_geometry(pProcArg->conn, notify->window);
+            cookie_qt = xcb_query_tree(pProcArg->conn, notify->window);
+            reply = xcb_get_geometry_reply(pProcArg->conn, cookie, NULL);
+            reply_qt = xcb_query_tree_reply(pProcArg->conn, cookie_qt, NULL);
 
+            if (reply && reply_qt) {
                 /*
                    It's a top-level window if the parent window is a root window
                    Only non-override_redirect windows can get reparented
                  */
-                if ((attr.root == parent) && !event.xmap.override_redirect) {
-                    XEvent event_send;
-
-                    event_send.type = ReparentNotify;
-                    event_send.xreparent.event = event.xmap.window;
-                    event_send.xreparent.window = event.xmap.window;
-                    event_send.xreparent.parent = parent;
-                    event_send.xreparent.x = attr.x;
-                    event_send.xreparent.y = attr.y;
-
-                    XSendEvent(event.xmap.display,
-                               event.xmap.window,
-                               True, StructureNotifyMask, &event_send);
+                if ((reply->root == reply_qt->parent) && !notify->override_redirect) {
+                    xcb_reparent_notify_event_t event_send;
+
+                    event_send.response_type = ReparentNotify;
+                    event_send.event = notify->window;
+                    event_send.window = notify->window;
+                    event_send.parent = reply_qt->parent;
+                    event_send.x = reply->x;
+                    event_send.y = reply->y;
+
+                    xcb_send_event (pProcArg->conn, TRUE, notify->window,
+                                    XCB_EVENT_MASK_STRUCTURE_NOTIFY,
+                                    (const char *)&event_send);
+
+                    free(reply_qt);
+                    free(reply);
                 }
             }
         }
-        else if (event.type == ConfigureNotify) {
-            if (!event.xconfigure.send_event) {
+        else if (type == XCB_CONFIGURE_NOTIFY) {
+            if (!send_event) {
                 /*
                    Java applications using AWT on JRE 1.6.0 break with non-reparenting WMs AWT
                    doesn't explicitly know about (See sun bug #6434227)
@@ -1169,21 +1227,24 @@ winMultiWindowXMsgProc(void *pArg)
                    Rather than tell all sorts of lies to get XWM to recognize us as one of
                    those, simply send a synthetic ConfigureNotify for every non-synthetic one
                  */
-                XEvent event_send = event;
+                xcb_configure_notify_event_t *notify = (xcb_configure_notify_event_t *)event;
+                xcb_configure_notify_event_t event_send = *notify;
 
-                event_send.xconfigure.send_event = TRUE;
-                event_send.xconfigure.event = event.xconfigure.window;
-                XSendEvent(event.xconfigure.display,
-                           event.xconfigure.window,
-                           True, StructureNotifyMask, &event_send);
+                event_send.event = notify->window;
+
+                xcb_send_event(pProcArg->conn, TRUE, notify->window,
+                               XCB_EVENT_MASK_STRUCTURE_NOTIFY,
+                               (const char *)&event_send);
             }
         }
-        else if (event.type == PropertyNotify) {
-            if (event.xproperty.atom == atmWmName) {
+        else if (type ==  XCB_PROPERTY_NOTIFY) {
+            xcb_property_notify_event_t *notify = (xcb_property_notify_event_t *)event;
+
+            if (notify->atom == atmWmName) {
                 memset(&msg, 0, sizeof(msg));
 
                 msg.msg = WM_WM_NAME_EVENT;
-                msg.iWindow = event.xproperty.window;
+                msg.iWindow = notify->window;
 
                 /* Other fields ignored */
                 winSendMessageToWM(pProcArg->pWMInfo, &msg);
@@ -1193,46 +1254,52 @@ winMultiWindowXMsgProc(void *pArg)
                    Several properties are considered for WM hints, check if this property change affects any of them...
                    (this list needs to be kept in sync with winApplyHints())
                  */
-                if ((event.xproperty.atom == atmWmHints) ||
-                    (event.xproperty.atom == atmWindowState) ||
-                    (event.xproperty.atom == atmMotifWmHints) ||
-                    (event.xproperty.atom == atmWindowType) ||
-                    (event.xproperty.atom == atmNormalHints)) {
+                if ((notify->atom == atmWmHints) ||
+                    (notify->atom == atmWindowState) ||
+                    (notify->atom == atmMotifWmHints) ||
+                    (notify->atom == atmWindowType) ||
+                    (notify->atom == atmNormalHints)) {
                     memset(&msg, 0, sizeof(msg));
                     msg.msg = WM_WM_HINTS_EVENT;
-                    msg.iWindow = event.xproperty.window;
+                    msg.iWindow = notify->window;
 
                     /* Other fields ignored */
                     winSendMessageToWM(pProcArg->pWMInfo, &msg);
                 }
 
                 /* Not an else as WM_HINTS affects both style and icon */
-                if ((event.xproperty.atom == atmWmHints) ||
-                    (event.xproperty.atom == atmNetWmIcon)) {
+                if ((notify->atom == atmWmHints) ||
+                    (notify->atom == atmNetWmIcon)) {
                     memset(&msg, 0, sizeof(msg));
                     msg.msg = WM_WM_ICON_EVENT;
-                    msg.iWindow = event.xproperty.window;
+                    msg.iWindow = notify->window;
 
                     /* Other fields ignored */
                     winSendMessageToWM(pProcArg->pWMInfo, &msg);
                 }
             }
         }
-        else if (event.type == ClientMessage
-                 && event.xclient.message_type == atmWmChange
-                 && event.xclient.data.l[0] == IconicState) {
-            ErrorF("winMultiWindowXMsgProc - WM_CHANGE_STATE - IconicState\n");
+        else if (type == XCB_CLIENT_MESSAGE) {
+            xcb_client_message_event_t *client_msg = (xcb_client_message_event_t *)event;
 
-            memset(&msg, 0, sizeof(msg));
+            if (client_msg->type == atmWmChange
+                 && client_msg->data.data32[0] == XCB_ICCCM_WM_STATE_ICONIC) {
+                ErrorF("winMultiWindowXMsgProc - WM_CHANGE_STATE - IconicState\n");
 
-            msg.msg = WM_WM_CHANGE_STATE;
-            msg.iWindow = event.xclient.window;
+                memset(&msg, 0, sizeof(msg));
 
-            winSendMessageToWM(pProcArg->pWMInfo, &msg);
+                msg.msg = WM_WM_CHANGE_STATE;
+                msg.iWindow = client_msg->window;
+
+                winSendMessageToWM(pProcArg->pWMInfo, &msg);
+            }
         }
+
+        /* Free the event */
+        free(event);
     }
 
-    XCloseDisplay(pProcArg->pDisplay);
+    xcb_disconnect(pProcArg->conn);
     pthread_exit(NULL);
     return NULL;
 }
@@ -1317,6 +1384,7 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
     int iRetries = 0;
     char pszDisplay[512];
     int iReturn;
+    xcb_auth_info_t *auth_info;
 
     winDebug("winInitMultiWindowWM - Hello\n");
 
@@ -1338,43 +1406,11 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
 
     ErrorF("winInitMultiWindowWM - pthread_mutex_lock () returned.\n");
 
-    /* Allow multiple threads to access Xlib */
-    if (XInitThreads() == 0) {
-        ErrorF("winInitMultiWindowWM - XInitThreads () failed.  Exiting.\n");
-        pthread_exit(NULL);
-    }
-
-    /* See if X supports the current locale */
-    if (XSupportsLocale() == False) {
-        ErrorF("winInitMultiWindowWM - Warning: Locale not supported by X.\n");
-    }
-
     /* Release the server started mutex */
     pthread_mutex_unlock(pProcArg->ppmServerStarted);
 
     ErrorF("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n");
 
-    /* Install our error handler */
-    XSetErrorHandler(winMultiWindowWMErrorHandler);
-    g_winMultiWindowWMThread = pthread_self();
-    g_winMultiWindowWMOldIOErrorHandler =
-        XSetIOErrorHandler(winMultiWindowWMIOErrorHandler);
-
-    /* Set jump point for IO Error exits */
-    iReturn = setjmp(g_jmpWMEntry);
-
-    /* Check if we should continue operations */
-    if (iReturn != WIN_JMP_ERROR_IO && iReturn != WIN_JMP_OKAY) {
-        /* setjmp returned an unknown value, exit */
-        ErrorF("winInitMultiWindowWM - setjmp returned: %d.  Exiting.\n",
-               iReturn);
-        pthread_exit(NULL);
-    }
-    else if (iReturn == WIN_JMP_ERROR_IO) {
-        ErrorF("winInitMultiWindowWM - Caught IO Error.  Exiting.\n");
-        pthread_exit(NULL);
-    }
-
     /* Setup the display connection string x */
     winGetDisplayName(pszDisplay, (int) pProcArg->dwScreen);
 
@@ -1382,13 +1418,14 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
     ErrorF("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay);
 
     /* Use our generated cookie for authentication */
-    winSetAuthorization();
+    auth_info = winGetXcbAuthInfo();
 
     /* Open the X display */
     do {
         /* Try to open the display */
-        pWMInfo->pDisplay = XOpenDisplay(pszDisplay);
-        if (pWMInfo->pDisplay == NULL) {
+        pWMInfo->conn = xcb_connect_to_display_with_auth_info(pszDisplay,
+                                                              auth_info, NULL);
+        if (xcb_connection_has_error(pWMInfo->conn)) {
             ErrorF("winInitMultiWindowWM - Could not open display, try: %d, "
                    "sleeping: %d\n", iRetries + 1, WIN_CONNECT_DELAY);
             ++iRetries;
@@ -1398,38 +1435,87 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
         else
             break;
     }
-    while (pWMInfo->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
+    while (xcb_connection_has_error(pWMInfo->conn) && iRetries < WIN_CONNECT_RETRIES);
 
     /* Make sure that the display opened */
-    if (pWMInfo->pDisplay == NULL) {
+    if (xcb_connection_has_error(pWMInfo->conn)) {
         ErrorF("winInitMultiWindowWM - Failed opening the display.  "
                "Exiting.\n");
         pthread_exit(NULL);
     }
 
-    ErrorF("winInitMultiWindowWM - XOpenDisplay () returned and "
+    ErrorF("winInitMultiWindowWM - xcb_connect () returned and "
            "successfully opened the display.\n");
 
     /* Create some atoms */
-    pWMInfo->atmWmProtos = XInternAtom(pWMInfo->pDisplay,
-                                       "WM_PROTOCOLS", False);
-    pWMInfo->atmWmDelete = XInternAtom(pWMInfo->pDisplay,
-                                       "WM_DELETE_WINDOW", False);
-    pWMInfo->atmWmTakeFocus = XInternAtom(pWMInfo->pDisplay,
-                                       "WM_TAKE_FOCUS", False);
-
-    pWMInfo->atmPrivMap = XInternAtom(pWMInfo->pDisplay,
-                                      WINDOWSWM_NATIVE_HWND, False);
-
-    if (1) {
-        Cursor cursor = XCreateFontCursor(pWMInfo->pDisplay, XC_left_ptr);
-
-        if (cursor) {
-            XDefineCursor(pWMInfo->pDisplay,
-                          DefaultRootWindow(pWMInfo->pDisplay), cursor);
-            XFreeCursor(pWMInfo->pDisplay, cursor);
+    pWMInfo->atmWmProtos = intern_atom(pWMInfo->conn, "WM_PROTOCOLS");
+    pWMInfo->atmWmDelete = intern_atom(pWMInfo->conn, "WM_DELETE_WINDOW");
+    pWMInfo->atmWmTakeFocus = intern_atom(pWMInfo->conn, "WM_TAKE_FOCUS");
+    pWMInfo->atmPrivMap = intern_atom(pWMInfo->conn, WINDOWSWM_NATIVE_HWND);
+    pWMInfo->atmUtf8String = intern_atom(pWMInfo->conn, "UTF8_STRING");
+
+    /* Initialization for the xcb_ewmh and EWMH atoms */
+    {
+        xcb_intern_atom_cookie_t *atoms_cookie;
+        atoms_cookie = xcb_ewmh_init_atoms(pWMInfo->conn, &pWMInfo->ewmh);
+        if (xcb_ewmh_init_atoms_replies(&pWMInfo->ewmh, atoms_cookie, NULL)) {
+            /* Set the _NET_SUPPORTED atom for this context.
+
+               TODO: Audit to ensure we implement everything defined as MUSTs
+               for window managers in the EWMH standard.*/
+            xcb_atom_t supported[] =
+                {
+                    pWMInfo->ewmh.WM_PROTOCOLS,
+                    pWMInfo->ewmh._NET_SUPPORTED,
+                    pWMInfo->ewmh._NET_SUPPORTING_WM_CHECK,
+                    pWMInfo->ewmh._NET_CLOSE_WINDOW,
+                    pWMInfo->ewmh._NET_WM_WINDOW_TYPE,
+                    pWMInfo->ewmh._NET_WM_WINDOW_TYPE_DOCK,
+                    pWMInfo->ewmh._NET_WM_STATE,
+                    pWMInfo->ewmh._NET_WM_STATE_HIDDEN,
+                    pWMInfo->ewmh._NET_WM_STATE_ABOVE,
+                    pWMInfo->ewmh._NET_WM_STATE_BELOW,
+                    pWMInfo->ewmh._NET_WM_STATE_SKIP_TASKBAR,
+                };
+
+            xcb_ewmh_set_supported(&pWMInfo->ewmh, pProcArg->dwScreen,
+                                   sizeof(supported)/sizeof(xcb_atom_t), supported);
+        }
+        else {
+            ErrorF("winInitMultiWindowWM - xcb_ewmh_init_atoms() failed\n");
         }
     }
+
+    /*
+      Set the root window cursor to left_ptr (this controls the cursor an
+      application gets over it's windows when it doesn't set one)
+    */
+    {
+#define XC_left_ptr 68
+        xcb_cursor_t cursor = xcb_generate_id(pWMInfo->conn);
+        xcb_font_t font = xcb_generate_id(pWMInfo->conn);
+        xcb_font_t *mask_font = &font; /* An alias to clarify */
+        int shape = XC_left_ptr;
+        uint32_t mask = XCB_CW_CURSOR;
+        uint32_t value_list = cursor;
+
+        xcb_screen_t *root_screen = xcb_aux_get_screen(pWMInfo->conn, pProcArg->dwScreen);
+        xcb_window_t window = root_screen->root;
+
+        static const uint16_t fgred = 0, fggreen = 0, fgblue = 0;
+        static const uint16_t bgred = 0xFFFF, bggreen = 0xFFFF, bgblue = 0xFFFF;
+
+        xcb_open_font(pWMInfo->conn, font, sizeof("cursor"), "cursor");
+
+        xcb_create_glyph_cursor(pWMInfo->conn, cursor, font, *mask_font,
+                                shape, shape + 1,
+                                fgred, fggreen, fgblue, bgred, bggreen, bgblue);
+
+        xcb_change_window_attributes(pWMInfo->conn, window, mask, &value_list);
+
+        xcb_free_cursor(pWMInfo->conn, cursor);
+        xcb_close_font(pWMInfo->conn, font);
+    }
 }
 
 /*
@@ -1453,116 +1539,36 @@ winSendMessageToWM(void *pWMInfo, winWMMessagePtr pMsg)
 }
 
 /*
- * Window manager error handler
- */
-
-static int
-winMultiWindowWMErrorHandler(Display * pDisplay, XErrorEvent * pErr)
-{
-    char pszErrorMsg[100];
-
-    if (pErr->request_code == X_ChangeWindowAttributes
-        && pErr->error_code == BadAccess) {
-        ErrorF("winMultiWindowWMErrorHandler - ChangeWindowAttributes "
-               "BadAccess.\n");
-        return 0;
-    }
-
-    XGetErrorText(pDisplay, pErr->error_code, pszErrorMsg, sizeof(pszErrorMsg));
-    ErrorF("winMultiWindowWMErrorHandler - ERROR: %s\n", pszErrorMsg);
-
-    return 0;
-}
-
-/*
- * Window manager IO error handler
- */
-
-static int
-winMultiWindowWMIOErrorHandler(Display * pDisplay)
-{
-    ErrorF("winMultiWindowWMIOErrorHandler!\n");
-
-    if (pthread_equal(pthread_self(), g_winMultiWindowWMThread)) {
-        if (g_shutdown)
-            pthread_exit(NULL);
-
-        /* Restart at the main entry point */
-        longjmp(g_jmpWMEntry, WIN_JMP_ERROR_IO);
-    }
-
-    if (g_winMultiWindowWMOldIOErrorHandler)
-        g_winMultiWindowWMOldIOErrorHandler(pDisplay);
-
-    return 0;
-}
-
-/*
- * X message procedure error handler
- */
-
-static int
-winMultiWindowXMsgProcErrorHandler(Display * pDisplay, XErrorEvent * pErr)
-{
-    char pszErrorMsg[100];
-
-    XGetErrorText(pDisplay, pErr->error_code, pszErrorMsg, sizeof(pszErrorMsg));
-#if CYGMULTIWINDOW_DEBUG
-    ErrorF("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n", pszErrorMsg);
-#endif
-
-    return 0;
-}
-
-/*
- * X message procedure IO error handler
- */
-
-static int
-winMultiWindowXMsgProcIOErrorHandler(Display * pDisplay)
-{
-    ErrorF("winMultiWindowXMsgProcIOErrorHandler!\n");
-
-    if (pthread_equal(pthread_self(), g_winMultiWindowXMsgProcThread)) {
-        /* Restart at the main entry point */
-        longjmp(g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO);
-    }
-
-    if (g_winMultiWindowXMsgProcOldIOErrorHandler)
-        g_winMultiWindowXMsgProcOldIOErrorHandler(pDisplay);
-
-    return 0;
-}
-
-/*
- * Catch RedirectError to detect other window manager running
- */
-
-static int
-winRedirectErrorHandler(Display * pDisplay, XErrorEvent * pErr)
-{
-    redirectError = TRUE;
-    return 0;
-}
-
-/*
  * Check if another window manager is running
  */
 
 static Bool
-CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen)
+CheckAnotherWindowManager(xcb_connection_t *conn, DWORD dwScreen)
 {
+    Bool redirectError = FALSE;
+
+    /* Get root window id */
+    xcb_screen_t *root_screen = xcb_aux_get_screen(conn, dwScreen);
+    xcb_window_t root_window_id = root_screen->root;
+
     /*
        Try to select the events which only one client at a time is allowed to select.
        If this causes an error, another window manager is already running...
      */
-    redirectError = FALSE;
-    XSetErrorHandler(winRedirectErrorHandler);
-    XSelectInput(pDisplay, RootWindow(pDisplay, dwScreen),
-                 ResizeRedirectMask | SubstructureRedirectMask |
-                 ButtonPressMask);
-    XSync(pDisplay, 0);
-    XSetErrorHandler(winMultiWindowXMsgProcErrorHandler);
+    const static uint32_t test_mask[] = { XCB_EVENT_MASK_RESIZE_REDIRECT |
+                                       XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
+                                       XCB_EVENT_MASK_BUTTON_PRESS };
+
+    xcb_void_cookie_t cookie = xcb_change_window_attributes_checked(conn,
+                                                                    root_window_id,
+                                                                    XCB_CW_EVENT_MASK,
+                                                                    test_mask);
+    xcb_generic_error_t *error;
+    if ((error = xcb_request_check(conn, cookie)))
+        {
+            redirectError = TRUE;
+            free(error);
+        }
 
     /*
        Side effect: select the events we are actually interested in...
@@ -1570,9 +1576,13 @@ CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen)
        Other WMs are not allowed, also select one of the events which only one client
        at a time is allowed to select, so other window managers won't start...
      */
-    XSelectInput(pDisplay, RootWindow(pDisplay, dwScreen),
-                 SubstructureNotifyMask | ButtonPressMask);
-    XSync(pDisplay, 0);
+    {
+        const uint32_t mask[] = { XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
+                                  XCB_EVENT_MASK_BUTTON_PRESS };
+
+        xcb_change_window_attributes(conn, root_window_id, XCB_CW_EVENT_MASK, mask);
+    }
+
     return redirectError;
 }
 
@@ -1601,18 +1611,16 @@ winDeinitMultiWindowWM(void)
 #define HINT_MIN	(1L<<1)
 
 static void
-winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
+winApplyHints(WMInfoPtr pWMInfo, xcb_window_t iWindow, HWND hWnd, HWND * zstyle)
 {
-    static Atom windowState, motif_wm_hints, windowType;
-    static Atom hiddenState, fullscreenState, belowState, aboveState,
+    xcb_connection_t *conn = pWMInfo->conn;
+    static xcb_atom_t windowState, motif_wm_hints;
+    static xcb_atom_t hiddenState, fullscreenState, belowState, aboveState,
         skiptaskbarState;
-    static Atom dockWindow;
     static int generation;
-    Atom type, *pAtom = NULL;
-    int format;
-    unsigned long hint = 0, maxmin = 0, nitems = 0, left = 0;
+
+    unsigned long hint = 0, maxmin = 0;
     unsigned long style, exStyle;
-    MwmHints *mwm_hint = NULL;
 
     if (!hWnd)
         return;
@@ -1621,25 +1629,22 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
 
     if (generation != serverGeneration) {
         generation = serverGeneration;
-        windowState = XInternAtom(pDisplay, "_NET_WM_STATE", False);
-        motif_wm_hints = XInternAtom(pDisplay, "_MOTIF_WM_HINTS", False);
-        windowType = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE", False);
-        hiddenState = XInternAtom(pDisplay, "_NET_WM_STATE_HIDDEN", False);
-        fullscreenState =
-            XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", False);
-        belowState = XInternAtom(pDisplay, "_NET_WM_STATE_BELOW", False);
-        aboveState = XInternAtom(pDisplay, "_NET_WM_STATE_ABOVE", False);
-        dockWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False);
-        skiptaskbarState =
-            XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_TASKBAR", False);
+        windowState = intern_atom(conn, "_NET_WM_STATE");
+        motif_wm_hints = intern_atom(conn, "_MOTIF_WM_HINTS");
+        hiddenState = intern_atom(conn, "_NET_WM_STATE_HIDDEN");
+        fullscreenState = intern_atom(conn, "_NET_WM_STATE_FULLSCREEN");
+        belowState = intern_atom(conn, "_NET_WM_STATE_BELOW");
+        aboveState = intern_atom(conn, "_NET_WM_STATE_ABOVE");
+        skiptaskbarState = intern_atom(conn, "_NET_WM_STATE_SKIP_TASKBAR");
     }
 
-    if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L,
-                           MAXINT, False, XA_ATOM, &type, &format,
-                           &nitems, &left,
-                           (unsigned char **) &pAtom) == Success) {
-        if (pAtom ) {
-            unsigned long i;
+    {
+      xcb_get_property_cookie_t cookie_wm_state = xcb_get_property(conn, FALSE, iWindow, windowState, XCB_ATOM_ATOM, 0L, INT_MAX);
+      xcb_get_property_reply_t *reply = xcb_get_property_reply(conn, cookie_wm_state, NULL);
+      if (reply) {
+        int i;
+        int nitems = xcb_get_property_value_length(reply)/sizeof(xcb_atom_t);
+        xcb_atom_t *pAtom = xcb_get_property_value(reply);
 
             for (i = 0; i < nitems; i++) {
                 if (pAtom[i] == skiptaskbarState)
@@ -1654,16 +1659,17 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
                     *zstyle = HWND_TOPMOST;
             }
 
-            XFree(pAtom);
-        }
+            free(reply);
+      }
     }
 
-    nitems = left = 0;
-    if (XGetWindowProperty(pDisplay, iWindow, motif_wm_hints, 0L,
-                           PropMwmHintsElements, False, motif_wm_hints, &type,
-                           &format, &nitems, &left,
-                           (unsigned char **) &mwm_hint) == Success) {
-        if (mwm_hint && nitems == PropMwmHintsElements &&
+    {
+      xcb_get_property_cookie_t cookie_mwm_hint = xcb_get_property(conn, FALSE, iWindow, motif_wm_hints, motif_wm_hints, 0L, sizeof(MwmHints));
+      xcb_get_property_reply_t *reply =  xcb_get_property_reply(conn, cookie_mwm_hint, NULL);
+      if (reply) {
+        int nitems = xcb_get_property_value_length(reply)/4;
+        MwmHints *mwm_hint = xcb_get_property_value(reply);
+        if (mwm_hint && (nitems >= PropMwmHintsElements) &&
             (mwm_hint->flags & MwmHintsDecorations)) {
             if (!mwm_hint->decorations)
                 hint |= (HINT_NOFRAME | HINT_NOSYSMENU | HINT_NOMINIMIZE | HINT_NOMAXIMIZE);
@@ -1688,48 +1694,45 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
                  */
             }
         }
-        if (mwm_hint)
-            XFree(mwm_hint);
+        free(reply);
+      }
     }
 
-    nitems = left = 0;
-    pAtom = NULL;
-    if (XGetWindowProperty(pDisplay, iWindow, windowType, 0L,
-                           1L, False, XA_ATOM, &type, &format,
-                           &nitems, &left,
-                           (unsigned char **) &pAtom) == Success) {
-        if (pAtom && nitems == 1) {
-            if (*pAtom == dockWindow) {
+    {
+      int i;
+      xcb_ewmh_get_atoms_reply_t type;
+      xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_window_type(&pWMInfo->ewmh, iWindow);
+      if (xcb_ewmh_get_wm_window_type_reply(&pWMInfo->ewmh, cookie, &type, NULL)) {
+        for (i = 0; i < type.atoms_len; i++) {
+            if (type.atoms[i] ==  pWMInfo->ewmh._NET_WM_WINDOW_TYPE_DOCK) {
                 hint = (hint & ~HINT_NOFRAME) | HINT_SKIPTASKBAR | HINT_SIZEBOX;
                 *zstyle = HWND_TOPMOST;
             }
         }
-        if (pAtom)
-            XFree(pAtom);
+      }
     }
 
     {
-        XSizeHints *normal_hint = XAllocSizeHints();
-        long supplied;
+        xcb_size_hints_t size_hints;
+        xcb_get_property_cookie_t cookie;
 
-        if (normal_hint &&
-            XGetWMNormalHints(pDisplay, iWindow, normal_hint, &supplied)) {
-            if (normal_hint->flags & PMaxSize) {
+        cookie = xcb_icccm_get_wm_normal_hints(conn, iWindow);
+        if (xcb_icccm_get_wm_normal_hints_reply(conn, cookie, &size_hints, NULL)) {
+            if (size_hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE) {
                 /* Not maximizable if a maximum size is specified */
                 hint |= HINT_NOMAXIMIZE;
 
-                if (normal_hint->flags & PMinSize) {
+                if (size_hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE) {
                     /*
                        If both minimum size and maximum size are specified and are the same,
                        don't bother with a resizing frame
                      */
-                    if ((normal_hint->min_width == normal_hint->max_width)
-                        && (normal_hint->min_height == normal_hint->max_height))
+                    if ((size_hints.min_width == size_hints.max_width)
+                        && (size_hints.min_height == size_hints.max_height))
                         hint = (hint & ~HINT_SIZEBOX);
                 }
             }
         }
-        XFree(normal_hint);
     }
 
     /*
@@ -1737,41 +1740,32 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
        application id for grouping.
      */
     {
-        XClassHint class_hint = { 0, 0 };
-        char *window_name = 0;
         char *application_id = 0;
+        char *window_name = 0;
+        char *res_name = 0;
+        char *res_class = 0;
 
-        if (XGetClassHint(pDisplay, iWindow, &class_hint)) {
-            XFetchName(pDisplay, iWindow, &window_name);
+        GetClassNames(pWMInfo, iWindow, &res_name, &res_class, &window_name);
 
-            style =
-                winOverrideStyle(class_hint.res_name, class_hint.res_class,
-                                 window_name);
+        style = STYLE_NONE;
+        style = winOverrideStyle(res_name, res_class, window_name);
 
 #define APPLICATION_ID_FORMAT	"%s.xwin.%s"
 #define APPLICATION_ID_UNKNOWN "unknown"
-            if (class_hint.res_class) {
-                asprintf(&application_id, APPLICATION_ID_FORMAT, XVENDORNAME,
-                         class_hint.res_class);
-            }
-            else {
-                asprintf(&application_id, APPLICATION_ID_FORMAT, XVENDORNAME,
-                         APPLICATION_ID_UNKNOWN);
-            }
-            winSetAppUserModelID(hWnd, application_id);
-
-            if (class_hint.res_name)
-                XFree(class_hint.res_name);
-            if (class_hint.res_class)
-                XFree(class_hint.res_class);
-            if (application_id)
-                free(application_id);
-            if (window_name)
-                XFree(window_name);
+        if (res_class) {
+            asprintf(&application_id, APPLICATION_ID_FORMAT, XVENDORNAME,
+                     res_class);
         }
         else {
-            style = STYLE_NONE;
+            asprintf(&application_id, APPLICATION_ID_FORMAT, XVENDORNAME,
+                     APPLICATION_ID_UNKNOWN);
         }
+        winSetAppUserModelID(hWnd, application_id);
+
+        free(application_id);
+        free(res_name);
+        free(res_class);
+        free(window_name);
     }
 
     if (style & STYLE_TOPMOST)
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index e07b6a8..e3a5948 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -1,5 +1,3 @@
-#if !defined(_WINWINDOW_H_)
-#define _WINWINDOW_H_
 /*
  *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
  *Copyright (C) Colin Harrison 2005-2009
@@ -31,6 +29,8 @@
  * Authors:	Kensuke Matsuzaki
  *              Colin Harrison
  */
+#if !defined(_WINWINDOW_H_)
+#define _WINWINDOW_H_
 
 #ifndef NO
 #define NO			0
@@ -122,10 +122,16 @@ typedef struct _winWMMessageRec {
 #define		MwmDecorMinimize	(1L << 5)
 #define		MwmDecorMaximize	(1L << 6)
 
-/* This structure only contains 3 elements... the Motif 2.0 structure
-contains 5... we only need the first 3... so that is all we will define */
+/*
+  This structure only contains 3 elements.  The Motif 2.0 structure contains 5,
+  but we only need the first 3, so that is all we will define
+
+  This structure represents xcb_get_property()'s view of the property as a
+  sequence of ints, rather than XGetWindowProperty()'s view of the property as a
+  sequence of arch-dependent longs.
+*/
 typedef struct MwmHints {
-    unsigned long flags, functions, decorations;
+    unsigned int flags, functions, decorations;
 } MwmHints;
 
 #define		PropMwmHintsElements	3
commit 8114b8127f01fc81390fc13e3d09bcc50e41a66f
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Wed Jul 1 16:30:36 2015 +0100

    hw/xwin: In multiwindow mode, do window minimization entirely in the WM
    
    Remove winMinimizeWindow(), implement as UpdateState() in the WM instead,
    which uses getHwnd() to map a Window XID to a HWND (like everything else in
    the WM), rather than peering into the servers internal data structures.
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index e82d915..4ec5634 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -800,44 +800,6 @@ winReorderWindowsMultiWindow(void)
 }
 
 /*
- * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE
- */
-
-void
-winMinimizeWindow(Window id)
-{
-    WindowPtr pWin;
-    winPrivWinPtr pWinPriv;
-
-    HWND hWnd;
-    ScreenPtr pScreen = NULL;
-    winPrivScreenPtr pScreenPriv = NULL;
-
-#if CYGWINDOWING_DEBUG
-    ErrorF("winMinimizeWindow\n");
-#endif
-
-    dixLookupResourceByType((void *) &pWin, id, RT_WINDOW, NullClient,
-                            DixUnknownAccess);
-    if (!pWin) {
-        ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__);
-        return;
-    }
-
-    pScreen = pWin->drawable.pScreen;
-    if (pScreen)
-        pScreenPriv = winGetScreenPriv(pScreen);
-
-    if (pScreenPriv)
-    {
-        pWinPriv = winGetWindowPriv(pWin);
-        hWnd = pWinPriv->hWnd;
-    }
-
-    ShowWindow(hWnd, SW_MINIMIZE);
-}
-
-/*
  * CopyWindow - See Porting Layer Definition - p. 39
  */
 void
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index e594794..80bb483 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -672,6 +672,25 @@ UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
                             WS_EX_APPWINDOW) ? TRUE : FALSE);
 }
 
+/*
+ * Updates the state of a HWND
+ * (only minimization supported at the moment)
+ */
+
+static void
+UpdateState(WMInfoPtr pWMInfo, Window iWindow)
+{
+    HWND hWnd;
+
+    winDebug("UpdateState: iWindow 0x%08x\n", (int)iWindow);
+
+    hWnd = getHwnd(pWMInfo, iWindow);
+    if (!hWnd)
+        return;
+
+    ShowWindow(hWnd, SW_MINIMIZE);
+}
+
 #if 0
 /*
  * Fix up any differences between the X11 and Win32 window stacks
@@ -879,8 +898,7 @@ winMultiWindowWMProc(void *pArg)
             break;
 
         case WM_WM_CHANGE_STATE:
-            /* Minimize the window in Windows */
-            winMinimizeWindow(pNode->msg.iWindow);
+            UpdateState(pWMInfo, pNode->msg.iWindow);
             break;
 
         default:
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 5a1759d..e07b6a8 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -145,9 +145,6 @@ void
  winDeinitMultiWindowWM(void);
 
 void
- winMinimizeWindow(Window id);
-
-void
  winPropertyStoreInit(void);
 
 void
commit 6a64b9d7af70dc7ff2cac8b35a1f7b0797823733
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Mon Nov 2 17:55:19 2015 +0000

    hw/xwin: xcbify code for converting X11 icon to Win32 icon
    
    Convert the code for converting an X11 icon to Win32 icon from Xlib to xcb.
    
    v2: some warning fixes in winXIconToHICON()
    v3: declaration-after-statement warning fixes
    v4: printf format fixes
    v5: convert in place rather than in a library
    
    This also avoids the xlib/xserver namespace collision issues, so
    winmultiwindowicons.h can be included everywhere it should be, which fixes
    compilation with -Werror=implicit-function-declaration
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/configure.ac b/configure.ac
index dff06ef..1e78b7d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2150,7 +2150,7 @@ if test "x$XWIN" = xyes; then
 	AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
 	AC_CHECK_TOOL(WINDRES, windres)
 
-	PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfixes])
+	PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfixes x11-xcb xcb-image xcb-icccm])
 
 	if test "x$WINDOWSWM" = xauto; then
 		PKG_CHECK_EXISTS($WINDOWSWMPROTO, [WINDOWSWM=yes], [WINDOWSWM=no])
diff --git a/hw/xwin/winmultiwindowicons.c b/hw/xwin/winmultiwindowicons.c
index cc45387..0507951 100644
--- a/hw/xwin/winmultiwindowicons.c
+++ b/hw/xwin/winmultiwindowicons.c
@@ -36,15 +36,21 @@
 #define WINVER 0x0500
 #endif
 
+#include <limits.h>
+#include <stdbool.h>
+
 #include <X11/Xwindows.h>
 #include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include <xcb/xcb.h>
+#include <xcb/xcb_icccm.h>
+#include <xcb/xcb_image.h>
 
 #include "winresource.h"
 #include "winprefs.h"
 #include "winmsg.h"
 #include "winmultiwindowicons.h"
 #include "winglobals.h"
+
 /*
  * global variables
  */
@@ -57,7 +63,7 @@ extern HINSTANCE g_hInstance;
 static void
 winScaleXImageToWindowsIcon(int iconSize,
                             int effBPP,
-                            int stride, XImage * pixmap, unsigned char *image)
+                            int stride, xcb_image_t* pixmap, unsigned char *image)
 {
     int row, column, effXBPP, effXDepth;
     unsigned char *outPtr;
@@ -69,15 +75,15 @@ winScaleXImageToWindowsIcon(int iconSize,
     unsigned int zero;
     unsigned int color;
 
-    effXBPP = pixmap->bits_per_pixel;
-    if (pixmap->bits_per_pixel == 15)
+    effXBPP = pixmap->bpp;
+    if (pixmap->bpp == 15)
         effXBPP = 16;
 
     effXDepth = pixmap->depth;
     if (pixmap->depth == 15)
         effXDepth = 16;
 
-    xStride = pixmap->bytes_per_line;
+    xStride = pixmap->stride;
     if (stride == 0 || xStride == 0) {
         ErrorF("winScaleXBitmapToWindows - stride or xStride is zero.  "
                "Bailing.\n");
@@ -330,8 +336,8 @@ NetWMToWinIconThreshold(uint32_t * icon)
 static HICON
 NetWMToWinIcon(int bpp, uint32_t * icon)
 {
-    static Bool hasIconAlphaChannel = FALSE;
-    static BOOL versionChecked = FALSE;
+    static bool hasIconAlphaChannel = FALSE;
+    static bool versionChecked = FALSE;
 
     if (!versionChecked) {
         OSVERSIONINFOEX osvi = { 0 };
@@ -366,8 +372,8 @@ NetWMToWinIcon(int bpp, uint32_t * icon)
  */
 
 static
- HICON
-winXIconToHICON(Display * pDisplay, Window id, int iconSize)
+HICON
+winXIconToHICON(xcb_connection_t *conn, xcb_window_t id, int iconSize)
 {
     unsigned char *mask, *image = NULL, *imageMask;
     unsigned char *dst, *src;
@@ -375,16 +381,13 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize)
     unsigned int biggest_size = 0;
     HDC hDC;
     ICONINFO ii;
-    XWMHints *hints;
+    xcb_icccm_wm_hints_t hints;
     HICON hIcon = NULL;
     uint32_t *biggest_icon = NULL;
-    static Atom _XA_NET_WM_ICON;
+    static xcb_atom_t _XA_NET_WM_ICON;
     static int generation;
     uint32_t *icon, *icon_data = NULL;
     unsigned long int size;
-    Atom type;
-    int format;
-    unsigned long int left;
 
     hDC = GetDC(GetDesktopWindow());
     planes = GetDeviceCaps(hDC, PLANES);
@@ -393,17 +396,31 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize)
 
     /* Always prefer _NET_WM_ICON icons */
     if (generation != serverGeneration) {
+        xcb_intern_atom_reply_t *atom_reply;
+        xcb_intern_atom_cookie_t atom_cookie;
+        const char *atomName = "_NET_WM_ICON";
+
         generation = serverGeneration;
-        _XA_NET_WM_ICON = XInternAtom(pDisplay, "_NET_WM_ICON", FALSE);
+
+        _XA_NET_WM_ICON = XCB_NONE;
+
+        atom_cookie = xcb_intern_atom(conn, 0, strlen(atomName), atomName);
+        atom_reply = xcb_intern_atom_reply(conn, atom_cookie, NULL);
+        if (atom_reply) {
+          _XA_NET_WM_ICON = atom_reply->atom;
+          free(atom_reply);
+        }
     }
 
-    if ((XGetWindowProperty(pDisplay, id, _XA_NET_WM_ICON,
-                            0, MAXINT, FALSE,
-                            AnyPropertyType, &type, &format, &size, &left,
-                            (unsigned char **) &icon_data) == Success) &&
-        (icon_data != NULL)) {
-        for (icon = icon_data; icon < &icon_data[size] && *icon;
-             icon = &icon[icon[0] * icon[1] + 2]) {
+    {
+        xcb_get_property_cookie_t cookie = xcb_get_property(conn, FALSE, id, _XA_NET_WM_ICON, XCB_ATOM_CARDINAL, 0L, INT_MAX);
+        xcb_get_property_reply_t *reply =  xcb_get_property_reply(conn, cookie, NULL);
+
+        if (reply &&
+            ((icon_data = xcb_get_property_value(reply)) != NULL)) {
+          size = xcb_get_property_value_length(reply)/sizeof(uint32_t);
+          for (icon = icon_data; icon < &icon_data[size] && *icon;
+               icon = &icon[icon[0] * icon[1] + 2]) {
             winDebug("winXIconToHICON: %u x %u NetIcon\n", icon[0], icon[1]);
 
             /* Icon data size will overflow an int and thus is bigger than the
@@ -441,40 +458,46 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize)
             hIcon = NetWMToWinIcon(bpp, biggest_icon);
         }
 
-        XFree(icon_data);
+        free(reply);
+      }
     }
 
     if (!hIcon) {
+        xcb_get_property_cookie_t wm_hints_cookie;
+
         winDebug("winXIconToHICON: no suitable NetIcon\n");
 
-        hints = XGetWMHints(pDisplay, id);
-        if (hints) {
+        wm_hints_cookie = xcb_icccm_get_wm_hints(conn, id);
+        if (xcb_icccm_get_wm_hints_reply(conn, wm_hints_cookie, &hints, NULL)) {
             winDebug("winXIconToHICON: id 0x%x icon_pixmap hint 0x%x\n",
                      (unsigned int)id,
-                     (unsigned int)hints->icon_pixmap);
-
-            if (hints->icon_pixmap) {
-                Window root;
-                int x, y;
-                unsigned int width, height, border_width, depth;
-                XImage *xImageIcon;
-                XImage *xImageMask = NULL;
-
-                XGetGeometry(pDisplay, hints->icon_pixmap, &root, &x, &y,
-                             &width, &height, &border_width, &depth);
-
-                xImageIcon =
-                    XGetImage(pDisplay, hints->icon_pixmap, 0, 0, width, height,
-                              0xFFFFFFFF, ZPixmap);
-                winDebug("winXIconToHICON: id 0x%x icon Ximage 0x%p\n",
-                         (unsigned int)id, xImageIcon);
-
-                if (hints->icon_mask)
-                    xImageMask =
-                        XGetImage(pDisplay, hints->icon_mask, 0, 0, width,
-                                  height, 0xFFFFFFFF, ZPixmap);
-
-                if (xImageIcon) {
+                     (unsigned int)hints.icon_pixmap);
+
+            if (hints.icon_pixmap) {
+                unsigned int width, height;
+                xcb_image_t *xImageIcon;
+                xcb_image_t *xImageMask = NULL;
+
+                xcb_get_geometry_cookie_t geom_cookie = xcb_get_geometry(conn, hints.icon_pixmap);
+                xcb_get_geometry_reply_t *geom_reply = xcb_get_geometry_reply(conn, geom_cookie, NULL);
+
+                if (geom_reply) {
+                  width = geom_reply->width;
+                  height = geom_reply->height;
+
+                  xImageIcon = xcb_image_get(conn, hints.icon_pixmap,
+                                             0, 0, width, height,
+                                             0xFFFFFF, XCB_IMAGE_FORMAT_Z_PIXMAP);
+
+                  winDebug("winXIconToHICON: id 0x%x icon Ximage 0x%p\n",
+                           (unsigned int)id, xImageIcon);
+
+                  if (hints.icon_mask)
+                    xImageMask = xcb_image_get(conn, hints.icon_mask,
+                                               0, 0, width, height,
+                                               0xFFFFFFFF, XCB_IMAGE_FORMAT_Z_PIXMAP);
+
+                  if (xImageIcon) {
                     int effBPP, stride, maskStride;
 
                     /* 15 BPP is really 16BPP as far as we care */
@@ -543,12 +566,12 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize)
                     free(imageMask);
 
                     if (xImageMask)
-                        XDestroyImage(xImageMask);
+                      xcb_image_destroy(xImageMask);
 
-                    XDestroyImage(xImageIcon);
+                    xcb_image_destroy(xImageIcon);
+                  }
                 }
             }
-            XFree(hints);
         }
     }
     return hIcon;
@@ -560,20 +583,22 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize)
 
 #ifdef XWIN_MULTIWINDOW
 void
-winUpdateIcon(HWND hWnd, Display * pDisplay, Window id, HICON hIconNew)
+winUpdateIcon(HWND hWnd, xcb_connection_t *conn, Window id, HICON hIconNew)
 {
     HICON hIcon, hIconSmall = NULL, hIconOld;
 
-    /* Start with the icon from preferences, if any */
-    hIcon = hIconNew;
-    hIconSmall = hIconNew;
-
-    /* If we still need an icon, try and get the icon from WM_HINTS */
-    if (!hIcon)
-        hIcon = winXIconToHICON(pDisplay, id, GetSystemMetrics(SM_CXICON));
-    if (!hIconSmall)
-        hIconSmall =
-            winXIconToHICON(pDisplay, id, GetSystemMetrics(SM_CXSMICON));
+    if (hIconNew)
+      {
+        /* Start with the icon from preferences, if any */
+        hIcon = hIconNew;
+        hIconSmall = hIconNew;
+      }
+    else
+      {
+        /* If we still need an icon, try and get the icon from WM_HINTS */
+        hIcon = winXIconToHICON(conn, id, GetSystemMetrics(SM_CXICON));
+        hIconSmall = winXIconToHICON(conn, id, GetSystemMetrics(SM_CXSMICON));
+      }
 
     /* If we got the small, but not the large one swap them */
     if (!hIcon && hIconSmall) {
diff --git a/hw/xwin/winmultiwindowicons.h b/hw/xwin/winmultiwindowicons.h
index bf7f6ed..87ba8d1 100644
--- a/hw/xwin/winmultiwindowicons.h
+++ b/hw/xwin/winmultiwindowicons.h
@@ -27,8 +27,10 @@
 #ifndef WINMULTIWINDOWICONS_H
 #define WINMULTIWINDOWICONS_H
 
+#include <xcb/xcb.h>
+
 void
- winUpdateIcon(HWND hWnd, Display * pDisplay, Window id, HICON hIconNew);
+ winUpdateIcon(HWND hWnd, xcb_connection_t *conn, Window id, HICON hIconNew);
 
 void
  winInitGlobalIcons(void);
diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index 6db576a..e82d915 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -35,9 +35,11 @@
 #ifdef HAVE_XWIN_CONFIG_H
 #include <xwin-config.h>
 #endif
+
 #include "win.h"
 #include "dixevents.h"
 #include "winmultiwindowclass.h"
+#include "winmultiwindowicons.h"
 
 /*
  * Prototypes for local functions
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index c5404cf..e594794 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -48,6 +48,7 @@
 #include <X11/X.h>
 #include <X11/Xatom.h>
 #include <X11/Xlib.h>
+#include <X11/Xlib-xcb.h>
 #include <X11/Xlocale.h>
 #include <X11/Xproto.h>
 #include <X11/Xutil.h>
@@ -62,6 +63,7 @@
 #include "windowstr.h"
 #include "winglobals.h"
 #include "windisplay.h"
+#include "winmultiwindowicons.h"
 
 #ifdef XWIN_MULTIWINDOWEXTWM
 #include <X11/extensions/windowswmstr.h>
@@ -628,7 +630,7 @@ UpdateIcon(WMInfoPtr pWMInfo, Window iWindow)
         }
     }
 
-    winUpdateIcon(hWnd, pWMInfo->pDisplay, iWindow, hIconNew);
+    winUpdateIcon(hWnd, XGetXCBConnection(pWMInfo->pDisplay), iWindow, hIconNew);
 }
 
 /*
diff --git a/hw/xwin/winprefs.c b/hw/xwin/winprefs.c
index 5052927..a180a9e 100644
--- a/hw/xwin/winprefs.c
+++ b/hw/xwin/winprefs.c
@@ -46,6 +46,7 @@
 #include "winprefs.h"
 #include "windisplay.h"
 #include "winmultiwindowclass.h"
+#include "winmultiwindowicons.h"
 
 /* Where will the custom menu commands start counting from? */
 #define STARTMENUID WM_USER
diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 95b8452..5280688 100644
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -40,6 +40,7 @@
 #define _WINDOWSWM_SERVER_
 #include <X11/extensions/windowswmstr.h>
 #include "winmultiwindowclass.h"
+#include "winmultiwindowicons.h"
 #include <X11/Xatom.h>
 
 /*
commit 0a69c1e2fa0ea63b02fff98e68d9f56a369e882b
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Wed Mar 30 18:31:38 2016 +0100

    xwin/glx: Build fix for warnings about missing WGL extensioons
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>

diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 5d7ebf5..26832e6 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -634,7 +634,7 @@ glxWinScreenProbe(ScreenPtr pScreen)
         if (strstr(wgl_extensions, "WGL_ARB_make_current_read"))
             screen->has_WGL_ARB_make_current_read = TRUE;
         else
-            LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_make_current_read\n")
+            LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_make_current_read\n");
 
         if (strstr(gl_extensions, "GL_WIN_swap_hint")) {
             __glXEnableExtension(screen->base.glx_enable_bits,
@@ -659,12 +659,12 @@ glxWinScreenProbe(ScreenPtr pScreen)
         if (strstr(wgl_extensions, "WGL_ARB_pbuffer"))
             screen->has_WGL_ARB_pbuffer = TRUE;
         else
-            LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_pbuffer\n")
+            LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_pbuffer\n");
 
         if (strstr(wgl_extensions, "WGL_ARB_multisample"))
             screen->has_WGL_ARB_multisample = TRUE;
         else
-            LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_multisample\n")
+            LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_multisample\n");
 
         screen->base.destroy = glxWinScreenDestroy;
         screen->base.createContext = glxWinCreateContext;
commit b08526eecf1e165ed9ec2e6b571a5a616a9b696e
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Mar 16 11:38:13 2016 -0400

    glx: Implement GLX_EXT_libglvnd (v2)
    
    For the dri2 backend, we depend on xfree86 already, so we can walk the
    options for the screen looking for a vendor string from xorg.conf.  For
    the swrast backend we don't have that luxury, so just say mesa.  This
    extension isn't really meaningful on Windows or OSX yet (since libglvnd
    isn't really functional there yet), so on those platforms we don't say
    anything and return BadValue for the token from QueryServerString.
    
    v2: Use xnf* allocators when parsing options (Eric and Emil)
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/extension_string.c b/glx/extension_string.c
index 7e74090..d1da481 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -85,6 +85,7 @@ static const struct extension_info known_glx_extensions[] = {
     { 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_libglvnd),                VER(0,0), N, },
     { GLX(EXT_stereo_tree),             VER(0,0), N, },
     { GLX(EXT_texture_from_pixmap),     VER(0,0), N, },
     { GLX(EXT_visual_info),             VER(0,0), Y, },
diff --git a/glx/extension_string.h b/glx/extension_string.h
index 425a805..a10d710 100644
--- a/glx/extension_string.h
+++ b/glx/extension_string.h
@@ -47,6 +47,7 @@ enum {
     EXT_create_context_es2_profile_bit,
     EXT_fbconfig_packed_float_bit,
     EXT_import_context_bit,
+    EXT_libglvnd_bit,
     EXT_stereo_tree_bit,
     EXT_texture_from_pixmap_bit,
     EXT_visual_info_bit,
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 4693e68..0f0b714 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -2444,6 +2444,10 @@ __glXDisp_QueryExtensionsString(__GLXclientState * cl, GLbyte * pc)
     return Success;
 }
 
+#ifndef GLX_VENDOR_NAMES_EXT
+#define GLX_VENDOR_NAMES_EXT 0x20F6
+#endif
+
 int
 __glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
 {
@@ -2471,6 +2475,12 @@ __glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
     case GLX_EXTENSIONS:
         ptr = pGlxScreen->GLXextensions;
         break;
+    case GLX_VENDOR_NAMES_EXT:
+        if (pGlxScreen->glvnd) {
+            ptr = pGlxScreen->glvnd;
+            break;
+        }
+        /* else fall through */
     default:
         return BadValue;
     }
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 15253d1..d1fc3f9 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -934,12 +934,23 @@ initializeExtensions(__GLXscreen * screen)
 /* white lie */
 extern glx_func_ptr glXGetProcAddressARB(const char *);
 
+enum {
+    GLXOPT_VENDOR_LIBRARY,
+};
+
+static const OptionInfoRec GLXOptions[] = {
+    { GLXOPT_VENDOR_LIBRARY, "GlxVendorLibrary", OPTV_STRING, {0}, FALSE },
+    { -1, NULL, OPTV_NONE, {0}, FALSE },
+};
+
 static __GLXscreen *
 __glXDRIscreenProbe(ScreenPtr pScreen)
 {
     const char *driverName, *deviceName;
     __GLXDRIscreen *screen;
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    const char *glvnd = NULL;
+    OptionInfoPtr options;
 
     screen = calloc(1, sizeof *screen);
     if (screen == NULL)
@@ -985,6 +996,17 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
                                                GLX_PIXMAP_BIT |
                                                GLX_PBUFFER_BIT);
 
+    options = xnfalloc(sizeof(GLXOptions));
+    memcpy(options, GLXOptions, sizeof(GLXOptions));
+    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+    glvnd = xf86GetOptValString(options, GLXOPT_VENDOR_LIBRARY);
+    if (glvnd)
+        screen->base.glvnd = xnfstrdup(glvnd);
+    free(options);
+
+    if (!screen->base.glvnd)
+        screen->base.glvnd = strdup("mesa");
+
     __glXScreenInit(&screen->base, pScreen);
 
     screen->enterVT = pScrn->EnterVT;
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index 0b5122f..1e46d97 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -487,6 +487,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
                                                GLX_PIXMAP_BIT |
                                                GLX_PBUFFER_BIT);
 
+#if !defined(XQUARTZ) && !defined(WIN32)
+    screen->base.glvnd = strdup("mesa");
+#endif
     __glXScreenInit(&screen->base, pScreen);
 
     __glXsetGetProcAddress(glXGetProcAddressARB);
diff --git a/glx/glxscreens.c b/glx/glxscreens.c
index 7e083cf..536c0c4 100644
--- a/glx/glxscreens.c
+++ b/glx/glxscreens.c
@@ -384,6 +384,9 @@ __glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen)
 
     dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen);
 
+    if (pGlxScreen->glvnd)
+        __glXEnableExtension(pGlxScreen->glx_enable_bits, "GLX_EXT_libglvnd");
+
     i = __glXGetExtensionString(pGlxScreen->glx_enable_bits, NULL);
     if (i > 0) {
         pGlxScreen->GLXextensions = xnfalloc(i);
@@ -396,6 +399,7 @@ __glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen)
 void
 __glXScreenDestroy(__GLXscreen * screen)
 {
+    free(screen->glvnd);
     free(screen->GLXextensions);
     free(screen->GLextensions);
     free(screen->visuals);
diff --git a/glx/glxscreens.h b/glx/glxscreens.h
index c63fb56..15196fa 100644
--- a/glx/glxscreens.h
+++ b/glx/glxscreens.h
@@ -143,6 +143,7 @@ struct __GLXscreen {
 
     char *GLextensions;
     char *GLXextensions;
+    char *glvnd;
     unsigned char glx_enable_bits[__GLX_EXT_BYTES];
 
     Bool (*CloseScreen) (ScreenPtr pScreen);
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
index d794df4..8c4aeb5 100644
--- a/hw/xfree86/man/xorg.conf.man
+++ b/hw/xfree86/man/xorg.conf.man
@@ -2039,6 +2039,12 @@ Note that disabling an operation will have no effect if the operation is
 not accelerated (whether due to lack of support in the hardware or in the
 driver).
 .TP 7
+.BI "Option \*qGlxVendorLibrary\*q \*q" string \*q
+This option specifies a space-separated list of OpenGL vendor libraries to
+use for the screen. This may be used to select an alternate implementation
+for development, debugging, or alternate feature sets.
+Default: mesa.
+.TP 7
 .BI "Option \*qInitPrimary\*q \*q" boolean \*q
 Use the Int10 module to initialize the primary graphics card.
 Normally, only secondary cards are soft-booted using the Int10 module, as the
commit 2e8781ead3067b195baec2e76a28091575679383
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Mar 23 15:41:24 2016 -0400

    glx: Compute the GLX extension string from __glXScreenInit
    
    Now that the enable bits are in the screen base class we can compute
    this in one place, rather than making every backend do it.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index fa93da1..15253d1 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -939,7 +939,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 {
     const char *driverName, *deviceName;
     __GLXDRIscreen *screen;
-    size_t buffer_size;
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
 
     screen = calloc(1, sizeof *screen);
@@ -988,17 +987,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 
     __glXScreenInit(&screen->base, pScreen);
 
-    /* The first call simply determines the length of the extension string.
-     * This allows us to allocate some memory to hold the extension string,
-     * but it requires that we call __glXGetExtensionString a second time.
-     */
-    buffer_size = __glXGetExtensionString(screen->base.glx_enable_bits, NULL);
-    if (buffer_size > 0) {
-        screen->base.GLXextensions = xnfalloc(buffer_size);
-        (void) __glXGetExtensionString(screen->base.glx_enable_bits,
-                                       screen->base.GLXextensions);
-    }
-
     screen->enterVT = pScrn->EnterVT;
     pScrn->EnterVT = glxDRIEnterVT;
     screen->leaveVT = pScrn->LeaveVT;
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index 27c98ed..0b5122f 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -448,7 +448,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 {
     const char *driverName = "swrast";
     __GLXDRIscreen *screen;
-    size_t buffer_size;
 
     screen = calloc(1, sizeof *screen);
     if (screen == NULL)
@@ -490,17 +489,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 
     __glXScreenInit(&screen->base, pScreen);
 
-    /* The first call simply determines the length of the extension string.
-     * This allows us to allocate some memory to hold the extension string,
-     * but it requires that we call __glXGetExtensionString a second time.
-     */
-    buffer_size = __glXGetExtensionString(screen->base.glx_enable_bits, NULL);
-    if (buffer_size > 0) {
-        screen->base.GLXextensions = xnfalloc(buffer_size);
-        (void) __glXGetExtensionString(screen->base.glx_enable_bits,
-                                       screen->base.GLXextensions);
-    }
-
     __glXsetGetProcAddress(glXGetProcAddressARB);
 
     LogMessage(X_INFO, "AIGLX: Loaded and initialized %s\n", driverName);
diff --git a/glx/glxscreens.c b/glx/glxscreens.c
index 61b8a52..7e083cf 100644
--- a/glx/glxscreens.c
+++ b/glx/glxscreens.c
@@ -383,6 +383,14 @@ __glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen)
     }
 
     dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen);
+
+    i = __glXGetExtensionString(pGlxScreen->glx_enable_bits, NULL);
+    if (i > 0) {
+        pGlxScreen->GLXextensions = xnfalloc(i);
+        (void) __glXGetExtensionString(pGlxScreen->glx_enable_bits,
+                                       pGlxScreen->GLXextensions);
+    }
+
 }
 
 void
diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 9eaeb94..2d88ef2 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -542,20 +542,6 @@ __glXAquaScreenProbe(ScreenPtr pScreen)
     __glXInitExtensionEnableBits(screen->base.glx_enable_bits);
     __glXScreenInit(&screen->base, pScreen);
 
-    //__glXEnableExtension(screen->base.glx_enable_bits, "GLX_ARB_create_context");
-    //__glXEnableExtension(screen->base.glx_enable_bits, "GLX_ARB_create_context_profile");
-
-    // Generate the GLX extensions string (overrides that set by __glXScreenInit())
-    {
-        unsigned int buffer_size =
-            __glXGetExtensionString(screen->base.glx_enable_bits, NULL);
-        if (buffer_size > 0) {
-            screen->base.GLXextensions = xnfalloc(buffer_size);
-            __glXGetExtensionString(screen->base.glx_enable_bits,
-                                    screen->base.GLXextensions);
-        }
-    }
-
     return &screen->base;
 }
 
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 3b8210f..5d7ebf5 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -706,17 +706,6 @@ glxWinScreenProbe(ScreenPtr pScreen)
         screen->base.numVisuals = 0;
 
         __glXScreenInit(&screen->base, pScreen);
-
-        // Generate the GLX extensions string (overrides that set by __glXScreenInit())
-        {
-            unsigned int buffer_size =
-                __glXGetExtensionString(screen->base.glx_enable_bits, NULL);
-            if (buffer_size > 0) {
-                screen->base.GLXextensions = xnfalloc(buffer_size);
-                __glXGetExtensionString(screen->base.glx_enable_bits,
-                                        screen->base.GLXextensions);
-            }
-        }
     }
 
     wglMakeCurrent(NULL, NULL);
commit e21de4bf3c5ff8cbb9c5ea023d04162e5e56b3df
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Mar 23 15:36:52 2016 -0400

    glx: Move glx_enable_bits up to the GLX screen base class
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index ad97eb5..fa93da1 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -75,8 +75,6 @@ struct __GLXDRIscreen {
     const __DRIswapControlExtension *swapControl;
     const __DRItexBufferExtension *texBuffer;
     const __DRIconfig **driConfigs;
-
-    unsigned char glx_enable_bits[__GLX_EXT_BYTES];
 };
 
 struct __GLXDRIcontext {
@@ -847,18 +845,19 @@ glxDRILeaveVT(ScrnInfoPtr scrn)
  * @param screen The screen where glx_enable_bits are to be set.
  */
 static void
-initializeExtensions(__GLXDRIscreen * screen)
+initializeExtensions(__GLXscreen * screen)
 {
-    ScreenPtr pScreen = screen->base.pScreen;
+    ScreenPtr pScreen = screen->pScreen;
+    __GLXDRIscreen *dri = (__GLXDRIscreen *)screen;
     const __DRIextension **extensions;
     int i;
 
-    extensions = screen->core->getExtensions(screen->driScreen);
+    extensions = dri->core->getExtensions(dri->driScreen);
 
     __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
     LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
 
-    if (screen->dri2->base.version >= 3) {
+    if (dri->dri2->base.version >= 3) {
         __glXEnableExtension(screen->glx_enable_bits,
                              "GLX_ARB_create_context");
         __glXEnableExtension(screen->glx_enable_bits,
@@ -901,7 +900,7 @@ initializeExtensions(__GLXDRIscreen * screen)
 
     for (i = 0; extensions[i]; i++) {
         if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
-            screen->texBuffer = (const __DRItexBufferExtension *) extensions[i];
+            dri->texBuffer = (const __DRItexBufferExtension *) extensions[i];
             __glXEnableExtension(screen->glx_enable_bits,
                                  "GLX_EXT_texture_from_pixmap");
             LogMessage(X_INFO,
@@ -910,11 +909,11 @@ initializeExtensions(__GLXDRIscreen * screen)
 
         if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 &&
             extensions[i]->version >= 3) {
-            screen->flush = (__DRI2flushExtension *) extensions[i];
+            dri->flush = (__DRI2flushExtension *) extensions[i];
         }
 
         if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0 &&
-            screen->dri2->base.version >= 3) {
+            dri->dri2->base.version >= 3) {
             __glXEnableExtension(screen->glx_enable_bits,
                                  "GLX_ARB_create_context_robustness");
             LogMessage(X_INFO,
@@ -960,7 +959,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     screen->base.swapInterval = __glXDRIdrawableSwapInterval;
     screen->base.pScreen = pScreen;
 
-    __glXInitExtensionEnableBits(screen->glx_enable_bits);
+    __glXInitExtensionEnableBits(screen->base.glx_enable_bits);
 
     screen->driver =
         glxProbeDriver(driverName, (void **) &screen->core, __DRI_CORE, 1,
@@ -980,7 +979,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
         goto handle_error;
     }
 
-    initializeExtensions(screen);
+    initializeExtensions(&screen->base);
 
     screen->base.fbconfigs = glxConvertConfigs(screen->core, screen->driConfigs,
                                                GLX_WINDOW_BIT |
@@ -993,10 +992,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
      * This allows us to allocate some memory to hold the extension string,
      * but it requires that we call __glXGetExtensionString a second time.
      */
-    buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
+    buffer_size = __glXGetExtensionString(screen->base.glx_enable_bits, NULL);
     if (buffer_size > 0) {
         screen->base.GLXextensions = xnfalloc(buffer_size);
-        (void) __glXGetExtensionString(screen->glx_enable_bits,
+        (void) __glXGetExtensionString(screen->base.glx_enable_bits,
                                        screen->base.GLXextensions);
     }
 
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index 65abdff..27c98ed 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -391,15 +391,16 @@ static const __DRIextension *loader_extensions[] = {
 };
 
 static void
-initializeExtensions(__GLXDRIscreen * screen)
+initializeExtensions(__GLXscreen * screen)
 {
     const __DRIextension **extensions;
+    __GLXDRIscreen *dri = (__GLXDRIscreen *)screen;
     int i;
 
     __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
     LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
 
-    if (screen->swrast->base.version >= 3) {
+    if (dri->swrast->base.version >= 3) {
         __glXEnableExtension(screen->glx_enable_bits,
                              "GLX_ARB_create_context");
         __glXEnableExtension(screen->glx_enable_bits,
@@ -415,16 +416,16 @@ initializeExtensions(__GLXDRIscreen * screen)
     __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_fbconfig_float");
     __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_fbconfig_packed_float");
 
-    extensions = screen->core->getExtensions(screen->driScreen);
+    extensions = dri->core->getExtensions(dri->driScreen);
 
     for (i = 0; extensions[i]; i++) {
         if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
-            screen->copySubBuffer =
+            dri->copySubBuffer =
                 (const __DRIcopySubBufferExtension *) extensions[i];
         }
 
         if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
-            screen->texBuffer = (const __DRItexBufferExtension *) extensions[i];
+            dri->texBuffer = (const __DRItexBufferExtension *) extensions[i];
             __glXEnableExtension(screen->glx_enable_bits,
                                  "GLX_EXT_texture_from_pixmap\n");
         }
@@ -459,7 +460,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     screen->base.swapInterval = NULL;
     screen->base.pScreen = pScreen;
 
-    __glXInitExtensionEnableBits(screen->glx_enable_bits);
+    __glXInitExtensionEnableBits(screen->base.glx_enable_bits);
 
     screen->driver = glxProbeDriver(driverName,
                                     (void **) &screen->core,
@@ -480,7 +481,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
         goto handle_error;
     }
 
-    initializeExtensions(screen);
+    initializeExtensions(&screen->base);
 
     screen->base.fbconfigs = glxConvertConfigs(screen->core, screen->driConfigs,
                                                GLX_WINDOW_BIT |
@@ -493,10 +494,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
      * This allows us to allocate some memory to hold the extension string,
      * but it requires that we call __glXGetExtensionString a second time.
      */
-    buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
+    buffer_size = __glXGetExtensionString(screen->base.glx_enable_bits, NULL);
     if (buffer_size > 0) {
         screen->base.GLXextensions = xnfalloc(buffer_size);
-        (void) __glXGetExtensionString(screen->glx_enable_bits,
+        (void) __glXGetExtensionString(screen->base.glx_enable_bits,
                                        screen->base.GLXextensions);
     }
 
diff --git a/glx/glxscreens.h b/glx/glxscreens.h
index 0fe85e6..c63fb56 100644
--- a/glx/glxscreens.h
+++ b/glx/glxscreens.h
@@ -35,6 +35,8 @@
  * Silicon Graphics, Inc.
  */
 
+#include "extension_string.h"
+
 typedef struct __GLXconfig __GLXconfig;
 struct __GLXconfig {
     __GLXconfig *next;
@@ -141,6 +143,7 @@ struct __GLXscreen {
 
     char *GLextensions;
     char *GLXextensions;
+    unsigned char glx_enable_bits[__GLX_EXT_BYTES];
 
     Bool (*CloseScreen) (ScreenPtr pScreen);
 };
diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index f857325..9eaeb94 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -112,9 +112,6 @@ typedef struct __GLXAquaDrawable __GLXAquaDrawable;
  */
 struct __GLXAquaScreen {
     __GLXscreen base;
-
-    /* Supported GLX extensions */
-    unsigned char glx_enable_bits[__GLX_EXT_BYTES];
 };
 
 struct __GLXAquaContext {
@@ -542,19 +539,19 @@ __glXAquaScreenProbe(ScreenPtr pScreen)
     screen->base.fbconfigs = __glXAquaCreateVisualConfigs(
         &screen->base.numFBConfigs, pScreen->myNum);
 
-    __glXInitExtensionEnableBits(screen->glx_enable_bits);
+    __glXInitExtensionEnableBits(screen->base.glx_enable_bits);
     __glXScreenInit(&screen->base, pScreen);
 
-    //__glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context");
-    //__glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context_profile");
+    //__glXEnableExtension(screen->base.glx_enable_bits, "GLX_ARB_create_context");
+    //__glXEnableExtension(screen->base.glx_enable_bits, "GLX_ARB_create_context_profile");
 
     // Generate the GLX extensions string (overrides that set by __glXScreenInit())
     {
         unsigned int buffer_size =
-            __glXGetExtensionString(screen->glx_enable_bits, NULL);
+            __glXGetExtensionString(screen->base.glx_enable_bits, NULL);
         if (buffer_size > 0) {
             screen->base.GLXextensions = xnfalloc(buffer_size);
-            __glXGetExtensionString(screen->glx_enable_bits,
+            __glXGetExtensionString(screen->base.glx_enable_bits,
                                     screen->base.GLXextensions);
         }
     }
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 70d88d7..3b8210f 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -136,9 +136,6 @@ struct __GLXWinDrawable {
 struct __GLXWinScreen {
     __GLXscreen base;
 
-    /* Supported GLX extensions */
-    unsigned char glx_enable_bits[__GLX_EXT_BYTES];
-
     Bool has_WGL_ARB_multisample;
     Bool has_WGL_ARB_pixel_format;
     Bool has_WGL_ARB_pbuffer;
@@ -632,7 +629,7 @@ glxWinScreenProbe(ScreenPtr pScreen)
         // Based on the WGL extensions available, enable various GLX extensions
         // XXX: make this table-driven ?
         //
-        __glXInitExtensionEnableBits(screen->glx_enable_bits);
+        __glXInitExtensionEnableBits(screen->base.glx_enable_bits);
 
         if (strstr(wgl_extensions, "WGL_ARB_make_current_read"))
             screen->has_WGL_ARB_make_current_read = TRUE;
@@ -640,13 +637,13 @@ glxWinScreenProbe(ScreenPtr pScreen)
             LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_make_current_read\n")
 
         if (strstr(gl_extensions, "GL_WIN_swap_hint")) {
-            __glXEnableExtension(screen->glx_enable_bits,
+            __glXEnableExtension(screen->base.glx_enable_bits,
                                  "GLX_MESA_copy_sub_buffer");
             LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
         }
 
         if (strstr(wgl_extensions, "WGL_EXT_swap_control")) {
-            __glXEnableExtension(screen->glx_enable_bits,
+            __glXEnableExtension(screen->base.glx_enable_bits,
                                  "GLX_SGI_swap_control");
             LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control\n");
         }
@@ -654,7 +651,7 @@ glxWinScreenProbe(ScreenPtr pScreen)
 /*       // Hmm?  screen->texOffset */
 /*       if (strstr(wgl_extensions, "WGL_ARB_render_texture")) */
 /*         { */
-/*           __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); */
+/*           __glXEnableExtension(screen->base.glx_enable_bits, "GLX_EXT_texture_from_pixmap"); */
 /*           LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); */
 /*           screen->has_WGL_ARB_render_texture = TRUE; */
 /*         } */
@@ -713,10 +710,10 @@ glxWinScreenProbe(ScreenPtr pScreen)
         // Generate the GLX extensions string (overrides that set by __glXScreenInit())
         {
             unsigned int buffer_size =
-                __glXGetExtensionString(screen->glx_enable_bits, NULL);
+                __glXGetExtensionString(screen->base.glx_enable_bits, NULL);
             if (buffer_size > 0) {
                 screen->base.GLXextensions = xnfalloc(buffer_size);
-                __glXGetExtensionString(screen->glx_enable_bits,
+                __glXGetExtensionString(screen->base.glx_enable_bits,
                                         screen->base.GLXextensions);
             }
         }
commit 23cce73221c0b96e7778da34616f8c3f4d6aa819
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Mar 23 15:13:51 2016 -0400

    xquartz/glx: Remove unused fields from the glx screen subclass
    
    dmt:~/git/xserver% git grep -E '\<(index|num_vis)\>' hw/xquartz/GL
    hw/xquartz/GL/indirect.c:    int index;
    hw/xquartz/GL/indirect.c:    int num_vis;
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 8233608..f857325 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -115,9 +115,6 @@ struct __GLXAquaScreen {
 
     /* Supported GLX extensions */
     unsigned char glx_enable_bits[__GLX_EXT_BYTES];
-
-    int index;
-    int num_vis;
 };
 
 struct __GLXAquaContext {
commit 36bcbf76dcc7e88cac093f8fb656c525bfeaf65d
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Mar 23 15:26:23 2016 -0400

    glx: Enable GLX 1.4 unconditionally
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 561faeb..4693e68 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -45,6 +45,7 @@
 #include "indirect_dispatch.h"
 #include "indirect_table.h"
 #include "indirect_util.h"
+#include "protocol-versions.h"
 
 static char GLXServerVendorName[] = "SGI";
 
@@ -797,8 +798,8 @@ __glXDisp_QueryVersion(__GLXclientState * cl, GLbyte * pc)
         .type = X_Reply,
         .sequenceNumber = client->sequence,
         .length = 0,
-        .majorVersion = glxMajorVersion,
-        .minorVersion = glxMinorVersion
+        .majorVersion = SERVER_GLX_MAJOR_VERSION,
+        .minorVersion = SERVER_GLX_MINOR_VERSION
     };
 
     if (client->swapped) {
@@ -2454,7 +2455,6 @@ __glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
     char *buf;
     __GLXscreen *pGlxScreen;
     int err;
-    char ver_str[16];
 
     REQUEST_SIZE_MATCH(xGLXQueryServerStringReq);
 
@@ -2466,11 +2466,7 @@ __glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
         ptr = GLXServerVendorName;
         break;
     case GLX_VERSION:
-        /* Return to the server version rather than the screen version
-         * to prevent confusion when they do not match.
-         */
-        snprintf(ver_str, 16, "%d.%d", glxMajorVersion, glxMinorVersion);
-        ptr = ver_str;
+        ptr = "1.4";
         break;
     case GLX_EXTENSIONS:
         ptr = pGlxScreen->GLXextensions;
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 71dab2a..ad97eb5 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -1000,18 +1000,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
                                        screen->base.GLXextensions);
     }
 
-    /* We're going to assume (perhaps incorrectly?) that all DRI2-enabled
-     * drivers support the required extensions for GLX 1.4.  The extensions
-     * we're assuming are:
-     *
-     *    - GLX_SGI_make_current_read (1.3)
-     *    - GLX_SGIX_fbconfig (1.3)
-     *    - GLX_SGIX_pbuffer (1.3)
-     *    - GLX_ARB_multisample (1.4)
-     */
-    screen->base.GLXmajor = 1;
-    screen->base.GLXminor = 4;
-
     screen->enterVT = pScrn->EnterVT;
     pScrn->EnterVT = glxDRIEnterVT;
     screen->leaveVT = pScrn->LeaveVT;
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index aaf55ca..65abdff 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -500,9 +500,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
                                        screen->base.GLXextensions);
     }
 
-    screen->base.GLXmajor = 1;
-    screen->base.GLXminor = 4;
-
     __glXsetGetProcAddress(glXGetProcAddressARB);
 
     LogMessage(X_INFO, "AIGLX: Loaded and initialized %s\n", driverName);
diff --git a/glx/glxext.c b/glx/glxext.c
index e41b881..f3d8fdd 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -380,8 +380,6 @@ GlxExtensionInit(void)
 
             glxScreen = p->screenProbe(pScreen);
             if (glxScreen != NULL) {
-                if (glxScreen->GLXminor < glxMinorVersion)
-                    glxMinorVersion = glxScreen->GLXminor;
                 LogMessage(X_INFO,
                            "GLX: Initialized %s GL provider for screen %d\n",
                            p->name, i);
diff --git a/glx/glxscreens.c b/glx/glxscreens.c
index 6a17016..61b8a52 100644
--- a/glx/glxscreens.c
+++ b/glx/glxscreens.c
@@ -154,9 +154,6 @@ static const char GLServerExtensions[] =
     "GL_SGIX_shadow_ambient "
     "GL_SUN_slice_accum ";
 
-unsigned glxMajorVersion = SERVER_GLX_MAJOR_VERSION;
-unsigned glxMinorVersion = SERVER_GLX_MINOR_VERSION;
-
 static Bool
 glxCloseScreen(ScreenPtr pScreen)
 {
@@ -313,15 +310,6 @@ __glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen)
     pGlxScreen->GLextensions = strdup(GLServerExtensions);
     pGlxScreen->GLXextensions = NULL;
 
-    /* All GLX providers must support all of the functionality required for at
-     * least GLX 1.2.  If the provider supports a higher version, the GLXminor
-     * version can be changed in the provider's screen-probe routine.  For
-     * most providers, the screen-probe routine is the caller of this
-     * function.
-     */
-    pGlxScreen->GLXmajor = 1;
-    pGlxScreen->GLXminor = 2;
-
     pGlxScreen->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = glxCloseScreen;
 
diff --git a/glx/glxscreens.h b/glx/glxscreens.h
index a905877..0fe85e6 100644
--- a/glx/glxscreens.h
+++ b/glx/glxscreens.h
@@ -140,20 +140,8 @@ struct __GLXscreen {
     GLint numVisuals;
 
     char *GLextensions;
-
     char *GLXextensions;
 
-    /**
-     * \name GLX version supported by this screen.
-     *
-     * Since the GLX version advertised by the server is for the whole server,
-     * the GLX protocol code uses the minimum version supported on all screens.
-     */
-    /*@{ */
-    unsigned GLXmajor;
-    unsigned GLXminor;
-    /*@} */
-
     Bool (*CloseScreen) (ScreenPtr pScreen);
 };
 
diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 398cdf1..8233608 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -548,9 +548,6 @@ __glXAquaScreenProbe(ScreenPtr pScreen)
     __glXInitExtensionEnableBits(screen->glx_enable_bits);
     __glXScreenInit(&screen->base, pScreen);
 
-    screen->base.GLXmajor = 1;
-    screen->base.GLXminor = 4;
-
     //__glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context");
     //__glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context_profile");
 
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 2df014e..70d88d7 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -720,27 +720,7 @@ glxWinScreenProbe(ScreenPtr pScreen)
                                         screen->base.GLXextensions);
             }
         }
-
-        //
-        // Override the GLX version (__glXScreenInit() sets it to "1.2")
-        // if we have all the needed extensions to operate as a higher version
-        //
-        // SGIX_fbconfig && SGIX_pbuffer && SGI_make_current_read -> 1.3
-        // ARB_multisample -> 1.4
-        //
-        if (screen->has_WGL_ARB_pbuffer) {
-            if (screen->has_WGL_ARB_multisample) {
-                screen->base.GLXmajor = 1;
-                screen->base.GLXminor = 4;
-            }
-            else {
-                screen->base.GLXmajor = 1;
-                screen->base.GLXminor = 3;
-            }
-        }
     }
-    LogMessage(X_INFO, "AIGLX: Set GLX version to %d.%d\n",
-               screen->base.GLXmajor, screen->base.GLXminor);
 
     wglMakeCurrent(NULL, NULL);
     wglDeleteContext(hglrc);
commit 2a72789ee8e88f612dff48ebe2ebe9fecda7a95d
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Mar 16 16:28:13 2016 -0400

    xwin/glx: Drop GLWIN_NO_WGL_EXTENSIONS hack
    
    This doesn't seem very useful, and we're about to implement 1.4 across
    the board, so some WGL extensions will become required.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index cbbc113..2df014e 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -628,16 +628,6 @@ glxWinScreenProbe(ScreenPtr pScreen)
     // those screens to be accelerated in XP and earlier...
 
     {
-        // testing facility to not use any WGL extensions
-        char *envptr = getenv("GLWIN_NO_WGL_EXTENSIONS");
-
-        if ((envptr != NULL) && (atoi(envptr) != 0)) {
-            ErrorF("GLWIN_NO_WGL_EXTENSIONS is set, ignoring WGL_EXTENSIONS\n");
-            wgl_extensions = "";
-        }
-    }
-
-    {
         //
         // Based on the WGL extensions available, enable various GLX extensions
         // XXX: make this table-driven ?
commit 77bdaa1313aa55191b49ec73c1e377928ca294fe
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Mar 22 14:40:37 2016 -0400

    glx: Use __glXInitExtensionEnableBits in all backends (v2)
    
    On xquartz this enables SGI_make_current_read, which is a mostly
    harmless lie as CGL doesn't implement it, as well as SGIX_pbuffer, which
    is fine because no pbuffer-enabled configs are created.
    
    On xwin this enables SGIX_pbuffer and ARB_multisample in all cases.
    Again this is harmless if the backend doesn't support the features,
    since no fbconfigs will be created to expose them.
    
    It also adds SGIX_visual_select_group to both xquartz and xwin.
    Amusingly, both were filling in the appropriate field in the fbconfig
    already.
    
    v2: Warn about missing WGL extensions (Emil)
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 544cb78..398cdf1 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -545,22 +545,12 @@ __glXAquaScreenProbe(ScreenPtr pScreen)
     screen->base.fbconfigs = __glXAquaCreateVisualConfigs(
         &screen->base.numFBConfigs, pScreen->myNum);
 
+    __glXInitExtensionEnableBits(screen->glx_enable_bits);
     __glXScreenInit(&screen->base, pScreen);
 
     screen->base.GLXmajor = 1;
     screen->base.GLXminor = 4;
 
-    memset(screen->glx_enable_bits, 0, __GLX_EXT_BYTES);
-
-    __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_info");
-    __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_rating");
-    __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_import_context");
-    __glXEnableExtension(screen->glx_enable_bits, "GLX_OML_swap_method");
-    __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_fbconfig");
-
-    __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIS_multisample");
-    __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_multisample");
-
     //__glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context");
     //__glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context_profile");
 
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 7828b6c..cbbc113 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -642,17 +642,12 @@ glxWinScreenProbe(ScreenPtr pScreen)
         // Based on the WGL extensions available, enable various GLX extensions
         // XXX: make this table-driven ?
         //
-        memset(screen->glx_enable_bits, 0, __GLX_EXT_BYTES);
-
-        __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_info");
-        __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_rating");
-        __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_import_context");
-        __glXEnableExtension(screen->glx_enable_bits, "GLX_OML_swap_method");
-        __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_fbconfig");
-        __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_make_current_read");
+        __glXInitExtensionEnableBits(screen->glx_enable_bits);
 
         if (strstr(wgl_extensions, "WGL_ARB_make_current_read"))
             screen->has_WGL_ARB_make_current_read = TRUE;
+        else
+            LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_make_current_read\n")
 
         if (strstr(gl_extensions, "GL_WIN_swap_hint")) {
             __glXEnableExtension(screen->glx_enable_bits,
@@ -674,21 +669,15 @@ glxWinScreenProbe(ScreenPtr pScreen)
 /*           screen->has_WGL_ARB_render_texture = TRUE; */
 /*         } */
 
-        if (strstr(wgl_extensions, "WGL_ARB_pbuffer")) {
-            __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_pbuffer");
-            LogMessage(X_INFO, "AIGLX: enabled GLX_SGIX_pbuffer\n");
+        if (strstr(wgl_extensions, "WGL_ARB_pbuffer"))
             screen->has_WGL_ARB_pbuffer = TRUE;
-        }
+        else
+            LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_pbuffer\n")
 
-        if (strstr(wgl_extensions, "WGL_ARB_multisample")) {
-            __glXEnableExtension(screen->glx_enable_bits,
-                                 "GLX_ARB_multisample");
-            __glXEnableExtension(screen->glx_enable_bits,
-                                 "GLX_SGIS_multisample");
-            LogMessage(X_INFO,
-                       "AIGLX: enabled GLX_ARB_multisample and GLX_SGIS_multisample\n");
+        if (strstr(wgl_extensions, "WGL_ARB_multisample"))
             screen->has_WGL_ARB_multisample = TRUE;
-        }
+        else
+            LogMessage(X_WARNING, "AIGLX: missing WGL_ARB_multisample\n")
 
         screen->base.destroy = glxWinScreenDestroy;
         screen->base.createContext = glxWinCreateContext;
commit 15af78fc56569dc3b6a7f2c5a6a49edb602111b7
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Mar 23 15:19:15 2016 -0400

    glx: Enable GLX_SGI_make_current_read in the core
    
    GLX 1.3 implies equivalent functionality, so this is safe to enable
    unconditionally, and bindContext always takes both drawable and readable
    arguments in any case. Mesa stopped exporting the __DRI_READ_DRAWABLE
    extension in 8.0 (when the DRI1 drivers were removed) so this will
    restore the extension string.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/extension_string.c b/glx/extension_string.c
index 30c3416..7e74090 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -92,7 +92,7 @@ static const struct extension_info known_glx_extensions[] = {
 
     { GLX(MESA_copy_sub_buffer),        VER(0,0), N, },
     { GLX(OML_swap_method),             VER(0,0), Y, },
-    { GLX(SGI_make_current_read),       VER(1,3), N, },
+    { GLX(SGI_make_current_read),       VER(1,3), Y, },
     { GLX(SGI_swap_control),            VER(0,0), N, },
     { GLX(SGIS_multisample),            VER(0,0), Y, },
     { GLX(SGIX_fbconfig),               VER(1,3), Y, },
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index c56a376..71dab2a 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -900,13 +900,6 @@ initializeExtensions(__GLXDRIscreen * screen)
     }
 
     for (i = 0; extensions[i]; i++) {
-        if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
-            __glXEnableExtension(screen->glx_enable_bits,
-                                 "GLX_SGI_make_current_read");
-
-            LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
-        }
-
         if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
             screen->texBuffer = (const __DRItexBufferExtension *) extensions[i];
             __glXEnableExtension(screen->glx_enable_bits,
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index 84fd3a1..aaf55ca 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -414,7 +414,6 @@ initializeExtensions(__GLXDRIscreen * screen)
     __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 9b2fc6d98691966f1c9186edad956f78c31f3698
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Mar 23 14:57:25 2016 -0400

    xwin/glx: Enable GLX_SGI_make_current_read unconditionally (v2)
    
    This seems to be fairly universal these days, and if it doesn't exist
    the only thing you break is separate drawable and readable, which is a
    rare feature to use. So pretend it's always there and just throw an
    error on MakeCurrent if it isn't, and don't consider it when computing
    the GLX version number.
    
    v2: Fix type-o for glxWinScreen (Jon Turney)
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index c4be791..7828b6c 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -143,6 +143,7 @@ struct __GLXWinScreen {
     Bool has_WGL_ARB_pixel_format;
     Bool has_WGL_ARB_pbuffer;
     Bool has_WGL_ARB_render_texture;
+    Bool has_WGL_ARB_make_current_read;
 
     /* wrapped screen functions */
     RealizeWindowProcPtr RealizeWindow;
@@ -637,8 +638,6 @@ glxWinScreenProbe(ScreenPtr pScreen)
     }
 
     {
-        Bool glx_sgi_make_current_read = FALSE;
-
         //
         // Based on the WGL extensions available, enable various GLX extensions
         // XXX: make this table-driven ?
@@ -650,13 +649,10 @@ glxWinScreenProbe(ScreenPtr pScreen)
         __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_import_context");
         __glXEnableExtension(screen->glx_enable_bits, "GLX_OML_swap_method");
         __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_fbconfig");
+        __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_make_current_read");
 
-        if (strstr(wgl_extensions, "WGL_ARB_make_current_read")) {
-            __glXEnableExtension(screen->glx_enable_bits,
-                                 "GLX_SGI_make_current_read");
-            LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
-            glx_sgi_make_current_read = TRUE;
-        }
+        if (strstr(wgl_extensions, "WGL_ARB_make_current_read"))
+            screen->has_WGL_ARB_make_current_read = TRUE;
 
         if (strstr(gl_extensions, "GL_WIN_swap_hint")) {
             __glXEnableExtension(screen->glx_enable_bits,
@@ -753,7 +749,7 @@ glxWinScreenProbe(ScreenPtr pScreen)
         // SGIX_fbconfig && SGIX_pbuffer && SGI_make_current_read -> 1.3
         // ARB_multisample -> 1.4
         //
-        if (screen->has_WGL_ARB_pbuffer && glx_sgi_make_current_read) {
+        if (screen->has_WGL_ARB_pbuffer) {
             if (screen->has_WGL_ARB_multisample) {
                 screen->base.GLXmajor = 1;
                 screen->base.GLXminor = 4;
@@ -1429,6 +1425,7 @@ static int
 glxWinContextMakeCurrent(__GLXcontext * base)
 {
     __GLXWinContext *gc = (__GLXWinContext *) base;
+    glxWinScreen *scr = (glxWinScreen *)base->pGlxScreen;
     BOOL ret;
     HDC drawDC;
     HDC readDC = NULL;
@@ -1461,7 +1458,14 @@ glxWinContextMakeCurrent(__GLXcontext * base)
     }
 
     if ((gc->base.readPriv != NULL) && (gc->base.readPriv != gc->base.drawPriv)) {
-        // XXX: should only occur with WGL_ARB_make_current_read
+        /*
+         * We enable GLX_SGI_make_current_read unconditionally, but the
+         * renderer might not support it. It's fairly rare to use this
+         * feature so just error out if it can't work.
+         */
+        if (!scr->has_WGL_ARB_make_current_read)
+            return False;
+
         /*
            If there is a separate read drawable, create a separate read DC, and
            use the wglMakeContextCurrent extension to make the context current drawing
commit b2ef7df476af619903ef7f6b6962b371ae14306c
Author: Adam Jackson <ajax at redhat.com>
Date:   Sat Mar 19 13:44:10 2016 -0400

    xquartz/glx: Error out for MakeContextCurrent(draw != read)
    
    CGL doesn't have a way to express this directly, unlike EGL WGL and GLX.
    It might be implementable, but it's never actually worked, and it's a
    fairly niche feature so we're better off throwing an error if someone
    attempts it.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 4f3e2e4..544cb78 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -387,6 +387,9 @@ __glXAquaContextMakeCurrent(__GLXcontext *baseContext)
 
     GLAQUA_DEBUG_MSG("glAquaMakeCurrent (ctx 0x%p)\n", baseContext);
 
+    if (context->base.drawPriv != context->base.readPriv)
+        return 0;
+
     if (attach(context, drawPriv))
         return /*error*/ 0;
 
commit f95645c6f70019316f8ad77b7beb84530fc0505f
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Mar 22 14:37:19 2016 -0400

    glx: Don't enable EXT_texture_from_pixmap unconditionally
    
    Not all backend servers implement this.  Those that don't happen to not
    use __glXInitExtensionEnableBits, but we'd like that to change, so fix
    it up before we switch them over.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/extension_string.c b/glx/extension_string.c
index 616c793..30c3416 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -86,7 +86,7 @@ static const struct extension_info known_glx_extensions[] = {
     { 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_texture_from_pixmap),     VER(0,0), N, },
     { GLX(EXT_visual_info),             VER(0,0), Y, },
     { GLX(EXT_visual_rating),           VER(0,0), Y, },
 
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 2a7c1e3..c56a376 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -909,7 +909,8 @@ initializeExtensions(__GLXDRIscreen * screen)
 
         if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
             screen->texBuffer = (const __DRItexBufferExtension *) extensions[i];
-            /* GLX_EXT_texture_from_pixmap is always enabled. */
+            __glXEnableExtension(screen->glx_enable_bits,
+                                 "GLX_EXT_texture_from_pixmap");
             LogMessage(X_INFO,
                        "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n");
         }
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index cb57e9a..84fd3a1 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -426,7 +426,8 @@ initializeExtensions(__GLXDRIscreen * screen)
 
         if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
             screen->texBuffer = (const __DRItexBufferExtension *) extensions[i];
-            /* GLX_EXT_texture_from_pixmap is always enabled. */
+            __glXEnableExtension(screen->glx_enable_bits,
+                                 "GLX_EXT_texture_from_pixmap\n");
         }
 
 #ifdef __DRI2_FLUSH_CONTROL
commit 410aec82556def5395f51299bcefbeb7d0bda604
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Mar 22 14:29:06 2016 -0400

    glx: Remove server-side mention of GLX_MESA_swap_control
    
    This extension is direct-only and has no GLX protocol. We don't even
    track an enable bit for it, trying to turn it on is pointless.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 948d653..2a7c1e3 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -876,10 +876,8 @@ initializeExtensions(__GLXDRIscreen * screen)
     if (DRI2HasSwapControl(pScreen)) {
         __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event");
         __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control");
-        __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_swap_control");
         LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n");
-        LogMessage(X_INFO,
-                   "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+        LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control\n");
     }
 
     /* enable EXT_framebuffer_sRGB extension (even if there are no sRGB capable fbconfigs) */
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index e515d18..c4be791 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -667,10 +667,7 @@ glxWinScreenProbe(ScreenPtr pScreen)
         if (strstr(wgl_extensions, "WGL_EXT_swap_control")) {
             __glXEnableExtension(screen->glx_enable_bits,
                                  "GLX_SGI_swap_control");
-            __glXEnableExtension(screen->glx_enable_bits,
-                                 "GLX_MESA_swap_control");
-            LogMessage(X_INFO,
-                       "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+            LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control\n");
         }
 
 /*       // Hmm?  screen->texOffset */
commit 3a21da59e59cf11a9113d71e3431c4bd394ff1e8
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Mar 16 19:05:17 2016 -0400

    glx: Remove default server glx extension string
    
    This existed only to be strdup'd and then immediately freed.
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 58e60b9..948d653 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -1003,8 +1003,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
      */
     buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
     if (buffer_size > 0) {
-        free(screen->base.GLXextensions);
-
         screen->base.GLXextensions = xnfalloc(buffer_size);
         (void) __glXGetExtensionString(screen->glx_enable_bits,
                                        screen->base.GLXextensions);
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index 924067c..cb57e9a 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -495,8 +495,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
      */
     buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
     if (buffer_size > 0) {
-        free(screen->base.GLXextensions);
-
         screen->base.GLXextensions = xnfalloc(buffer_size);
         (void) __glXGetExtensionString(screen->glx_enable_bits,
                                        screen->base.GLXextensions);
diff --git a/glx/glxscreens.c b/glx/glxscreens.c
index b0ad3b7..6a17016 100644
--- a/glx/glxscreens.c
+++ b/glx/glxscreens.c
@@ -154,26 +154,8 @@ static const char GLServerExtensions[] =
     "GL_SGIX_shadow_ambient "
     "GL_SUN_slice_accum ";
 
-/*
-** We have made the simplifying assuption that the same extensions are
-** supported across all screens in a multi-screen system.
-*/
 unsigned glxMajorVersion = SERVER_GLX_MAJOR_VERSION;
 unsigned glxMinorVersion = SERVER_GLX_MINOR_VERSION;
-static char GLXServerExtensions[] =
-    "GLX_ARB_multisample "
-    "GLX_EXT_visual_info "
-    "GLX_EXT_visual_rating "
-    "GLX_EXT_import_context "
-    "GLX_EXT_texture_from_pixmap "
-    "GLX_OML_swap_method "
-    "GLX_SGI_make_current_read "
-#ifndef __APPLE__
-    "GLX_SGIS_multisample "
-#endif
-    "GLX_SGIX_fbconfig "
-    "GLX_SGIX_pbuffer "
-    "GLX_MESA_copy_sub_buffer ";
 
 static Bool
 glxCloseScreen(ScreenPtr pScreen)
@@ -329,7 +311,7 @@ __glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen)
 
     pGlxScreen->pScreen = pScreen;
     pGlxScreen->GLextensions = strdup(GLServerExtensions);
-    pGlxScreen->GLXextensions = strdup(GLXServerExtensions);
+    pGlxScreen->GLXextensions = NULL;
 
     /* All GLX providers must support all of the functionality required for at
      * least GLX 1.2.  If the provider supports a higher version, the GLXminor
diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 4e6ab3d..4f3e2e4 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -566,8 +566,6 @@ __glXAquaScreenProbe(ScreenPtr pScreen)
         unsigned int buffer_size =
             __glXGetExtensionString(screen->glx_enable_bits, NULL);
         if (buffer_size > 0) {
-            free(screen->base.GLXextensions);
-
             screen->base.GLXextensions = xnfalloc(buffer_size);
             __glXGetExtensionString(screen->glx_enable_bits,
                                     screen->base.GLXextensions);
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index e4be642..e515d18 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -743,8 +743,6 @@ glxWinScreenProbe(ScreenPtr pScreen)
             unsigned int buffer_size =
                 __glXGetExtensionString(screen->glx_enable_bits, NULL);
             if (buffer_size > 0) {
-                free(screen->base.GLXextensions);
-
                 screen->base.GLXextensions = xnfalloc(buffer_size);
                 __glXGetExtensionString(screen->glx_enable_bits,
                                         screen->base.GLXextensions);
commit 44e1c97ca6fe992bbb6ef9ecb0b82a113adfa57e
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Mon Mar 21 09:53:17 2016 +0100

    xwayland: Pretend we support viewport in vidmode
    
    Some games (namely openttd) will raise an XError and fail with a
    BadValue if their request to XF86VidModeSetViewPort fails.
    
    Support only the default zoom and viewport, fail for everything else.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xwayland/xwayland-vidmode.c b/hw/xwayland/xwayland-vidmode.c
index 6d70e39..0bcd114 100644
--- a/hw/xwayland/xwayland-vidmode.c
+++ b/hw/xwayland/xwayland-vidmode.c
@@ -208,15 +208,26 @@ xwlVidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
 static Bool
 xwlVidModeZoomViewport(ScreenPtr pScreen, int zoom)
 {
-    /* Unsupported for now */
-    return FALSE;
+    /* Support only no zoom */
+    return (zoom == 1);
 }
 
 static Bool
 xwlVidModeSetViewPort(ScreenPtr pScreen, int x, int y)
 {
-    /* Unsupported for now */
-    return FALSE;
+    RROutputPtr output;
+    RRCrtcPtr crtc;
+
+    output = RRFirstOutput(pScreen);
+    if (output == NULL)
+        return FALSE;
+
+    crtc = output->crtc;
+    if (crtc == NULL)
+        return FALSE;
+
+    /* Support only default viewport */
+    return (x == crtc->x && y == crtc->y);
 }
 
 static Bool
commit 6e3a6e30a6ac66942a0756a5d079993181f02e34
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Mar 17 14:39:45 2016 +0100

    xwayland: do not include frequency in mode name
    
    Some applications (e.g. using lwjgl) try to parse the output of the
    xrandr command and get confused with the mode name returned by Xwayland,
    because it contains "@[frequency]" (e.g. "1024x640 at 60.0Hz").
    
    Remove the @[frequency] part of the mode name to match what is found in
    usual mode names on regular X servers to please those applications.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94589
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Daniel Stone <daniels at collabora.com>

diff --git a/hw/xwayland/xwayland-cvt.c b/hw/xwayland/xwayland-cvt.c
index 3566559..9655e10 100644
--- a/hw/xwayland/xwayland-cvt.c
+++ b/hw/xwayland/xwayland-cvt.c
@@ -296,8 +296,8 @@ xwayland_cvt(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
     if (Interlaced)
         modeinfo.modeFlags |= RR_Interlace;
 
-    snprintf(name, sizeof name, "%dx%d@%.1fHz",
-             modeinfo.width, modeinfo.height, VRefresh);
+    snprintf(name, sizeof name, "%dx%d",
+             modeinfo.width, modeinfo.height);
     modeinfo.nameLength = strlen(name);
 
     return RRModeGet(&modeinfo, name);
commit 418fe365b45a143680d3b4143dc60f7cdc5a3507
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Mar 24 17:34:23 2016 +0900

    xfree86/modes: Make sure the HW cursor is hidden when it should be
    
    When the HW cursor is hidden (e.g. because xf86CursorResetCursor
    triggers a switch from HW cursor to SW cursor), the driver isn't
    notified of this for disabled CRTCs. If the HW cursor was shown when the
    CRTC was disabled, it may still be displayed when the CRTC is enabled
    again.
    
    Prevent this by explicitly hiding the HW cursor again after setting a
    mode if it's currently supposed to be hidden.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94560
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 2639a30..6091b5e 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -368,6 +368,12 @@ xf86CrtcSetModeTransform(xf86CrtcPtr crtc, DisplayModePtr mode,
             xf86CrtcSetScreenSubpixelOrder(scrn->pScreen);
         if (scrn->ModeSet)
             scrn->ModeSet(scrn);
+
+        /* Make sure the HW cursor is hidden if it's supposed to be, in case
+         * it was hidden while the CRTC was disabled
+         */
+        if (!xf86_config->cursor_on)
+            xf86_hide_cursors(scrn);
     }
     else {
         crtc->x = saved_x;
commit adefbaee499b9679c6cac21f52ec6545af2b36b5
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Mar 28 18:11:09 2016 +0900

    os: Treat ssh as a non-local client (v4)
    
    By the time we get to ComputeLocalClient, we've already done
    NextAvailableClient → ReserveClientIds → DetermineClientCmd (assuming
    we're built with #define CLIENTIDS), so we can look up the name of the
    client process and refuse to treat ssh's X forwarding as if it were
    local.
    
    v2: (Michel Dänzer)
        * Only match "ssh" itself, not other executable names starting with
          that prefix.
        * Ignore executable path for the match.
    v3: (Michel Dänzer)
        * Use GetClientCmdName (Mark Kettenis)
        * Perform check on Windows as well, but only ignore path on Cygwin
          (Martin Peres, Emil Velikov, Jon Turney)
    v4: (Michel Dänzer)
        * Cut of any colon and whatever comes after it. (Adam Jackson)
        * Add bugzilla reference.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93261
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/os/access.c b/os/access.c
index 8b2177f..58f95a9 100644
--- a/os/access.c
+++ b/os/access.c
@@ -173,6 +173,10 @@ SOFTWARE.
 
 #endif                          /* WIN32 */
 
+#if !defined(WIN32) || defined(__CYGWIN__)
+#include <libgen.h>
+#endif
+
 #define X_INCLUDE_NETDB_H
 #include <X11/Xos_r.h>
 
@@ -1080,9 +1084,8 @@ ResetHosts(const char *display)
     }
 }
 
-/* Is client on the local host */
-Bool
-ComputeLocalClient(ClientPtr client)
+static Bool
+xtransLocalClient(ClientPtr client)
 {
     int alen, family, notused;
     Xtransaddr *from = NULL;
@@ -1115,6 +1118,40 @@ ComputeLocalClient(ClientPtr client)
     return FALSE;
 }
 
+/* Is client on the local host */
+Bool
+ComputeLocalClient(ClientPtr client)
+{
+    const char *cmdname = GetClientCmdName(client);
+
+    if (!xtransLocalClient(client))
+        return FALSE;
+
+    /* If the executable name is "ssh", assume that this client connection
+     * is forwarded from another host via SSH
+     */
+    if (cmdname) {
+        char **cmd;
+        Bool ret;
+
+        /* Cut off any colon and whatever comes after it, see
+         * https://lists.freedesktop.org/archives/xorg-devel/2015-December/048164.html
+         */
+        cmd = xstrtokenize(cmdname, ":");
+
+#if !defined(WIN32) || defined(__CYGWIN__)
+        cmd[0] = basename(cmd[0]);
+#endif
+
+        ret = strcmp(cmd[0], "ssh") != 0;
+        free(cmd);
+
+        return ret;
+    }
+
+    return TRUE;
+}
+
 /*
  * Return the uid and all gids of a connected local client
  * Allocates a LocalClientCredRec - caller must call FreeLocalClientCreds
commit 1c90797565385426ad63bd2108085c8466695c0b
Author: Sonny Jiang <sonny.jiang at amd.com>
Date:   Mon Mar 28 16:36:50 2016 +0900

    DRI2: add Polaris PCI IDs
    
    Signed-off-by: Sonny Jiang <sonny.jiang at amd.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com> (Polaris10)
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com> (Polaris11)
    
    (Ported from Mesa commit f00c840578a70e479ffb99f6b64c73dc420179fa)
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h b/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h
index bcf15a1..4df8e9d 100644
--- a/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h
+++ b/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h
@@ -182,4 +182,14 @@ CHIPSET(0x9877, CARRIZO_, CARRIZO)
 
 CHIPSET(0x7300, FIJI_, FIJI)
 
+CHIPSET(0x67E0, POLARIS11_, POLARIS11)
+CHIPSET(0x67E1, POLARIS11_, POLARIS11)
+CHIPSET(0x67E8, POLARIS11_, POLARIS11)
+CHIPSET(0x67E9, POLARIS11_, POLARIS11)
+CHIPSET(0x67EB, POLARIS11_, POLARIS11)
+CHIPSET(0x67FF, POLARIS11_, POLARIS11)
+
+CHIPSET(0x67C0, POLARIS10_, POLARIS10)
+CHIPSET(0x67DF, POLARIS10_, POLARIS10)
+
 CHIPSET(0x98E4, STONEY_, STONEY)
commit 3b385105b2d19a1c55e9779ae88d775185eea231
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Mar 24 17:42:47 2016 +0900

    present: Only requeue for next MSC after flip failure
    
    This code was added to deal with the driver present hook failing, in
    which case we need to wait for the next MSC before executing the
    presentation.
    
    However, it could also take effect in cases where the driver incorrectly
    thinks the current MSC matches the target one (e.g. due to the kernel
    interface only supporting 32-bit MSC values), in which case it could
    result in the presentation getting requeued over and over.
    
    To prevent such issues, check specifically for the target MSC
    immediately following the current MSC.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94596
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/present/present.c b/present/present.c
index 55f6aa7..105e2bf 100644
--- a/present/present.c
+++ b/present/present.c
@@ -726,7 +726,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
         }
 
         /* If present_flip failed, we may have to requeue for the target MSC */
-        if (msc_is_after(vblank->target_msc, crtc_msc) &&
+        if (vblank->target_msc == crtc_msc + 1 &&
             Success == present_queue_vblank(screen,
                                             vblank->crtc,
                                             vblank->event_id,
commit 8ac0e05cc6c6e87b223ba7cb31d8856771c5d41a
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Mar 23 14:42:08 2016 -0400

    vfb: Re-add LD_EXPORT_SYMBOLS_FLAG to LDFLAGS
    
    Accidentally removed, breaks Xvfb on cygwin.
    
    Reviewed-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/vfb/Makefile.am b/hw/vfb/Makefile.am
index c9ac35e..f0f9fee 100644
--- a/hw/vfb/Makefile.am
+++ b/hw/vfb/Makefile.am
@@ -21,6 +21,7 @@ XVFB_LIBS = \
 
 Xvfb_LDADD = $(XVFB_LIBS) $(XVFB_SYS_LIBS) $(XSERVER_SYS_LIBS)
 Xvfb_DEPENDENCIES = $(XVFB_LIBS)
+Xvfb_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
 
 relink:
 	$(AM_V_at)rm -f Xvfb$(EXEEXT) && $(MAKE) Xvfb$(EXEEXT)
commit a288cf58a0dc0f965a6f964c76bb86bb1989d797
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Mar 16 10:45:54 2016 +1000

    glamor: swizzle RED to 0 for alpha textures
    
    I'm pretty sure Eric suspected this could cause a problem, and we
    couldn't find a test. Well loading feedly in firefox seems to trigger
    badness that this solves.
    
    bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94554
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Tested-by: Timo Aaltonen <tjaalton at ubuntu.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index a531f60..f4f8749 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -352,8 +352,10 @@ _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)
+    if (format == glamor_priv->one_channel_format && format == GL_RED) {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ZERO);
         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);
commit 4583fa9a6cd3095d7497c075d68e7430ea3c5cb0
Author: Ángel González <ingenit at zoho.com>
Date:   Mon Oct 15 22:04:22 2012 +0200

    security: Fix reversed comment
    
    Commit 6045506be0cebca4ebbe943ae77f020aafa703d4 changed back
    the behavior to only allow the trusted extensions to the untrusted clients,
    but left the 8b5d21cc1d1f4e9d20e5d5eca44cb1e60a419763
    comment intended for Security*Un*trustedExtensions saying that
    "untrusted clients shouldn't have access to these".
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Ángel González <ingenit at zoho.com>

diff --git a/Xext/security.c b/Xext/security.c
index 04382ff..8cb3a2c 100644
--- a/Xext/security.c
+++ b/Xext/security.c
@@ -63,7 +63,7 @@ typedef struct {
     XID authId;
 } SecurityStateRec;
 
-/* Extensions that untrusted clients shouldn't have access to */
+/* The only extensions that untrusted clients have access to */
 static const char *SecurityTrustedExtensions[] = {
     "XC-MISC",
     "BIG-REQUESTS",
commit b78897d0a04a833720698901fbac9535570875e4
Author: Evgeny M. Zubok <evgeny.zubok at tochka.ru>
Date:   Thu Apr 8 03:58:21 2010 -0700

    xfree86: Change VBE version early-out to 1.2. (#22672)
    
    Reporter has an S3 Trio with DDC and VESA 1.2.
    
    Signed-off-by: Corbin Simpson <MostAwesomeDude at gmail.com>
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/hw/xfree86/vbe/vbe.c b/hw/xfree86/vbe/vbe.c
index ef12cb8..d23e0f5 100644
--- a/hw/xfree86/vbe/vbe.c
+++ b/hw/xfree86/vbe/vbe.c
@@ -325,7 +325,7 @@ vbeDoEDID(vbeInfoPtr pVbe, void *unused)
 
     if (!pVbe)
         return NULL;
-    if (pVbe->version < 0x200)
+    if (pVbe->version < 0x102)
         return NULL;
 
     DDC_data = vbeReadEDID(pVbe);
commit 184fbf7541012090b8716c7eaf00895efd16d0ac
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Mar 14 11:37:32 2016 -0400

    xfree86: Finish removing font modules
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/doc/ddxDesign.xml b/hw/xfree86/doc/ddxDesign.xml
index aed77a9..53647d0 100644
--- a/hw/xfree86/doc/ddxDesign.xml
+++ b/hw/xfree86/doc/ddxDesign.xml
@@ -5560,10 +5560,6 @@ The fields are used as follows:
 		    <term><constant>ABI_CLASS_EXTENSION</constant></term>
 		    <listitem><para>requires the extension module ABI
 		      </para></listitem></varlistentry>
-		  <varlistentry>
-		    <term><constant>ABI_CLASS_FONT</constant></term>
-		    <listitem><para>requires the font module ABI
-		      </para></listitem></varlistentry>
 		</variablelist>
 
 	      </para></listitem></varlistentry>
@@ -5583,7 +5579,6 @@ The fields are used as follows:
                    ABI_VIDEODRV_VERSION
                    ABI_XINPUT_VERSION
                    ABI_EXTENSION_VERSION
-                   ABI_FONT_VERSION
 		  </constant></literallayout>
 
 	      </para></listitem></varlistentry>
@@ -5603,7 +5598,6 @@ The fields are used as follows:
                    MOD_CLASS_NONE
                    MOD_CLASS_VIDEODRV
                    MOD_CLASS_XINPUT
-                   MOD_CLASS_FONT
                    MOD_CLASS_EXTENSION
 		  </constant></literallayout>
 
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index 73dc1b8..702d4e7 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -86,7 +86,6 @@ const ModuleVersions LoaderVersionInfo = {
     ABI_VIDEODRV_VERSION,
     ABI_XINPUT_VERSION,
     ABI_EXTENSION_VERSION,
-    ABI_FONT_VERSION
 };
 
 static int ModuleDuplicated[] = { };
@@ -613,8 +612,6 @@ CheckVersion(const char *module, XF86ModuleVersionInfo * data,
             ver = LoaderVersionInfo.xinputVersion;
         else if (!strcmp(data->abiclass, ABI_CLASS_EXTENSION))
             ver = LoaderVersionInfo.extensionVersion;
-        else if (!strcmp(data->abiclass, ABI_CLASS_FONT))
-            ver = LoaderVersionInfo.fontVersion;
 
         abimaj = GET_ABI_MAJOR(data->abiversion);
         abimin = GET_ABI_MINOR(data->abiversion);
commit 69d1528bc35073331e281448dfb04eb4240ff472
Author: Adam Jackson <ajax at redhat.com>
Date:   Thu Apr 26 16:42:20 2012 -0400

    xfree86: Font modules aren't a real thing
    
    There are no longer any loadable font modules (not that they ever did
    much in the first place), so stop pretending they're a defined ABI
    surface.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>

diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index 7a8b7ab..fc61120 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -62,7 +62,6 @@ typedef enum {
 #define ABI_CLASS_VIDEODRV	"X.Org Video Driver"
 #define ABI_CLASS_XINPUT	"X.Org XInput driver"
 #define ABI_CLASS_EXTENSION	"X.Org Server Extension"
-#define ABI_CLASS_FONT		"X.Org Font Renderer"
 
 #define ABI_MINOR_MASK		0x0000FFFF
 #define ABI_MAJOR_MASK		0xFFFF0000
@@ -83,7 +82,6 @@ typedef enum {
 #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(21, 0)
 #define ABI_XINPUT_VERSION	SET_ABI_VERSION(22, 1)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(9, 0)
-#define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
 #define MODINFOSTRING1	0xef23fdc5
 #define MODINFOSTRING2	0x10dc023a
@@ -122,7 +120,6 @@ typedef enum {
 #define MOD_CLASS_NONE		NULL
 #define MOD_CLASS_VIDEODRV	"X.Org Video Driver"
 #define MOD_CLASS_XINPUT	"X.Org XInput Driver"
-#define MOD_CLASS_FONT		"X.Org Font Renderer"
 #define MOD_CLASS_EXTENSION	"X.Org Server Extension"
 
 /* This structure is expected to be returned by the initfunc */
diff --git a/hw/xfree86/loader/loader.c b/hw/xfree86/loader/loader.c
index 3132984..c8d7540 100644
--- a/hw/xfree86/loader/loader.c
+++ b/hw/xfree86/loader/loader.c
@@ -180,7 +180,6 @@ LoaderGetABIVersion(const char *abiclass)
         {ABI_CLASS_VIDEODRV, LoaderVersionInfo.videodrvVersion},
         {ABI_CLASS_XINPUT, LoaderVersionInfo.xinputVersion},
         {ABI_CLASS_EXTENSION, LoaderVersionInfo.extensionVersion},
-        {ABI_CLASS_FONT, LoaderVersionInfo.fontVersion},
         {NULL, 0}
     };
     int i;
commit 4f8151c7a4bcf2d55848e70c83b2f9ce458cf316
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Mar 14 11:20:39 2016 -0400

    Fix the typo from the previous patch, d'oh
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/Xext/vidmode.c b/Xext/vidmode.c
index 0cbbdc3..499a2a8 100644
--- a/Xext/vidmode.c
+++ b/Xext/vidmode.c
@@ -662,7 +662,7 @@ ProcVidModeDeleteModeLine(ClientPtr client)
             bytes_to_int32(sizeof(xXF86VidModeDeleteModeLineReq));
     }
     if (len != stuff->privsize) {
-        DebufF("req_len = %ld, sizeof(Req) = %d, privsize = %ld, "
+        DebugF("req_len = %ld, sizeof(Req) = %d, privsize = %ld, "
                "len = %d, length = %d\n",
                (unsigned long) client->req_len,
                (int) sizeof(xXF86VidModeDeleteModeLineReq) >> 2,
commit 75eecf28ae3709181a51571132b0accd9cae316e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Mar 13 13:54:01 2016 +0000

    Xext/vidmode: Reduce verbosity of GetModeLine debug messages
    
    In commit f175cf45aebcdda53f3ae49c0eaf27da1f194e92
    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
    
    the verbosity of some old debug messages (which print the reply to every
    GetModeLine client request and others) was increased leading to lots of
    log spam. Downgrade the logging back to DebugF.
    
    [ajax: Fix a typo so it compiles.]
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    References: https://bugs.freedesktop.org/show_bug.cgi?id=94515
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/Xext/vidmode.c b/Xext/vidmode.c
index 7c838f4..0cbbdc3 100644
--- a/Xext/vidmode.c
+++ b/Xext/vidmode.c
@@ -69,7 +69,7 @@ typedef struct {
     dixSetPrivate(&(c)->devPrivates, VidModeClientPrivateKey, p)
 
 #ifdef DEBUG
-#define DEBUG_P(x) LogMessage(X_INFO, x"\n");
+#define DEBUG_P(x) DebugF(x"\n")
 #else
 #define DEBUG_P(x) /**/
 #endif
@@ -267,13 +267,13 @@ ProcVidModeGetModeLine(ClientPtr client)
     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);
+    DebugF("GetModeLine - scrn: %d clock: %ld\n",
+           stuff->screen, (unsigned long) rep.dotclock);
+    DebugF("GetModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
+           rep.hdisplay, rep.hsyncstart, rep.hsyncend, rep.htotal);
+    DebugF("              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
@@ -483,23 +483,23 @@ ProcVidModeAddModeLine(ClientPtr client)
         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);
+    DebugF("AddModeLine - scrn: %d clock: %ld\n",
+           (int) stuff->screen, (unsigned long) stuff->dotclock);
+    DebugF("AddModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
+           stuff->hdisplay, stuff->hsyncstart,
+           stuff->hsyncend, stuff->htotal);
+    DebugF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+           stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
+           stuff->vtotal, (unsigned long) stuff->flags);
+    DebugF("      after - scrn: %d clock: %ld\n",
+           (int) stuff->screen, (unsigned long) stuff->after_dotclock);
+    DebugF("              hdsp: %d hbeg: %d hend: %d httl: %d\n",
+           stuff->after_hdisplay, stuff->after_hsyncstart,
+           stuff->after_hsyncend, stuff->after_htotal);
+    DebugF("              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);
@@ -572,7 +572,7 @@ ProcVidModeAddModeLine(ClientPtr client)
     VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
 
     if (stuff->privsize)
-        LogMessage(X_INFO, "AddModeLine - Privates in request have been ignored\n");
+        DebugF("AddModeLine - Privates in request have been ignored\n");
 
     /* Check that the mode is consistent with the monitor specs */
     switch (pVidMode->CheckModeForMonitor(pScreen, mode)) {
@@ -601,7 +601,7 @@ ProcVidModeAddModeLine(ClientPtr client)
 
     pVidMode->AddModeline(pScreen, mode);
 
-    LogMessage(X_INFO, "AddModeLine - Succeeded\n");
+    DebugF("AddModeLine - Succeeded\n");
 
     return Success;
 }
@@ -640,14 +640,14 @@ ProcVidModeDeleteModeLine(ClientPtr client)
         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);
+    DebugF("DeleteModeLine - scrn: %d clock: %ld\n",
+           (int) stuff->screen, (unsigned long) stuff->dotclock);
+    DebugF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
+           stuff->hdisplay, stuff->hsyncstart,
+           stuff->hsyncend, stuff->htotal);
+    DebugF("                 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);
@@ -662,11 +662,11 @@ ProcVidModeDeleteModeLine(ClientPtr client)
             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);
+        DebufF("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;
     }
 
@@ -681,46 +681,46 @@ ProcVidModeDeleteModeLine(ClientPtr client)
     if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
         return BadValue;
 
-    LogMessage(X_INFO, "Checking against clock: %d (%d)\n",
+    DebugF("Checking against clock: %d (%d)\n",
+           VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
+    DebugF("                 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));
+    DebugF("                 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 {
+        DebugF("Checking against clock: %d (%d)\n",
                VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
-    LogMessage(X_INFO, "                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
+        DebugF("                 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",
+        DebugF("                 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");
+            DebugF("DeleteModeLine - Succeeded\n");
             return Success;
         }
     } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
@@ -761,12 +761,12 @@ ProcVidModeModModeLine(ClientPtr client)
         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);
+    DebugF("ModModeLine - scrn: %d hdsp: %d hbeg: %d hend: %d httl: %d\n",
+           (int) stuff->screen, stuff->hdisplay, stuff->hsyncstart,
+           stuff->hsyncend, stuff->htotal);
+    DebugF("              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);
@@ -816,7 +816,7 @@ ProcVidModeModModeLine(ClientPtr client)
     VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
 
     if (stuff->privsize)
-        LogMessage(X_INFO, "ModModeLine - Privates in request have been ignored\n");
+        DebugF("ModModeLine - Privates in request have been ignored\n");
 
     /* Check that the mode is consistent with the monitor specs */
     switch (pVidMode->CheckModeForMonitor(pScreen, modetmp)) {
@@ -856,7 +856,7 @@ ProcVidModeModModeLine(ClientPtr client)
     pVidMode->SetCrtcForMode(pScreen, mode);
     pVidMode->SwitchMode(pScreen, mode);
 
-    LogMessage(X_INFO, "ModModeLine - Succeeded\n");
+    DebugF("ModModeLine - Succeeded\n");
     return Success;
 }
 
@@ -896,14 +896,14 @@ ProcVidModeValidateModeLine(ClientPtr client)
         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);
+    DebugF("ValidateModeLine - scrn: %d clock: %ld\n",
+           (int) stuff->screen, (unsigned long) stuff->dotclock);
+    DebugF("                   hdsp: %d hbeg: %d hend: %d httl: %d\n",
+           stuff->hdisplay, stuff->hsyncstart,
+           stuff->hsyncend, stuff->htotal);
+    DebugF("                   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);
@@ -956,7 +956,7 @@ ProcVidModeValidateModeLine(ClientPtr client)
     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");
+        DebugF("ValidateModeLine - Privates in request have been ignored\n");
 
     /* Check that the mode is consistent with the monitor specs */
     if ((status =
@@ -982,7 +982,7 @@ ProcVidModeValidateModeLine(ClientPtr client)
         swapl(&rep.status);
     }
     WriteToClient(client, sizeof(xXF86VidModeValidateModeLineReply), &rep);
-    LogMessage(X_INFO, "ValidateModeLine - Succeeded (status = %d)\n", status);
+    DebugF("ValidateModeLine - Succeeded (status = %d)\n", status);
 
     return Success;
 }
@@ -1046,14 +1046,14 @@ ProcVidModeSwitchToMode(ClientPtr client)
         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);
+    DebugF("SwitchToMode - scrn: %d clock: %ld\n",
+           (int) stuff->screen, (unsigned long) stuff->dotclock);
+    DebugF("               hdsp: %d hbeg: %d hend: %d httl: %d\n",
+           stuff->hdisplay, stuff->hsyncstart,
+           stuff->hsyncend, stuff->htotal);
+    DebugF("               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);
@@ -1089,19 +1089,19 @@ ProcVidModeSwitchToMode(ClientPtr client)
         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));
+        DebugF("Checking against clock: %d (%d)\n",
+               VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
+        DebugF("                 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));
+        DebugF("                 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)) {
@@ -1109,7 +1109,7 @@ ProcVidModeSwitchToMode(ClientPtr client)
             if (!pVidMode->SwitchMode(pScreen, mode))
                 return BadValue;
 
-            LogMessage(X_INFO, "SwitchToMode - Succeeded\n");
+            DebugF("SwitchToMode - Succeeded\n");
             return Success;
         }
     } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
commit 744c292ae49dd1f9d33b860d2b4f0ae27023809b
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Mar 11 13:50:32 2016 -0500

    vidmode: Remove stray vidmodeproc.h from EXTRA_DIST
    
    Was removed from the tree in:
    
        commit f175cf45aebcdda53f3ae49c0eaf27da1f194e92
        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
    
    but not removed from the Makefile, which broke 'make dist'.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am
index 2eed5de..caae7fd 100644
--- a/hw/xfree86/common/Makefile.am
+++ b/hw/xfree86/common/Makefile.am
@@ -67,7 +67,6 @@ CLEANFILES = $(BUILT_SOURCES)
 EXTRA_DIST = \
 	compiler.h \
 	fourcc.h \
-	vidmodeproc.h \
 	xf86.h \
 	xf86Bus.h \
 	xf86Config.h \
commit 47bc7fcaa567b0d9e2627b4a21b112e96f81725b
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>

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 316948734c2bba72d42c4cf4530932b5862c109f
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Fri Mar 11 12:21:06 2016 +0900

    glamor: Make context current in glamor_pixmap_fbo_cache_put
    
    Without this, we may be manipulating the context of another screen.
    
    In a system with two GPUs using glamor, this fixes lots of
    
    (EE) glamor256: GL error: GL_INVALID_OPERATION in glBindTexture(non-gen name)
    
    spew since 0b4c0c75 ('glamor: Replace "finish access" shader with texture
    swizzling').
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index d5311a9..a531f60 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -174,6 +174,7 @@ glamor_pixmap_fbo_cache_put(glamor_screen_private *glamor_priv,
      * glamor_picture.c.  Don't reset GL_RED -> GL_ALPHA swizzle, though
      */
     if (glamor_priv->has_texture_swizzle && n_format != 2) {
+        glamor_make_current(glamor_priv);
         glBindTexture(GL_TEXTURE_2D, fbo->tex);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
commit ef3005da3d5dc92b3ee5a0ee78164e739a3216dc
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>

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 d15cb654b6ba365dac9a62064e277adebde2fdab
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>

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 a18238877bbf9aab95843d849a6f434275e9cd6c
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>

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 47c1d6b7abcfb1c6b478367bbc2e869c91485bc0
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>

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 c01094c5312fbd84146dd83122e5256a8e57d092
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>

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 0b4c0c75d06f3dbe92be1a26a637e9f05529cb3d
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:14 2016 -0800

    glamor: Replace "finish access" shader with texture swizzling.
    
    For pictures without alpha, and for most other formats for GLES2, we
    would make a temporary FBO, make another temporary texture, upload our
    GLAMOR_MEMORY pixmap to the texture, then run the "finish access" shader
    across it to swizzle its values around into the temporary FBO (which we
    would use for a single Render operation and then throw away).
    
    We can simplify everything by using GL_ARB_texture_swizzle (or its
    GLES3 counterpart).  It's just not worth the complexity to try to
    improve the performance of this already low-performance path (SHM
    pixmaps + Render) on GLES2.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index e9c1d9e..efe5953 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -605,9 +605,15 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_priv->max_fbo_size = MAX_FBO_SIZE;
 #endif
 
+    glamor_priv->has_texture_swizzle =
+        (epoxy_has_gl_extension("GL_ARB_texture_swizzle") ||
+         (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && gl_version >= 30));
+
     glamor_priv->one_channel_format = GL_ALPHA;
-    if (epoxy_has_gl_extension("GL_ARB_texture_rg") && epoxy_has_gl_extension("GL_ARB_texture_swizzle"))
+    if (epoxy_has_gl_extension("GL_ARB_texture_rg") &&
+        glamor_priv->has_texture_swizzle) {
         glamor_priv->one_channel_format = GL_RED;
+    }
 
     glamor_set_debug_level(&glamor_debug_level);
 
@@ -668,7 +674,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
     glamor_init_vbo(screen);
     glamor_init_pixmap_fbo(screen);
-    glamor_init_finish_access_shaders(screen);
 
 #ifdef GLAMOR_GRADIENT_SHADER
     glamor_init_gradient_shader(screen);
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index a8768f4..7b2b396 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -113,164 +113,6 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
     }
 }
 
-/*
- *  When downloading a unsupported color format to CPU memory,
-    we need to shuffle the color elements and then use a supported
-    color format to read it back to CPU memory.
-
-    For an example, the picture's format is PICT_b8g8r8a8,
-    Then the expecting color layout is as below (little endian):
-    0	1	2	3   : address
-    a	r	g	b
-
-    Now the in GLES2 the supported color format is GL_RGBA, type is
-    GL_UNSIGNED_TYPE, then we need to shuffle the fragment
-    color as :
-	frag_color = sample(texture).argb;
-    before we use glReadPixel to get it back.
-
-    For the uploading process, the shuffle is a revert shuffle.
-    We still use GL_RGBA, GL_UNSIGNED_BYTE to upload the color
-    to a texture, then let's see
-    0	1	2	3   : address
-    a	r	g	b   : correct colors
-    R	G	B	A   : GL_RGBA with GL_UNSIGNED_BYTE
-
-    Now we need to shuffle again, the mapping rule is
-    r = G, g = B, b = A, a = R. Then the uploading shuffle is as
-    below:
-	frag_color = sample(texture).gbar;
-*/
-
-void
-glamor_init_finish_access_shaders(ScreenPtr screen)
-{
-    glamor_screen_private *glamor_priv;
-    const char *vs_source =
-        "attribute vec4 v_position;\n"
-        "attribute vec4 v_texcoord0;\n"
-        "varying vec2 source_texture;\n"
-        "void main()\n"
-        "{\n"
-        "	gl_Position = v_position;\n"
-        "	source_texture = v_texcoord0.xy;\n"
-        "}\n";
-
-    const char *common_source =
-        GLAMOR_DEFAULT_PRECISION
-        "varying vec2 source_texture;\n"
-        "uniform sampler2D sampler;\n"
-        "uniform int revert;\n"
-        "uniform int swap_rb;\n"
-        "#define REVERT_NONE       			0\n"
-        "#define REVERT_NORMAL     			1\n"
-        "#define SWAP_UPLOADING	  		2\n"
-        "#define SWAP_NONE_UPLOADING		3\n";
-
-    const char *fs_source =
-        "void main()\n"
-        "{\n"
-        "   vec4 color = texture2D(sampler, source_texture);\n"
-        "   if (revert == REVERT_NONE) \n"
-        "    { \n"
-        "     if ((swap_rb != SWAP_NONE_UPLOADING))   \n"
-        "		gl_FragColor = color.bgra;\n"
-        "     else \n"
-        "		gl_FragColor = color.rgba;\n"
-        "    } \n"
-        "   else \n"
-        "    { \n"
-        "     if (swap_rb == SWAP_UPLOADING)\n"
-        "		gl_FragColor = color.gbar;\n"
-        "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
-        "		gl_FragColor = color.abgr;\n"
-        "    } \n"
-        "}\n";
-
-    const char *set_alpha_source =
-        "void main()\n"
-        "{\n"
-        "   vec4 color = texture2D(sampler, source_texture);\n"
-        "   if (revert == REVERT_NONE) \n"
-        "    { \n"
-        "     if (swap_rb != SWAP_NONE_UPLOADING)   \n"
-        "		gl_FragColor = vec4(color.bgr, 1);\n"
-        "     else \n"
-        "		gl_FragColor = vec4(color.rgb, 1);\n"
-        "    } \n"
-        "   else \n"
-        "    { \n"
-        "     if (swap_rb == SWAP_UPLOADING)\n"
-        "		gl_FragColor = vec4(color.gba, 1);\n"
-        "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
-        "		gl_FragColor = vec4(color.abg, 1);\n"
-        "    } \n"
-        "}\n";
-    GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
-    GLint sampler_uniform_location;
-    char *source;
-
-    glamor_priv = glamor_get_screen_private(screen);
-    glamor_make_current(glamor_priv);
-    glamor_priv->finish_access_prog[0] = glCreateProgram();
-    glamor_priv->finish_access_prog[1] = glCreateProgram();
-
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
-
-    XNFasprintf(&source, "%s%s", common_source, fs_source);
-    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
-    free(source);
-
-    glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
-    glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
-
-    avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
-
-    XNFasprintf(&source, "%s%s", common_source, set_alpha_source);
-    set_alpha_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER,
-                                              source);
-    free(source);
-
-    glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
-    glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog);
-
-    glBindAttribLocation(glamor_priv->finish_access_prog[0],
-                         GLAMOR_VERTEX_POS, "v_position");
-    glBindAttribLocation(glamor_priv->finish_access_prog[0],
-                         GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-    glamor_link_glsl_prog(screen, glamor_priv->finish_access_prog[0],
-                          "finish access 0");
-
-    glBindAttribLocation(glamor_priv->finish_access_prog[1],
-                         GLAMOR_VERTEX_POS, "v_position");
-    glBindAttribLocation(glamor_priv->finish_access_prog[1],
-                         GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-    glamor_link_glsl_prog(screen, glamor_priv->finish_access_prog[1],
-                          "finish access 1");
-
-    glamor_priv->finish_access_revert[0] =
-        glGetUniformLocation(glamor_priv->finish_access_prog[0], "revert");
-
-    glamor_priv->finish_access_swap_rb[0] =
-        glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb");
-    sampler_uniform_location =
-        glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
-    glUseProgram(glamor_priv->finish_access_prog[0]);
-    glUniform1i(sampler_uniform_location, 0);
-    glUniform1i(glamor_priv->finish_access_revert[0], 0);
-    glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
-
-    glamor_priv->finish_access_revert[1] =
-        glGetUniformLocation(glamor_priv->finish_access_prog[1], "revert");
-    glamor_priv->finish_access_swap_rb[1] =
-        glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb");
-    sampler_uniform_location =
-        glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
-    glUseProgram(glamor_priv->finish_access_prog[1]);
-    glUniform1i(glamor_priv->finish_access_revert[1], 0);
-    glUniform1i(sampler_uniform_location, 0);
-    glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
-}
 
 static GCOps glamor_gc_ops = {
     .FillSpans = glamor_fill_spans,
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 0bfc1dd..d5311a9 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -170,6 +170,17 @@ glamor_pixmap_fbo_cache_put(glamor_screen_private *glamor_priv,
         ("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n",
          fbo, cache, fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
 
+    /* Reset the texture swizzle that may have been set by
+     * glamor_picture.c.  Don't reset GL_RED -> GL_ALPHA swizzle, though
+     */
+    if (glamor_priv->has_texture_swizzle && n_format != 2) {
+        glBindTexture(GL_TEXTURE_2D, fbo->tex);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
+    }
+
     glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
     xorg_list_add(&fbo->list, cache);
     fbo->expire = glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 42fee1b..84a33ad 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright © 2016 Broadcom
  * Copyright © 2009 Intel Corporation
  * Copyright © 1998 Keith Packard
  *
@@ -20,10 +21,19 @@
  * 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.
+ */
+
+/**
+ * @file glamor_picture.c
  *
- * Authors:
- *    Zhigang Gong <zhigang.gong at gmail.com>
+ * Implements temporary uploads of GL_MEMORY Pixmaps to a texture that
+ * is swizzled appropriately for a given Render picture format.
+ * laid *
  *
+ * This is important because GTK likes to use SHM Pixmaps for Render
+ * blending operations, and we don't want a blend operation to fall
+ * back to software (readback is more expensive than the upload we do
+ * here, and you'd have to re-upload the fallback output anyway).
  */
 
 #include <stdlib.h>
@@ -31,40 +41,54 @@
 #include "glamor_priv.h"
 #include "mipict.h"
 
-/*
- * Map picture's format to the correct gl texture format and type.
- * no_alpha is used to indicate whehter we need to wire alpha to 1.
- *
- * Although opengl support A1/GL_BITMAP, we still don't use it
- * here, it seems that mesa has bugs when uploading a A1 bitmap.
+static void byte_swap_swizzle(GLenum *swizzle)
+{
+    GLenum temp;
+
+    temp = swizzle[0];
+    swizzle[0] = swizzle[3];
+    swizzle[3] = temp;
+
+    temp = swizzle[1];
+    swizzle[1] = swizzle[2];
+    swizzle[2] = temp;
+}
+
+/**
+ * Returns the GL format and type for uploading our bits to a given PictFormat.
  *
- * Return 0 if find a matched texture type. Otherwise return -1.
- **/
+ * We may need to tell the caller to translate the bits to another
+ * format, as in PICT_a1 (which GL doesn't support).  We may also need
+ * to tell the GL to swizzle the texture on sampling, because GLES3
+ * doesn't support the GL_UNSIGNED_INT_8_8_8_8{,_REV} types, so we
+ * don't have enough channel reordering options at upload time without
+ * it.
+ */
 static Bool
 glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
                                            PictFormatShort format,
+                                           PictFormatShort *temp_format,
                                            GLenum *tex_format,
                                            GLenum *tex_type,
-                                           int *no_alpha,
-                                           int *revert,
-                                           int *swap_rb)
+                                           GLenum *swizzle)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
     Bool is_little_endian = IMAGE_BYTE_ORDER == LSBFirst;
 
-    *no_alpha = 0;
-    *revert = REVERT_NONE;
-    *swap_rb = SWAP_NONE_UPLOADING;
+    *temp_format = format;
+    swizzle[0] = GL_RED;
+    swizzle[1] = GL_GREEN;
+    swizzle[2] = GL_BLUE;
+    swizzle[3] = GL_ALPHA;
 
     switch (format) {
     case PICT_a1:
         *tex_format = glamor_priv->one_channel_format;
         *tex_type = GL_UNSIGNED_BYTE;
-        *revert = REVERT_UPLOADING_A1;
+        *temp_format = PICT_a8;
         break;
 
     case PICT_b8g8r8x8:
-        *no_alpha = 1;
     case PICT_b8g8r8a8:
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
             *tex_format = GL_BGRA;
@@ -72,13 +96,18 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
         } else {
             *tex_format = GL_RGBA;
             *tex_type = GL_UNSIGNED_BYTE;
-            *swap_rb = SWAP_UPLOADING;
-            *revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
+
+            swizzle[0] = GL_GREEN;
+            swizzle[1] = GL_BLUE;
+            swizzle[2] = GL_ALPHA;
+            swizzle[3] = GL_RED;
+
+            if (!is_little_endian)
+                byte_swap_swizzle(swizzle);
         }
         break;
 
     case PICT_x8r8g8b8:
-        *no_alpha = 1;
     case PICT_a8r8g8b8:
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
             *tex_format = GL_BGRA;
@@ -86,26 +115,31 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
         } else {
             *tex_format = GL_RGBA;
             *tex_type = GL_UNSIGNED_BYTE;
-            *swap_rb = SWAP_UPLOADING;
-            *revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
+
+            swizzle[0] = GL_BLUE;
+            swizzle[2] = GL_RED;
+
+            if (!is_little_endian)
+                byte_swap_swizzle(swizzle);
             break;
         }
         break;
 
     case PICT_x8b8g8r8:
-        *no_alpha = 1;
     case PICT_a8b8g8r8:
         *tex_format = GL_RGBA;
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
             *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
         } else {
+            *tex_format = GL_RGBA;
             *tex_type = GL_UNSIGNED_BYTE;
-            *revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
+
+            if (!is_little_endian)
+                byte_swap_swizzle(swizzle);
         }
         break;
 
     case PICT_x2r10g10b10:
-        *no_alpha = 1;
     case PICT_a2r10g10b10:
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
             *tex_format = GL_BGRA;
@@ -116,7 +150,6 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
         break;
 
     case PICT_x2b10g10r10:
-        *no_alpha = 1;
     case PICT_a2b10g10r10:
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
             *tex_format = GL_RGBA;
@@ -129,8 +162,6 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
     case PICT_r5g6b5:
         *tex_format = GL_RGB;
         *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-        if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP)
-            *revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
         break;
     case PICT_b5g6r5:
         *tex_format = GL_RGB;
@@ -138,14 +169,12 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
             *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
         } else {
             *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-            if (is_little_endian)
-                *swap_rb = SWAP_UPLOADING;
-            *revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
+            swizzle[0] = GL_BLUE;
+            swizzle[2] = GL_RED;
         }
         break;
 
     case PICT_x1b5g5r5:
-        *no_alpha = 1;
     case PICT_a1b5g5r5:
         *tex_format = GL_RGBA;
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
@@ -156,7 +185,6 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
         break;
 
     case PICT_x1r5g5b5:
-        *no_alpha = 1;
     case PICT_a1r5g5b5:
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
             *tex_format = GL_BGRA;
@@ -172,35 +200,36 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
         break;
 
     case PICT_x4r4g4b4:
-        *no_alpha = 1;
     case PICT_a4r4g4b4:
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
             *tex_format = GL_BGRA;
             *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
         } else {
+            /* XXX */
             *tex_format = GL_RGBA;
             *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
-            *revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
-            *swap_rb = SWAP_UPLOADING;
         }
         break;
 
     case PICT_x4b4g4r4:
-        *no_alpha = 1;
     case PICT_a4b4g4r4:
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
             *tex_format = GL_RGBA;
             *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
         } else {
+            /* XXX */
             *tex_format = GL_RGBA;
             *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
-            *revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
         }
         break;
 
     default:
         return FALSE;
     }
+
+    if (!PICT_FORMAT_A(format))
+        swizzle[3] = GL_ONE;
+
     return TRUE;
 }
 
@@ -238,194 +267,6 @@ glamor_get_converted_image(PictFormatShort dst_format,
 }
 
 /**
- * Upload pixmap to a specified texture.
- * This texture may not be the one attached to it.
- **/
-static Bool
-__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
-                                  GLenum format,
-                                  GLenum type,
-                                  int x, int y, int w, int h,
-                                  void *bits)
-{
-    glamor_screen_private *glamor_priv =
-        glamor_get_screen_private(pixmap->drawable.pScreen);
-    int non_sub = 0;
-    unsigned int iformat = 0;
-
-    glamor_make_current(glamor_priv);
-    if (*tex == 0) {
-        glGenTextures(1, tex);
-        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-            iformat = gl_iformat_for_pixmap(pixmap);
-        else
-            iformat = format;
-        non_sub = 1;
-        assert(x == 0 && y == 0);
-    }
-
-    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);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-
-    glamor_priv->suppress_gl_out_of_memory_logging = true;
-    if (non_sub)
-        glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
-    else
-        glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, type, bits);
-    glamor_priv->suppress_gl_out_of_memory_logging = false;
-    if (glGetError() == GL_OUT_OF_MEMORY) {
-        if (non_sub) {
-            glDeleteTextures(1, tex);
-            *tex = 0;
-        }
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-static Bool
-_glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
-                                      GLenum type, int no_alpha, int revert,
-                                      int swap_rb, int x, int y, int w, int h,
-                                      int stride, void *bits)
-{
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    glamor_screen_private *glamor_priv =
-        glamor_get_screen_private(pixmap->drawable.pScreen);
-    float dst_xscale, dst_yscale;
-    GLuint tex = 0;
-    pixman_image_t *converted_image = NULL;
-
-    if (revert == REVERT_UPLOADING_A1) {
-        converted_image = glamor_get_converted_image(PICT_a8,
-                                                     PICT_a1,
-                                                     bits,
-                                                     PixmapBytePad(w, 1),
-                                                     w, h);
-        if (!converted_image)
-            return FALSE;
-
-        bits = pixman_image_get_data(converted_image);
-    }
-
-    /* Try fast path firstly, upload the pixmap to the texture attached
-     * to the fbo directly. */
-    if (no_alpha == 0
-        && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING) {
-        int fbo_x_off, fbo_y_off;
-
-        assert(pixmap_priv->fbo->tex);
-        pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
-
-        assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
-        assert(x + fbo_x_off + w <= pixmap_priv->fbo->width);
-        assert(y + fbo_y_off + h <= pixmap_priv->fbo->height);
-        if (!__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
-                                               format, type,
-                                               x + fbo_x_off, y + fbo_y_off,
-                                               w, h,
-                                               bits)) {
-            if (converted_image)
-                pixman_image_unref(bits);
-            return FALSE;
-        }
-    } else {
-        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,
-                                     v);
-        /* Slow path, we need to flip y or wire alpha to 1. */
-        glamor_make_current(glamor_priv);
-
-        if (!__glamor_upload_pixmap_to_texture(pixmap, &tex,
-                                               format, type, 0, 0, w, h, bits)) {
-            if (converted_image)
-                pixman_image_unref(bits);
-            return FALSE;
-        }
-
-        memcpy(&v[8], texcoords_inv, 8 * sizeof(GLfloat));
-
-        glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                              GL_FALSE, 2 * sizeof(float), vbo_offset);
-        glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-        glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-                              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);
-        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);
-        glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-        glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
-        glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
-
-        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-        glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-        glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-        glDeleteTextures(1, &tex);
-        glBindFramebuffer(GL_FRAMEBUFFER, 0);
-    }
-
-    if (converted_image)
-        pixman_image_unref(bits);
-    return TRUE;
-}
-
-/*
- * Prepare to upload a pixmap to texture memory.
- * no_alpha equals 1 means the format needs to wire alpha to 1.
- */
-static int
-glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
-                             int revert, int swap_rb)
-{
-    int flag = 0;
-    glamor_screen_private *glamor_priv =
-        glamor_get_screen_private(pixmap->drawable.pScreen);
-    GLenum iformat;
-
-    if (!(no_alpha || (revert == REVERT_NORMAL)
-          || (swap_rb != SWAP_NONE_UPLOADING))) {
-        /* We don't need a fbo, a simple texture uploading should work. */
-
-        flag = GLAMOR_CREATE_FBO_NO_FBO;
-    }
-
-    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-        iformat = gl_iformat_for_pixmap(pixmap);
-    else
-        iformat = format;
-
-    if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag))
-        return -1;
-
-    return 0;
-}
-
-/**
  * Uploads a picture based on a GLAMOR_MEMORY pixmap to a texture in a
  * temporary FBO.
  */
@@ -433,17 +274,24 @@ Bool
 glamor_upload_picture_to_texture(PicturePtr picture)
 {
     PixmapPtr pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-    void *bits = pixmap->devPrivate.ptr;
-    int stride = pixmap->devKind;
     ScreenPtr screen = pixmap->drawable.pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    GLenum format, type;
-    int no_alpha, revert, swap_rb;
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    PictFormatShort converted_format;
+    void *bits = pixmap->devPrivate.ptr;
+    int stride = pixmap->devKind;
+    GLenum format, type;
+    GLenum swizzle[4];
+    GLenum iformat;
+    Bool ret = TRUE;
+    Bool needs_swizzle;
+    pixman_image_t *converted_image = NULL;
 
     assert(glamor_pixmap_is_memory(pixmap));
     assert(!pixmap_priv->fbo);
 
+    glamor_make_current(glamor_priv);
+
     /* No handling of large pixmap pictures here (would need to make
      * an FBO array and split the uploads across it).
      */
@@ -455,20 +303,73 @@ glamor_upload_picture_to_texture(PicturePtr picture)
 
     if (!glamor_get_tex_format_type_from_pictformat(screen,
                                                     picture->format,
+                                                    &converted_format,
                                                     &format,
                                                     &type,
-                                                    &no_alpha,
-                                                    &revert, &swap_rb)) {
+                                                    swizzle)) {
         glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
         return FALSE;
     }
-    if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
+
+    needs_swizzle = (swizzle[0] != GL_RED ||
+                     swizzle[1] != GL_GREEN ||
+                     swizzle[2] != GL_BLUE ||
+                     swizzle[3] != GL_ALPHA);
+
+    if (!glamor_priv->has_texture_swizzle && needs_swizzle) {
+        glamor_fallback("Couldn't upload temporary picture due to missing "
+                        "GL_ARB_texture_swizzle.\n");
         return FALSE;
+    }
+
+    if (converted_format != picture->format) {
+        converted_image = glamor_get_converted_image(converted_format,
+                                                     picture->format,
+                                                     bits, stride,
+                                                     pixmap->drawable.width,
+                                                     pixmap->drawable.height);
+        if (!converted_image)
+            return FALSE;
+
+        bits = pixman_image_get_data(converted_image);
+        stride = pixman_image_get_stride(converted_image);
+    }
+
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+        iformat = gl_iformat_for_pixmap(pixmap);
+    else
+        iformat = format;
+
+    if (!glamor_pixmap_ensure_fbo(pixmap, iformat, GLAMOR_CREATE_FBO_NO_FBO))
+        goto fail;
+
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+    glamor_priv->suppress_gl_out_of_memory_logging = true;
+
+    /* We can't use glamor_pixmap_loop() because GLAMOR_MEMORY pixmaps
+     * don't have initialized boxes.
+     */
+    glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
+    glTexImage2D(GL_TEXTURE_2D, 0, iformat,
+                 pixmap->drawable.width, pixmap->drawable.height, 0,
+                 format, type, bits);
+
+    if (needs_swizzle) {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, swizzle[0]);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, swizzle[1]);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, swizzle[2]);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, swizzle[3]);
+    }
+
+    glamor_priv->suppress_gl_out_of_memory_logging = false;
+    if (glGetError() == GL_OUT_OF_MEMORY) {
+        ret = FALSE;
+    }
+
+fail:
+    if (converted_image)
+        pixman_image_unref(converted_image);
 
-    return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type,
-                                                 no_alpha, revert, swap_rb,
-                                                 0, 0,
-                                                 pixmap->drawable.width,
-                                                 pixmap->drawable.height,
-                                                 stride, bits);
+    return ret;
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 6656b28..8f994ea 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -208,6 +208,7 @@ typedef struct glamor_screen_private {
     Bool use_quads;
     Bool has_vertex_array_object;
     Bool has_dual_blend;
+    Bool has_texture_swizzle;
     Bool is_core_profile;
     int max_fbo_size;
 
@@ -286,11 +287,6 @@ typedef struct glamor_screen_private {
         [glamor_program_alpha_count]
         [SHADER_DEST_SWIZZLE_COUNT];
 
-    /* shaders to restore a texture to another texture. */
-    GLint finish_access_prog[2];
-    GLint finish_access_revert[2];
-    GLint finish_access_swap_rb[2];
-
     /* glamor gradient, 0 for small nstops, 1 for
        large nstops and 2 for dynamic generate. */
     GLint gradient_prog[SHADER_GRADIENT_COUNT][3];
@@ -586,8 +582,6 @@ void glamor_gldrawarrays_quads_using_indices(glamor_screen_private *glamor_priv,
                                              unsigned count);
 
 /* glamor_core.c */
-void glamor_init_finish_access_shaders(ScreenPtr screen);
-
 Bool glamor_get_drawable_location(const DrawablePtr drawable);
 void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
                                 int *x, int *y);
commit b0cc04992ced5d96bb5c52fc1e5c868797cc0a17
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:13 2016 -0800

    glamor: Drop dead large-pixmap handling code in temp picture uploads.
    
    The glamor_pixmap_ensure_fbo() in glamor_pixmap_upload_prepare() will
    always fail on a large pixmap, so we can just be explicit about
    bailing out here and then dump the rest of this garbage.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index e0458a6..42fee1b 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -315,11 +315,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
     /* Try fast path firstly, upload the pixmap to the texture attached
      * to the fbo directly. */
     if (no_alpha == 0
-        && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING
-#ifdef WALKAROUND_LARGE_TEXTURE_MAP
-        && glamor_pixmap_priv_is_small(pixmap_priv)
-#endif
-        ) {
+        && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING) {
         int fbo_x_off, fbo_y_off;
 
         assert(pixmap_priv->fbo->tex);
@@ -429,26 +425,6 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
     return 0;
 }
 
-/*
- * upload sub region to a large region.
- * */
-static void
-glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits,
-                int src_stride, int bpp, int x, int y, int w, int h)
-{
-    int j;
-    int byte_per_pixel;
-
-    byte_per_pixel = bpp / 8;
-    src_bits += y * src_stride + (x * byte_per_pixel);
-
-    for (j = y; j < y + h; j++) {
-        memcpy(dst_bits, src_bits, w * byte_per_pixel);
-        src_bits += src_stride;
-        dst_bits += dst_stride;
-    }
-}
-
 /**
  * Uploads a picture based on a GLAMOR_MEMORY pixmap to a texture in a
  * temporary FBO.
@@ -464,11 +440,19 @@ glamor_upload_picture_to_texture(PicturePtr picture)
     GLenum format, type;
     int no_alpha, revert, swap_rb;
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    Bool force_clip;
 
     assert(glamor_pixmap_is_memory(pixmap));
     assert(!pixmap_priv->fbo);
 
+    /* No handling of large pixmap pictures here (would need to make
+     * an FBO array and split the uploads across it).
+     */
+    if (!glamor_check_fbo_size(glamor_priv,
+                               pixmap->drawable.width,
+                               pixmap->drawable.height)) {
+        return FALSE;
+    }
+
     if (!glamor_get_tex_format_type_from_pictformat(screen,
                                                     picture->format,
                                                     &format,
@@ -481,89 +465,10 @@ glamor_upload_picture_to_texture(PicturePtr picture)
     if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
         return FALSE;
 
-    force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP;
-
-    if (glamor_pixmap_priv_is_large(pixmap_priv) || force_clip) {
-        RegionRec region;
-        BoxRec box;
-        int n_region;
-        glamor_pixmap_clipped_regions *clipped_regions;
-        void *sub_bits;
-        int i, j;
-
-        sub_bits = xallocarray(pixmap->drawable.height, stride);
-        if (sub_bits == NULL)
-            return FALSE;
-        box.x1 = 0;
-        box.y1 = 0;
-        box.x2 = pixmap->drawable.width;
-        box.y2 = pixmap->drawable.height;
-        RegionInitBoxes(&region, &box, 1);
-        if (!force_clip)
-            clipped_regions =
-                glamor_compute_clipped_regions(pixmap, &region, &n_region,
-                                               0, 0, 0);
-        else
-            clipped_regions =
-                glamor_compute_clipped_regions_ext(pixmap, &region,
-                                                   &n_region,
-                                                   pixmap_priv->block_w,
-                                                   pixmap_priv->block_h,
-                                                   0,
-                                                   0);
-        DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
-        for (i = 0; i < n_region; i++) {
-            BoxPtr boxes;
-            int nbox;
-            int temp_stride;
-            void *temp_bits;
-
-            glamor_set_pixmap_fbo_current(pixmap_priv, clipped_regions[i].block_idx);
-
-            boxes = RegionRects(clipped_regions[i].region);
-            nbox = RegionNumRects(clipped_regions[i].region);
-            DEBUGF("split to %d boxes\n", nbox);
-            for (j = 0; j < nbox; j++) {
-                temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
-                                            pixmap->drawable.depth);
-
-                if (boxes[j].x1 == 0 && temp_stride == stride) {
-                    temp_bits = (char *) bits + boxes[j].y1 * stride;
-                }
-                else {
-                    temp_bits = sub_bits;
-                    glamor_put_bits(temp_bits, temp_stride, bits, stride,
-                                    pixmap->drawable.bitsPerPixel,
-                                    boxes[j].x1, boxes[j].y1,
-                                    boxes[j].x2 - boxes[j].x1,
-                                    boxes[j].y2 - boxes[j].y1);
-                }
-                DEBUGF("upload x %d y %d w %d h %d temp stride %d \n",
-                       boxes[j].x1, boxes[j].y1,
-                       boxes[j].x2 - boxes[j].x1,
-                       boxes[j].y2 - boxes[j].y1, temp_stride);
-                if (!_glamor_upload_bits_to_pixmap_texture
-                    (pixmap, format, type, no_alpha, revert, swap_rb,
-                     boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1,
-                     boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits)) {
-                    RegionUninit(&region);
-                    free(sub_bits);
-                    assert(0);
-                    return FALSE;
-                }
-            }
-            RegionDestroy(clipped_regions[i].region);
-        }
-        free(sub_bits);
-        free(clipped_regions);
-        RegionUninit(&region);
-        return TRUE;
-    }
-    else
-        return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type,
-                                                     no_alpha, revert, swap_rb,
-                                                     0, 0,
-                                                     pixmap->drawable.width,
-                                                     pixmap->drawable.height,
-                                                     stride, bits);
+    return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type,
+                                                 no_alpha, revert, swap_rb,
+                                                 0, 0,
+                                                 pixmap->drawable.width,
+                                                 pixmap->drawable.height,
+                                                 stride, bits);
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 422b0fd..6656b28 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -926,7 +926,6 @@ void glamor_xv_render(glamor_port_private *port_priv);
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 #define GLAMOR_GRADIENT_SHADER
 #define GLAMOR_TEXTURED_LARGE_PIXMAP 1
-#define WALKAROUND_LARGE_TEXTURE_MAP
 #if 0
 #define MAX_FBO_SIZE 32         /* For test purpose only. */
 #endif
commit 094b1bea8bd08eec029e4d61ba40d81441c37905
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:12 2016 -0800

    glamor: Drop unused PBO code in temporary picture uploading.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index e0f5828..e0458a6 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -246,7 +246,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
                                   GLenum format,
                                   GLenum type,
                                   int x, int y, int w, int h,
-                                  void *bits, int pbo)
+                                  void *bits)
 {
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(pixmap->drawable.pScreen);
@@ -269,11 +269,6 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 
-    assert(pbo || bits != 0);
-    if (bits == NULL) {
-        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
-        glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
-    }
     glamor_priv->suppress_gl_out_of_memory_logging = true;
     if (non_sub)
         glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
@@ -288,9 +283,6 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
         return FALSE;
     }
 
-    if (bits == NULL)
-        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-
     return TRUE;
 }
 
@@ -298,7 +290,7 @@ static Bool
 _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
                                       GLenum type, int no_alpha, int revert,
                                       int swap_rb, int x, int y, int w, int h,
-                                      int stride, void *bits, int pbo)
+                                      int stride, void *bits)
 {
     ScreenPtr screen = pixmap->drawable.pScreen;
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -308,9 +300,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
     GLuint tex = 0;
     pixman_image_t *converted_image = NULL;
 
-    if (bits == NULL)
-        goto ready_to_upload;
-
     if (revert == REVERT_UPLOADING_A1) {
         converted_image = glamor_get_converted_image(PICT_a8,
                                                      PICT_a1,
@@ -323,8 +312,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
         bits = pixman_image_get_data(converted_image);
     }
 
- ready_to_upload:
-
     /* Try fast path firstly, upload the pixmap to the texture attached
      * to the fbo directly. */
     if (no_alpha == 0
@@ -345,7 +332,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
                                                format, type,
                                                x + fbo_x_off, y + fbo_y_off,
                                                w, h,
-                                               bits, pbo)) {
+                                               bits)) {
             if (converted_image)
                 pixman_image_unref(bits);
             return FALSE;
@@ -371,8 +358,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
         glamor_make_current(glamor_priv);
 
         if (!__glamor_upload_pixmap_to_texture(pixmap, &tex,
-                                               format, type, 0, 0, w, h, bits,
-                                               pbo)) {
+                                               format, type, 0, 0, w, h, bits)) {
             if (converted_image)
                 pixman_image_unref(bits);
             return FALSE;
@@ -556,11 +542,10 @@ glamor_upload_picture_to_texture(PicturePtr picture)
                        boxes[j].x1, boxes[j].y1,
                        boxes[j].x2 - boxes[j].x1,
                        boxes[j].y2 - boxes[j].y1, temp_stride);
-                if (_glamor_upload_bits_to_pixmap_texture
+                if (!_glamor_upload_bits_to_pixmap_texture
                     (pixmap, format, type, no_alpha, revert, swap_rb,
                      boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1,
-                     boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits,
-                     0) == FALSE) {
+                     boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits)) {
                     RegionUninit(&region);
                     free(sub_bits);
                     assert(0);
@@ -580,6 +565,5 @@ glamor_upload_picture_to_texture(PicturePtr picture)
                                                      0, 0,
                                                      pixmap->drawable.width,
                                                      pixmap->drawable.height,
-                                                     stride, bits,
-                                                     0);
+                                                     stride, bits);
 }
commit 6112fecc3a4fd7dfb0ef77a98cfd1f7c91ccea0c
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:11 2016 -0800

    glamor: Generalize the a1-to-a8 conversion path.
    
    Pixman is quite qualified to allocate our temporary memory, and all we
    need to do is decide what formats to convert from and to.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 63d4365..e0f5828 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -204,21 +204,26 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
     return TRUE;
 }
 
-static void *
-glamor_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride)
+/**
+ * Takes a set of source bits with a given format and returns an
+ * in-memory pixman image of those bits in a destination format.
+ */
+static pixman_image_t *
+glamor_get_converted_image(PictFormatShort dst_format,
+                           PictFormatShort src_format,
+                           void *src_bits,
+                           int src_stride,
+                           int w, int h)
 {
-    PictFormatShort dst_format = PICT_a8, src_format = PICT_a1;
     pixman_image_t *dst_image;
     pixman_image_t *src_image;
-    int src_stride = PixmapBytePad(w, 1);
 
-    dst_image = pixman_image_create_bits(dst_format, w, h, dst_bits, stride);
+    dst_image = pixman_image_create_bits(dst_format, w, h, NULL, 0);
     if (dst_image == NULL) {
         return NULL;
     }
 
-    src_image = pixman_image_create_bits(src_format,
-                                         w, h, src_bits, src_stride);
+    src_image = pixman_image_create_bits(src_format, w, h, src_bits, src_stride);
 
     if (src_image == NULL) {
         pixman_image_unref(dst_image);
@@ -229,8 +234,7 @@ glamor_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride)
                            0, 0, 0, 0, 0, 0, w, h);
 
     pixman_image_unref(src_image);
-    pixman_image_unref(dst_image);
-    return dst_bits;
+    return dst_image;
 }
 
 /**
@@ -302,34 +306,21 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
         glamor_get_screen_private(pixmap->drawable.pScreen);
     float dst_xscale, dst_yscale;
     GLuint tex = 0;
-    int need_free_bits = 0;
+    pixman_image_t *converted_image = NULL;
 
     if (bits == NULL)
         goto ready_to_upload;
 
     if (revert == REVERT_UPLOADING_A1) {
-        /* XXX if we are restoring the pixmap, then we may not need to allocate
-         * new buffer */
-        void *converted_bits;
-
-        if (pixmap->drawable.depth == 1)
-            stride = (((w * 8 + 7) / 8) + 3) & ~3;
-
-        converted_bits = xallocarray(h, stride);
-
-        if (converted_bits == NULL)
-            return FALSE;
-        bits = glamor_convert_a1_a8(bits, converted_bits, w, h, stride);
-        if (bits == NULL) {
-            free(converted_bits);
-            ErrorF("Failed to convert pixmap no_alpha %d,"
-                   "revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb);
+        converted_image = glamor_get_converted_image(PICT_a8,
+                                                     PICT_a1,
+                                                     bits,
+                                                     PixmapBytePad(w, 1),
+                                                     w, h);
+        if (!converted_image)
             return FALSE;
-        }
-        no_alpha = 0;
-        revert = REVERT_NONE;
-        swap_rb = SWAP_NONE_UPLOADING;
-        need_free_bits = TRUE;
+
+        bits = pixman_image_get_data(converted_image);
     }
 
  ready_to_upload:
@@ -355,8 +346,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
                                                x + fbo_x_off, y + fbo_y_off,
                                                w, h,
                                                bits, pbo)) {
-            if (need_free_bits)
-                free(bits);
+            if (converted_image)
+                pixman_image_unref(bits);
             return FALSE;
         }
     } else {
@@ -382,8 +373,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
         if (!__glamor_upload_pixmap_to_texture(pixmap, &tex,
                                                format, type, 0, 0, w, h, bits,
                                                pbo)) {
-            if (need_free_bits)
-                free(bits);
+            if (converted_image)
+                pixman_image_unref(bits);
             return FALSE;
         }
 
@@ -416,8 +407,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
         glBindFramebuffer(GL_FRAMEBUFFER, 0);
     }
 
-    if (need_free_bits)
-        free(bits);
+    if (converted_image)
+        pixman_image_unref(bits);
     return TRUE;
 }
 
commit 8f1411c3847a742f84ff07c4a0bb610801f5bfee
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:10 2016 -0800

    glamor: Drop the REVERT_UPLOADING_1_5_5_5 path.
    
    There was only a pretty special case that could have even worked --
    you've got a GLES2 renderer, you've got a SHM pixmap, it's 1555 (not
    the usual 565 for 16-bit), and you're little endian (BE was broken,
    since GL's 5_5_5_1 picks the 1 bit from the lowest bit of the short,
    and on BE we weren't doing the conversion path that swaps around the
    channels).  This is just not worth the complexity.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 5c6a1a5..63d4365 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -151,11 +151,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
             *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
         } else {
-            *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
-            if (is_little_endian)
-                *revert = REVERT_UPLOADING_1_5_5_5;
-            else
-                *revert = REVERT_NONE;
+            return FALSE;
         }
         break;
 
@@ -166,13 +162,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
             *tex_format = GL_BGRA;
             *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
         } else {
-            *tex_format = GL_RGBA;
-            *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
-            if (is_little_endian)
-                *revert = REVERT_UPLOADING_1_5_5_5;
-            else
-                *revert = REVERT_NONE;
-            *swap_rb = SWAP_UPLOADING;
+            return FALSE;
         }
         break;
 
@@ -215,8 +205,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
 }
 
 static void *
-_glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h,
-                            int stride)
+glamor_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride)
 {
     PictFormatShort dst_format = PICT_a8, src_format = PICT_a1;
     pixman_image_t *dst_image;
@@ -244,107 +233,6 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h,
     return dst_bits;
 }
 
-#define ADJUST_BITS(d, src_bits, dst_bits)	(((dst_bits) == (src_bits)) ? (d) : 				\
-							(((dst_bits) > (src_bits)) ? 				\
-							  (((d) << ((dst_bits) - (src_bits))) 			\
-								   + (( 1 << ((dst_bits) - (src_bits))) >> 1))	\
-								:  ((d) >> ((src_bits) - (dst_bits)))))
-
-#define GLAMOR_DO_CONVERT(src, dst, no_alpha, swap,		\
-			  a_shift_src, a_bits_src,		\
-			  b_shift_src, b_bits_src,		\
-			  g_shift_src, g_bits_src,		\
-			  r_shift_src, r_bits_src,		\
-			  a_shift, a_bits,			\
-			  b_shift, b_bits,			\
-			  g_shift, g_bits,			\
-			  r_shift, r_bits)			\
-	do {								\
-		typeof(src) a,b,g,r;					\
-		typeof(src) a_mask_src, b_mask_src, g_mask_src, r_mask_src;\
-		a_mask_src = (((1 << (a_bits_src)) - 1) << a_shift_src);\
-		b_mask_src = (((1 << (b_bits_src)) - 1) << b_shift_src);\
-		g_mask_src = (((1 << (g_bits_src)) - 1) << g_shift_src);\
-		r_mask_src = (((1 << (r_bits_src)) - 1) << r_shift_src);\
-		if (no_alpha)						\
-			a = (a_mask_src) >> (a_shift_src);			\
-		else							\
-			a = ((src) & (a_mask_src)) >> (a_shift_src);	\
-		b = ((src) & (b_mask_src)) >> (b_shift_src);		\
-		g = ((src) & (g_mask_src)) >> (g_shift_src);		\
-		r = ((src) & (r_mask_src)) >> (r_shift_src);		\
-		a = ADJUST_BITS(a, a_bits_src, a_bits);			\
-		b = ADJUST_BITS(b, b_bits_src, b_bits);			\
-		g = ADJUST_BITS(g, g_bits_src, g_bits);			\
-		r = ADJUST_BITS(r, r_bits_src, r_bits);			\
-		if (swap == 0)						\
-			(*dst) = ((a) << (a_shift)) | ((b) << (b_shift)) | ((g) << (g_shift)) | ((r) << (r_shift)); \
-		else 												    \
-			(*dst) = ((a) << (a_shift)) | ((r) << (b_shift)) | ((g) << (g_shift)) | ((b) << (r_shift)); \
-	} while (0)
-
-
-static void *
-_glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h,
-                              int stride, int no_alpha, int swap_rb)
-{
-    int x, y;
-    unsigned short *words, *saved_words, *source_words;
-    int swap = swap_rb != SWAP_NONE_UPLOADING;
-
-    words = dst_bits;
-    source_words = src_bits;
-    saved_words = words;
-
-    for (y = 0; y < h; y++) {
-        DEBUGF("Line %d :  ", y);
-        for (x = 0; x < w; x++) {
-            unsigned short pixel = source_words[x];
-
-            GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
-                              15, 1, 10, 5, 5, 5, 0, 5,
-                              0, 1, 1, 5, 6, 5, 11, 5);
-            DEBUGF("%04x:%04x ", pixel, words[x]);
-        }
-        DEBUGF("\n");
-        words += stride / sizeof(*words);
-        source_words += stride / sizeof(*words);
-    }
-    DEBUGF("\n");
-    return saved_words;
-}
-
-/*
- * This function is to convert an unsupported color format to/from a
- * supported GL format.
- * Here are the current scenarios:
- *
- * @no_alpha:
- * 	If it is set, then we need to wire the alpha value to 1.
- * @revert:
-	REVERT_UPLOADING_A1		: convert an A1 buffer to an Alpha8 buffer
-	REVERT_UPLOADING_1_5_5_5    	: convert X1R5G5B5 to B5G5R5X1
-   @swap_rb: if we have the swap_rb set, then we need to swap the R and B's position.
- *
- */
-
-static void *
-glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h,
-                             int stride, int no_alpha, int revert, int swap_rb)
-{
-    if (revert == REVERT_UPLOADING_A1) {
-        return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride);
-    }
-    else if (revert == REVERT_UPLOADING_1_5_5_5) {
-        return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride,
-                                             no_alpha, swap_rb);
-    }
-    else
-        ErrorF("convert a non-supported mode %x.\n", revert);
-
-    return NULL;
-}
-
 /**
  * Upload pixmap to a specified texture.
  * This texture may not be the one attached to it.
@@ -419,7 +307,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
     if (bits == NULL)
         goto ready_to_upload;
 
-    if (revert > REVERT_NORMAL) {
+    if (revert == REVERT_UPLOADING_A1) {
         /* XXX if we are restoring the pixmap, then we may not need to allocate
          * new buffer */
         void *converted_bits;
@@ -431,8 +319,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
 
         if (converted_bits == NULL)
             return FALSE;
-        bits = glamor_color_convert_to_bits(bits, converted_bits, w, h,
-                                            stride, no_alpha, revert, swap_rb);
+        bits = glamor_convert_a1_a8(bits, converted_bits, w, h, stride);
         if (bits == NULL) {
             free(converted_bits);
             ErrorF("Failed to convert pixmap no_alpha %d,"
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index fc33995..5617611 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -768,7 +768,6 @@ format_for_pixmap(PixmapPtr pixmap)
 #define REVERT_NONE       		0
 #define REVERT_NORMAL     		1
 #define REVERT_UPLOADING_A1		3
-#define REVERT_UPLOADING_1_5_5_5    	8
 
 #define SWAP_UPLOADING	  	2
 #define SWAP_NONE_UPLOADING	3
commit 2cc7a0815e5e2c2b1b1267cae9c348a8e95b1082
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:09 2016 -0800

    glamor: Drop the GLES2 REVERT_UPLOADING_2_10_10_10 paths.
    
    These just smash your 2_10_10_10 data into 8888, despite what the
    comments said.  That's not valid rendering, so just ditch this path
    and fall back to software.  One might also note in the code being
    removed here that the REVERT_UPLOADING_10_10_10_2 path wasn't even
    connected.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index e11280f..5c6a1a5 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -111,18 +111,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
             *tex_format = GL_BGRA;
             *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
         } else {
-            /* glReadPixmap doesn't support
-             * GL_UNSIGNED_INT_10_10_10_2.  We have to use
-             * GL_UNSIGNED_BYTE and do the conversion in a shader
-             * later.
-             */
-            *tex_format = GL_RGBA;
-            *tex_type = GL_UNSIGNED_BYTE;
-            if (!is_little_endian)
-                *revert = REVERT_UPLOADING_10_10_10_2;
-            else
-                *revert = REVERT_UPLOADING_2_10_10_10;
-            *swap_rb = SWAP_UPLOADING;
+            return FALSE;
         }
         break;
 
@@ -133,13 +122,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
             *tex_format = GL_RGBA;
             *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
         } else {
-            *tex_format = GL_RGBA;
-            *tex_type = GL_UNSIGNED_BYTE;
-            if (!is_little_endian)
-                *revert = REVERT_UPLOADING_10_10_10_2;
-            else
-                *revert = REVERT_UPLOADING_2_10_10_10;
-            break;
+            return FALSE;
         }
         break;
 
@@ -300,37 +283,6 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h,
 			(*dst) = ((a) << (a_shift)) | ((r) << (b_shift)) | ((g) << (g_shift)) | ((b) << (r_shift)); \
 	} while (0)
 
-static void *
-_glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h,
-                                 int stride, int no_alpha,
-                                 int swap_rb)
-{
-    int x, y;
-    unsigned int *words, *saved_words, *source_words;
-    int swap = swap_rb != SWAP_NONE_UPLOADING;
-
-    source_words = src_bits;
-    words = dst_bits;
-    saved_words = words;
-
-    for (y = 0; y < h; y++) {
-        DEBUGF("Line %d :  ", y);
-        for (x = 0; x < w; x++) {
-            unsigned int pixel = source_words[x];
-
-            GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
-                              30, 2, 20, 10, 10, 10, 0, 10,
-                              24, 8, 16, 8, 8, 8, 0, 8);
-            DEBUGF("%x:%x ", pixel, words[x]);
-        }
-        DEBUGF("\n");
-        words += stride / sizeof(*words);
-        source_words += stride / sizeof(*words);
-    }
-    DEBUGF("\n");
-    return saved_words;
-
-}
 
 static void *
 _glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h,
@@ -371,7 +323,6 @@ _glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h,
  * 	If it is set, then we need to wire the alpha value to 1.
  * @revert:
 	REVERT_UPLOADING_A1		: convert an A1 buffer to an Alpha8 buffer
-	REVERT_UPLOADING_2_10_10_10 	: convert X2B10G10R10 to R10G10B10X2
 	REVERT_UPLOADING_1_5_5_5    	: convert X1R5G5B5 to B5G5R5X1
    @swap_rb: if we have the swap_rb set, then we need to swap the R and B's position.
  *
@@ -384,10 +335,6 @@ glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h,
     if (revert == REVERT_UPLOADING_A1) {
         return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride);
     }
-    else if (revert == REVERT_UPLOADING_2_10_10_10) {
-        return _glamor_color_revert_x2b10g10r10(src_bits, dst_bits, w, h,
-                                                stride, no_alpha, swap_rb);
-    }
     else if (revert == REVERT_UPLOADING_1_5_5_5) {
         return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride,
                                              no_alpha, swap_rb);
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index e23de86..fc33995 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -768,9 +768,7 @@ format_for_pixmap(PixmapPtr pixmap)
 #define REVERT_NONE       		0
 #define REVERT_NORMAL     		1
 #define REVERT_UPLOADING_A1		3
-#define REVERT_UPLOADING_2_10_10_10 	5
 #define REVERT_UPLOADING_1_5_5_5    	8
-#define REVERT_UPLOADING_10_10_10_2 	10
 
 #define SWAP_UPLOADING	  	2
 #define SWAP_NONE_UPLOADING	3
commit f667d5177024d3fdfb1b51694bdaeba6cee67962
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:08 2016 -0800

    glamor: Merge the two GL-type-from-pictformat paths.
    
    It clarifies what the difference is between the two paths, and would
    potentially encourage us to handle GLES extensions that expose
    additional types.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 34cf4a3..e11280f 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -40,275 +40,195 @@
  *
  * Return 0 if find a matched texture type. Otherwise return -1.
  **/
-static int
-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)
+static Bool
+glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+                                           PictFormatShort format,
+                                           GLenum *tex_format,
+                                           GLenum *tex_type,
+                                           int *no_alpha,
+                                           int *revert,
+                                           int *swap_rb)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
+    Bool is_little_endian = IMAGE_BYTE_ORDER == LSBFirst;
+
     *no_alpha = 0;
     *revert = REVERT_NONE;
     *swap_rb = SWAP_NONE_UPLOADING;
+
     switch (format) {
     case PICT_a1:
         *tex_format = glamor_priv->one_channel_format;
         *tex_type = GL_UNSIGNED_BYTE;
         *revert = REVERT_UPLOADING_A1;
         break;
-    case PICT_b8g8r8x8:
-        *no_alpha = 1;
-    case PICT_b8g8r8a8:
-        *tex_format = GL_BGRA;
-        *tex_type = GL_UNSIGNED_INT_8_8_8_8;
-        break;
-
-    case PICT_x8r8g8b8:
-        *no_alpha = 1;
-    case PICT_a8r8g8b8:
-        *tex_format = GL_BGRA;
-        *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-        break;
-    case PICT_x8b8g8r8:
-        *no_alpha = 1;
-    case PICT_a8b8g8r8:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-        break;
-    case PICT_x2r10g10b10:
-        *no_alpha = 1;
-    case PICT_a2r10g10b10:
-        *tex_format = GL_BGRA;
-        *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
-        break;
-    case PICT_x2b10g10r10:
-        *no_alpha = 1;
-    case PICT_a2b10g10r10:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
-        break;
-
-    case PICT_r5g6b5:
-        *tex_format = GL_RGB;
-        *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-        break;
-    case PICT_b5g6r5:
-        *tex_format = GL_RGB;
-        *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
-        break;
-    case PICT_x1b5g5r5:
-        *no_alpha = 1;
-    case PICT_a1b5g5r5:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-        break;
-
-    case PICT_x1r5g5b5:
-        *no_alpha = 1;
-    case PICT_a1r5g5b5:
-        *tex_format = GL_BGRA;
-        *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-        break;
-    case PICT_a8:
-        *tex_format = glamor_priv->one_channel_format;
-        *tex_type = GL_UNSIGNED_BYTE;
-        break;
-    case PICT_x4r4g4b4:
-        *no_alpha = 1;
-    case PICT_a4r4g4b4:
-        *tex_format = GL_BGRA;
-        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-        break;
-
-    case PICT_x4b4g4r4:
-        *no_alpha = 1;
-    case PICT_a4b4g4r4:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-        break;
-
-    default:
-        return -1;
-    }
-    return 0;
-}
-
-#define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
-
-static int
-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)
-{
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
-    int need_swap_rb = 0;
 
-    *no_alpha = 0;
-    *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
-
-    switch (format) {
     case PICT_b8g8r8x8:
         *no_alpha = 1;
     case PICT_b8g8r8a8:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_BYTE;
-        need_swap_rb = 1;
-        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+            *tex_format = GL_BGRA;
+            *tex_type = GL_UNSIGNED_INT_8_8_8_8;
+        } else {
+            *tex_format = GL_RGBA;
+            *tex_type = GL_UNSIGNED_BYTE;
+            *swap_rb = SWAP_UPLOADING;
+            *revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
+        }
         break;
 
     case PICT_x8r8g8b8:
         *no_alpha = 1;
     case PICT_a8r8g8b8:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_BYTE;
-        need_swap_rb = 1;
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+            *tex_format = GL_BGRA;
+            *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+        } else {
+            *tex_format = GL_RGBA;
+            *tex_type = GL_UNSIGNED_BYTE;
+            *swap_rb = SWAP_UPLOADING;
+            *revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
+            break;
+        }
         break;
 
     case PICT_x8b8g8r8:
         *no_alpha = 1;
     case PICT_a8b8g8r8:
         *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_BYTE;
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+            *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+        } else {
+            *tex_type = GL_UNSIGNED_BYTE;
+            *revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
+        }
         break;
 
     case PICT_x2r10g10b10:
         *no_alpha = 1;
     case PICT_a2r10g10b10:
-        *tex_format = GL_RGBA;
-        /* glReadPixmap doesn't support GL_UNSIGNED_INT_10_10_10_2.
-         * we have to use GL_UNSIGNED_BYTE and do the conversion in
-         * shader latter.*/
-        *tex_type = GL_UNSIGNED_BYTE;
-        if (!IS_LITTLE_ENDIAN)
-            *revert = REVERT_UPLOADING_10_10_10_2;
-        else
-            *revert = REVERT_UPLOADING_2_10_10_10;
-        need_swap_rb = 1;
-
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+            *tex_format = GL_BGRA;
+            *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+        } else {
+            /* glReadPixmap doesn't support
+             * GL_UNSIGNED_INT_10_10_10_2.  We have to use
+             * GL_UNSIGNED_BYTE and do the conversion in a shader
+             * later.
+             */
+            *tex_format = GL_RGBA;
+            *tex_type = GL_UNSIGNED_BYTE;
+            if (!is_little_endian)
+                *revert = REVERT_UPLOADING_10_10_10_2;
+            else
+                *revert = REVERT_UPLOADING_2_10_10_10;
+            *swap_rb = SWAP_UPLOADING;
+        }
         break;
 
     case PICT_x2b10g10r10:
         *no_alpha = 1;
     case PICT_a2b10g10r10:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_BYTE;
-        if (!IS_LITTLE_ENDIAN)
-            *revert = REVERT_UPLOADING_10_10_10_2;
-        else
-            *revert = REVERT_UPLOADING_2_10_10_10;
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+            *tex_format = GL_RGBA;
+            *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+        } else {
+            *tex_format = GL_RGBA;
+            *tex_type = GL_UNSIGNED_BYTE;
+            if (!is_little_endian)
+                *revert = REVERT_UPLOADING_10_10_10_2;
+            else
+                *revert = REVERT_UPLOADING_2_10_10_10;
+            break;
+        }
         break;
 
     case PICT_r5g6b5:
         *tex_format = GL_RGB;
         *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-        *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
-
+        if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP)
+            *revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
         break;
-
     case PICT_b5g6r5:
         *tex_format = GL_RGB;
-        *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-        need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+            *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
+        } else {
+            *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+            if (is_little_endian)
+                *swap_rb = SWAP_UPLOADING;
+            *revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
+        }
         break;
 
     case PICT_x1b5g5r5:
         *no_alpha = 1;
     case PICT_a1b5g5r5:
         *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
-        if (IS_LITTLE_ENDIAN)
-            *revert = REVERT_UPLOADING_1_5_5_5;
-        else
-            *revert = REVERT_NONE;
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+            *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+        } else {
+            *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
+            if (is_little_endian)
+                *revert = REVERT_UPLOADING_1_5_5_5;
+            else
+                *revert = REVERT_NONE;
+        }
         break;
 
     case PICT_x1r5g5b5:
         *no_alpha = 1;
     case PICT_a1r5g5b5:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
-        if (IS_LITTLE_ENDIAN)
-            *revert = REVERT_UPLOADING_1_5_5_5;
-        else
-            *revert = REVERT_NONE;
-        need_swap_rb = 1;
-        break;
-
-    case PICT_a1:
-        *tex_format = glamor_priv->one_channel_format;
-        *tex_type = GL_UNSIGNED_BYTE;
-        *revert = REVERT_UPLOADING_A1;
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+            *tex_format = GL_BGRA;
+            *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+        } else {
+            *tex_format = GL_RGBA;
+            *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
+            if (is_little_endian)
+                *revert = REVERT_UPLOADING_1_5_5_5;
+            else
+                *revert = REVERT_NONE;
+            *swap_rb = SWAP_UPLOADING;
+        }
         break;
 
     case PICT_a8:
         *tex_format = glamor_priv->one_channel_format;
         *tex_type = GL_UNSIGNED_BYTE;
-        *revert = REVERT_NONE;
         break;
 
     case PICT_x4r4g4b4:
         *no_alpha = 1;
     case PICT_a4r4g4b4:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
-        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
-        need_swap_rb = 1;
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+            *tex_format = GL_BGRA;
+            *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+        } else {
+            *tex_format = GL_RGBA;
+            *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
+            *revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
+            *swap_rb = SWAP_UPLOADING;
+        }
         break;
 
     case PICT_x4b4g4r4:
         *no_alpha = 1;
     case PICT_a4b4g4r4:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
-        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+            *tex_format = GL_RGBA;
+            *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+        } else {
+            *tex_format = GL_RGBA;
+            *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
+            *revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
+        }
         break;
 
     default:
-        LogMessageVerb(X_INFO, 0,
-                       "fail to get matched format for %x \n", format);
-        return -1;
-    }
-
-    if (need_swap_rb)
-        *swap_rb = SWAP_UPLOADING;
-    else
-        *swap_rb = SWAP_NONE_UPLOADING;
-    return 0;
-}
-
-static int
-glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
-                                       PictFormatShort pict_format,
-                                       GLenum *format,
-                                       GLenum *type,
-                                       int *no_alpha,
-                                       int *revert, int *swap_rb)
-{
-    glamor_screen_private *glamor_priv =
-        glamor_get_screen_private(pixmap->drawable.pScreen);
-
-    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-        return glamor_get_tex_format_type_from_pictformat_gl(pixmap->drawable.pScreen,
-                                                             pict_format,
-                                                             format, type,
-                                                             no_alpha,
-                                                             revert,
-                                                             swap_rb);
-    } else {
-        return glamor_get_tex_format_type_from_pictformat_gles2(pixmap->drawable.pScreen,
-                                                                pict_format,
-                                                                format, type,
-                                                                no_alpha,
-                                                                revert,
-                                                                swap_rb);
+        return FALSE;
     }
+    return TRUE;
 }
 
 static void *
@@ -738,12 +658,12 @@ glamor_upload_picture_to_texture(PicturePtr picture)
     assert(glamor_pixmap_is_memory(pixmap));
     assert(!pixmap_priv->fbo);
 
-    if (glamor_get_tex_format_type_from_pixmap(pixmap,
-                                               picture->format,
-                                               &format,
-                                               &type,
-                                               &no_alpha,
-                                               &revert, &swap_rb)) {
+    if (!glamor_get_tex_format_type_from_pictformat(screen,
+                                                    picture->format,
+                                                    &format,
+                                                    &type,
+                                                    &no_alpha,
+                                                    &revert, &swap_rb)) {
         glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
         return FALSE;
     }
commit c7574c63c618d3a017105c380542eb04341b04a2
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:07 2016 -0800

    glamor: Propagate that is_upload is always true.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index b9948b5..a8768f4 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -164,8 +164,6 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
         "uniform int swap_rb;\n"
         "#define REVERT_NONE       			0\n"
         "#define REVERT_NORMAL     			1\n"
-        "#define SWAP_NONE_DOWNLOADING  		0\n"
-        "#define SWAP_DOWNLOADING  			1\n"
         "#define SWAP_UPLOADING	  		2\n"
         "#define SWAP_NONE_UPLOADING		3\n";
 
@@ -175,18 +173,14 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
         "   vec4 color = texture2D(sampler, source_texture);\n"
         "   if (revert == REVERT_NONE) \n"
         "    { \n"
-        "     if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING))   \n"
+        "     if ((swap_rb != SWAP_NONE_UPLOADING))   \n"
         "		gl_FragColor = color.bgra;\n"
         "     else \n"
         "		gl_FragColor = color.rgba;\n"
         "    } \n"
         "   else \n"
         "    { \n"
-        "     if (swap_rb == SWAP_DOWNLOADING)   \n"
-        "		gl_FragColor = color.argb;\n"
-        "     else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
-        "		gl_FragColor = color.abgr;\n"
-        "     else if (swap_rb == SWAP_UPLOADING)\n"
+        "     if (swap_rb == SWAP_UPLOADING)\n"
         "		gl_FragColor = color.gbar;\n"
         "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
         "		gl_FragColor = color.abgr;\n"
@@ -199,18 +193,14 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
         "   vec4 color = texture2D(sampler, source_texture);\n"
         "   if (revert == REVERT_NONE) \n"
         "    { \n"
-        "     if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING))   \n"
+        "     if (swap_rb != SWAP_NONE_UPLOADING)   \n"
         "		gl_FragColor = vec4(color.bgr, 1);\n"
         "     else \n"
         "		gl_FragColor = vec4(color.rgb, 1);\n"
         "    } \n"
         "   else \n"
         "    { \n"
-        "     if (swap_rb == SWAP_DOWNLOADING)   \n"
-        "		gl_FragColor = vec4(1, color.rgb);\n"
-        "     else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
-        "		gl_FragColor = vec4(1, color.bgr);\n"
-        "     else if (swap_rb == SWAP_UPLOADING)\n"
+        "     if (swap_rb == SWAP_UPLOADING)\n"
         "		gl_FragColor = vec4(color.gba, 1);\n"
         "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
         "		gl_FragColor = vec4(color.abg, 1);\n"
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index a032ed0..34cf4a3 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -47,17 +47,17 @@ glamor_get_tex_format_type_from_pictformat_gl(ScreenPtr pScreen,
                                               GLenum *tex_type,
                                               int *no_alpha,
                                               int *revert,
-                                              int *swap_rb, int is_upload)
+                                              int *swap_rb)
 {
     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;
+    *swap_rb = SWAP_NONE_UPLOADING;
     switch (format) {
     case PICT_a1:
         *tex_format = glamor_priv->one_channel_format;
         *tex_type = GL_UNSIGNED_BYTE;
-        *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
+        *revert = REVERT_UPLOADING_A1;
         break;
     case PICT_b8g8r8x8:
         *no_alpha = 1;
@@ -145,7 +145,7 @@ glamor_get_tex_format_type_from_pictformat_gles2(ScreenPtr pScreen,
                                                  GLenum *tex_type,
                                                  int *no_alpha,
                                                  int *revert,
-                                                 int *swap_rb, int is_upload)
+                                                 int *swap_rb)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
     int need_swap_rb = 0;
@@ -186,20 +186,10 @@ glamor_get_tex_format_type_from_pictformat_gles2(ScreenPtr pScreen,
          * we have to use GL_UNSIGNED_BYTE and do the conversion in
          * shader latter.*/
         *tex_type = GL_UNSIGNED_BYTE;
-        if (is_upload == 1) {
-            if (!IS_LITTLE_ENDIAN)
-                *revert = REVERT_UPLOADING_10_10_10_2;
-            else
-                *revert = REVERT_UPLOADING_2_10_10_10;
-        }
-        else {
-            if (!IS_LITTLE_ENDIAN) {
-                *revert = REVERT_DOWNLOADING_10_10_10_2;
-            }
-            else {
-                *revert = REVERT_DOWNLOADING_2_10_10_10;
-            }
-        }
+        if (!IS_LITTLE_ENDIAN)
+            *revert = REVERT_UPLOADING_10_10_10_2;
+        else
+            *revert = REVERT_UPLOADING_2_10_10_10;
         need_swap_rb = 1;
 
         break;
@@ -209,20 +199,10 @@ glamor_get_tex_format_type_from_pictformat_gles2(ScreenPtr pScreen,
     case PICT_a2b10g10r10:
         *tex_format = GL_RGBA;
         *tex_type = GL_UNSIGNED_BYTE;
-        if (is_upload == 1) {
-            if (!IS_LITTLE_ENDIAN)
-                *revert = REVERT_UPLOADING_10_10_10_2;
-            else
-                *revert = REVERT_UPLOADING_2_10_10_10;
-        }
-        else {
-            if (!IS_LITTLE_ENDIAN) {
-                *revert = REVERT_DOWNLOADING_10_10_10_2;
-            }
-            else {
-                *revert = REVERT_DOWNLOADING_2_10_10_10;
-            }
-        }
+        if (!IS_LITTLE_ENDIAN)
+            *revert = REVERT_UPLOADING_10_10_10_2;
+        else
+            *revert = REVERT_UPLOADING_2_10_10_10;
         break;
 
     case PICT_r5g6b5:
@@ -243,11 +223,8 @@ glamor_get_tex_format_type_from_pictformat_gles2(ScreenPtr pScreen,
     case PICT_a1b5g5r5:
         *tex_format = GL_RGBA;
         *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
-        if (IS_LITTLE_ENDIAN) {
-            *revert =
-                is_upload ? REVERT_UPLOADING_1_5_5_5 :
-                REVERT_DOWNLOADING_1_5_5_5;
-        }
+        if (IS_LITTLE_ENDIAN)
+            *revert = REVERT_UPLOADING_1_5_5_5;
         else
             *revert = REVERT_NONE;
         break;
@@ -257,11 +234,8 @@ glamor_get_tex_format_type_from_pictformat_gles2(ScreenPtr pScreen,
     case PICT_a1r5g5b5:
         *tex_format = GL_RGBA;
         *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
-        if (IS_LITTLE_ENDIAN) {
-            *revert =
-                is_upload ? REVERT_UPLOADING_1_5_5_5 :
-                REVERT_DOWNLOADING_1_5_5_5;
-        }
+        if (IS_LITTLE_ENDIAN)
+            *revert = REVERT_UPLOADING_1_5_5_5;
         else
             *revert = REVERT_NONE;
         need_swap_rb = 1;
@@ -270,7 +244,7 @@ glamor_get_tex_format_type_from_pictformat_gles2(ScreenPtr pScreen,
     case PICT_a1:
         *tex_format = glamor_priv->one_channel_format;
         *tex_type = GL_UNSIGNED_BYTE;
-        *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
+        *revert = REVERT_UPLOADING_A1;
         break;
 
     case PICT_a8:
@@ -303,9 +277,9 @@ glamor_get_tex_format_type_from_pictformat_gles2(ScreenPtr pScreen,
     }
 
     if (need_swap_rb)
-        *swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING;
+        *swap_rb = SWAP_UPLOADING;
     else
-        *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
+        *swap_rb = SWAP_NONE_UPLOADING;
     return 0;
 }
 
@@ -315,7 +289,7 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
                                        GLenum *format,
                                        GLenum *type,
                                        int *no_alpha,
-                                       int *revert, int *swap_rb, int is_upload)
+                                       int *revert, int *swap_rb)
 {
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(pixmap->drawable.pScreen);
@@ -326,38 +300,25 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
                                                              format, type,
                                                              no_alpha,
                                                              revert,
-                                                             swap_rb,
-                                                             is_upload);
+                                                             swap_rb);
     } else {
         return glamor_get_tex_format_type_from_pictformat_gles2(pixmap->drawable.pScreen,
                                                                 pict_format,
                                                                 format, type,
                                                                 no_alpha,
                                                                 revert,
-                                                                swap_rb,
-                                                                is_upload);
+                                                                swap_rb);
     }
 }
 
 static void *
 _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h,
-                            int stride, int revert)
+                            int stride)
 {
-    PictFormatShort dst_format, src_format;
+    PictFormatShort dst_format = PICT_a8, src_format = PICT_a1;
     pixman_image_t *dst_image;
     pixman_image_t *src_image;
-    int src_stride;
-
-    if (revert == REVERT_UPLOADING_A1) {
-        src_format = PICT_a1;
-        dst_format = PICT_a8;
-        src_stride = PixmapBytePad(w, 1);
-    }
-    else {
-        dst_format = PICT_a1;
-        src_format = PICT_a8;
-        src_stride = (((w * 8 + 7) / 8) + 3) & ~3;
-    }
+    int src_stride = PixmapBytePad(w, 1);
 
     dst_image = pixman_image_create_bits(dst_format, w, h, dst_bits, stride);
     if (dst_image == NULL) {
@@ -421,13 +382,12 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h,
 
 static void *
 _glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h,
-                                 int stride, int no_alpha, int revert,
+                                 int stride, int no_alpha,
                                  int swap_rb)
 {
     int x, y;
     unsigned int *words, *saved_words, *source_words;
-    int swap = !(swap_rb == SWAP_NONE_DOWNLOADING ||
-                 swap_rb == SWAP_NONE_UPLOADING);
+    int swap = swap_rb != SWAP_NONE_UPLOADING;
 
     source_words = src_bits;
     words = dst_bits;
@@ -438,14 +398,9 @@ _glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h,
         for (x = 0; x < w; x++) {
             unsigned int pixel = source_words[x];
 
-            if (revert == REVERT_DOWNLOADING_2_10_10_10)
-                GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
-                                  24, 8, 16, 8, 8, 8, 0, 8,
-                                  30, 2, 20, 10, 10, 10, 0, 10);
-            else
-                GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
-                                  30, 2, 20, 10, 10, 10, 0, 10,
-                                  24, 8, 16, 8, 8, 8, 0, 8);
+            GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+                              30, 2, 20, 10, 10, 10, 0, 10,
+                              24, 8, 16, 8, 8, 8, 0, 8);
             DEBUGF("%x:%x ", pixel, words[x]);
         }
         DEBUGF("\n");
@@ -459,12 +414,11 @@ _glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h,
 
 static void *
 _glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h,
-                              int stride, int no_alpha, int revert, int swap_rb)
+                              int stride, int no_alpha, int swap_rb)
 {
     int x, y;
     unsigned short *words, *saved_words, *source_words;
-    int swap = !(swap_rb == SWAP_NONE_DOWNLOADING ||
-                 swap_rb == SWAP_NONE_UPLOADING);
+    int swap = swap_rb != SWAP_NONE_UPLOADING;
 
     words = dst_bits;
     source_words = src_bits;
@@ -475,14 +429,9 @@ _glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h,
         for (x = 0; x < w; x++) {
             unsigned short pixel = source_words[x];
 
-            if (revert == REVERT_DOWNLOADING_1_5_5_5)
-                GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
-                                  0, 1, 1, 5, 6, 5, 11, 5,
-                                  15, 1, 10, 5, 5, 5, 0, 5);
-            else
-                GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
-                                  15, 1, 10, 5, 5, 5, 0, 5,
-                                  0, 1, 1, 5, 6, 5, 11, 5);
+            GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+                              15, 1, 10, 5, 5, 5, 0, 5,
+                              0, 1, 1, 5, 6, 5, 11, 5);
             DEBUGF("%04x:%04x ", pixel, words[x]);
         }
         DEBUGF("\n");
@@ -501,11 +450,8 @@ _glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h,
  * @no_alpha:
  * 	If it is set, then we need to wire the alpha value to 1.
  * @revert:
-	REVERT_DOWNLOADING_A1		: convert an Alpha8 buffer to a A1 buffer.
 	REVERT_UPLOADING_A1		: convert an A1 buffer to an Alpha8 buffer
-	REVERT_DOWNLOADING_2_10_10_10 	: convert r10G10b10X2 to X2B10G10R10
 	REVERT_UPLOADING_2_10_10_10 	: convert X2B10G10R10 to R10G10B10X2
-	REVERT_DOWNLOADING_1_5_5_5  	: convert B5G5R5X1 to X1R5G5B5
 	REVERT_UPLOADING_1_5_5_5    	: convert X1R5G5B5 to B5G5R5X1
    @swap_rb: if we have the swap_rb set, then we need to swap the R and B's position.
  *
@@ -515,20 +461,16 @@ static void *
 glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h,
                              int stride, int no_alpha, int revert, int swap_rb)
 {
-    if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) {
-        return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride,
-                                           revert);
+    if (revert == REVERT_UPLOADING_A1) {
+        return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride);
     }
-    else if (revert == REVERT_DOWNLOADING_2_10_10_10 ||
-             revert == REVERT_UPLOADING_2_10_10_10) {
+    else if (revert == REVERT_UPLOADING_2_10_10_10) {
         return _glamor_color_revert_x2b10g10r10(src_bits, dst_bits, w, h,
-                                                stride, no_alpha, revert,
-                                                swap_rb);
+                                                stride, no_alpha, swap_rb);
     }
-    else if (revert == REVERT_DOWNLOADING_1_5_5_5 ||
-             revert == REVERT_UPLOADING_1_5_5_5) {
+    else if (revert == REVERT_UPLOADING_1_5_5_5) {
         return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride,
-                                             no_alpha, revert, swap_rb);
+                                             no_alpha, swap_rb);
     }
     else
         ErrorF("convert a non-supported mode %x.\n", revert);
@@ -801,7 +743,7 @@ glamor_upload_picture_to_texture(PicturePtr picture)
                                                &format,
                                                &type,
                                                &no_alpha,
-                                               &revert, &swap_rb, 1)) {
+                                               &revert, &swap_rb)) {
         glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
         return FALSE;
     }
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 5128a33..e23de86 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -767,17 +767,11 @@ format_for_pixmap(PixmapPtr pixmap)
 
 #define REVERT_NONE       		0
 #define REVERT_NORMAL     		1
-#define REVERT_DOWNLOADING_A1		2
 #define REVERT_UPLOADING_A1		3
-#define REVERT_DOWNLOADING_2_10_10_10 	4
 #define REVERT_UPLOADING_2_10_10_10 	5
-#define REVERT_DOWNLOADING_1_5_5_5  	7
 #define REVERT_UPLOADING_1_5_5_5    	8
-#define REVERT_DOWNLOADING_10_10_10_2 	9
 #define REVERT_UPLOADING_10_10_10_2 	10
 
-#define SWAP_NONE_DOWNLOADING  	0
-#define SWAP_DOWNLOADING  	1
 #define SWAP_UPLOADING	  	2
 #define SWAP_NONE_UPLOADING	3
 
commit 1bed5ef2b80c77c1bb9b62971367bea864fd8f66
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:06 2016 -0800

    glamor: Drop dead fbo handling from GLAMOR_MEMORY pict uploads.
    
    The previous commit asserts that we don't have one.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 9bb2c74..a032ed0 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -734,27 +734,10 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
                              int revert, int swap_rb)
 {
     int flag = 0;
-    glamor_pixmap_private *pixmap_priv;
-    glamor_screen_private *glamor_priv;
-    glamor_pixmap_fbo *fbo;
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(pixmap->drawable.pScreen);
     GLenum iformat;
 
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-    glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-
-    if (pixmap_priv->gl_fbo != GLAMOR_FBO_UNATTACHED)
-        return 0;
-
-    if (pixmap_priv->fbo
-        && (pixmap_priv->fbo->width < pixmap->drawable.width
-            || pixmap_priv->fbo->height < pixmap->drawable.height)) {
-        fbo = glamor_pixmap_detach_fbo(pixmap_priv);
-        glamor_destroy_fbo(glamor_priv, fbo);
-    }
-
-    if (pixmap_priv->fbo && pixmap_priv->fbo->fb)
-        return 0;
-
     if (!(no_alpha || (revert == REVERT_NORMAL)
           || (swap_rb != SWAP_NONE_UPLOADING))) {
         /* We don't need a fbo, a simple texture uploading should work. */
@@ -762,10 +745,6 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
         flag = GLAMOR_CREATE_FBO_NO_FBO;
     }
 
-    if ((flag == GLAMOR_CREATE_FBO_NO_FBO
-         && pixmap_priv->fbo && pixmap_priv->fbo->tex))
-        return 0;
-
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
         iformat = gl_iformat_for_pixmap(pixmap);
     else
commit ee7ca670b1695d64bc12cb37302913acc066a569
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:05 2016 -0800

    glamor: Make sure that GLAMOR_MEMORY pixmaps don't retain an FBO.
    
    glamor_composite_choose_shader() may upload our scratch pixmaps to get
    a Render operation completed.  We don't want to hang onto GL memory
    for our scratch pixmaps, since we'll just have to reallocate them at a
    new w/h next time around, and the contents will be updated as well.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 5bfffe5..0bfc1dd 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -510,6 +510,7 @@ glamor_pixmap_destroy_fbo(PixmapPtr pixmap)
         for (i = 0; i < priv->block_wcnt * priv->block_hcnt; i++)
             glamor_destroy_fbo(glamor_priv, priv->fbo_array[i]);
         free(priv->fbo_array);
+        priv->fbo_array = NULL;
     }
     else {
         fbo = glamor_pixmap_detach_fbo(priv);
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index e91461c..9bb2c74 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -797,9 +797,10 @@ glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits,
     }
 }
 
-/* Upload picture to texture.  We may need to flip the y axis or
- * wire alpha to 1. So we may conditional create fbo for the picture.
- * */
+/**
+ * Uploads a picture based on a GLAMOR_MEMORY pixmap to a texture in a
+ * temporary FBO.
+ */
 Bool
 glamor_upload_picture_to_texture(PicturePtr picture)
 {
@@ -810,9 +811,12 @@ glamor_upload_picture_to_texture(PicturePtr picture)
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     GLenum format, type;
     int no_alpha, revert, swap_rb;
-    glamor_pixmap_private *pixmap_priv;
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     Bool force_clip;
 
+    assert(glamor_pixmap_is_memory(pixmap));
+    assert(!pixmap_priv->fbo);
+
     if (glamor_get_tex_format_type_from_pixmap(pixmap,
                                                picture->format,
                                                &format,
@@ -825,7 +829,6 @@ glamor_upload_picture_to_texture(PicturePtr picture)
     if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
         return FALSE;
 
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
     force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP;
 
     if (glamor_pixmap_priv_is_large(pixmap_priv) || force_clip) {
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index d47e7d7..65f7059 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1125,7 +1125,7 @@ glamor_composite_with_shader(CARD8 op,
                                         &key, &shader, &op_info,
                                         &saved_source_format, ca_state)) {
         glamor_fallback("glamor_composite_choose_shader failed\n");
-        return ret;
+        goto fail;
     }
     if (ca_state == CA_TWO_PASS) {
         if (!glamor_composite_choose_shader(PictOpAdd, source, mask, dest,
@@ -1135,7 +1135,7 @@ glamor_composite_with_shader(CARD8 op,
                                             &key_ca, &shader_ca, &op_info_ca,
                                             &saved_source_format, ca_state)) {
             glamor_fallback("glamor_composite_choose_shader failed\n");
-            return ret;
+            goto fail;
         }
     }
 
@@ -1267,6 +1267,13 @@ glamor_composite_with_shader(CARD8 op,
         source->format = saved_source_format;
 
     ret = TRUE;
+
+fail:
+    if (mask_pixmap && glamor_pixmap_is_memory(mask_pixmap))
+        glamor_pixmap_destroy_fbo(mask_pixmap);
+    if (source_pixmap && glamor_pixmap_is_memory(source_pixmap))
+        glamor_pixmap_destroy_fbo(source_pixmap);
+
     return ret;
 }
 
commit a96c6d4658e3f386002f96eede660af3b01e5209
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 1 13:58:04 2016 -0800

    glamor: Simplify temporary picture uploading call stack.
    
    glamor_upload_sub_pixmap_to_texture() only had the one caller, so we
    can merge it in, fix its silly return value, and propagate a bunch of
    constants.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index b069ce5..e91461c 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -797,11 +797,15 @@ glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits,
     }
 }
 
-static Bool
-glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
-                                    int h, int stride, void *bits, int pbo,
-                                    PictFormatShort pict_format)
+/* Upload picture to texture.  We may need to flip the y axis or
+ * wire alpha to 1. So we may conditional create fbo for the picture.
+ * */
+Bool
+glamor_upload_picture_to_texture(PicturePtr picture)
 {
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+    void *bits = pixmap->devPrivate.ptr;
+    int stride = pixmap->devKind;
     ScreenPtr screen = pixmap->drawable.pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     GLenum format, type;
@@ -810,7 +814,7 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
     Bool force_clip;
 
     if (glamor_get_tex_format_type_from_pixmap(pixmap,
-                                               pict_format,
+                                               picture->format,
                                                &format,
                                                &type,
                                                &no_alpha,
@@ -822,8 +826,7 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
         return FALSE;
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
-    force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
-        && !glamor_check_fbo_size(glamor_priv, w, h);
+    force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP;
 
     if (glamor_pixmap_priv_is_large(pixmap_priv) || force_clip) {
         RegionRec region;
@@ -833,13 +836,13 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
         void *sub_bits;
         int i, j;
 
-        sub_bits = xallocarray(h, stride);
+        sub_bits = xallocarray(pixmap->drawable.height, stride);
         if (sub_bits == NULL)
             return FALSE;
-        box.x1 = x;
-        box.y1 = y;
-        box.x2 = x + w;
-        box.y2 = y + h;
+        box.x1 = 0;
+        box.y1 = 0;
+        box.x2 = pixmap->drawable.width;
+        box.y2 = pixmap->drawable.height;
         RegionInitBoxes(&region, &box, 1);
         if (!force_clip)
             clipped_regions =
@@ -860,8 +863,6 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
             int temp_stride;
             void *temp_bits;
 
-            assert(pbo == 0);
-
             glamor_set_pixmap_fbo_current(pixmap_priv, clipped_regions[i].block_idx);
 
             boxes = RegionRects(clipped_regions[i].region);
@@ -871,26 +872,26 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
                 temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
                                             pixmap->drawable.depth);
 
-                if (boxes[j].x1 == x && temp_stride == stride) {
-                    temp_bits = (char *) bits + (boxes[j].y1 - y) * stride;
+                if (boxes[j].x1 == 0 && temp_stride == stride) {
+                    temp_bits = (char *) bits + boxes[j].y1 * stride;
                 }
                 else {
                     temp_bits = sub_bits;
                     glamor_put_bits(temp_bits, temp_stride, bits, stride,
                                     pixmap->drawable.bitsPerPixel,
-                                    boxes[j].x1 - x, boxes[j].y1 - y,
+                                    boxes[j].x1, boxes[j].y1,
                                     boxes[j].x2 - boxes[j].x1,
                                     boxes[j].y2 - boxes[j].y1);
                 }
                 DEBUGF("upload x %d y %d w %d h %d temp stride %d \n",
-                       boxes[j].x1 - x, boxes[j].y1 - y,
+                       boxes[j].x1, boxes[j].y1,
                        boxes[j].x2 - boxes[j].x1,
                        boxes[j].y2 - boxes[j].y1, temp_stride);
                 if (_glamor_upload_bits_to_pixmap_texture
                     (pixmap, format, type, no_alpha, revert, swap_rb,
                      boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1,
                      boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits,
-                     pbo) == FALSE) {
+                     0) == FALSE) {
                     RegionUninit(&region);
                     free(sub_bits);
                     assert(0);
@@ -907,28 +908,9 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
     else
         return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type,
                                                      no_alpha, revert, swap_rb,
-                                                     x, y, w, h, stride, bits,
-                                                     pbo);
-}
-
-/* Upload picture to texture.  We may need to flip the y axis or
- * wire alpha to 1. So we may conditional create fbo for the picture.
- * */
-enum glamor_pixmap_status
-glamor_upload_picture_to_texture(PicturePtr picture)
-{
-    PixmapPtr pixmap;
-
-    assert(picture->pDrawable);
-    pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-
-    if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0,
-                                            pixmap->drawable.width,
-                                            pixmap->drawable.height,
-                                            pixmap->devKind,
-                                            pixmap->devPrivate.ptr, 0,
-                                            picture->format))
-        return GLAMOR_UPLOAD_DONE;
-    else
-        return GLAMOR_UPLOAD_FAILED;
+                                                     0, 0,
+                                                     pixmap->drawable.width,
+                                                     pixmap->drawable.height,
+                                                     stride, bits,
+                                                     0);
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index a70f10e..422b0fd 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -514,22 +514,6 @@ glamor_pixmap_hcnt(glamor_pixmap_private *priv)
     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
- * temporarily uploading pixmaps to GL textures to get a Composite
- * operation done.
- */
-typedef enum glamor_pixmap_status {
-    /** initial status, don't need to do anything. */
-    GLAMOR_NONE,
-    /** marked as need to be uploaded to gl texture. */
-    GLAMOR_UPLOAD_PENDING,
-    /** the pixmap has been uploaded successfully. */
-    GLAMOR_UPLOAD_DONE,
-    /** fail to upload the pixmap. */
-    GLAMOR_UPLOAD_FAILED
-} glamor_pixmap_status_t;
-
 /* GC private structure. Currently holds only any computed dash pixmap */
 
 typedef struct {
@@ -739,7 +723,7 @@ Bool glamor_composite_largepixmap_region(CARD8 op,
  * Upload a picture to gl texture. Similar to the
  * glamor_upload_pixmap_to_texture. Used in rendering.
  **/
-enum glamor_pixmap_status glamor_upload_picture_to_texture(PicturePtr picture);
+Bool glamor_upload_picture_to_texture(PicturePtr picture);
 
 void glamor_add_traps(PicturePtr pPicture,
                       INT16 x_off, INT16 y_off, int ntrap, xTrap *traps);
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 73ac831..d47e7d7 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -788,8 +788,8 @@ glamor_composite_choose_shader(CARD8 op,
 {
     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;
+    Bool source_needs_upload = FALSE;
+    Bool mask_needs_upload = FALSE;
     PictFormatShort saved_source_format = 0;
     struct shader_key key;
     GLfloat source_solid_color[4];
@@ -900,7 +900,7 @@ glamor_composite_choose_shader(CARD8 op,
         }
         if (source_pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED) {
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-            source_status = GLAMOR_UPLOAD_PENDING;
+            source_needs_upload = TRUE;
 #else
             glamor_fallback("no texture in source\n");
             goto fail;
@@ -916,7 +916,7 @@ glamor_composite_choose_shader(CARD8 op,
         }
         if (mask_pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED) {
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-            mask_status = GLAMOR_UPLOAD_PENDING;
+            mask_needs_upload = TRUE;
 #else
             glamor_fallback("no texture in mask\n");
             goto fail;
@@ -925,8 +925,7 @@ glamor_composite_choose_shader(CARD8 op,
     }
 
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-    if (source_status == GLAMOR_UPLOAD_PENDING
-        && mask_status == GLAMOR_UPLOAD_PENDING
+    if (source_needs_upload && mask_needs_upload
         && source_pixmap == mask_pixmap) {
 
         if (source->format != mask->format) {
@@ -962,20 +961,17 @@ glamor_composite_choose_shader(CARD8 op,
             if (!PICT_FORMAT_A(mask->format)
                 && PICT_FORMAT_A(saved_source_format))
                 key.mask = SHADER_MASK_TEXTURE;
-
-            mask_status = GLAMOR_NONE;
         }
 
-        source_status = glamor_upload_picture_to_texture(source);
-        if (source_status != GLAMOR_UPLOAD_DONE) {
+        if (!glamor_upload_picture_to_texture(source)) {
             glamor_fallback("Failed to upload source texture.\n");
             goto fail;
         }
+        mask_needs_upload = FALSE;
     }
     else {
-        if (source_status == GLAMOR_UPLOAD_PENDING) {
-            source_status = glamor_upload_picture_to_texture(source);
-            if (source_status != GLAMOR_UPLOAD_DONE) {
+        if (source_needs_upload) {
+            if (!glamor_upload_picture_to_texture(source)) {
                 glamor_fallback("Failed to upload source texture.\n");
                 goto fail;
             }
@@ -986,9 +982,8 @@ glamor_composite_choose_shader(CARD8 op,
             }
         }
 
-        if (mask_status == GLAMOR_UPLOAD_PENDING) {
-            mask_status = glamor_upload_picture_to_texture(mask);
-            if (mask_status != GLAMOR_UPLOAD_DONE) {
+        if (mask_needs_upload) {
+            if (!glamor_upload_picture_to_texture(mask)) {
                 glamor_fallback("Failed to upload mask texture.\n");
                 goto fail;
             }
commit 25ce263fd88684be9370025f93ba3a2bfc72ff1a
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>

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 da7724d3d277c6c8a814881785b716896802629a
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>

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 8e77a84..ad66cf6 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -569,5 +569,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 d11fdff50c91575e977a63617806a61bca98cd35
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Fri Jan 3 13:21:40 2014 +0000

    hw/xwin: Tidy-up of winmsg.h
    
    - winVMsg() has no uses, so remove
    - winMsgVerb() has only one use, with default verbosity, so remove
    - winMsg() is identical to LogMessage()
    - Put winDrvMsg() and winDrvMsgVerb() under XWIN_XF86CONFIG
    - Include what you use Xfuncproto.h for _X_ATTRIBUTE_PRINTF
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c
index fb99113..31894d2 100644
--- a/hw/xwin/winconfig.c
+++ b/hw/xwin/winconfig.c
@@ -264,8 +264,9 @@ winConfigKeyboard(DeviceIntPtr pDevice)
                 break;
             }
             g_winInfo.keyboard.rate = (kbd_speed > 0) ? kbd_speed : 1;
-            winMsgVerb(X_PROBED, 1, "Setting autorepeat to delay=%ld, rate=%ld\n",
-                       g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
+            winMsg(X_PROBED, "Setting autorepeat to delay=%ld, rate=%ld\n",
+                   g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
+
         }
     }
 
diff --git a/hw/xwin/winmsg.c b/hw/xwin/winmsg.c
index 575bc47..2ee48ce 100644
--- a/hw/xwin/winmsg.c
+++ b/hw/xwin/winmsg.c
@@ -38,17 +38,7 @@
 #endif
 #include <stdarg.h>
 
-void
-winVMsg(int, MessageType, int verb, const char *, va_list)
-_X_ATTRIBUTE_PRINTF(4, 0);
-
-void
-winVMsg(int scrnIndex, MessageType type, int verb, const char *format,
-        va_list ap)
-{
-    LogVMessageVerb(type, verb, format, ap);
-}
-
+#ifdef XWIN_XF86CONFIG
 void
 winDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
 {
@@ -60,16 +50,6 @@ winDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
 }
 
 void
-winMsg(MessageType type, const char *format, ...)
-{
-    va_list ap;
-
-    va_start(ap, format);
-    LogVMessageVerb(type, 1, format, ap);
-    va_end(ap);
-}
-
-void
 winDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
               ...)
 {
@@ -79,16 +59,7 @@ winDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
     LogVMessageVerb(type, verb, format, ap);
     va_end(ap);
 }
-
-void
-winMsgVerb(MessageType type, int verb, const char *format, ...)
-{
-    va_list ap;
-
-    va_start(ap, format);
-    LogVMessageVerb(type, verb, format, ap);
-    va_end(ap);
-}
+#endif
 
 void
 winErrorFVerb(int verb, const char *format, ...)
diff --git a/hw/xwin/winmsg.h b/hw/xwin/winmsg.h
index 6c96c40..02f672f 100644
--- a/hw/xwin/winmsg.h
+++ b/hw/xwin/winmsg.h
@@ -1,5 +1,3 @@
-#ifndef __WIN_MSG_H__
-#define __WIN_MSG_H__
 /*
  *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
  *
@@ -30,12 +28,17 @@
  * Authors: Alexander Gottwald	
  */
 
+#ifndef __WIN_MSG_H__
+#define __WIN_MSG_H__
+
 #include <X11/Xwindows.h>
+#include <X11/Xfuncproto.h>
 
 /*
  * Function prototypes
  */
 
+#ifdef XWIN_XF86CONFIG
 void
 winDrvMsgVerb(int scrnIndex,
               MessageType type, int verb, const char *format, ...)
@@ -43,12 +46,10 @@ _X_ATTRIBUTE_PRINTF(4, 5);
 void
 winDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
 _X_ATTRIBUTE_PRINTF(3, 4);
-void
-winMsgVerb(MessageType type, int verb, const char *format, ...)
-_X_ATTRIBUTE_PRINTF(3, 4);
-void
-winMsg(MessageType type, const char *format, ...)
-_X_ATTRIBUTE_PRINTF(2, 3);
+#endif
+
+#define winMsg LogMessage
+
 void
 winDebug(const char *format, ...)
 _X_ATTRIBUTE_PRINTF(1, 2);
commit 519b98765f0c7d083a744ae7beb641753e4eb751
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Thu Mar 3 22:32:28 2016 +0000

    hw/xwin: Remove GC privates, unused since native GDI engine removal
    
    Unused since native GDI engine removal in commit 8465ee78
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 0574707..f9c44b3 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -293,15 +293,6 @@ typedef Bool (*winReleasePrimarySurfaceProcPtr) (ScreenPtr);
 typedef Bool (*winCreateScreenResourcesProc) (ScreenPtr);
 
 /*
- * GC (graphics context) privates
- */
-
-typedef struct {
-    HDC hdc;
-    HDC hdcMem;
-} winPrivGCRec, *winPrivGCPtr;
-
-/*
  * Pixmap privates
  */
 
@@ -324,6 +315,7 @@ typedef struct {
     PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES];
 } winPrivCmapRec, *winPrivCmapPtr;
 
+
 /*
  * Windows Cursor handling.
  */
diff --git a/hw/xwin/winallpriv.c b/hw/xwin/winallpriv.c
index 816b030..e25e6bd 100644
--- a/hw/xwin/winallpriv.c
+++ b/hw/xwin/winallpriv.c
@@ -79,13 +79,6 @@ winAllocatePrivates(ScreenPtr pScreen)
     /* Save the screen private pointer */
     winSetScreenPriv(pScreen, pScreenPriv);
 
-    /* Reserve GC memory for our privates */
-    if (!dixRegisterPrivateKey
-        (g_iGCPrivateKey, PRIVATE_GC, sizeof(winPrivGCRec))) {
-        ErrorF("winAllocatePrivates - AllocateGCPrivate () failed\n");
-        return FALSE;
-    }
-
     /* Reserve Pixmap memory for our privates */
     if (!dixRegisterPrivateKey
         (g_iPixmapPrivateKey, PRIVATE_PIXMAP, sizeof(winPrivPixmapRec))) {
commit 9d28ff2a9be86662f56463aa1fd46d12988e30fa
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Fri Jul 31 20:23:59 2015 +0100

    hw/xwin: Use NULL rather than NoopDDA for unimplemented engine functions
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index d72114f..0574707 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -162,7 +162,6 @@
 #include "mipointer.h"
 #include "X11/keysym.h"
 #include "micoord.h"
-#include "dix.h"
 #include "miline.h"
 #include "shadow.h"
 #include "fb.h"
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index c84bf56..22836c5 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -1143,10 +1143,8 @@ winSetEngineFunctionsShadowGDI(ScreenPtr pScreen)
     pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI;
     pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI;
     pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI;
-    pScreenPriv->pwinCreatePrimarySurface =
-        (winCreatePrimarySurfaceProcPtr) (void (*)(void)) NoopDDA;
-    pScreenPriv->pwinReleasePrimarySurface =
-        (winReleasePrimarySurfaceProcPtr) (void (*)(void)) NoopDDA;
+    pScreenPriv->pwinCreatePrimarySurface = NULL;
+    pScreenPriv->pwinReleasePrimarySurface = NULL;
 
     return TRUE;
 }
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index b3b720b..7423643 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -290,22 +290,16 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                  * the display dimensions change.
                  */
 
-                /*
-                 * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface
-                 * and CreatePrimarySurface function pointers to point
-                 * to the no operation function, NoopDDA.  This allows us
-                 * to blindly call these functions, even if they are not
-                 * relevant to the current engine (e.g., Shadow GDI).
-                 */
-
                 winDebug
                     ("winWindowProc - WM_DISPLAYCHANGE - Releasing and recreating primary surface\n");
 
                 /* Release the old primary surface */
-                (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);
+                if (*s_pScreenPriv->pwinReleasePrimarySurface)
+                    (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);
 
                 /* Create the new primary surface */
-                (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen);
+                if (*s_pScreenPriv->pwinCreatePrimarySurface)
+                    (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen);
             }
         }
 
commit a309085a56de4d30dfbc44d9ff5302c7d9fdbf73
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Fri Jul 31 20:20:00 2015 +0100

    hw/xwin: Remove unused FinishCreateWindowsWindow engine function
    
    This only ever had an (unused) implementation in the DDNL engine, which was
    removed in commit 57bbf6e2.
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 927a08e..d72114f 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -291,8 +291,6 @@ typedef Bool (*winCreatePrimarySurfaceProcPtr) (ScreenPtr);
 
 typedef Bool (*winReleasePrimarySurfaceProcPtr) (ScreenPtr);
 
-typedef Bool (*winFinishCreateWindowsWindowProcPtr) (WindowPtr pWin);
-
 typedef Bool (*winCreateScreenResourcesProc) (ScreenPtr);
 
 /*
@@ -522,14 +520,8 @@ typedef struct _winPrivScreenRec {
     winDestroyColormapProcPtr pwinDestroyColormap;
     winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface;
     winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface;
-
     winCreateScreenResourcesProc pwinCreateScreenResources;
 
-#ifdef XWIN_MULTIWINDOW
-    /* Window Procedures for MultiWindow mode */
-    winFinishCreateWindowsWindowProcPtr pwinFinishCreateWindowsWindow;
-#endif
-
     /* Window Procedures for Rootless mode */
     CreateWindowProcPtr CreateWindow;
     DestroyWindowProcPtr DestroyWindow;
diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index 74d722c..6db576a 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -485,7 +485,6 @@ winCreateWindowsWindow(WindowPtr pWin)
     HWND hFore = NULL;
 
     winWindowPriv(pWin);
-    winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv;
     WinXSizeHints hints;
     Window daddyId;
     DWORD dwStyle, dwExStyle;
@@ -606,9 +605,6 @@ winCreateWindowsWindow(WindowPtr pWin)
 
     /* Flag that this Windows window handles its own activation */
     SetProp(hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
-
-    /* Call engine-specific create window procedure */
-    (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin);
 }
 
 Bool winInDestroyWindowsWindow = FALSE;
diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c
index 074ebf3..0ec5246 100644
--- a/hw/xwin/winshadddnl.c
+++ b/hw/xwin/winshadddnl.c
@@ -1213,10 +1213,6 @@ winSetEngineFunctionsShadowDDNL(ScreenPtr pScreen)
     pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDDNL;
     pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDDNL;
     pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDDNL;
-#ifdef XWIN_MULTIWINDOW
-    pScreenPriv->pwinFinishCreateWindowsWindow
-        = (winFinishCreateWindowsWindowProcPtr) (void (*)(void)) NoopDDA;
-#endif
 
     return TRUE;
 }
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index ba2e84e..c84bf56 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -1147,10 +1147,6 @@ winSetEngineFunctionsShadowGDI(ScreenPtr pScreen)
         (winCreatePrimarySurfaceProcPtr) (void (*)(void)) NoopDDA;
     pScreenPriv->pwinReleasePrimarySurface =
         (winReleasePrimarySurfaceProcPtr) (void (*)(void)) NoopDDA;
-#ifdef XWIN_MULTIWINDOW
-    pScreenPriv->pwinFinishCreateWindowsWindow =
-        (winFinishCreateWindowsWindowProcPtr) (void (*)(void)) NoopDDA;
-#endif
 
     return TRUE;
 }
commit fa6f9d06a3d1a90134d9349f5ce4ec5b4eeff5e3
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Fri Jul 31 20:12:37 2015 +0100

    hw/xwin: Remove unused HotKeyAltTab engine function
    
    This was only ever used by the primaryfb engine, removed in commit c79f824b
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 3b8e93d..927a08e 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -287,8 +287,6 @@ typedef Bool (*winCreateColormapProcPtr) (ColormapPtr pColormap);
 
 typedef Bool (*winDestroyColormapProcPtr) (ColormapPtr pColormap);
 
-typedef Bool (*winHotKeyAltTabProcPtr) (ScreenPtr);
-
 typedef Bool (*winCreatePrimarySurfaceProcPtr) (ScreenPtr);
 
 typedef Bool (*winReleasePrimarySurfaceProcPtr) (ScreenPtr);
@@ -522,7 +520,6 @@ typedef struct _winPrivScreenRec {
     winStoreColorsProcPtr pwinStoreColors;
     winCreateColormapProcPtr pwinCreateColormap;
     winDestroyColormapProcPtr pwinDestroyColormap;
-    winHotKeyAltTabProcPtr pwinHotKeyAltTab;
     winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface;
     winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface;
 
diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c
index d4f940e..074ebf3 100644
--- a/hw/xwin/winshadddnl.c
+++ b/hw/xwin/winshadddnl.c
@@ -1211,8 +1211,6 @@ winSetEngineFunctionsShadowDDNL(ScreenPtr pScreen)
     pScreenPriv->pwinStoreColors = winStoreColorsShadowDDNL;
     pScreenPriv->pwinCreateColormap = winCreateColormapShadowDDNL;
     pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDDNL;
-    pScreenPriv->pwinHotKeyAltTab =
-        (winHotKeyAltTabProcPtr) (void (*)(void)) NoopDDA;
     pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDDNL;
     pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDDNL;
 #ifdef XWIN_MULTIWINDOW
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index bf65517..ba2e84e 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -1143,8 +1143,6 @@ winSetEngineFunctionsShadowGDI(ScreenPtr pScreen)
     pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI;
     pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI;
     pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI;
-    pScreenPriv->pwinHotKeyAltTab =
-        (winHotKeyAltTabProcPtr) (void (*)(void)) NoopDDA;
     pScreenPriv->pwinCreatePrimarySurface =
         (winCreatePrimarySurfaceProcPtr) (void (*)(void)) NoopDDA;
     pScreenPriv->pwinReleasePrimarySurface =
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index a2365a0..b3b720b 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -1107,14 +1107,6 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             winFixShiftKeys(iScanCode);
         return 0;
 
-    case WM_HOTKEY:
-        if (s_pScreenPriv == NULL)
-            break;
-
-        /* Call the engine-specific hot key handler */
-        (*s_pScreenPriv->pwinHotKeyAltTab) (s_pScreen);
-        return 0;
-
     case WM_ACTIVATE:
         if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
             break;
commit 7bd25aa8437ec410e7a7de1b0636ba33298fc8d6
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Fri Jul 31 19:44:34 2015 +0100

    hw/xwin: Return FALSE to indicate failure in winSetEngine()
    
    Return FALSE to indicate failure in winSetEngine(), if it couldn't find a
    drawing engine to use
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winengine.c b/hw/xwin/winengine.c
index b8f8da0..d816851 100644
--- a/hw/xwin/winengine.c
+++ b/hw/xwin/winengine.c
@@ -203,7 +203,7 @@ winSetEngine(ScreenPtr pScreen)
         return TRUE;
     }
 
-    return TRUE;
+    return FALSE;
 }
 
 /*
commit 52e05b9282f0f220d7c762793ce0b8f606a45deb
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Tue Feb 23 23:09:43 2016 +0000

    hw/xwin: Remove WM_WM_MAP message, which is now unused
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 54d9a8a..c5404cf 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -243,9 +243,6 @@ MessageName(winWMMessagePtr msg)
     case WM_WM_CHANGE_STATE:
       return "WM_WM_CHANGE_STATE";
       break;
-    case WM_WM_MAP:
-      return "WM_WM_MAP";
-      break;
     case WM_WM_MAP2:
       return "WM_WM_MAP2";
       break;
@@ -772,16 +769,6 @@ winMultiWindowWMProc(void *pArg)
             XLowerWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
             break;
 
-        case WM_WM_MAP:
-            /* Put a note as to the HWND associated with this Window */
-            XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER,
-                            32,
-                            PropModeReplace,
-                            (unsigned char *) &(pNode->msg.hwndWindow), sizeof(HWND)/4);
-            UpdateName(pWMInfo, pNode->msg.iWindow);
-            UpdateIcon(pWMInfo, pNode->msg.iWindow);
-            break;
-
         case WM_WM_MAP2:
             XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER,
                             32,
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 129a77c..5a1759d 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -102,7 +102,6 @@ typedef struct _winWMMessageRec {
 #define		WM_WM_SIZE		(WM_USER + 2)
 #define		WM_WM_RAISE		(WM_USER + 3)
 #define		WM_WM_LOWER		(WM_USER + 4)
-#define		WM_WM_MAP		(WM_USER + 5)
 #define		WM_WM_UNMAP		(WM_USER + 6)
 #define		WM_WM_KILL		(WM_USER + 7)
 #define		WM_WM_ACTIVATE		(WM_USER + 8)
commit c42217aa3d372acaa5ca7c64895edbfbd20c8475
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Mon Nov 2 20:24:33 2015 +0000

    hw/xwin: Remove WM_(UN|)MANAGE messages, which are now never sent
    
    Remove fAnotherWMRunning which tracks this message (although since it was
    never initialized, I doubt this worked reliably), and the only use of that,
    which was to prevent winMWExtWMRestackWindows() from being used when the
    internalwm is running
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index f3d1eab..3b8e93d 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -404,7 +404,6 @@ typedef struct {
     Bool fDecoration;
 #ifdef XWIN_MULTIWINDOWEXTWM
     Bool fMWExtWM;
-    Bool fAnotherWMRunning;
 #endif
     Bool fRootless;
 #ifdef XWIN_MULTIWINDOW
diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c
index ab7d82b..5575f4b 100644
--- a/hw/xwin/winwin32rootlesswndproc.c
+++ b/hw/xwin/winwin32rootlesswndproc.c
@@ -1072,14 +1072,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                                     - wBorderWidth(pWin) * 2);
         break;
 
-    case WM_MANAGE:
-        ErrorF("winMWExtWMWindowProc - WM_MANAGE\n");
-        break;
-
-    case WM_UNMANAGE:
-        ErrorF("winMWExtWMWindowProc - WM_UNMANAGE\n");
-        break;
-
     default:
         break;
     }
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 0b2bf93..129a77c 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -112,8 +112,6 @@ typedef struct _winWMMessageRec {
 #define		WM_WM_MAP2		(WM_USER + 12)
 #define		WM_WM_MAP3		(WM_USER + 13)
 #define		WM_WM_HINTS_EVENT	(WM_USER + 14)
-#define		WM_MANAGE		(WM_USER + 100)
-#define		WM_UNMANAGE		(WM_USER + 102)
 
 #define		MwmHintsDecorations	(1L << 1)
 
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 5104c7b..a2365a0 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -1192,7 +1192,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 #ifdef XWIN_MULTIWINDOWEXTWM
         if (s_pScreenPriv->fActive) {
             /* Restack all window unless using built-in wm. */
-            if (s_pScreenInfo->fAnotherWMRunning)
+            if (s_pScreenInfo->fMWExtWM)
                 winMWExtWMRestackWindows(s_pScreen);
         }
 #endif
@@ -1256,18 +1256,6 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         }
         break;
 
-#ifdef XWIN_MULTIWINDOWEXTWM
-    case WM_MANAGE:
-        ErrorF("winWindowProc - WM_MANAGE\n");
-        s_pScreenInfo->fAnotherWMRunning = FALSE;
-        break;
-
-    case WM_UNMANAGE:
-        ErrorF("winWindowProc - WM_UNMANAGE\n");
-        s_pScreenInfo->fAnotherWMRunning = TRUE;
-        break;
-#endif
-
     default:
         if (message == s_uTaskbarRestart) {
             winInitNotifyIcon(s_pScreenPriv);
commit b6bdf368420355332e41c604c523584bd39933f9
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Mon Nov 2 20:51:51 2015 +0000

    hw/xwin: Remove allowOtherWM, which is now always FALSE
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 97b893f..54d9a8a 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -118,7 +118,6 @@ typedef struct _WMInfo {
     Atom atmWmDelete;
     Atom atmWmTakeFocus;
     Atom atmPrivMap;
-    Bool fAllowOtherWM;
 } WMInfoRec, *WMInfoPtr;
 
 typedef struct _WMProcArgRec {
@@ -184,9 +183,7 @@ static void
 #endif
 
 static Bool
-
-CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen,
-                          Bool fAllowOtherWM);
+CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen);
 
 static void
  winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle);
@@ -206,7 +203,6 @@ static XIOErrorHandler g_winMultiWindowXMsgProcOldIOErrorHandler;
 static pthread_t g_winMultiWindowXMsgProcThread;
 static Bool g_shutdown = FALSE;
 static Bool redirectError = FALSE;
-static Bool g_fAnotherWMRunning = FALSE;
 
 /*
  * Translate msg id to text, for debug purposes
@@ -739,11 +735,6 @@ winMultiWindowWMProc(void *pArg)
     for (;;) {
         WMMsgNodePtr pNode;
 
-        if (g_fAnotherWMRunning) {      /* Another Window manager exists. */
-            Sleep(1000);
-            continue;
-        }
-
         /* Pop a message off of our queue */
         pNode = PopMessage(&pWMInfo->wmMsgQueue, pWMInfo);
         if (pNode == NULL) {
@@ -1047,11 +1038,7 @@ winMultiWindowXMsgProc(void *pArg)
            "successfully opened the display.\n");
 
     /* Check if another window manager is already running */
-    g_fAnotherWMRunning =
-        CheckAnotherWindowManager(pProcArg->pDisplay, pProcArg->dwScreen,
-                                  pProcArg->pWMInfo->fAllowOtherWM);
-
-    if (g_fAnotherWMRunning && !pProcArg->pWMInfo->fAllowOtherWM) {
+    if (CheckAnotherWindowManager(pProcArg->pDisplay, pProcArg->dwScreen)) {
         ErrorF("winMultiWindowXMsgProc - "
                "another window manager is running.  Exiting.\n");
         pthread_exit(NULL);
@@ -1093,24 +1080,6 @@ winMultiWindowXMsgProc(void *pArg)
         if (g_shutdown)
             break;
 
-        if (pProcArg->pWMInfo->fAllowOtherWM && !XPending(pProcArg->pDisplay)) {
-            if (CheckAnotherWindowManager
-                (pProcArg->pDisplay, pProcArg->dwScreen, TRUE)) {
-                if (!g_fAnotherWMRunning) {
-                    g_fAnotherWMRunning = TRUE;
-                    SendMessage(pProcArg->hwndScreen, WM_UNMANAGE, 0, 0);
-                }
-            }
-            else {
-                if (g_fAnotherWMRunning) {
-                    g_fAnotherWMRunning = FALSE;
-                    SendMessage(pProcArg->hwndScreen, WM_MANAGE, 0, 0);
-                }
-            }
-            Sleep(500);
-            continue;
-        }
-
         /* Fetch next event */
         XNextEvent(pProcArg->pDisplay, &event);
 
@@ -1272,7 +1241,7 @@ winInitWM(void **ppWMInfo,
           pthread_t * ptWMProc,
           pthread_t * ptXMsgProc,
           pthread_mutex_t * ppmServerStarted,
-          int dwScreen, HWND hwndScreen, BOOL allowOtherWM)
+          int dwScreen, HWND hwndScreen)
 {
     WMProcArgPtr pArg = malloc(sizeof(WMProcArgRec));
     WMInfoPtr pWMInfo = malloc(sizeof(WMInfoRec));
@@ -1294,7 +1263,6 @@ winInitWM(void **ppWMInfo,
 
     /* Set a return pointer to the Window Manager info structure */
     *ppWMInfo = pWMInfo;
-    pWMInfo->fAllowOtherWM = allowOtherWM;
 
     /* Setup the argument structure for the thread function */
     pArg->dwScreen = dwScreen;
@@ -1575,8 +1543,7 @@ winRedirectErrorHandler(Display * pDisplay, XErrorEvent * pErr)
  */
 
 static Bool
-CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen,
-                          Bool fAllowOtherWM)
+CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen)
 {
     /*
        Try to select the events which only one client at a time is allowed to select.
@@ -1593,12 +1560,11 @@ CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen,
     /*
        Side effect: select the events we are actually interested in...
 
-       If other WMs are not allowed, also select one of the events which only one client
+       Other WMs are not allowed, also select one of the events which only one client
        at a time is allowed to select, so other window managers won't start...
      */
     XSelectInput(pDisplay, RootWindow(pDisplay, dwScreen),
-                 SubstructureNotifyMask | (!fAllowOtherWM ? ButtonPressMask :
-                                           0));
+                 SubstructureNotifyMask | ButtonPressMask);
     XSync(pDisplay, 0);
     return redirectError;
 }
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index f75b2f9..6cbf08d 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -544,8 +544,8 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
                        &pScreenPriv->ptWMProc,
                        &pScreenPriv->ptXMsgProc,
                        &pScreenPriv->pmServerStarted,
-                       pScreenInfo->dwScreen, (HWND) &pScreenPriv->hwndScreen,
-                       FALSE)) {
+                       pScreenInfo->dwScreen,
+                       (HWND) &pScreenPriv->hwndScreen)) {
             ErrorF("winFinishScreenInitFB - winInitWM () failed.\n");
             return FALSE;
         }
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 7e6bd56..0b2bf93 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -142,7 +142,7 @@ winInitWM(void **ppWMInfo,
           pthread_t * ptWMProc,
           pthread_t * ptXMsgProc,
           pthread_mutex_t * ppmServerStarted,
-          int dwScreen, HWND hwndScreen, BOOL allowOtherWM);
+          int dwScreen, HWND hwndScreen);
 
 void
  winDeinitMultiWindowWM(void);
commit 8407d3096287868b5c5e50ca5a98d470918c85a9
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Mon Nov 2 20:34:09 2015 +0000

    hw/xwin: Remove winIsInternalWMRunning(), which now always returns FALSE
    
    Also remove then unused variables and IsRaiseonClick()
    
    v2:
    Also remove unused pScreenInfo variable in winMWEXtWMRestackFrame()
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index d43771e..f3d1eab 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -1136,9 +1136,6 @@ winMWExtWMUpdateWindowDecoration(win32RootlessWindowPtr pRLWinPriv,
 
 wBOOL CALLBACK winMWExtWMDecorateWindow(HWND hwnd, LPARAM lParam);
 
-Bool
- winIsInternalWMRunning(winScreenInfoPtr pScreenInfo);
-
 void
  winMWExtWMRestackWindows(ScreenPtr pScreen);
 #endif
diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 8fe6f42..95b8452 100644
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -516,12 +516,6 @@ winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
     win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid;
 
     winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen);
-    winScreenInfo *pScreenInfo = NULL;
-    DWORD dwCurrentProcessID = GetCurrentProcessId();
-    DWORD dwWindowProcessID = 0;
-    HWND hWnd;
-    Bool fFirst = TRUE;
-    Bool fNeedRestack = TRUE;
 
 #if CYGMULTIWINDOW_DEBUG
     winDebug("winMWExtWMRestackFrame (%p)\n", pRLWinPriv);
@@ -530,9 +524,6 @@ winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
     if (pScreenPriv && pScreenPriv->fRestacking)
         return;
 
-    if (pScreenPriv)
-        pScreenInfo = pScreenPriv->pScreenInfo;
-
     pRLWinPriv->fRestackingNow = TRUE;
 
     /* Show window */
@@ -547,62 +538,6 @@ winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
         SetWindowPos(pRLWinPriv->hWnd, HWND_TOP,
                      0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
     }
-    else if (winIsInternalWMRunning(pScreenInfo)) {
-        /* using mulwinidow wm */
-#if CYGMULTIWINDOW_DEBUG
-        winDebug("Win %p is not top\n", pRLWinPriv);
-#endif
-        for (hWnd = GetNextWindow(pRLWinPriv->hWnd, GW_HWNDPREV);
-             fNeedRestack && hWnd != NULL;
-             hWnd = GetNextWindow(hWnd, GW_HWNDPREV)) {
-            GetWindowThreadProcessId(hWnd, &dwWindowProcessID);
-
-            if ((dwWindowProcessID == dwCurrentProcessID)
-                && GetProp(hWnd, WIN_WINDOW_PROP)) {
-                if (hWnd == pRLNextWinPriv->hWnd) {
-                    /* Enable interleave X window and Windows window */
-                    if (!fFirst) {
-#if CYGMULTIWINDOW_DEBUG
-                        winDebug("raise: Insert after Win %p\n",
-                                 pRLNextWinPriv);
-#endif
-                        SetWindowPos(pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
-                                     0, 0, 0, 0,
-                                     SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
-                    }
-                    else {
-#if CYGMULTIWINDOW_DEBUG
-                        winDebug("No change\n");
-#endif
-                    }
-                    fNeedRestack = FALSE;
-                    break;
-                }
-                if (fFirst)
-                    fFirst = FALSE;
-            }
-        }
-
-        for (hWnd = GetNextWindow(pRLWinPriv->hWnd, GW_HWNDNEXT);
-             fNeedRestack && hWnd != NULL;
-             hWnd = GetNextWindow(hWnd, GW_HWNDNEXT)) {
-            GetWindowThreadProcessId(hWnd, &dwWindowProcessID);
-
-            if ((dwWindowProcessID == dwCurrentProcessID)
-                && GetProp(hWnd, WIN_WINDOW_PROP)) {
-                if (hWnd == pRLNextWinPriv->hWnd) {
-#if CYGMULTIWINDOW_DEBUG
-                    winDebug("lower: Insert after Win %p\n", pRLNextWinPriv);
-#endif
-                    SetWindowPos(pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
-                                 0, 0, 0, 0,
-                                 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
-                    fNeedRestack = FALSE;
-                    break;
-                }
-            }
-        }
-    }
     else {
         /* using general wm like twm, wmaker etc.
            Interleave X window and Windows window will cause problem. */
diff --git a/hw/xwin/winwin32rootlesswindow.c b/hw/xwin/winwin32rootlesswindow.c
index 524051f..817cd09 100644
--- a/hw/xwin/winwin32rootlesswindow.c
+++ b/hw/xwin/winwin32rootlesswindow.c
@@ -194,10 +194,6 @@ winMWExtWMUpdateWindowDecoration(win32RootlessWindowPtr pRLWinPriv,
     /* Get current window placement */
     GetWindowPlacement(pRLWinPriv->hWnd, &wndPlace);
 
-    if (winIsInternalWMRunning(pScreenInfo)) {
-        if (!pRLWinPriv->pFrame->win->overrideRedirect)
-            fDecorate = TRUE;
-    }
 #if 0
     if (wndPlace.showCmd == SW_HIDE)
         return;                 //showCmd = SWP_HIDEWINDOW;
@@ -345,15 +341,6 @@ winMWExtWMUpdateWindowDecoration(win32RootlessWindowPtr pRLWinPriv,
 }
 
 /*
- * winIsInternalWMRunning (winScreenInfoPtr pScreenInfo)
- */
-Bool
-winIsInternalWMRunning(winScreenInfoPtr pScreenInfo)
-{
-    return FALSE;
-}
-
-/*
  * winMWExtWMRestackWindows
  */
 
diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c
index 6618c05..ab7d82b 100644
--- a/hw/xwin/winwin32rootlesswndproc.c
+++ b/hw/xwin/winwin32rootlesswndproc.c
@@ -60,9 +60,9 @@ static UINT_PTR g_uipMousePollingTimerID = 0;
  * Local function
  */
 
-DEFINE_ATOM_HELPER(AtmWindowsWmRaiseOnClick, WINDOWSWM_RAISE_ON_CLICK)
-    DEFINE_ATOM_HELPER(AtmWindowsWMMouseActivate, WINDOWSWM_MOUSE_ACTIVATE)
+DEFINE_ATOM_HELPER(AtmWindowsWMMouseActivate, WINDOWSWM_MOUSE_ACTIVATE)
 /* DEFINE_ATOM_HELPER(AtmWindowsWMClientWindow, WINDOWSWM_CLIENT_WINDOW) */
+
 /*
  * ConstrainSize - Taken from TWM sources - Respects hints for sizing
  */
@@ -272,55 +272,6 @@ ValidateSizing(HWND hwnd, WindowPtr pWin, WPARAM wParam, LPARAM lParam)
 }
 
 /*
- * IsRaiseOnClick
- */
-
-static Bool
-IsRaiseOnClick(WindowPtr pWin)
-{
-
-    struct _Window *pwin;
-    struct _Property *prop;
-
-    /* XXX We're getting inputInfo.poniter here, but this might be really wrong.
-     * Which pointer's current window do we want? */
-    WindowPtr pRoot = GetCurrentRootWindow(inputInfo.pointer);
-
-    if (!pWin) {
-        ErrorF("IsRaiseOnClick - no prop use default value:%d\n",
-               RAISE_ON_CLICK_DEFAULT);
-        return RAISE_ON_CLICK_DEFAULT;
-    }
-
-    pwin = (struct _Window *) pWin;
-
-    if (pwin->optional)
-        prop = (struct _Property *) pwin->optional->userProps;
-    else
-        prop = NULL;
-
-    while (prop) {
-        if (prop->propertyName == AtmWindowsWmRaiseOnClick()
-            && prop->type == XA_INTEGER && prop->format == 32) {
-            return *(int *) prop->data;
-        }
-        else
-            prop = prop->next;
-    }
-
-    if (pWin != pRoot) {
-        return IsRaiseOnClick(pRoot);
-    }
-    else {
-#if CYGMULTIWINDOW_DEBUG
-        winDebug("IsRaiseOnClick - no prop use default value:%d\n",
-                 RAISE_ON_CLICK_DEFAULT);
-#endif
-        return RAISE_ON_CLICK_DEFAULT;
-    }
-}
-
-/*
  * IsMouseActive
  */
 
@@ -388,8 +339,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     PAINTSTRUCT ps;
     LPWINDOWPOS pWinPos = NULL;
     RECT rcClient;
-    winWMMessageRec wmMsg;
-    Bool fWMMsgInitialized = FALSE;
 
     /* Check if the Windows window property for our X window pointer is valid */
     if ((pRLWinPriv =
@@ -403,16 +352,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         if (pScreenPriv)
             hwndScreen = pScreenPriv->hwndScreen;
 
-        wmMsg.msg = 0;
-        wmMsg.hwndWindow = hwnd;
-        wmMsg.iWindow = (Window) pWin->drawable.id;
-
-        wmMsg.iX = pRLWinPriv->pFrame->x;
-        wmMsg.iY = pRLWinPriv->pFrame->y;
-        wmMsg.iWidth = pRLWinPriv->pFrame->width;
-        wmMsg.iHeight = pRLWinPriv->pFrame->height;
-
-        fWMMsgInitialized = TRUE;
 #if CYGDEBUG
         winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam,
                              lParam);
@@ -446,12 +385,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             DestroyWindow(hwnd);
         }
         else {
-            if (winIsInternalWMRunning(pScreenInfo)) {
-                /* Tell our Window Manager thread to kill the window */
-                wmMsg.msg = WM_WM_KILL;
-                if (fWMMsgInitialized)
-                    winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
-            }
             winWindowsWMSendEvent(WindowsWMControllerNotify,
                                   WindowsWMControllerNotifyMask,
                                   1,
@@ -680,19 +613,7 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 #if CYGMULTIWINDOW_DEBUG
         winDebug("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n");
 #endif
-#if 1
-        /* Check if this window needs to be made active when clicked */
-        if (winIsInternalWMRunning(pScreenInfo) && pWin->overrideRedirect) {
-#if CYGMULTIWINDOW_DEBUG
-            winDebug("winMWExtWMWindowProc - WM_MOUSEACTIVATE - "
-                     "MA_NOACTIVATE\n");
-#endif
-
-            /* */
-            return MA_NOACTIVATE;
-        }
-#endif
-        if (!winIsInternalWMRunning(pScreenInfo) && !IsMouseActive(pWin))
+        if (!IsMouseActive(pWin))
             return MA_NOACTIVATE;
 
         break;
@@ -805,19 +726,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         winDebug("winMWExtWMWindowProc - WM_ACTIVATE\n");
 #endif
         if (LOWORD(wParam) != WA_INACTIVE) {
-            if (winIsInternalWMRunning(pScreenInfo)) {
-#if 0
-                /* Raise the window to the top in Z order */
-                wmMsg.msg = WM_WM_RAISE;
-                if (fWMMsgInitialized)
-                    winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
-#endif
-                /* Tell our Window Manager thread to activate the window */
-                wmMsg.msg = WM_WM_ACTIVATE;
-                if (fWMMsgInitialized)
-                    if (!pWin || !pWin->overrideRedirect)       /* for OOo menus */
-                        winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
-            }
             winWindowsWMSendEvent(WindowsWMControllerNotify,
                                   WindowsWMControllerNotifyMask,
                                   1,
@@ -838,14 +746,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                 break;
             }
 
-            if (winIsInternalWMRunning(pScreenInfo) || IsRaiseOnClick(pWin)) {
-#if CYGMULTIWINDOW_DEBUG
-                winDebug("Win %p has WINDOWSWM_RAISE_ON_CLICK.\n",
-                         pRLWinPriv);
-#endif
-                break;
-            }
-
 #if CYGMULTIWINDOW_DEBUG
             winDebug("Win %p forbid to change z order (%p).\n",
                      pRLWinPriv,
@@ -889,9 +789,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                  (short) HIWORD(lParam));
 #endif
         if (!pRLWinPriv->fMovingOrSizing) {
-            if (winIsInternalWMRunning(pScreenInfo))
-                winAdjustXWindow(pWin, hwnd);
-
             winMWExtWMMoveXWindow(pWin, (LOWORD(lParam) - wBorderWidth(pWin)
                                          - GetSystemMetrics(SM_XVIRTUALSCREEN)),
                                   (HIWORD(lParam) - wBorderWidth(pWin)
@@ -909,26 +806,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         winMWExtWMUpdateWindowDecoration(pRLWinPriv, pScreenInfo);
 
-        if (winIsInternalWMRunning(pScreenInfo)) {
-#if CYGMULTIWINDOW_DEBUG || TRUE
-            winDebug("\tMapWindow\n");
-#endif
-            /* Tell X to map the window */
-            MapWindow(pWin, wClient(pWin));
-
-            if (!pRLWinPriv->pFrame->win->overrideRedirect)
-                /* Bring the Windows window to the foreground */
-                SetForegroundWindow(hwnd);
-
-            /* Setup the Window Manager message */
-            wmMsg.msg = WM_WM_MAP;
-            wmMsg.iWidth = pRLWinPriv->pFrame->width;
-            wmMsg.iHeight = pRLWinPriv->pFrame->height;
-
-            /* Tell our Window Manager thread to map the window */
-            if (fWMMsgInitialized)
-                winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
-        }
         break;
 
     case WM_SIZING:
@@ -964,72 +841,12 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         if (pWinPos->flags & SWP_HIDEWINDOW)
             break;
 
-        /* Reorder if window z order was changed */
-        if ((pScreenPriv != NULL)
-            && !(pWinPos->flags & SWP_NOZORDER)
-            && !(pWinPos->flags & SWP_SHOWWINDOW)
-            && winIsInternalWMRunning(pScreenInfo)) {
-#if CYGMULTIWINDOW_DEBUG
-            winDebug("\twindow z order was changed\n");
-#endif
-            if (pWinPos->hwndInsertAfter == HWND_TOP
-                || pWinPos->hwndInsertAfter == HWND_TOPMOST
-                || pWinPos->hwndInsertAfter == HWND_NOTOPMOST) {
-#if CYGMULTIWINDOW_DEBUG
-                winDebug("\traise to top\n");
-#endif
-                /* Raise the window to the top in Z order */
-                wmMsg.msg = WM_WM_RAISE;
-                if (fWMMsgInitialized)
-                    winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
-            }
-#if 1
-            else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) {
-            }
-            else {
-                /* Check if this window is top of X windows. */
-                HWND hWndAbove = NULL;
-                DWORD dwCurrentProcessID = GetCurrentProcessId();
-                DWORD dwWindowProcessID = 0;
-
-                for (hWndAbove = pWinPos->hwndInsertAfter;
-                     hWndAbove != NULL;
-                     hWndAbove = GetNextWindow(hWndAbove, GW_HWNDPREV)) {
-                    /* Ignore other XWin process's window */
-                    GetWindowThreadProcessId(hWndAbove, &dwWindowProcessID);
-
-                    if ((dwWindowProcessID == dwCurrentProcessID)
-                        && GetProp(hWndAbove, WIN_WINDOW_PROP)
-                        && !IsWindowVisible(hWndAbove)
-                        && !IsIconic(hWndAbove))        /* ignore minimized windows */
-                        break;
-                }
-                /* If this is top of X windows in Windows stack,
-                   raise it in X stack. */
-                if (hWndAbove == NULL) {
-#if CYGMULTIWINDOW_DEBUG
-                    winDebug("\traise to top\n");
-#endif
-                    /* Raise the window to the top in Z order */
-                    wmMsg.msg = WM_WM_RAISE;
-                    if (fWMMsgInitialized)
-                        winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
-                }
-            }
-#endif
-        }
-
         if (!(pWinPos->flags & SWP_NOSIZE)) {
             if (IsIconic(hwnd)) {
 #if CYGMULTIWINDOW_DEBUG
                 winDebug("\tIconic -> MINIMIZED\n");
 #endif
-                if (winIsInternalWMRunning(pScreenInfo)) {
-                    /* Raise the window to the top in Z order */
-                    wmMsg.msg = WM_WM_LOWER;
-                    if (fWMMsgInitialized)
-                        winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
-                }
+
                 winWindowsWMSendEvent(WindowsWMControllerNotify,
                                       WindowsWMControllerNotifyMask,
                                       1,
@@ -1069,8 +886,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 #if CYGMULTIWINDOW_DEBUG
                     winDebug("\tmove & resize\n");
 #endif
-                    if (winIsInternalWMRunning(pScreenInfo))
-                        winAdjustXWindow(pWin, hwnd);
 
                     winMWExtWMMoveResizeXWindow(pWin,
                                                 rcClient.left -
@@ -1092,8 +907,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 #if CYGMULTIWINDOW_DEBUG
                     winDebug("\tmove\n");
 #endif
-                    if (winIsInternalWMRunning(pScreenInfo))
-                        winAdjustXWindow(pWin, hwnd);
 
                     winMWExtWMMoveResizeXWindow(pWin,
                                                 rcClient.left -
@@ -1115,8 +928,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 #if CYGMULTIWINDOW_DEBUG
                     winDebug("\tmove\n");
 #endif
-                    if (winIsInternalWMRunning(pScreenInfo))
-                        winAdjustXWindow(pWin, hwnd);
 
                     winMWExtWMMoveXWindow(pWin,
                                           rcClient.left - wBorderWidth(pWin)
@@ -1129,8 +940,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 #if CYGMULTIWINDOW_DEBUG
                     winDebug("\tresize\n");
 #endif
-                    if (winIsInternalWMRunning(pScreenInfo))
-                        winAdjustXWindow(pWin, hwnd);
 
                     winMWExtWMResizeXWindow(pWin,
                                             rcClient.right - rcClient.left
@@ -1165,12 +974,7 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 #if CYGMULTIWINDOW_DEBUG
             winDebug("\tSIZE_MINIMIZED\n");
 #endif
-            if (winIsInternalWMRunning(pScreenInfo)) {
-                /* Raise the window to the top in Z order */
-                wmMsg.msg = WM_WM_LOWER;
-                if (fWMMsgInitialized)
-                    winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
-            }
+
             winWindowsWMSendEvent(WindowsWMControllerNotify,
                                   WindowsWMControllerNotifyMask,
                                   1,
@@ -1206,9 +1010,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         /* Perform the resize and notify the X client */
         if (!pRLWinPriv->fMovingOrSizing) {
-            if (winIsInternalWMRunning(pScreenInfo))
-                winAdjustXWindow(pWin, hwnd);
-
             winMWExtWMResizeXWindow(pWin, (short) LOWORD(lParam)
                                     - wBorderWidth(pWin) * 2,
                                     (short) HIWORD(lParam)
@@ -1221,10 +1022,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         winDebug("winMWExtWMWindowProc - WM_ACTIVATEAPP\n");
 #endif
         if (wParam) {
-            if (winIsInternalWMRunning(pScreenInfo)) {
-            }
-            else {
-            }
             winWindowsWMSendEvent(WindowsWMActivationNotify,
                                   WindowsWMActivationNotifyMask,
                                   1,
@@ -1265,9 +1062,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT) &rcClient, 2);
 
-        if (winIsInternalWMRunning(pScreenInfo))
-            winAdjustXWindow(pWin, hwnd);
-
         winMWExtWMMoveResizeXWindow(pWin, rcClient.left - wBorderWidth(pWin)
                                     - GetSystemMetrics(SM_XVIRTUALSCREEN),
                                     rcClient.top - wBorderWidth(pWin)
commit 2779a28a86a13831b334e8678cd4e838b3b38472
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Mon Nov 2 20:07:04 2015 +0000

    hw/xwin: Remove fInternalWM flag
    
    Remove the fInternalWM flag as it is now always FALSE after removing the
    -internalwm option
    
    v2:
    Also remove then unused pRLWinPriv local from pRLWinPriv()
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 5710ea8..d43771e 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -404,7 +404,6 @@ typedef struct {
     Bool fDecoration;
 #ifdef XWIN_MULTIWINDOWEXTWM
     Bool fMWExtWM;
-    Bool fInternalWM;
     Bool fAnotherWMRunning;
 #endif
     Bool fRootless;
diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index 8b85785..74d722c 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -811,9 +811,6 @@ winMinimizeWindow(Window id)
     WindowPtr pWin;
     winPrivWinPtr pWinPriv;
 
-#ifdef XWIN_MULTIWINDOWEXTWM
-    win32RootlessWindowPtr pRLWinPriv;
-#endif
     HWND hWnd;
     ScreenPtr pScreen = NULL;
     winPrivScreenPtr pScreenPriv = NULL;
@@ -833,16 +830,7 @@ winMinimizeWindow(Window id)
     if (pScreen)
         pScreenPriv = winGetScreenPriv(pScreen);
 
-#ifdef XWIN_MULTIWINDOWEXTWM
-    if (pScreenPriv && pScreenPriv->pScreenInfo->fInternalWM) {
-        pRLWinPriv =
-            (win32RootlessWindowPtr) RootlessFrameForWindow(pWin, FALSE);
-        hWnd = pRLWinPriv->hWnd;
-    }
-    else
-#else
     if (pScreenPriv)
-#endif
     {
         pWinPriv = winGetWindowPriv(pWin);
         hWnd = pWinPriv->hWnd;
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index bf70cf1..5c58480 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -130,7 +130,6 @@ winInitializeScreenDefaults(void)
     defaultScreenInfo.fDecoration = TRUE;
 #ifdef XWIN_MULTIWINDOWEXTWM
     defaultScreenInfo.fMWExtWM = FALSE;
-    defaultScreenInfo.fInternalWM = FALSE;
 #endif
     defaultScreenInfo.fRootless = FALSE;
 #ifdef XWIN_MULTIWINDOW
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index 735ce93..f75b2f9 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -534,9 +534,6 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
 #ifdef XWIN_MULTIWINDOW
         || pScreenInfo->fMultiWindow
 #endif
-#ifdef XWIN_MULTIWINDOWEXTWM
-        || pScreenInfo->fInternalWM
-#endif
         ) {
 #if CYGDEBUG || YES
         winDebug("winFinishScreenInitFB - Calling winInitWM.\n");
@@ -548,9 +545,6 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
                        &pScreenPriv->ptXMsgProc,
                        &pScreenPriv->pmServerStarted,
                        pScreenInfo->dwScreen, (HWND) &pScreenPriv->hwndScreen,
-#ifdef XWIN_MULTIWINDOWEXTWM
-                       pScreenInfo->fInternalWM ||
-#endif
                        FALSE)) {
             ErrorF("winFinishScreenInitFB - winInitWM () failed.\n");
             return FALSE;
diff --git a/hw/xwin/winwin32rootlesswindow.c b/hw/xwin/winwin32rootlesswindow.c
index ba4fb51..524051f 100644
--- a/hw/xwin/winwin32rootlesswindow.c
+++ b/hw/xwin/winwin32rootlesswindow.c
@@ -350,7 +350,7 @@ winMWExtWMUpdateWindowDecoration(win32RootlessWindowPtr pRLWinPriv,
 Bool
 winIsInternalWMRunning(winScreenInfoPtr pScreenInfo)
 {
-    return pScreenInfo->fInternalWM && !pScreenInfo->fAnotherWMRunning;
+    return FALSE;
 }
 
 /*
diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c
index 47de608..6618c05 100644
--- a/hw/xwin/winwin32rootlesswndproc.c
+++ b/hw/xwin/winwin32rootlesswndproc.c
@@ -907,9 +907,6 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         if (!wParam)
             return 0;
 
-        if (!pScreenInfo->fInternalWM)  //XXXX
-            return 0;
-
         winMWExtWMUpdateWindowDecoration(pRLWinPriv, pScreenInfo);
 
         if (winIsInternalWMRunning(pScreenInfo)) {
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 123b84f..5104c7b 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -1192,7 +1192,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 #ifdef XWIN_MULTIWINDOWEXTWM
         if (s_pScreenPriv->fActive) {
             /* Restack all window unless using built-in wm. */
-            if (s_pScreenInfo->fInternalWM && s_pScreenInfo->fAnotherWMRunning)
+            if (s_pScreenInfo->fAnotherWMRunning)
                 winMWExtWMRestackWindows(s_pScreen);
         }
 #endif
@@ -1260,21 +1260,11 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     case WM_MANAGE:
         ErrorF("winWindowProc - WM_MANAGE\n");
         s_pScreenInfo->fAnotherWMRunning = FALSE;
-
-        if (s_pScreenInfo->fInternalWM) {
-            EnumThreadWindows(g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0);
-            //RootlessRepositionWindows (s_pScreen);
-        }
         break;
 
     case WM_UNMANAGE:
         ErrorF("winWindowProc - WM_UNMANAGE\n");
         s_pScreenInfo->fAnotherWMRunning = TRUE;
-
-        if (s_pScreenInfo->fInternalWM) {
-            EnumThreadWindows(g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0);
-            winMWExtWMRestackWindows(s_pScreen);
-        }
         break;
 #endif
 
commit 98238ece5756801a8a67b9235e42cb9ab2318633
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Mon Nov 2 19:37:40 2015 +0000

    hw/xwin: Ignore the obsolete, undocumented -internalwm option
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 57e514f..1190124 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -745,10 +745,6 @@ winUseMsg(void)
 
     ErrorF("-ignoreinput\n" "\tIgnore keyboard and mouse input.\n");
 
-#ifdef XWIN_MULTIWINDOWEXTWM
-    ErrorF("-internalwm\n" "\tRun the internal window manager.\n");
-#endif
-
 #ifdef XWIN_XF86CONFIG
     ErrorF("-keyboard\n"
            "\tSpecify a keyboard device from the configuration file.\n");
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index 50fdba2..7ffdd6c 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -346,9 +346,6 @@ Color map manipulation is not supported, so the PseudoColor visual will
 not have the correct colors.
 This option is intended to allow applications which only work with a depth 8
 visual to operate in TrueColor modes.
-.TP 8
-.B \-internalwm
-Run the internal window manager.
 
 .SH LOG FILE
 As it runs \fIXWin\fP writes messages indicating the most relevant events
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 2bf6560..bf70cf1 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -577,11 +577,8 @@ ddxProcessArgument(int argc, char *argv[], int i)
      * Look for the '-internalwm' argument
      */
     if (IS_OPTION("-internalwm")) {
-        if (!screenInfoPtr->fMultiMonitorOverride)
-            screenInfoPtr->fMultipleMonitors = TRUE;
-        screenInfoPtr->fMWExtWM = TRUE;
-        screenInfoPtr->fInternalWM = TRUE;
-
+        ErrorF("Ignoring obsolete -internalwm option\n");
+        /* Ignored, but we still accept the arg for backwards compatibility */
         /* Indicate that we have processed this argument */
         return 1;
     }
commit cdeaebad9889d81d2698b8a10fec5e55d8dec7a1
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Tue Mar 1 21:37:05 2016 +0000

    hw/xwin: Remove the long-broken -silent-dup-error option
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index b6f2583..57e514f 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -76,9 +76,6 @@ typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner,
  * Function prototypes
  */
 
-static Bool
- winCheckDisplayNumber(void);
-
 void
  winLogCommandLine(int argc, char *argv[]);
 
@@ -824,11 +821,6 @@ winUseMsg(void)
            "\t -screen 0 1024x768 at 3        ; 3rd monitor size 1024x768\n"
            "\t -screen 0 @1 ; on 1st monitor using its full resolution (the default)\n");
 
-    ErrorF("-silent-dup-error\n"
-           "\tIf another instance of " EXECUTABLE_NAME
-           " with the same display number is running\n"
-           "\texit silently and don't display any error message.\n");
-
     ErrorF("-swcursor\n"
            "\tDisable the usage of the Windows cursor and use the X11 software\n"
            "\tcursor instead.\n");
@@ -918,14 +910,6 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
                    "Exiting.\n");
     }
 
-    /* Check for duplicate invocation on same display number. */
-    if (serverGeneration == 1 && !winCheckDisplayNumber()) {
-        if (g_fSilentDupError)
-            g_fSilentFatalError = TRUE;
-        FatalError("InitOutput - Duplicate invocation on display "
-                   "number: %s.  Exiting.\n", display);
-    }
-
 #ifdef XWIN_XF86CONFIG
     /* Try to read the xorg.conf-style configuration file */
     if (!winReadConfigfile())
@@ -1050,70 +1034,3 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
     winDebug("InitOutput - Returning.\n");
 #endif
 }
-
-/*
- * winCheckDisplayNumber - Check if another instance of Cygwin/X is
- * already running on the same display number.  If no one exists,
- * make a mutex to prevent new instances from running on the same display.
- *
- * return FALSE if the display number is already used.
- */
-
-static Bool
-winCheckDisplayNumber(void)
-{
-    int nDisp;
-    HANDLE mutex;
-    char name[MAX_PATH];
-    const char *pszPrefix = '\0';
-    OSVERSIONINFO osvi = { 0 };
-
-    /* Check display range */
-    nDisp = atoi(display);
-    if (nDisp < 0 || nDisp > 65535) {
-        ErrorF("winCheckDisplayNumber - Bad display number: %d\n", nDisp);
-        return FALSE;
-    }
-
-    /* Set first character of mutex name to null */
-    name[0] = '\0';
-
-    /* Get operating system version information */
-    osvi.dwOSVersionInfoSize = sizeof(osvi);
-    GetVersionEx(&osvi);
-
-    /* Want a mutex shared among all terminals on NT > 4.0 */
-    if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion >= 5) {
-        pszPrefix = "Global\\";
-    }
-
-    /* Setup Cygwin/X specific part of name */
-    snprintf(name, sizeof(name), "%sCYGWINX_DISPLAY:%d", pszPrefix, nDisp);
-
-    /* Windows automatically releases the mutex when this process exits */
-    mutex = CreateMutex(NULL, FALSE, name);
-    if (!mutex) {
-        LPVOID lpMsgBuf;
-
-        /* Display a fancy error message */
-        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                      FORMAT_MESSAGE_FROM_SYSTEM |
-                      FORMAT_MESSAGE_IGNORE_INSERTS,
-                      NULL,
-                      GetLastError(),
-                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                      (LPTSTR) &lpMsgBuf, 0, NULL);
-        ErrorF("winCheckDisplayNumber - CreateMutex failed: %s\n",
-               (LPSTR) lpMsgBuf);
-        LocalFree(lpMsgBuf);
-
-        return FALSE;
-    }
-    if (GetLastError() == ERROR_ALREADY_EXISTS) {
-        ErrorF("winCheckDisplayNumber - "
-               PROJECT_NAME " is already running on display %d\n", nDisp);
-        return FALSE;
-    }
-
-    return TRUE;
-}
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index d68ee2a..50fdba2 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -305,10 +305,6 @@ and for \fIlevel\fP=3 detailed log
 information (including trace and debug output) is produced.  Bigger
 values will yield a still more detailed debug output.
 .TP 8
-.B \-silent-dup-error
-If another instance of \fIXWin\fP with the same display number is found running,
-exit silently and don't display any error message.
-.TP 8
 .B "\-xkblayout \fIlayout\fP"
 .TP 8
 .B "\-xkbmodel \fImodel\fP"
diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c
index 1382c89..66019b4 100644
--- a/hw/xwin/winglobals.c
+++ b/hw/xwin/winglobals.c
@@ -76,7 +76,6 @@ DWORD g_dwCurrentThreadID = 0;
 Bool g_fKeyboardHookLL = FALSE;
 Bool g_fNoHelpMessageBox = FALSE;
 Bool g_fSoftwareCursor = FALSE;
-Bool g_fSilentDupError = FALSE;
 Bool g_fNativeGl = TRUE;
 Bool g_fHostInTitle = TRUE;
 pthread_mutex_t g_pmTerminating = PTHREAD_MUTEX_INITIALIZER;
diff --git a/hw/xwin/winglobals.h b/hw/xwin/winglobals.h
index d7b813d..d143fb8 100644
--- a/hw/xwin/winglobals.h
+++ b/hw/xwin/winglobals.h
@@ -52,7 +52,6 @@ extern Bool g_fAuthEnabled;
 extern Bool g_fXdmcpEnabled;
 
 extern Bool g_fNoHelpMessageBox;
-extern Bool g_fSilentDupError;
 extern Bool g_fNativeGl;
 extern Bool g_fHostInTitle;
 
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 73aa027..2bf6560 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -1078,11 +1078,6 @@ ddxProcessArgument(int argc, char *argv[], int i)
         return 1;
     }
 
-    if (IS_OPTION("-silent-dup-error")) {
-        g_fSilentDupError = TRUE;
-        return 1;
-    }
-
     if (IS_OPTION("-wgl")) {
         g_fNativeGl = TRUE;
         return 1;
commit 24042b4e367803dd64f3fcdc1bef7b2bf36c4145
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>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 0d34ca1..262e015 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 b04767c84deafc44993723add4b1c5163fc11711
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>

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 a4ffa8721debb34bd36fd4624890d9c26886c618
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>

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 c3e4e9fc5d84bfc17b3ed63f67488ea25ba150ce
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>

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 a3e681eafa5355b8bb3b099d47983f14f0d5e197
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>

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 b05ae79ee3bebef9790c97eedc033d1ffb3ec39a
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>

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 947e94a341fa153258e9e86060b83af95934672b
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>

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 40a164b8f4e720b0d6ebf228ee175eb397ffeec2
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>

diff --git a/configure.ac b/configure.ac
index 2c70cda..dff06ef 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 2be527b1d4ce2b0412c4484539a8c9607645ec6d
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>

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 4217db89ecd480fda2ee74fecba06c6713c2a0f0
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>

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 054f80717812d4781741cd05393623fe6f6c627f
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>

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 d0c1a5bc61a3d151f2234aa3820862f16c0f00c7
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>

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 acf263df81ad6813e0233033610fb44521cab1b4
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>

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 164753f158e78f615f903467bfd234d7c58244ef
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>

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 59b9c3d5e4bf05aeaaac2ee4ea12c301a67aae2c
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>

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 ac97fb2b804809c39b12fe0032d96fb076657258
Author: Julien Cristau <jcristau at debian.org>
Date:   Mon Mar 7 23:20:27 2016 +0100

    dri3: return an error if AddResource fails
    
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>

diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c
index 2b36221..35548b6 100644
--- a/dri3/dri3_request.c
+++ b/dri3/dri3_request.c
@@ -178,8 +178,8 @@ proc_dri3_pixmap_from_buffer(ClientPtr client)
         (*drawable->pScreen->DestroyPixmap) (pixmap);
         return rc;
     }
-    if (AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap))
-        return Success;
+    if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap))
+        return BadAlloc;
 
     return Success;
 }
commit 119d5c0e2f800737c949ef760c5fe25d963200bf
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>

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 a2c3c34b44b866440a152511e682c98879ee13b7
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>

diff --git a/configure.ac b/configure.ac
index c166841..2c70cda 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 setitimer])
+	mmap posix_fallocate seteuid shmctl64 strncasecmp vasprintf vsnprintf \
+	walkcontext setitimer])
 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 940d2b7..a164c15 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -521,4 +521,7 @@
 /* Have setitimer support */
 #undef HAVE_SETITIMER
 
+/* Have posix_fallocate() */
+#undef HAVE_POSIX_FALLOCATE
+
 #endif /* _DIX_CONFIG_H_ */
commit 939ce0bae68b682b57675f65c901653c1a094ebb
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>

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 05e1bcf56e1c511a1ef539acfe11e37727e1179e
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>

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 093f9505c12565cc19bdf6e33b263f31d104c3ef
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>

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 ac4d8c7cee13947b688ebb26035f06f7744db201
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>

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 9c88cb9b059111e0531852f3fa8fa571c0306f57
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Thu Feb 25 16:37:57 2016 -0300

    kdrive/ephyr: map host X server's keymap into Xephyr, if supported
    
    Currently Xephyr doesn't inherit host X server's keymap, which
    may lead to keymap mismatches when using a non-US keyboard in a
    window inside Xephyr. This patch makes Xephyr change its keymap
    to match host X server's one (unless XKB support is disabled),
    using xcb-xkb to retrieve the needed XKB controls.
    This implementation is analogous to Xnest one at commit 83fef4235.
    
    Supersedes: https://patchwork.freedesktop.org/patch/67504
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/configure.ac b/configure.ac
index 312fc69..c166841 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2393,7 +2393,7 @@ if test "$KDRIVE" = yes; then
        AC_DEFINE(KDRIVE_MOUSE, 1, [Enable KDrive mouse driver])
     fi
 
-    XEPHYR_REQUIRED_LIBS="xau xdmcp xcb xcb-shape xcb-render xcb-renderutil xcb-aux xcb-image xcb-icccm xcb-shm xcb-keysyms xcb-randr"
+    XEPHYR_REQUIRED_LIBS="xau xdmcp xcb xcb-shape xcb-render xcb-renderutil xcb-aux xcb-image xcb-icccm xcb-shm xcb-keysyms xcb-randr xcb-xkb"
     if test "x$XV" = xyes; then
         XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xcb-xv"
     fi
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index a272882..f6897cc 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -47,7 +47,6 @@ extern Bool ephyr_glamor;
 
 KdKeyboardInfo *ephyrKbd;
 KdPointerInfo *ephyrMouse;
-EphyrKeySyms ephyrKeySyms;
 Bool ephyrNoDRI = FALSE;
 Bool ephyrNoXV = FALSE;
 
@@ -1291,16 +1290,29 @@ KdPointerDriver EphyrMouseDriver = {
 static Status
 EphyrKeyboardInit(KdKeyboardInfo * ki)
 {
+    KeySymsRec keySyms;
+    CARD8 modmap[MAP_LENGTH];
+    XkbControlsRec controls;
+
     ki->driverPrivate = (EphyrKbdPrivate *)
         calloc(sizeof(EphyrKbdPrivate), 1);
-    hostx_load_keymap();
-    if (!ephyrKeySyms.minKeyCode) {
-        ErrorF("Couldn't load keymap from host\n");
-        return BadAlloc;
+
+    if (hostx_load_keymap(&keySyms, modmap, &controls)) {
+        XkbApplyMappingChange(ki->dixdev, &keySyms,
+                              keySyms.minKeyCode,
+                              keySyms.maxKeyCode - keySyms.minKeyCode + 1,
+                              modmap, serverClient);
+        XkbDDXChangeControls(ki->dixdev, &controls, &controls);
+        free(keySyms.map);
+    }
+
+    ki->minScanCode = keySyms.minKeyCode;
+    ki->maxScanCode = keySyms.maxKeyCode;
+
+    if (ki->name != NULL) {
+        free(ki->name);
     }
-    ki->minScanCode = ephyrKeySyms.minKeyCode;
-    ki->maxScanCode = ephyrKeySyms.maxKeyCode;
-    free(ki->name);
+
     ki->name = strdup("Xephyr virtual keyboard");
     ephyrKbd = ki;
     return Success;
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index ce9faca..cdb12b0 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -52,6 +52,7 @@
 #include <xcb/shape.h>
 #include <xcb/xcb_keysyms.h>
 #include <xcb/randr.h>
+#include <xcb/xkb.h>
 #ifdef GLAMOR
 #include <epoxy/gl.h>
 #include "glamor.h"
@@ -86,8 +87,6 @@ static EphyrHostXVars HostX;
 
 static int HostXWantDamageDebug = 0;
 
-extern EphyrKeySyms ephyrKeySyms;
-
 extern Bool EphyrWantResize;
 
 char *ephyrResName = NULL;
@@ -1082,18 +1081,136 @@ hostx_paint_debug_rect(KdScreenInfo *screen,
     nanosleep(&tspec, NULL);
 }
 
-void
-hostx_load_keymap(void)
+Bool
+hostx_load_keymap(KeySymsPtr keySyms, CARD8 *modmap, XkbControlsPtr controls)
 {
     int min_keycode, max_keycode;
-
+    int map_width;
+    size_t i, j;
+    int keymap_len;
+    xcb_keysym_t *keymap;
+    xcb_keycode_t *modifier_map;
+    xcb_get_keyboard_mapping_cookie_t mapping_c;
+    xcb_get_keyboard_mapping_reply_t *mapping_r;
+    xcb_get_modifier_mapping_cookie_t modifier_c;
+    xcb_get_modifier_mapping_reply_t *modifier_r;
+    xcb_xkb_use_extension_cookie_t use_c;
+    xcb_xkb_use_extension_reply_t *use_r;
+    xcb_xkb_get_controls_cookie_t controls_c;
+    xcb_xkb_get_controls_reply_t *controls_r;
+
+    /* First of all, collect host X server's
+     * min_keycode and max_keycode, which are
+     * independent from XKB support. */
     min_keycode = xcb_get_setup(HostX.conn)->min_keycode;
     max_keycode = xcb_get_setup(HostX.conn)->max_keycode;
 
     EPHYR_DBG("min: %d, max: %d", min_keycode, max_keycode);
 
-    ephyrKeySyms.minKeyCode = min_keycode;
-    ephyrKeySyms.maxKeyCode = max_keycode;
+    keySyms->minKeyCode = min_keycode;
+    keySyms->maxKeyCode = max_keycode;
+
+    /* Check for XKB availability in host X server */
+    if (!hostx_has_extension(&xcb_xkb_id)) {
+        EPHYR_LOG_ERROR("XKB extension is not supported in host X server.");
+        return FALSE;
+    }
+
+    use_c = xcb_xkb_use_extension(HostX.conn,
+                                  XCB_XKB_MAJOR_VERSION,
+                                  XCB_XKB_MINOR_VERSION);
+    use_r = xcb_xkb_use_extension_reply(HostX.conn, use_c, NULL);
+
+    if (!use_r) {
+        EPHYR_LOG_ERROR("Couldn't use XKB extension.");
+        return FALSE;
+    } else if (!use_r->supported) {
+        EPHYR_LOG_ERROR("XKB extension is not supported in host X server.");
+        free(use_r);
+        return FALSE;
+    }
+
+    free(use_r);
+
+    /* Send all needed XCB requests at once,
+     * and process the replies as needed. */
+    mapping_c = xcb_get_keyboard_mapping(HostX.conn,
+                                         min_keycode,
+                                         max_keycode - min_keycode + 1);
+    modifier_c = xcb_get_modifier_mapping(HostX.conn);
+    controls_c = xcb_xkb_get_controls(HostX.conn,
+                                      XCB_XKB_ID_USE_CORE_KBD);
+
+    mapping_r = xcb_get_keyboard_mapping_reply(HostX.conn,
+                                               mapping_c,
+                                               NULL);
+
+    if (!mapping_r) {
+        EPHYR_LOG_ERROR("xcb_get_keyboard_mapping_reply() failed.");
+        return FALSE;
+    }
+
+    map_width = mapping_r->keysyms_per_keycode;
+    keymap = xcb_get_keyboard_mapping_keysyms(mapping_r);
+    keymap_len = xcb_get_keyboard_mapping_keysyms_length(mapping_r);
+
+    keySyms->mapWidth = map_width;
+    keySyms->map = calloc(keymap_len, sizeof(KeySym));
+
+    if (!keySyms->map) {
+        EPHYR_LOG_ERROR("Failed to allocate KeySym map.");
+        free(mapping_r);
+        return FALSE;
+    }
+
+    for (i = 0; i < keymap_len; i++) {
+        keySyms->map[i] = keymap[i];
+    }
+
+    free(mapping_r);
+
+    modifier_r = xcb_get_modifier_mapping_reply(HostX.conn,
+                                                modifier_c,
+                                                NULL);
+
+    if (!modifier_r) {
+        EPHYR_LOG_ERROR("xcb_get_modifier_mapping_reply() failed.");
+        return FALSE;
+    }
+
+    modifier_map = xcb_get_modifier_mapping_keycodes(modifier_r);
+    memset(modmap, 0, sizeof(CARD8) * MAP_LENGTH);
+
+    for (j = 0; j < 8; j++) {
+        for (i = 0; i < modifier_r->keycodes_per_modifier; i++) {
+            CARD8 keycode;
+
+            if ((keycode = modifier_map[j * modifier_r->keycodes_per_modifier + i])) {
+                modmap[keycode] |= 1 << j;
+            }
+        }
+    }
+
+    free(modifier_r);
+
+    controls_r = xcb_xkb_get_controls_reply(HostX.conn,
+                                            controls_c,
+                                            NULL);
+
+    if (!controls_r) {
+        EPHYR_LOG_ERROR("xcb_xkb_get_controls_reply() failed.");
+        return FALSE;
+    }
+
+    controls->enabled_ctrls = controls_r->enabledControls;
+
+    for (i = 0; i < XkbPerKeyBitArraySize; i++) {
+        controls->per_key_repeat[i] = controls_r->perKeyRepeat[i];
+    }
+
+    free(controls_r);
+
+    return TRUE;
 }
 
 xcb_connection_t *
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 5e642dc..96d7394 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -44,11 +44,6 @@
 typedef struct EphyrHostXVars EphyrHostXVars;
 
 typedef struct {
-    int minKeyCode;
-    int maxKeyCode;
-} EphyrKeySyms;
-
-typedef struct {
     VisualID visualid;
     int screen;
     int depth;
@@ -153,8 +148,8 @@ void
 hostx_paint_rect(KdScreenInfo *screen,
                  int sx, int sy, int dx, int dy, int width, int height);
 
-void
- hostx_load_keymap(void);
+Bool
+hostx_load_keymap(KeySymsPtr keySyms, CARD8 *modmap, XkbControlsPtr controls);
 
 xcb_connection_t *
 hostx_get_xcbconn(void);
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index ae19a9d..52be7ad 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -759,10 +759,6 @@ KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
             return BadImplementation;
         }
 
-        if ((*ki->driver->Init) (ki) != Success) {
-            return !Success;
-        }
-
         memset(&rmlvo, 0, sizeof(rmlvo));
         rmlvo.rules = ki->xkbRules;
         rmlvo.model = ki->xkbModel;
@@ -775,6 +771,10 @@ KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
             return BadImplementation;
         }
 
+        if ((*ki->driver->Init) (ki) != Success) {
+            return !Success;
+        }
+
         xiclass = AtomFromName(XI_KEYBOARD);
         AssignTypeAndName(pDevice, xiclass,
                           ki->name ? ki->name : "Generic KDrive Keyboard");
commit daa6d2d58f65b9301b1b1f3c6df07719ecb5c03d
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Feb 12 14:18:02 2016 -0200

    config/udev: distinguish between real keyboards and other key devices
    
    This patch introduces a new flag ATTR_KEY for hotplugged input devices,
    so we can better distinguish between real keyboards (i.e. devices with
    udev property ID_INPUT_KEYBOARD="1") and other key input devices like
    lid switches, power buttons, etc.
    
    All supported hotplug backends (udev, hal, and wscons) will set both
    flags ATTR_KEY and ATTR_KEYBOARD for real keyboards, but udev backend
    will set ATTR_KEY, but not ATTR_KEYBOARD, for non-keyboard key input
    devices (hal and wscons will set both flags in any case). With this
    distinction, kdrive input hotplugging mechanism will be allowed to only
    grab real keyboards, as other key input devices are currently not
    supported.
    
    In order to don't break current behaviour, this patch will replace all
    ATTR_KEYBOARD occurrences with ATTR_KEY in hw/xfree86/common/xf86Xinput.c.
    
    [ajax: Just add ATTR_KEY, don't re-number the other attributes]
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/config/hal.c b/config/hal.c
index ea574ca..c76eced 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -170,7 +170,7 @@ device_added(LibHalContext * hal_ctx, const char *udi)
     free(hal_tags);
 
     if (libhal_device_query_capability(hal_ctx, udi, "input.keys", NULL))
-        attrs.flags |= ATTR_KEYBOARD;
+        attrs.flags |= ATTR_KEY | ATTR_KEYBOARD;
     if (libhal_device_query_capability(hal_ctx, udi, "input.mouse", NULL))
         attrs.flags |= ATTR_POINTER;
     if (libhal_device_query_capability(hal_ctx, udi, "input.joystick", NULL))
diff --git a/config/udev.c b/config/udev.c
index 08a954b..1a6e82a 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -240,6 +240,10 @@ device_added(struct udev_device *udev_device)
         }
         else if (!strcmp(key, "ID_INPUT_KEY")) {
             LOG_PROPERTY(path, key, value);
+            attrs.flags |= ATTR_KEY;
+        }
+        else if (!strcmp(key, "ID_INPUT_KEYBOARD")) {
+            LOG_PROPERTY(path, key, value);
             attrs.flags |= ATTR_KEYBOARD;
         }
         else if (!strcmp(key, "ID_INPUT_MOUSE")) {
diff --git a/config/wscons.c b/config/wscons.c
index fb114bd..ee45675 100644
--- a/config/wscons.c
+++ b/config/wscons.c
@@ -163,7 +163,7 @@ wscons_add_keyboard(void)
         }
 
  kbd_config_done:
-    attrs.flags |= ATTR_KEYBOARD;
+    attrs.flags |= ATTR_KEY | ATTR_KEYBOARD;
     rc = NewInputDeviceRequest(input_options, &attrs, &dev);
     if (rc != Success)
         goto unwind;
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 836db79..ae19a9d 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -2343,7 +2343,9 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
         *pdev = ki->dixdev;
     }
     else {
-        ErrorF("unrecognised device identifier!\n");
+        ErrorF("unrecognised device identifier: %s\n",
+               input_option_get_value(input_option_find(optionsdup,
+                                                        "device")));
         input_option_free_list(&optionsdup);
         return BadValue;
     }
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index a9ce62a..4f2e6c8 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -635,7 +635,7 @@ InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
 
     /* MatchIs* booleans */
     if (iclass->is_keyboard.set &&
-        iclass->is_keyboard.val != ! !(attrs->flags & ATTR_KEYBOARD))
+        iclass->is_keyboard.val != ! !(attrs->flags & ATTR_KEY))
         return FALSE;
     if (iclass->is_pointer.set &&
         iclass->is_pointer.val != ! !(attrs->flags & ATTR_POINTER))
diff --git a/include/input.h b/include/input.h
index d8bd9c6..9662123 100644
--- a/include/input.h
+++ b/include/input.h
@@ -236,6 +236,7 @@ typedef struct _InputAttributes {
 #define ATTR_TABLET (1<<3)
 #define ATTR_TOUCHPAD (1<<4)
 #define ATTR_TOUCHSCREEN (1<<5)
+#define ATTR_KEY (1<<6)
 
 /* Key/Button has been run through all input processing and events sent to clients. */
 #define KEY_PROCESSED 1
commit 851ff9ec04b73412c7dbad7b4911a1feac21f354
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Feb 12 14:18:01 2016 -0200

    ephyr: enable option -sw-cursor by default in multi-seat mode
    
    Option -seat passed to Xephyr requires -sw-cursor to be passed as well,
    otherwise the mouse cursor will remain invisible for the given seat.
    This patch takes care of enabling -sw-cursor if -seat is passed.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 849a4e1..149ea98 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -373,6 +373,9 @@ OsVendorInit(void)
 {
     EPHYR_DBG("mark");
 
+    if (SeatId)
+        hostx_use_sw_cursor();
+
     if (hostx_want_host_cursor())
         ephyrFuncs.initCursor = &ephyrCursorInit;
 
commit 40e32e9fc9f3a1bd8287ee03dd399d8161cb98dd
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Feb 12 14:18:00 2016 -0200

    kdrive: add options to set default XKB properties
    
    This patch introduces convenient command-line options -xkb-rules,
    -xkb-model, -xkb-layout, -xkb-variant, and -xkb-options, to set default
    values for these properties.
    
    These options can be handful for cases in which compile-time default
    values don't match user locale, since kdrive doesn't support InputClass
    matching rules yet and not all Linux distros provide default rules to
    store these values in udev properties (which by the way is a discouraged
    practice).
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index 269b609..52bea5a 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -89,6 +89,11 @@ char *kdSwitchCmd;
 DDXPointRec kdOrigin;
 Bool kdHasPointer = FALSE;
 Bool kdHasKbd = FALSE;
+const char *kdGlobalXkbRules = NULL;
+const char *kdGlobalXkbModel = NULL;
+const char *kdGlobalXkbLayout = NULL;
+const char *kdGlobalXkbVariant = NULL;
+const char *kdGlobalXkbOptions = NULL;
 
 static Bool kdCaughtSignal = FALSE;
 
@@ -455,6 +460,11 @@ KdUseMsg(void)
         ("-mouse driver [,n,,options]    Specify the pointer driver and its options (n is the number of buttons)\n");
     ErrorF
         ("-keybd driver [,,options]      Specify the keyboard driver and its options\n");
+    ErrorF("-xkb-rules       Set default XkbRules value (can be overriden by -keybd options)\n");
+    ErrorF("-xkb-model       Set default XkbModel value (can be overriden by -keybd options)\n");
+    ErrorF("-xkb-layout      Set default XkbLayout value (can be overriden by -keybd options)\n");
+    ErrorF("-xkb-variant     Set default XkbVariant value (can be overriden by -keybd options)\n");
+    ErrorF("-xkb-options     Set default XkbOptions value (can be overriden by -keybd options)\n");
     ErrorF("-zaphod          Disable cursor screen switching\n");
     ErrorF("-2button         Emulate 3 button mouse\n");
     ErrorF("-3button         Disable 3 button mouse emulation\n");
@@ -563,6 +573,46 @@ KdProcessArgument(int argc, char **argv, int i)
         sscanf(argv[i], "vt%2d", &kdVirtualTerminal) == 1) {
         return 1;
     }
+    if (!strcmp(argv[i], "-xkb-rules")) {
+        if (i + 1 >= argc) {
+            UseMsg();
+            FatalError("Missing argument for option -xkb-rules.\n");
+        }
+        kdGlobalXkbRules = argv[i + 1];
+        return 2;
+    }
+    if (!strcmp(argv[i], "-xkb-model")) {
+        if (i + 1 >= argc) {
+            UseMsg();
+            FatalError("Missing argument for option -xkb-model.\n");
+        }
+        kdGlobalXkbModel = argv[i + 1];
+        return 2;
+    }
+    if (!strcmp(argv[i], "-xkb-layout")) {
+        if (i + 1 >= argc) {
+            UseMsg();
+            FatalError("Missing argument for option -xkb-layout.\n");
+        }
+        kdGlobalXkbLayout = argv[i + 1];
+        return 2;
+    }
+    if (!strcmp(argv[i], "-xkb-variant")) {
+        if (i + 1 >= argc) {
+            UseMsg();
+            FatalError("Missing argument for option -xkb-variant.\n");
+        }
+        kdGlobalXkbVariant = argv[i + 1];
+        return 2;
+    }
+    if (!strcmp(argv[i], "-xkb-options")) {
+        if (i + 1 >= argc) {
+            UseMsg();
+            FatalError("Missing argument for option -xkb-options.\n");
+        }
+        kdGlobalXkbOptions = argv[i + 1];
+        return 2;
+    }
     if (!strcmp(argv[i], "-mouse") || !strcmp(argv[i], "-pointer")) {
         if (i + 1 >= argc)
             UseMsg();
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index fd6a952..836db79 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -102,6 +102,12 @@ static int kdNumInputFds;
 
 extern Bool kdRawPointerCoordinates;
 
+extern const char *kdGlobalXkbRules;
+extern const char *kdGlobalXkbModel;
+extern const char *kdGlobalXkbLayout;
+extern const char *kdGlobalXkbVariant;
+extern const char *kdGlobalXkbOptions;
+
 static void
 KdSigio(int sig)
 {
@@ -909,11 +915,11 @@ KdNewKeyboard(void)
     ki->options = NULL;
     ki->name = strdup("Generic Keyboard");
     ki->path = NULL;
-    ki->xkbRules = strdup(XKB_DFLT_RULES);
-    ki->xkbModel = strdup(XKB_DFLT_MODEL);
-    ki->xkbLayout = strdup(XKB_DFLT_LAYOUT);
-    ki->xkbVariant = strdup(XKB_DFLT_VARIANT);
-    ki->xkbOptions = strdup(XKB_DFLT_OPTIONS);
+    ki->xkbRules = strdup(kdGlobalXkbRules ? kdGlobalXkbRules : XKB_DFLT_RULES);
+    ki->xkbModel = strdup(kdGlobalXkbModel ? kdGlobalXkbModel : XKB_DFLT_MODEL);
+    ki->xkbLayout = strdup(kdGlobalXkbLayout ? kdGlobalXkbLayout : XKB_DFLT_LAYOUT);
+    ki->xkbVariant = strdup(kdGlobalXkbVariant ? kdGlobalXkbVariant :XKB_DFLT_VARIANT);
+    ki->xkbOptions = strdup(kdGlobalXkbOptions ? kdGlobalXkbOptions : XKB_DFLT_OPTIONS);
 
     return ki;
 }
commit 0cf3d72be6bd99cd2c66b7885339322c7e5bf73d
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Feb 12 14:17:59 2016 -0200

    kdrive: introduce input hot-plugging support for udev and hal backends (#33140)
    
    This patch introduces input hot-plugging support for kdrive-based
    applications in multi-seat context. This feature is enabled by passing
    -seat option with desired seat name. All keyboard/mouse devices assigned
    to that seat will be automatically grabbed by kdrive.
    
    It supports udev and hal backends for input hot-plugging support.
    Another patches may be required for wscons backend.
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=33140
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/hw/kdrive/src/Makefile.am b/hw/kdrive/src/Makefile.am
index d69f0dd..b7f94b0 100644
--- a/hw/kdrive/src/Makefile.am
+++ b/hw/kdrive/src/Makefile.am
@@ -23,3 +23,11 @@ libkdrive_la_SOURCES =	\
 	kshadow.c	\
 	$(KDRIVE_XV_SOURCES) \
         $(top_srcdir)/mi/miinitext.c
+
+if CONFIG_UDEV
+libkdrive_la_LIBADD = $(top_builddir)/config/libconfig.la
+else
+if CONFIG_HAL
+libkdrive_la_LIBADD = $(top_builddir)/config/libconfig.la
+endif
+endif
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index 582ff66..269b609 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -45,6 +45,14 @@
 
 #include <signal.h>
 
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+#include <hotplug.h>
+#endif
+
+/* This stub can be safely removed once we can
+ * split input and GPU parts in hotplug.h et al. */
+#include <systemd-logind.h>
+
 typedef struct _kdDepths {
     CARD8 depth;
     CARD8 bpp;
@@ -1125,6 +1133,11 @@ KdInitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
             KdAddScreen(pScreenInfo, screen, argc, argv);
 
     OsRegisterSigWrapper(KdSignalWrapper);
+
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+    if (SeatId) /* Enable input hot-plugging */
+        config_pre_init();
+#endif
 }
 
 void
@@ -1143,3 +1156,36 @@ DPMSSupported(void)
 {
     return FALSE;
 }
+
+/* These stubs can be safely removed once we can
+ * split input and GPU parts in hotplug.h et al. */
+#ifdef CONFIG_UDEV_KMS
+void
+NewGPUDeviceRequest(struct OdevAttributes *attribs)
+{
+}
+
+void
+DeleteGPUDeviceRequest(struct OdevAttributes *attribs)
+{
+}
+#endif
+
+struct xf86_platform_device *
+xf86_find_platform_device_by_devnum(int major, int minor)
+{
+    return NULL;
+}
+
+#ifdef SYSTEMD_LOGIND
+void
+systemd_logind_vtenter(void)
+{
+}
+
+void
+systemd_logind_release_fd(int major, int minor, int fd)
+{
+    close(fd);
+}
+#endif
diff --git a/hw/kdrive/src/kinfo.c b/hw/kdrive/src/kinfo.c
index 01ae1e4..f91d575 100644
--- a/hw/kdrive/src/kinfo.c
+++ b/hw/kdrive/src/kinfo.c
@@ -134,6 +134,7 @@ KdFreePointer(KdPointerInfo * pi)
     free(pi->name);
     free(pi->path);
     input_option_free_list(&pi->options);
+    pi->next = NULL;
     free(pi);
 }
 
@@ -145,6 +146,9 @@ KdFreeKeyboard(KdKeyboardInfo * ki)
     free(ki->xkbRules);
     free(ki->xkbModel);
     free(ki->xkbLayout);
+    free(ki->xkbVariant);
+    free(ki->xkbOptions);
+    input_option_free_list(&ki->options);
     ki->next = NULL;
     free(ki);
 }
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 3a1c6a0..fd6a952 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -51,6 +51,10 @@
 #include "inpututils.h"
 #include "optionstr.h"
 
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+#include <hotplug.h>
+#endif
+
 #ifdef KDRIVE_EVDEV
 #define DEV_INPUT_EVENT_PREFIX "/dev/input/event"
 #define DEV_INPUT_EVENT_PREFIX_LEN (sizeof(DEV_INPUT_EVENT_PREFIX) - 1)
@@ -407,7 +411,8 @@ KdPointerProc(DeviceIntPtr pDevice, int onoff)
 #endif
         if (!pi->driver) {
             if (!pi->driverPrivate) {
-                ErrorF("no driver specified for %s\n", pi->name);
+                ErrorF("no driver specified for pointer device \"%s\" (%s)\n",
+                       pi->name ? pi->name : "(unnamed)", pi->path);
                 return BadImplementation;
             }
 
@@ -727,7 +732,8 @@ KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
 #endif
         if (!ki->driver) {
             if (!ki->driverPrivate) {
-                ErrorF("no driver specified!\n");
+                ErrorF("no driver specified for keyboard device \"%s\" (%s)\n",
+                       ki->name ? ki->name : "(unnamed)", ki->path);
                 return BadImplementation;
             }
 
@@ -901,6 +907,8 @@ KdNewKeyboard(void)
     ki->bellDuration = 200;
     ki->next = NULL;
     ki->options = NULL;
+    ki->name = strdup("Generic Keyboard");
+    ki->path = NULL;
     ki->xkbRules = strdup(XKB_DFLT_RULES);
     ki->xkbModel = strdup(XKB_DFLT_MODEL);
     ki->xkbLayout = strdup(XKB_DFLT_LAYOUT);
@@ -1084,18 +1092,52 @@ KdParseKbdOptions(KdKeyboardInfo * ki)
         const char *key = input_option_get_key(option);
         const char *value = input_option_get_value(option);
 
-        if (strcasecmp(key, "XkbRules") == 0)
+        if (
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+            strcasecmp(key, "xkb_rules") == 0 ||
+#endif
+            strcasecmp(key, "XkbRules") == 0)
             ki->xkbRules = strdup(value);
-        else if (strcasecmp(key, "XkbModel") == 0)
+        else if (
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+                 strcasecmp(key, "xkb_model") == 0 ||
+#endif
+                 strcasecmp(key, "XkbModel") == 0)
             ki->xkbModel = strdup(value);
-        else if (strcasecmp(key, "XkbLayout") == 0)
+        else if (
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+                 strcasecmp(key, "xkb_layout") == 0 ||
+#endif
+                 strcasecmp(key, "XkbLayout") == 0)
             ki->xkbLayout = strdup(value);
-        else if (strcasecmp(key, "XkbVariant") == 0)
+        else if (
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+                 strcasecmp(key, "xkb_variant") == 0 ||
+#endif
+                 strcasecmp(key, "XkbVariant") == 0)
             ki->xkbVariant = strdup(value);
-        else if (strcasecmp(key, "XkbOptions") == 0)
+        else if (
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+                 strcasecmp(key, "xkb_options") == 0 ||
+#endif
+                 strcasecmp(key, "XkbOptions") == 0)
             ki->xkbOptions = strdup(value);
-        else if (!strcasecmp(key, "device"))
+        else if (!strcasecmp(key, "device")) {
+            if (ki->path != NULL)
+                free(ki->path);
             ki->path = strdup(value);
+        }
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+        else if (!strcasecmp(key, "path")) {
+            if (ki->path != NULL)
+                free(ki->path);
+            ki->path = strdup(value);
+        }
+        else if (!strcasecmp(key, "name")) {
+            free(ki->name);
+            ki->name = strdup(value);
+        }
+#endif
         else if (!strcasecmp(key, "driver"))
             ki->driver = KdFindKeyboardDriver(value);
         else
@@ -1196,8 +1238,22 @@ KdParsePointerOptions(KdPointerInfo * pi)
             pi->transformCoordinates = TRUE;
         else if (!strcasecmp(key, "rawcoord"))
             pi->transformCoordinates = FALSE;
-        else if (!strcasecmp(key, "device"))
+        else if (!strcasecmp(key, "device")) {
+            if (pi->path != NULL)
+                free(pi->path);
+            pi->path = strdup(value);
+        }
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+        else if (!strcasecmp(key, "path")) {
+            if (pi->path != NULL)
+                free(pi->path);
             pi->path = strdup(value);
+        }
+        else if (!strcasecmp(key, "name")) {
+            free(pi->name);
+            pi->name = strdup(value);
+        }
+#endif
         else if (!strcasecmp(key, "protocol"))
             pi->protocol = strdup(value);
         else if (!strcasecmp(key, "driver"))
@@ -1320,11 +1376,21 @@ KdInitInput(void)
     }
 
     mieqInit();
+
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+    if (SeatId) /* Enable input hot-plugging */
+        config_init();
+#endif
 }
 
 void
 KdCloseInput(void)
 {
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
+    if (SeatId) /* Input hot-plugging is enabled */
+        config_fini();
+#endif
+
     mieqFini();
 }
 
@@ -2141,24 +2207,29 @@ int
 NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
                       DeviceIntPtr *pdev)
 {
-    InputOption *option = NULL;
+    InputOption *option = NULL, *optionsdup = NULL;
     KdPointerInfo *pi = NULL;
     KdKeyboardInfo *ki = NULL;
 
     nt_list_for_each_entry(option, options, list.next) {
         const char *key = input_option_get_key(option);
         const char *value = input_option_get_value(option);
+        optionsdup = input_option_new(optionsdup, key, value);
 
         if (strcmp(key, "type") == 0) {
             if (strcmp(value, "pointer") == 0) {
                 pi = KdNewPointer();
-                if (!pi)
+                if (!pi) {
+                    input_option_free_list(&optionsdup);
                     return BadAlloc;
+                }
             }
             else if (strcmp(value, "keyboard") == 0) {
                 ki = KdNewKeyboard();
-                if (!ki)
+                if (!ki) {
+                    input_option_free_list(&optionsdup);
                     return BadAlloc;
+                }
             }
             else {
                 ErrorF("unrecognised device type!\n");
@@ -2168,25 +2239,66 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
 #ifdef CONFIG_HAL
         else if (strcmp(key, "_source") == 0 &&
                  strcmp(value, "server/hal") == 0) {
-            ErrorF("Ignoring device from HAL.\n");
-            return BadValue;
+            if (SeatId) {
+                /* Input hot-plugging is enabled */
+                if (attrs->flags & ATTR_POINTER) {
+                    pi = KdNewPointer();
+                    if (!pi) {
+                        input_option_free_list(&optionsdup);
+                        return BadAlloc;
+                    }
+                }
+                else if (attrs->flags & ATTR_KEYBOARD) {
+                    ki = KdNewKeyboard();
+                    if (!ki) {
+                        input_option_free_list(&optionsdup);
+                        return BadAlloc;
+                    }
+                }
+            }
+            else {
+                ErrorF("Ignoring device from HAL.\n");
+                input_option_free_list(&optionsdup);
+                return BadValue;
+            }
         }
 #endif
 #ifdef CONFIG_UDEV
         else if (strcmp(key, "_source") == 0 &&
                  strcmp(value, "server/udev") == 0) {
-            ErrorF("Ignoring device from udev.\n");
-            return BadValue;
+            if (SeatId) {
+                /* Input hot-plugging is enabled */
+                if (attrs->flags & ATTR_POINTER) {
+                    pi = KdNewPointer();
+                    if (!pi) {
+                        input_option_free_list(&optionsdup);
+                        return BadAlloc;
+                    }
+                }
+                else if (attrs->flags & ATTR_KEYBOARD) {
+                    ki = KdNewKeyboard();
+                    if (!ki) {
+                        input_option_free_list(&optionsdup);
+                        return BadAlloc;
+                    }
+                }
+            }
+            else {
+                ErrorF("Ignoring device from udev.\n");
+                input_option_free_list(&optionsdup);
+                return BadValue;
+            }
         }
 #endif
     }
 
     if (pi) {
-        pi->options = options;
+        pi->options = optionsdup;
         KdParsePointerOptions(pi);
 
         if (!pi->driver) {
-            ErrorF("couldn't find driver!\n");
+            ErrorF("couldn't find driver for pointer device \"%s\" (%s)\n",
+                   pi->name ? pi->name : "(unnamed)", pi->path);
             KdFreePointer(pi);
             return BadValue;
         }
@@ -2194,18 +2306,21 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
         if (KdAddPointer(pi) != Success ||
             ActivateDevice(pi->dixdev, TRUE) != Success ||
             EnableDevice(pi->dixdev, TRUE) != TRUE) {
-            ErrorF("couldn't add or enable pointer\n");
+            ErrorF("couldn't add or enable pointer \"%s\" (%s)\n",
+                   pi->name ? pi->name : "(unnamed)", pi->path);
+            KdFreePointer(pi);
             return BadImplementation;
         }
 
         *pdev = pi->dixdev;
     }
     else if (ki) {
-        ki->options = options;
+        ki->options = optionsdup;
         KdParseKbdOptions(ki);
 
         if (!ki->driver) {
-            ErrorF("couldn't find driver!\n");
+            ErrorF("couldn't find driver for keyboard device \"%s\" (%s)\n",
+                   ki->name ? ki->name : "(unnamed)", ki->path);
             KdFreeKeyboard(ki);
             return BadValue;
         }
@@ -2213,7 +2328,9 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
         if (KdAddKeyboard(ki) != Success ||
             ActivateDevice(ki->dixdev, TRUE) != Success ||
             EnableDevice(ki->dixdev, TRUE) != TRUE) {
-            ErrorF("couldn't add or enable keyboard\n");
+            ErrorF("couldn't add or enable keyboard \"%s\" (%s)\n",
+                   ki->name ? ki->name : "(unnamed)", ki->path);
+            KdFreeKeyboard(ki);
             return BadImplementation;
         }
 
@@ -2221,6 +2338,7 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
     }
     else {
         ErrorF("unrecognised device identifier!\n");
+        input_option_free_list(&optionsdup);
         return BadValue;
     }
 
commit 2116f03be04240e961649ca750a7aa5438b8446c
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>

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 1bee4e254ca0305cb23e574b4c8b250d276ee998
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>

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 4611e902c291b8a789f374cff3300f74645bc2b2
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>

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 72328e5eb98a3f27e1f0a0e17beae6db447bd87c
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>

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 43eb5b6047c9b35c337e553ec054f08bdc835abb
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>

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 6070a749d953951bacbfb149c5c36451293aad35
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>

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 c97f57d..151e044 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)
 {
@@ -712,6 +717,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 b430f53bb753f9b064ab62d014820c1c3c76a841
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>

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 48fccde2bfb60efdbf45a96fa53bcd9a6570bf89
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>

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 f175cf45aebcdda53f3ae49c0eaf27da1f194e92
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>

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 f2b8e8a..4830fb3 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 17097e083b2392c8989474f6e0da8cc234329e9c
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>

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 ddfb8c009ac651209eb0087aaf86b54e1446e8b2
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>

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 e29a64de662112b8ebcd3f20c89df0e8c51890ef
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>

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 b7962ade5265a21ac7c60da6cc07ece15ef7e648
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>

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 12f714fd95dc9d912c0bf2524005a73ec6e8ee4f
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>

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 f6f7e21133c13c34f306a191137d566e83b40929
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>

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 6e898ef080df93e885ead9d6fee8854b34e0216f
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>

diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index 2eefeaf..f2b8e8a 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 341f3bccafde71754a9ed2303df9908e509c6d31
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>

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 d8882954570aba656d5a7be7d357feaba21cb099
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>

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 bc3634010c096dffd1935c0c6cf8ba37534ae3d8
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>

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 9fecc4cd571641f8920f25473ce5abb3fdca8b40
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Tue Jan 12 16:18:35 2016 +0000

    xwin: Remove unhelpful debug about WM message queue size
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index b8577c8..97b893f 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -109,7 +109,6 @@ typedef struct _WMMsgQueueRec {
     struct _WMMsgNodeRec *pTail;
     pthread_mutex_t pmMutex;
     pthread_cond_t pcNotEmpty;
-    int nQueueSize;
 } WMMsgQueueRec, *WMMsgQueuePtr;
 
 typedef struct _WMInfo {
@@ -289,9 +288,6 @@ PushMessage(WMMsgQueuePtr pQueue, WMMsgNodePtr pNode)
         pQueue->pHead = pNode;
     }
 
-    /* Increase the count of elements in the queue by one */
-    ++(pQueue->nQueueSize);
-
     /* Release the queue mutex */
     pthread_mutex_unlock(&pQueue->pmMutex);
 
@@ -299,25 +295,6 @@ PushMessage(WMMsgQueuePtr pQueue, WMMsgNodePtr pNode)
     pthread_cond_signal(&pQueue->pcNotEmpty);
 }
 
-#if CYGMULTIWINDOW_DEBUG
-/*
- * QueueSize - Return the size of the queue
- */
-
-static int
-QueueSize(WMMsgQueuePtr pQueue)
-{
-    WMMsgNodePtr pNode;
-    int nSize = 0;
-
-    /* Loop through all elements in the queue */
-    for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext)
-        ++nSize;
-
-    return nSize;
-}
-#endif
-
 /*
  * PopMessage - Pop a message from the queue
  */
@@ -344,13 +321,6 @@ PopMessage(WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo)
         pQueue->pTail = NULL;
     }
 
-    /* Drop the number of elements in the queue by one */
-    --(pQueue->nQueueSize);
-
-#if CYGMULTIWINDOW_DEBUG
-    ErrorF("Queue Size %d %d\n", pQueue->nQueueSize, QueueSize(pQueue));
-#endif
-
     /* Release the queue mutex */
     pthread_mutex_unlock(&pQueue->pmMutex);
 
@@ -394,14 +364,6 @@ InitQueue(WMMsgQueuePtr pQueue)
     pQueue->pHead = NULL;
     pQueue->pTail = NULL;
 
-    /* There are no elements initially */
-    pQueue->nQueueSize = 0;
-
-#if CYGMULTIWINDOW_DEBUG
-    winDebug("InitQueue - Queue Size %d %d\n", pQueue->nQueueSize,
-             QueueSize(pQueue));
-#endif
-
     winDebug("InitQueue - Calling pthread_mutex_init\n");
 
     /* Create synchronization objects */
commit f7d1e5acdf5ed4ab4ed5c18727aa6f3d379ef560
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>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 0fdaf5d..b8577c8 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -1765,7 +1765,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 e7f87f8f76e5ac9479a71e3daf2cfdefd4b5f684
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>

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 856a28f63739bffe32f5a8156fd2680e5c5259a1
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Thu Jul 2 13:32:40 2015 +0100

    xwin: Factor out MessageName() debug helper
    
    Factor out the MessageName() debug helper for message id -> text, and
    use it on message queue and dequeue.
    
    Reorder in numerical order to match winwindow.h
    
    Add missing WM_WM_ICON_EVENT
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index c010134..0fdaf5d 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -210,6 +210,64 @@ static Bool redirectError = FALSE;
 static Bool g_fAnotherWMRunning = FALSE;
 
 /*
+ * Translate msg id to text, for debug purposes
+ */
+
+static const char *
+MessageName(winWMMessagePtr msg)
+{
+  switch (msg->msg)
+    {
+    case WM_WM_MOVE:
+      return "WM_WM_MOVE";
+      break;
+    case WM_WM_SIZE:
+      return "WM_WM_SIZE";
+      break;
+    case WM_WM_RAISE:
+      return "WM_WM_RAISE";
+      break;
+    case WM_WM_LOWER:
+      return "WM_WM_LOWER";
+      break;
+    case WM_WM_UNMAP:
+      return "WM_WM_UNMAP";
+      break;
+    case WM_WM_KILL:
+      return "WM_WM_KILL";
+      break;
+    case WM_WM_ACTIVATE:
+      return "WM_WM_ACTIVATE";
+      break;
+    case WM_WM_NAME_EVENT:
+      return "WM_WM_NAME_EVENT";
+      break;
+    case WM_WM_ICON_EVENT:
+      return "WM_WM_ICON_EVENT";
+      break;
+    case WM_WM_CHANGE_STATE:
+      return "WM_WM_CHANGE_STATE";
+      break;
+    case WM_WM_MAP:
+      return "WM_WM_MAP";
+      break;
+    case WM_WM_MAP2:
+      return "WM_WM_MAP2";
+      break;
+    case WM_WM_MAP3:
+      return "WM_WM_MAP3";
+      break;
+    case WM_WM_HINTS_EVENT:
+      return "WM_WM_HINTS_EVENT";
+      break;
+    default:
+      return "Unknown Message";
+      break;
+    }
+}
+
+
+/*
  * PushMessage - Push a message onto the queue
  */
 
@@ -231,44 +289,6 @@ PushMessage(WMMsgQueuePtr pQueue, WMMsgNodePtr pNode)
         pQueue->pHead = pNode;
     }
 
-#if 0
-    switch (pNode->msg.msg) {
-    case WM_WM_MOVE:
-        ErrorF("\tWM_WM_MOVE\n");
-        break;
-    case WM_WM_SIZE:
-        ErrorF("\tWM_WM_SIZE\n");
-        break;
-    case WM_WM_RAISE:
-        ErrorF("\tWM_WM_RAISE\n");
-        break;
-    case WM_WM_LOWER:
-        ErrorF("\tWM_WM_LOWER\n");
-        break;
-    case WM_WM_MAP:
-        ErrorF("\tWM_WM_MAP\n");
-        break;
-    case WM_WM_MAP2:
-        ErrorF("\tWM_WM_MAP2\n");
-        break;
-    case WM_WM_MAP3:
-        ErrorF("\tWM_WM_MAP3\n");
-        break;
-    case WM_WM_UNMAP:
-        ErrorF("\tWM_WM_UNMAP\n");
-        break;
-    case WM_WM_KILL:
-        ErrorF("\tWM_WM_KILL\n");
-        break;
-    case WM_WM_ACTIVATE:
-        ErrorF("\tWM_WM_ACTIVATE\n");
-        break;
-    default:
-        ErrorF("\tUnknown Message.\n");
-        break;
-    }
-#endif
-
     /* Increase the count of elements in the queue by one */
     ++(pQueue->nQueueSize);
 
@@ -772,26 +792,21 @@ winMultiWindowWMProc(void *pArg)
         }
 
 #if CYGMULTIWINDOW_DEBUG
-        ErrorF("winMultiWindowWMProc - MSG: %d ID: %d\n",
-               (int) pNode->msg.msg, (int) pNode->msg.dwID);
+        ErrorF("winMultiWindowWMProc - MSG: %s (%d) ID: %d\n",
+               MessageName(&(pNode->msg)), (int)pNode->msg.msg, (int)pNode->msg.dwID);
 #endif
 
         /* Branch on the message type */
         switch (pNode->msg.msg) {
 #if 0
         case WM_WM_MOVE:
-            ErrorF("\tWM_WM_MOVE\n");
             break;
 
         case WM_WM_SIZE:
-            ErrorF("\tWM_WM_SIZE\n");
             break;
 #endif
 
         case WM_WM_RAISE:
-#if CYGMULTIWINDOW_DEBUG
-            ErrorF("\tWM_WM_RAISE\n");
-#endif
             /* Raise the window */
             XRaiseWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
 #if 0
@@ -800,18 +815,11 @@ winMultiWindowWMProc(void *pArg)
             break;
 
         case WM_WM_LOWER:
-#if CYGMULTIWINDOW_DEBUG
-            ErrorF("\tWM_WM_LOWER\n");
-#endif
-
             /* Lower the window */
             XLowerWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
             break;
 
         case WM_WM_MAP:
-#if CYGMULTIWINDOW_DEBUG
-            ErrorF("\tWM_WM_MAP\n");
-#endif
             /* Put a note as to the HWND associated with this Window */
             XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER,
                             32,
@@ -822,9 +830,6 @@ winMultiWindowWMProc(void *pArg)
             break;
 
         case WM_WM_MAP2:
-#if CYGMULTIWINDOW_DEBUG
-            ErrorF("\tWM_WM_MAP2\n");
-#endif
             XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER,
                             32,
                             PropModeReplace,
@@ -832,9 +837,6 @@ winMultiWindowWMProc(void *pArg)
             break;
 
         case WM_WM_MAP3:
-#if CYGMULTIWINDOW_DEBUG
-            ErrorF("\tWM_WM_MAP3\n");
-#endif
             /* Put a note as to the HWND associated with this Window */
             XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER,
                             32,
@@ -858,18 +860,12 @@ winMultiWindowWMProc(void *pArg)
             break;
 
         case WM_WM_UNMAP:
-#if CYGMULTIWINDOW_DEBUG
-            ErrorF("\tWM_WM_UNMAP\n");
-#endif
 
             /* Unmap the window */
             XUnmapWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
             break;
 
         case WM_WM_KILL:
-#if CYGMULTIWINDOW_DEBUG
-            ErrorF("\tWM_WM_KILL\n");
-#endif
             {
                 /* --- */
                 if (IsWmProtocolAvailable(pWMInfo->pDisplay,
@@ -884,9 +880,6 @@ winMultiWindowWMProc(void *pArg)
             break;
 
         case WM_WM_ACTIVATE:
-#if CYGMULTIWINDOW_DEBUG
-            ErrorF("\tWM_WM_ACTIVATE\n");
-#endif
             /* Set the input focus */
 
             /*
@@ -1512,7 +1505,7 @@ winSendMessageToWM(void *pWMInfo, winWMMessagePtr pMsg)
     WMMsgNodePtr pNode;
 
 #if CYGMULTIWINDOW_DEBUG
-    ErrorF("winSendMessageToWM ()\n");
+    ErrorF("winSendMessageToWM %s\n", MessageName(pMsg));
 #endif
 
     pNode = malloc(sizeof(WMMsgNodeRec));
commit 8c2006ddc5abbd4ac374dabf1cfdd3df8fc88779
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>

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 8c97a0078e7fe22e6159fa53490dfca2f4d267a9
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>

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 a4d8a64c4ba467964476c4a1486da698bd6aed9e
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>

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 008efebda801b9b80e2ab3f2c95aeef8c82102ee
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>

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 de7f1fd6f8f10f07b366ae5428a8c65a224bda98
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>

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 a9e73131b6453e0fa2da5360e84af7a2eae3b205
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>

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 d7cef6fbe23381b31c163468f349feee2f1b1eba
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>

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 f75404be3ad94c8da493688397712c65ea66cb90
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>

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 9dc32746f2cd161b512cce8f39c95287bdf1a3a3
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Tue Nov 10 10:27:07 2015 +0000

    xwin: Fix format warnings when ./configured --enable-debug --enable-windowswm
    
    Fix format warnings (mainly pointer format fixes) which show up when
    ./configured --enable-debug --enable-windowswm
    
    Signed-off-by: Jon Turney <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 660a78f..8fe6f42 100644
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -541,7 +541,7 @@ winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
 
     if (pRLNextWinPriv == NULL) {
 #if CYGMULTIWINDOW_DEBUG
-        winDebug("Win %08x is top\n", pRLWinPriv);
+        winDebug("Win %p is top\n", pRLWinPriv);
 #endif
         pScreenPriv->widTop = wid;
         SetWindowPos(pRLWinPriv->hWnd, HWND_TOP,
@@ -550,7 +550,7 @@ winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
     else if (winIsInternalWMRunning(pScreenInfo)) {
         /* using mulwinidow wm */
 #if CYGMULTIWINDOW_DEBUG
-        winDebug("Win %08x is not top\n", pRLWinPriv);
+        winDebug("Win %p is not top\n", pRLWinPriv);
 #endif
         for (hWnd = GetNextWindow(pRLWinPriv->hWnd, GW_HWNDPREV);
              fNeedRestack && hWnd != NULL;
@@ -563,7 +563,7 @@ winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
                     /* Enable interleave X window and Windows window */
                     if (!fFirst) {
 #if CYGMULTIWINDOW_DEBUG
-                        winDebug("raise: Insert after Win %08x\n",
+                        winDebug("raise: Insert after Win %p\n",
                                  pRLNextWinPriv);
 #endif
                         SetWindowPos(pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
@@ -592,7 +592,7 @@ winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
                 && GetProp(hWnd, WIN_WINDOW_PROP)) {
                 if (hWnd == pRLNextWinPriv->hWnd) {
 #if CYGMULTIWINDOW_DEBUG
-                    winDebug("lower: Insert after Win %08x\n", pRLNextWinPriv);
+                    winDebug("lower: Insert after Win %p\n", pRLNextWinPriv);
 #endif
                     SetWindowPos(pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
                                  0, 0, 0, 0,
diff --git a/hw/xwin/winwin32rootlesswindow.c b/hw/xwin/winwin32rootlesswindow.c
index 1faa531..ba4fb51 100644
--- a/hw/xwin/winwin32rootlesswindow.c
+++ b/hw/xwin/winwin32rootlesswindow.c
@@ -402,7 +402,7 @@ winMWExtWMRestackWindows(ScreenPtr pScreen)
 
 #if CYGMULTIWINDOW_DEBUG
                 winDebug
-                    ("winMWExtWMRestackWindows - DeferWindowPos (%08x, %08x)\n",
+                    ("winMWExtWMRestackWindows - DeferWindowPos (%p, %p)\n",
                      pRLWin->hWnd, pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP);
 #endif
                 hWinPosInfo = DeferWindowPos(hWinPosInfo, pRLWin->hWnd,
diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c
index 79d9591..47de608 100644
--- a/hw/xwin/winwin32rootlesswndproc.c
+++ b/hw/xwin/winwin32rootlesswndproc.c
@@ -417,12 +417,12 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam,
                              lParam);
 
-        winDebug("\thWnd %08X\n", hwnd);
-        winDebug("\tpScreenPriv %08X\n", pScreenPriv);
-        winDebug("\tpScreenInfo %08X\n", pScreenInfo);
-        winDebug("\thwndScreen %08X\n", hwndScreen);
-        winDebug("winMWExtWMWindowProc (%08x) %08x %08x %08x\n",
-                 pRLWinPriv, message, wParam, lParam);
+        winDebug("\thWnd %p\n", hwnd);
+        winDebug("\tpScreenPriv %p\n", pScreenPriv);
+        winDebug("\tpScreenInfo %p\n", pScreenInfo);
+        winDebug("\thwndScreen %p\n", hwndScreen);
+        winDebug("winMWExtWMWindowProc (%p) %08x %08x %08x\n",
+                 pRLWinPriv, message, (int)wParam, (int)lParam);
 #endif
     }
     /* Branch on message type */
diff --git a/hw/xwin/winwindowswm.c b/hw/xwin/winwindowswm.c
index db41d6b..b9399fa 100644
--- a/hw/xwin/winwindowswm.c
+++ b/hw/xwin/winwindowswm.c
@@ -312,7 +312,7 @@ ProcWindowsWMFrameGetRect(ClientPtr client)
     REQUEST(xWindowsWMFrameGetRectReq);
 
 #if CYGMULTIWINDOW_DEBUG
-    ErrorF("ProcWindowsWMFrameGetRect %d %d\n",
+    ErrorF("ProcWindowsWMFrameGetRect %zu %d\n",
            (sizeof(xWindowsWMFrameGetRectReq) >> 2), (int) client->req_len);
 #endif
 
commit b4ac7b142fa3c536e9b283cfd34b94d82c03aac6
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>

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 e7a35b9e16aa12970908f5d55371bb1b862f8f24
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>

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 1a9f8c4623c4e6b6955cb6d5f44d29c244dfd32a
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>

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 0461bca0cb2f7918c77ed45d2cbc756cf65021be
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>

diff --git a/hw/kdrive/linux/evdev.c b/hw/kdrive/linux/evdev.c
index cdd45e7..8415772 100644
--- a/hw/kdrive/linux/evdev.c
+++ b/hw/kdrive/linux/evdev.c
@@ -442,10 +442,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));
 
@@ -468,7 +474,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 30b7d7995ef70b7473e0fb170eb8ae23b8d1f4a7
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>

diff --git a/os/osdep.h b/os/osdep.h
index 2fbfc48..3dc2daf 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
@@ -178,7 +178,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);
@@ -193,7 +193,7 @@ extern Bool NumNotifyWriteFd;
 extern WorkQueuePtr workQueue;
 
 /* in WaitFor.c */
-#ifdef WIN32
+#if defined(WIN32) && !defined(__CYGWIN__)
 typedef long int fd_mask;
 #endif
 #define ffs mffs
commit 544b4149268561d3d794aa540172831fa7550a20
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>

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 5627708e5f447d0e360bbc9eb8d1c4e58c5046d0
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>

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 e957a2e5dd288f515f3e93724823542c20333f6a
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>

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 7f6fb9a..8e77a84 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 3d36205..c97f57d 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -590,6 +590,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 dbe8d03c42f01332b3dc41fe9290aed142f1436f
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>

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 eddf848c44349c7ebc7da9957bffb3630f3faaa9
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>

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 b3e9c534e2b0dc2c9acd2fe9b942e1fc5227339b
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Feb 8 17:36:03 2016 -0500

    os: unifdef STREAMSCONN
    
    Removed from xtrans in 2012, and never wired up in the modular build
    anyway.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/os/access.c b/os/access.c
index 10a48c3..8b2177f 100644
--- a/os/access.c
+++ b/os/access.c
@@ -106,7 +106,7 @@ SOFTWARE.
 #include <pwd.h>
 #endif
 
-#if defined(TCPCONN) || defined(STREAMSCONN)
+#if defined(TCPCONN)
 #include <netinet/in.h>
 #endif                          /* TCPCONN || STREAMSCONN */
 
@@ -426,7 +426,7 @@ ifioctl(int fd, int cmd, char *arg)
 void
 DefineSelf(int fd)
 {
-#if !defined(TCPCONN) && !defined(STREAMSCONN) && !defined(UNIXCONN)
+#if !defined(TCPCONN) && !defined(UNIXCONN)
     return;
 #else
     register int n;
@@ -934,11 +934,10 @@ ResetHosts(const char *display)
     char *ptr;
     int i, hostlen;
 
-#if (defined(TCPCONN) || defined(STREAMSCONN) ) && \
-     (!defined(IPv6) || !defined(AF_INET6))
+#if defined(TCPCONN) &&  (!defined(IPv6) || !defined(AF_INET6))
     union {
         struct sockaddr sa;
-#if defined(TCPCONN) || defined(STREAMSCONN)
+#if defined(TCPCONN)
         struct sockaddr_in in;
 #endif                          /* TCPCONN || STREAMSCONN */
     } saddr;
@@ -984,7 +983,7 @@ ResetHosts(const char *display)
                 NewHost(family, "", 0, FALSE);
                 LocalHostRequested = TRUE;      /* Fix for XFree86 bug #156 */
             }
-#if defined(TCPCONN) || defined(STREAMSCONN)
+#if defined(TCPCONN)
             else if (!strncmp("inet:", lhostname, 5)) {
                 family = FamilyInternet;
                 hostname = ohostname + 5;
@@ -1023,7 +1022,7 @@ ResetHosts(const char *display)
             }
             else
 #endif                          /* SECURE_RPC */
-#if defined(TCPCONN) || defined(STREAMSCONN)
+#if defined(TCPCONN)
             {
 #if defined(IPv6) && defined(AF_INET6)
                 if ((family == FamilyInternet) || (family == FamilyInternet6) ||
@@ -1441,7 +1440,7 @@ CheckAddr(int family, const void *pAddr, unsigned length)
     int len;
 
     switch (family) {
-#if defined(TCPCONN) || defined(STREAMSCONN)
+#if defined(TCPCONN)
     case FamilyInternet:
         if (length == sizeof(struct in_addr))
             len = length;
@@ -1524,7 +1523,7 @@ ConvertAddr(register struct sockaddr *saddr, int *len, void **addr)
     case AF_UNIX:
 #endif
         return FamilyLocal;
-#if defined(TCPCONN) || defined(STREAMSCONN)
+#if defined(TCPCONN)
     case AF_INET:
 #ifdef WIN32
         if (16777343 == *(long *) &((struct sockaddr_in *) saddr)->sin_addr)
diff --git a/os/connection.c b/os/connection.c
index 2a4fc8d..4c1ba4b 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -82,7 +82,7 @@ SOFTWARE.
 #ifndef WIN32
 #include <sys/socket.h>
 
-#if defined(TCPCONN) || defined(STREAMSCONN)
+#if defined(TCPCONN)
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #ifdef apollo
@@ -554,7 +554,7 @@ AuthAudit(ClientPtr client, Bool letin,
 #endif
             strlcpy(addr, "local host", sizeof(addr));
             break;
-#if defined(TCPCONN) || defined(STREAMSCONN)
+#if defined(TCPCONN)
         case AF_INET:
             snprintf(addr, sizeof(addr), "IP %s",
                      inet_ntoa(((struct sockaddr_in *) saddr)->sin_addr));
diff --git a/os/utils.c b/os/utils.c
index ef7a2cc..e48d9f8 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -108,7 +108,7 @@ __stdcall unsigned long GetTickCount(void);
 
 #include <stdlib.h>             /* for malloc() */
 
-#if defined(TCPCONN) || defined(STREAMSCONN)
+#if defined(TCPCONN)
 #ifndef WIN32
 #include <netdb.h>
 #endif
@@ -1069,7 +1069,7 @@ int
 set_font_authorizations(char **authorizations, int *authlen, void *client)
 {
 #define AUTHORIZATION_NAME "hp-hostname-1"
-#if defined(TCPCONN) || defined(STREAMSCONN)
+#if defined(TCPCONN)
     static char *result = NULL;
     static char *p = NULL;
 
diff --git a/os/xdmauth.c b/os/xdmauth.c
index 482bc67..cb2e39e 100644
--- a/os/xdmauth.c
+++ b/os/xdmauth.c
@@ -277,7 +277,7 @@ XdmAuthorizationValidate(unsigned char *plain, int length,
         if (_XSERVTransGetPeerAddr(((OsCommPtr) xclient->osPrivate)->trans_conn,
                                    &family, &addr_len, &addr) == 0
             && _XSERVTransConvertAddress(&family, &addr_len, &addr) == 0) {
-#if defined(TCPCONN) || defined(STREAMSCONN)
+#if defined(TCPCONN)
             if (family == FamilyInternet &&
                 memcmp((char *) addr, client->client, 4) != 0) {
                 free(client);
diff --git a/os/xdmcp.c b/os/xdmcp.c
index dbf43ef..2cb8d76 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -46,12 +46,6 @@
 #include "opaque.h"
 #include "site.h"
 
-#ifdef STREAMSCONN
-#include <tiuser.h>
-#include <netconfig.h>
-#include <netdir.h>
-#endif
-
 #define XSERV_t
 #define TRANS_SERVER
 #define TRANS_REOPEN
@@ -912,43 +906,6 @@ XdmcpAddAuthorization(ARRAY8Ptr name, ARRAY8Ptr data)
 static void
 get_xdmcp_sock(void)
 {
-#ifdef STREAMSCONN
-    struct netconfig *nconf;
-
-    if ((xdmcpSocket = t_open("/dev/udp", O_RDWR, 0)) < 0) {
-        XdmcpWarning("t_open() of /dev/udp failed");
-        return;
-    }
-
-    if (t_bind(xdmcpSocket, NULL, NULL) < 0) {
-        XdmcpWarning("UDP socket creation failed");
-        t_error("t_bind(xdmcpSocket) failed");
-        t_close(xdmcpSocket);
-        return;
-    }
-
-    /*
-     * This part of the code looks contrived. It will actually fit in nicely
-     * when the CLTS part of Xtrans is implemented.
-     */
-
-    if ((nconf = getnetconfigent("udp")) == NULL) {
-        XdmcpWarning("UDP socket creation failed: getnetconfigent()");
-        t_unbind(xdmcpSocket);
-        t_close(xdmcpSocket);
-        return;
-    }
-
-    if (netdir_options(nconf, ND_SET_BROADCAST, xdmcpSocket, NULL)) {
-        XdmcpWarning("UDP set broadcast option failed: netdir_options()");
-        freenetconfigent(nconf);
-        t_unbind(xdmcpSocket);
-        t_close(xdmcpSocket);
-        return;
-    }
-
-    freenetconfigent(nconf);
-#else
     int soopts = 1;
 
 #if defined(IPv6) && defined(AF_INET6)
@@ -969,7 +926,6 @@ get_xdmcp_sock(void)
                        xdm_from);
         }
     }
-#endif                          /* STREAMSCONN */
 }
 
 static void
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
    
    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>

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 a722d617a092f08f69086630f5cfb598d4a21cc7
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>

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 7bb64d8c1de9659f11da7917772919b071e9db82
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>

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 87d5534f701242d7c23aa20545a6292a0779c89c
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>

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 61ca70b..f9e3255 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 b7d392931a309d0fe754869efb456ccd0385f3aa
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>

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 da69f2f15a9917c3ed04e305061683c41338126e
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Dec 11 11:43:14 2015 -0200

    ephyr: don't load ephyr input driver if -seat option is passed
    
    When used for single-GPU multi-seat purposes, there's no need to enable
    ephyr virtual input devices, since Xephyr is supposed to handle its own
    hardware devices.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 9ddf86e..849a4e1 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -91,29 +91,30 @@ InitInput(int argc, char **argv)
     KdKeyboardInfo *ki;
     KdPointerInfo *pi;
 
-    KdAddKeyboardDriver(&EphyrKeyboardDriver);
 #ifdef KDRIVE_EVDEV
     KdAddKeyboardDriver(&LinuxEvdevKeyboardDriver);
-#endif
-    KdAddPointerDriver(&EphyrMouseDriver);
-#ifdef KDRIVE_EVDEV
     KdAddPointerDriver(&LinuxEvdevMouseDriver);
 #endif
 
-    if (!kdHasKbd) {
-        ki = KdNewKeyboard();
-        if (!ki)
-            FatalError("Couldn't create Xephyr keyboard\n");
-        ki->driver = &EphyrKeyboardDriver;
-        KdAddKeyboard(ki);
-    }
+    if (!SeatId) {
+        KdAddKeyboardDriver(&EphyrKeyboardDriver);
+        KdAddPointerDriver(&EphyrMouseDriver);
 
-    if (!kdHasPointer) {
-        pi = KdNewPointer();
-        if (!pi)
-            FatalError("Couldn't create Xephyr pointer\n");
-        pi->driver = &EphyrMouseDriver;
-        KdAddPointer(pi);
+        if (!kdHasKbd) {
+            ki = KdNewKeyboard();
+            if (!ki)
+                FatalError("Couldn't create Xephyr keyboard\n");
+            ki->driver = &EphyrKeyboardDriver;
+            KdAddKeyboard(ki);
+        }
+
+        if (!kdHasPointer) {
+            pi = KdNewPointer();
+            if (!pi)
+                FatalError("Couldn't create Xephyr pointer\n");
+            pi->driver = &EphyrMouseDriver;
+            KdAddPointer(pi);
+        }
     }
 
     KdInitInput();
commit 7213e99cbc38a60f0076bc2115b144798ea4c3ba
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Dec 11 11:43:13 2015 -0200

    ephyr: ignore Xorg multiseat command line options
    
    Multi-seat-capable display managers commonly pass command-line options
    like "-novtswitch", "-sharevts", or "-layout seatXXXX" to Xorg server,
    but Xephyr currently refuses to start if these options are passed to it,
    which may break Xephyr-based single-GPU multiseat setups.
    
    [ajax: shortened summary]
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 6b6c4b1..9ddf86e 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -356,6 +356,13 @@ ddxProcessArgument(int argc, char **argv, int i)
         EphyrWantNoHostGrab = 1;
         return 1;
     }
+    else if (!strcmp(argv[i], "-sharevts") ||
+             !strcmp(argv[i], "-novtswitch")) {
+        return 1;
+    }
+    else if (!strcmp(argv[i], "-layout")) {
+        return 2;
+    }
 
     return KdProcessArgument(argc, argv, i);
 }
commit edd443f69ea385a957b8eae0b066ad8e77fb947b
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Dec 11 11:43:11 2015 -0200

    kdrive: don't let evdev driver overwrite existing device names
    
    KDrive evdev driver deliberately name grabbed devices as "Evdev mouse"
    or "Evdev keyboard". This patch will make it skip this step if grabbed
    devices are already named (i.e. from udev).
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/hw/kdrive/linux/evdev.c b/hw/kdrive/linux/evdev.c
index 63e8409..cdd45e7 100644
--- a/hw/kdrive/linux/evdev.c
+++ b/hw/kdrive/linux/evdev.c
@@ -220,7 +220,8 @@ EvdevPtrInit(KdPointerInfo * pi)
 
     close(fd);
 
-    pi->name = strdup("Evdev mouse");
+    if (!pi->name)
+        pi->name = strdup("Evdev mouse");
 
     return Success;
 }
@@ -390,7 +391,8 @@ EvdevKbdInit(KdKeyboardInfo * ki)
 
     close(fd);
 
-    ki->name = strdup("Evdev keyboard");
+    if (!ki->name)
+        ki->name = strdup("Evdev keyboard");
 
     readMapping(ki);
 
commit 0b80da0d18713df4712c05973388b6226bb0227f
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Dec 11 11:43:07 2015 -0200

    kdrive: set "evdev" driver for input devices automatically, if available.
    
    If kdrive input driver "evdev" is available, no other driver was
    explicitly set for a given input device, and its kernel device node is
    /dev/input/event*, this patch will make kdrive set "evdev" driver
    automatically for such device.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 980fd3e..3a1c6a0 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -51,6 +51,11 @@
 #include "inpututils.h"
 #include "optionstr.h"
 
+#ifdef KDRIVE_EVDEV
+#define DEV_INPUT_EVENT_PREFIX "/dev/input/event"
+#define DEV_INPUT_EVENT_PREFIX_LEN (sizeof(DEV_INPUT_EVENT_PREFIX) - 1)
+#endif
+
 #define AtomFromName(x) MakeAtom(x, strlen(x), 1)
 
 struct KdConfigDevice {
@@ -1097,6 +1102,16 @@ KdParseKbdOptions(KdKeyboardInfo * ki)
             ErrorF("Kbd option key (%s) of value (%s) not assigned!\n",
                    key, value);
     }
+
+#ifdef KDRIVE_EVDEV
+    if (!ki->driver && ki->path != NULL &&
+        strncasecmp(ki->path,
+                    DEV_INPUT_EVENT_PREFIX,
+                    DEV_INPUT_EVENT_PREFIX_LEN) == 0) {
+            ki->driver = KdFindKeyboardDriver("evdev");
+            ki->options = input_option_new(ki->options, "driver", "evdev");
+    }
+#endif
 }
 
 KdKeyboardInfo *
@@ -1191,6 +1206,16 @@ KdParsePointerOptions(KdPointerInfo * pi)
             ErrorF("Pointer option key (%s) of value (%s) not assigned!\n",
                    key, value);
     }
+
+#ifdef KDRIVE_EVDEV
+    if (!pi->driver && pi->path != NULL &&
+        strncasecmp(pi->path,
+                    DEV_INPUT_EVENT_PREFIX,
+                    DEV_INPUT_EVENT_PREFIX_LEN) == 0) {
+            pi->driver = KdFindPointerDriver("evdev");
+            pi->options = input_option_new(pi->options, "driver", "evdev");
+    }
+#endif
 }
 
 KdPointerInfo *
commit 6d6fd688ecf95f2e84f2af276d681ff42f9d5610
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Dec 11 11:43:06 2015 -0200

    kdrive: fix up NewInputDeviceRequest() implementation
    
    This patch simplifies NewInputDeviceRequest() implementation in
    kinput.c, making use of improved KdParseKbdOptions() /
    KdParsePointerOptions() and merging several "if (ki)"/"if (pi)" clauses.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 1fdaa52..980fd3e 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -1091,6 +1091,8 @@ KdParseKbdOptions(KdKeyboardInfo * ki)
             ki->xkbOptions = strdup(value);
         else if (!strcasecmp(key, "device"))
             ki->path = strdup(value);
+        else if (!strcasecmp(key, "driver"))
+            ki->driver = KdFindKeyboardDriver(value);
         else
             ErrorF("Kbd option key (%s) of value (%s) not assigned!\n",
                    key, value);
@@ -1171,18 +1173,20 @@ KdParsePointerOptions(KdPointerInfo * pi)
         const char *key = input_option_get_key(option);
         const char *value = input_option_get_value(option);
 
-        if (!strcmp(key, "emulatemiddle"))
+        if (!strcasecmp(key, "emulatemiddle"))
             pi->emulateMiddleButton = TRUE;
-        else if (!strcmp(key, "noemulatemiddle"))
+        else if (!strcasecmp(key, "noemulatemiddle"))
             pi->emulateMiddleButton = FALSE;
-        else if (!strcmp(key, "transformcoord"))
+        else if (!strcasecmp(key, "transformcoord"))
             pi->transformCoordinates = TRUE;
-        else if (!strcmp(key, "rawcoord"))
+        else if (!strcasecmp(key, "rawcoord"))
             pi->transformCoordinates = FALSE;
         else if (!strcasecmp(key, "device"))
             pi->path = strdup(value);
         else if (!strcasecmp(key, "protocol"))
             pi->protocol = strdup(value);
+        else if (!strcasecmp(key, "driver"))
+            pi->driver = KdFindPointerDriver(value);
         else
             ErrorF("Pointer option key (%s) of value (%s) not assigned!\n",
                    key, value);
@@ -2152,68 +2156,48 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
 #endif
     }
 
-    if (!ki && !pi) {
-        ErrorF("unrecognised device identifier!\n");
-        return BadValue;
-    }
-
-    /* FIXME: change this code below to use KdParseKbdOptions and
-     * KdParsePointerOptions */
-    nt_list_for_each_entry(option, options, list.next) {
-        const char *key = input_option_get_key(option);
-        const char *value = input_option_get_value(option);
+    if (pi) {
+        pi->options = options;
+        KdParsePointerOptions(pi);
 
-        if (strcmp(key, "device") == 0) {
-            if (pi && value)
-                pi->path = strdup(value);
-            else if (ki && value)
-                ki->path = strdup(value);
-        }
-        else if (strcmp(key, "driver") == 0) {
-            if (pi) {
-                pi->driver = KdFindPointerDriver(value);
-                if (!pi->driver) {
-                    ErrorF("couldn't find driver!\n");
-                    KdFreePointer(pi);
-                    return BadValue;
-                }
-                pi->options = options;
-            }
-            else if (ki) {
-                ki->driver = KdFindKeyboardDriver(value);
-                if (!ki->driver) {
-                    ErrorF("couldn't find driver!\n");
-                    KdFreeKeyboard(ki);
-                    return BadValue;
-                }
-                ki->options = options;
-            }
+        if (!pi->driver) {
+            ErrorF("couldn't find driver!\n");
+            KdFreePointer(pi);
+            return BadValue;
         }
-    }
 
-    if (pi) {
         if (KdAddPointer(pi) != Success ||
             ActivateDevice(pi->dixdev, TRUE) != Success ||
             EnableDevice(pi->dixdev, TRUE) != TRUE) {
             ErrorF("couldn't add or enable pointer\n");
             return BadImplementation;
         }
+
+        *pdev = pi->dixdev;
     }
     else if (ki) {
+        ki->options = options;
+        KdParseKbdOptions(ki);
+
+        if (!ki->driver) {
+            ErrorF("couldn't find driver!\n");
+            KdFreeKeyboard(ki);
+            return BadValue;
+        }
+
         if (KdAddKeyboard(ki) != Success ||
             ActivateDevice(ki->dixdev, TRUE) != Success ||
             EnableDevice(ki->dixdev, TRUE) != TRUE) {
             ErrorF("couldn't add or enable keyboard\n");
             return BadImplementation;
         }
-    }
 
-    if (pi) {
-        *pdev = pi->dixdev;
-    }
-    else if (ki) {
         *pdev = ki->dixdev;
     }
+    else {
+        ErrorF("unrecognised device identifier!\n");
+        return BadValue;
+    }
 
     return Success;
 }
commit 2c3e8768443caa66d78775ea79bb16a5faae3a3c
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>

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 e82c8c81df80de487aa795d69e874a0811c537ea
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>

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 2c3273861cdf874b165ce5a1953102187f71b48e
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>

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 990a8ee01324332ee9b4a4bb124ce8f73be24349
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>

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 20cb5b2d65ce63ea7934b77f1520387550c778a8
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>

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 07f0d90e4a8b05ef968b1ef47acda7c9f4580340
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>

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 0dbce65b08f4812dcaa4b77cd37aebac334c47a2
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>

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 9b676786de32f06aedf9d4c9535c10fda247335a
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>

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 03f34f85563c81e1655626e10f75fd7e21393c92
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>

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 f368a0ba3aa58e5260d839d11d2f3aef75feaeaf
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>

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 294e45b60d99cf7d11c657288bbe2670b56775f3
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>

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 5d7bef2eedfd965359dd4eebb6ab806cdad5b83f
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>

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 4494a450405cf539743cbcfe6907bf5bdd2d80cb
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>

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 f7c24e6ac345aab91df5fc959f239a33f37113b1
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>

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 1fcb6f4cbf3d6514716435a0e79c0e6d53c31a3a
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>

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 9ef11f13af7f552dadb4a90c248e525a257e0a2c
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>

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 b8229cc5f5298a37a4735dd002b0e0ebfc8bc75a
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>

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 68f236ebd4b268a9e525d623986999d230feb453
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>

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 623ff251dd025929f5bb6174ca86580c5e707261
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 8 17:41:38 2015 -0500

    xephyr: Remove DRI1
    
    This only worked if the backend server supported DRI1, which is
    stunningly unlikely these days.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 155e11e..6ce0d6f 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -46,19 +46,6 @@ GLAMOR_SRCS = \
 	$()
 endif
 
-if DRI
-DRI_SRCS =			\
-	ephyrdriext.c		\
-	ephyrdriext.h		\
-	ephyrdri.c		\
-	ephyrdri.h		\
-	ephyrglxext.c		\
-	ephyrglxext.h		\
-	ephyrhostglx.c		\
-	ephyrhostglx.h		\
-	$()
-endif
-
 bin_PROGRAMS = Xephyr
 
 Xephyr_SOURCES = \
@@ -72,7 +59,6 @@ Xephyr_SOURCES = \
 	hostx.c \
 	hostx.h \
 	$(XV_SRCS) \
-	$(DRI_SRCS) \
 	$(GLAMOR_SRCS) \
 	$()
 
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 896bac5..a272882 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -36,13 +36,6 @@
 #include "scrnintstr.h"
 #include "ephyrlog.h"
 
-#ifdef XF86DRI
-#include <xcb/xf86dri.h>
-#include "ephyrdri.h"
-#include "ephyrdriext.h"
-#include "ephyrglxext.h"
-#endif                          /* XF86DRI */
-
 #ifdef GLAMOR
 #include "glamor.h"
 #endif
@@ -658,16 +651,6 @@ ephyrInitScreen(ScreenPtr pScreen)
         }
     }
 #endif /*XV*/
-#ifdef XF86DRI
-    if (!ephyrNoDRI && !hostx_has_extension(&xcb_xf86dri_id)) {
-        EPHYR_LOG("host x does not support DRI. Disabling DRI forwarding\n");
-        ephyrNoDRI = TRUE;
-    }
-    if (!ephyrNoDRI) {
-        ephyrDRIExtensionInit(pScreen);
-        ephyrHijackGLXExtension();
-    }
-#endif
 
     return TRUE;
 }
@@ -849,40 +832,6 @@ miPointerScreenFuncRec ephyrPointerScreenFuncs = {
     ephyrWarpCursor,
 };
 
-#ifdef XF86DRI
-/**
- * find if the remote window denoted by a_remote
- * is paired with an internal Window within the Xephyr server.
- * If the remove window is paired with an internal window, send an
- * expose event to the client insterested in the internal window expose event.
- *
- * Pairing happens when a drawable inside Xephyr is associated with
- * a GL surface in a DRI environment.
- * Look at the function ProcXF86DRICreateDrawable in ephyrdriext.c to
- * know a paired window is created.
- *
- * This is useful to make GL drawables (only windows for now) handle
- * expose events and send those events to clients.
- */
-static void
-ephyrExposePairedWindow(int a_remote)
-{
-    EphyrWindowPair *pair = NULL;
-    RegionRec reg;
-    ScreenPtr screen;
-
-    if (!findWindowPairFromRemote(a_remote, &pair)) {
-        EPHYR_LOG("did not find a pair for this window\n");
-        return;
-    }
-    screen = pair->local->drawable.pScreen;
-    RegionNull(&reg);
-    RegionCopy(&reg, &pair->local->clipList);
-    screen->WindowExposures(pair->local, &reg);
-    RegionUninit(&reg);
-}
-#endif                          /* XF86DRI */
-
 static KdScreenInfo *
 screen_from_window(Window w)
 {
@@ -939,16 +888,6 @@ ephyrProcessExpose(xcb_generic_event_t *xev)
                          scrpriv->win_height);
     } else {
         EPHYR_LOG_ERROR("failed to get host screen\n");
-#ifdef XF86DRI
-        /*
-         * We only receive expose events when the expose event
-         * have be generated for a drawable that is a host X
-         * window managed by Xephyr. Host X windows managed by
-         * Xephyr exists for instance when Xephyr is asked to
-         * create a GL drawable in a DRI environment.
-         */
-        ephyrExposePairedWindow(expose->window);
-#endif                          /* XF86DRI */
     }
 }
 
@@ -974,25 +913,10 @@ ephyrProcessMouseMotion(xcb_generic_event_t *xev)
     else {
         int x = 0, y = 0;
 
-#ifdef XF86DRI
-        EphyrWindowPair *pair = NULL;
-#endif
         EPHYR_LOG("enqueuing mouse motion:%d\n", screen->pScreen->myNum);
         x = motion->event_x;
         y = motion->event_y;
         EPHYR_LOG("initial (x,y):(%d,%d)\n", x, y);
-#ifdef XF86DRI
-        EPHYR_LOG("is this window peered by a gl drawable ?\n");
-        if (findWindowPairFromRemote(motion->event, &pair)) {
-            EPHYR_LOG("yes, it is peered\n");
-            x += pair->local->drawable.x;
-            y += pair->local->drawable.y;
-        }
-        else {
-            EPHYR_LOG("no, it is not peered\n");
-        }
-        EPHYR_LOG("final (x,y):(%d,%d)\n", x, y);
-#endif
 
         /* convert coords into desktop-wide coordinates.
          * fill_pointer_events will convert that back to
diff --git a/hw/kdrive/ephyr/ephyrdri.c b/hw/kdrive/ephyr/ephyrdri.c
deleted file mode 100644
index 1e34301..0000000
--- a/hw/kdrive/ephyr/ephyrdri.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- *          Authored by Matthew Allum <mallum at openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors:
- *    Dodji Seketeli <dodji at openedhand.com>
- */
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-
-#include <X11/Xdefs.h>
-#include <xcb/xf86dri.h>
-#include "hostx.h"
-#include "ephyrdri.h"
-#define _HAVE_XALLOC_DECLS
-#include "ephyrlog.h"
-#include "dixstruct.h"
-#include "pixmapstr.h"
-
-#ifndef TRUE
-#define TRUE 1
-#endif /*TRUE*/
-#ifndef FALSE
-#define FALSE 0
-#endif /*FALSE*/
-    Bool
-ephyrDRIQueryDirectRenderingCapable(int a_screen, Bool *a_is_capable)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    Bool is_ok = FALSE;
-    xcb_xf86dri_query_direct_rendering_capable_cookie_t cookie;
-    xcb_xf86dri_query_direct_rendering_capable_reply_t *reply;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_is_capable, FALSE);
-    EPHYR_LOG("enter\n");
-    cookie = xcb_xf86dri_query_direct_rendering_capable(conn,
-                                                        hostx_get_screen());
-    reply = xcb_xf86dri_query_direct_rendering_capable_reply(conn, cookie, NULL);
-    if (reply) {
-        is_ok = TRUE;
-        *a_is_capable = reply->is_capable;
-        free(reply);
-    }
-    EPHYR_LOG("leave. is_capable:%d, is_ok=%d\n", *a_is_capable, is_ok);
-
-    return is_ok;
-}
-
-Bool
-ephyrDRIOpenConnection(int a_screen,
-                       drm_handle_t * a_sarea, char **a_bus_id_string)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    Bool is_ok = FALSE;
-    xcb_xf86dri_open_connection_cookie_t cookie;
-    xcb_xf86dri_open_connection_reply_t *reply;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_bus_id_string, FALSE);
-    EPHYR_LOG("enter. screen:%d\n", a_screen);
-    cookie = xcb_xf86dri_open_connection(conn, hostx_get_screen());
-    reply = xcb_xf86dri_open_connection_reply(conn, cookie, NULL);
-    if (!reply)
-        goto out;
-    *a_sarea = reply->sarea_handle_low;
-    if (sizeof(drm_handle_t) == 8) {
-        int shift = 32;
-        *a_sarea |= ((drm_handle_t) reply->sarea_handle_high) << shift;
-    }
-    *a_bus_id_string = malloc(reply->bus_id_len + 1);
-    if (!*a_bus_id_string)
-        goto out;
-    memcpy(*a_bus_id_string, xcb_xf86dri_open_connection_bus_id(reply), reply->bus_id_len);
-    *a_bus_id_string[reply->bus_id_len] = '\0';
-    is_ok = TRUE;
-out:
-    free(reply);
-    EPHYR_LOG("leave. bus_id_string:%s, is_ok:%d\n", *a_bus_id_string, is_ok);
-    return is_ok;
-}
-
-Bool
-ephyrDRIAuthConnection(int a_screen, drm_magic_t a_magic)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    int screen = hostx_get_screen();
-    xcb_xf86dri_auth_connection_cookie_t cookie;
-    xcb_xf86dri_auth_connection_reply_t *reply;
-    Bool is_ok = FALSE;
-
-    EPHYR_LOG("enter\n");
-    cookie = xcb_xf86dri_auth_connection(conn, screen, a_magic);
-    reply = xcb_xf86dri_auth_connection_reply(conn, cookie, NULL);
-    is_ok = reply->authenticated;
-    free(reply);
-    EPHYR_LOG("leave. is_ok:%d\n", is_ok);
-    return is_ok;
-}
-
-Bool
-ephyrDRICloseConnection(int a_screen)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    int screen = hostx_get_screen();
-
-    EPHYR_LOG("enter\n");
-    xcb_xf86dri_close_connection(conn, screen);
-    EPHYR_LOG("leave\n");
-    return TRUE;
-}
-
-Bool
-ephyrDRIGetClientDriverName(int a_screen,
-                            int *a_ddx_driver_major_version,
-                            int *a_ddx_driver_minor_version,
-                            int *a_ddx_driver_patch_version,
-                            char **a_client_driver_name)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    int screen = hostx_get_screen();
-    xcb_xf86dri_get_client_driver_name_cookie_t cookie;
-    xcb_xf86dri_get_client_driver_name_reply_t *reply;
-    Bool is_ok = FALSE;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_ddx_driver_major_version
-                             && a_ddx_driver_minor_version
-                             && a_ddx_driver_patch_version
-                             && a_client_driver_name, FALSE);
-    EPHYR_LOG("enter\n");
-    cookie = xcb_xf86dri_get_client_driver_name(conn, screen);
-    reply = xcb_xf86dri_get_client_driver_name_reply(conn, cookie, NULL);
-    if (!reply)
-        goto out;
-    *a_ddx_driver_major_version = reply->client_driver_major_version;
-    *a_ddx_driver_minor_version = reply->client_driver_minor_version;
-    *a_ddx_driver_patch_version = reply->client_driver_patch_version;
-    *a_client_driver_name = malloc(reply->client_driver_name_len + 1);
-    if (!*a_client_driver_name)
-        goto out;
-    memcpy(*a_client_driver_name,
-           xcb_xf86dri_get_client_driver_name_client_driver_name(reply),
-           reply->client_driver_name_len);
-    (*a_client_driver_name)[reply->client_driver_name_len] = '\0';
-    is_ok = TRUE;
-    EPHYR_LOG("major:%d, minor:%d, patch:%d, name:%s\n",
-              *a_ddx_driver_major_version,
-              *a_ddx_driver_minor_version,
-              *a_ddx_driver_patch_version, *a_client_driver_name);
- out:
-    free(reply);
-    EPHYR_LOG("leave:%d\n", is_ok);
-    return is_ok;
-}
-
-Bool
-ephyrDRICreateContext(int a_screen,
-                      int a_visual_id,
-                      CARD32 ctxt_id, drm_context_t * a_hw_ctxt)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    int screen = hostx_get_screen();
-    Bool is_ok = FALSE;
-    xcb_xf86dri_create_context_cookie_t cookie;
-    xcb_xf86dri_create_context_reply_t *reply;
-
-    ctxt_id = xcb_generate_id(conn);
-
-    EPHYR_LOG("enter. screen:%d, visual:%d\n", a_screen, a_visual_id);
-    cookie = xcb_xf86dri_create_context(conn, screen, a_visual_id, ctxt_id);
-    reply = xcb_xf86dri_create_context_reply(conn, cookie, NULL);
-    if (!reply)
-        goto out;
-    *a_hw_ctxt = reply->hw_context;
-    is_ok = TRUE;
-out:
-    free(reply);
-    EPHYR_LOG("leave:%d\n", is_ok);
-    return is_ok;
-}
-
-Bool
-ephyrDRIDestroyContext(int a_screen, int a_context_id)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn ();
-    int screen = hostx_get_screen();
-
-    EPHYR_LOG("enter\n");
-    xcb_xf86dri_destroy_context(conn, screen, a_context_id);
-    EPHYR_LOG("leave\n");
-    return TRUE;
-}
-
-Bool
-ephyrDRICreateDrawable(int a_screen,
-                       int a_drawable, drm_drawable_t * a_hw_drawable)
-{
-    Bool is_ok = FALSE;
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    int screen = hostx_get_screen();
-    xcb_xf86dri_create_drawable_cookie_t cookie;
-    xcb_xf86dri_create_drawable_reply_t *reply;
-
-    EPHYR_LOG("enter\n");
-    cookie = xcb_xf86dri_create_drawable(conn, screen, a_drawable);
-    reply = xcb_xf86dri_create_drawable_reply(conn, cookie, NULL);
-    if (!reply)
-        goto out;
-    *a_hw_drawable = reply->hw_drawable_handle;
-    is_ok = TRUE;
-out:
-    free(reply);
-    EPHYR_LOG("leave. is_ok:%d\n", is_ok);
-    return is_ok;
-}
-
-Bool
-ephyrDRIDestroyDrawable(int a_screen, int a_drawable)
-{
-    EPHYR_LOG("enter\n");
-    EPHYR_LOG_ERROR("not implemented yet\n");
-    EPHYR_LOG("leave\n");
-    return FALSE;
-}
-
-Bool
-ephyrDRIGetDrawableInfo(int a_screen,
-                        int a_drawable,
-                        unsigned int *a_index,
-                        unsigned int *a_stamp,
-                        int *a_x,
-                        int *a_y,
-                        int *a_w,
-                        int *a_h,
-                        int *a_num_clip_rects,
-                        drm_clip_rect_t ** a_clip_rects,
-                        int *a_back_x,
-                        int *a_back_y,
-                        int *a_num_back_clip_rects,
-                        drm_clip_rect_t ** a_back_clip_rects)
-{
-    Bool is_ok = FALSE;
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    int screen = hostx_get_screen();
-    xcb_xf86dri_get_drawable_info_cookie_t cookie;
-    xcb_xf86dri_get_drawable_info_reply_t *reply = NULL;
-    EphyrHostWindowAttributes attrs;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_x && a_y && a_w && a_h
-                             && a_num_clip_rects, FALSE);
-
-    EPHYR_LOG("enter\n");
-    memset(&attrs, 0, sizeof(attrs));
-    if (!hostx_get_window_attributes(a_drawable, &attrs)) {
-        EPHYR_LOG_ERROR("failed to query host window attributes\n");
-        goto out;
-    }
-    cookie = xcb_xf86dri_get_drawable_info(conn, screen, a_drawable);
-    reply =  xcb_xf86dri_get_drawable_info_reply(conn, cookie, NULL);
-    if (!reply) {
-        EPHYR_LOG_ERROR ("XF86DRIGetDrawableInfo ()\n");
-        goto out;
-    }
-    *a_index = reply->drawable_table_index;
-    *a_stamp = reply->drawable_table_stamp;
-    *a_x = reply->drawable_origin_X;
-    *a_y = reply->drawable_origin_Y;
-    *a_w = reply->drawable_size_W;
-    *a_h = reply->drawable_size_H;
-    *a_num_clip_rects = reply->num_clip_rects;
-    *a_clip_rects = calloc(*a_num_clip_rects, sizeof(drm_clip_rect_t));
-    memcpy(*a_clip_rects, xcb_xf86dri_get_drawable_info_clip_rects(reply),
-           *a_num_clip_rects * sizeof(drm_clip_rect_t));
-    EPHYR_LOG("host x,y,w,h: (%d,%d,%d,%d)\n", *a_x, *a_y, *a_w, *a_h);
-    if (*a_num_clip_rects) {
-        free(*a_back_clip_rects);
-        *a_back_clip_rects = calloc(*a_num_clip_rects, sizeof(drm_clip_rect_t));
-        memmove(*a_back_clip_rects,
-                *a_clip_rects, *a_num_clip_rects * sizeof(drm_clip_rect_t));
-        *a_num_back_clip_rects = *a_num_clip_rects;
-    }
-    EPHYR_LOG("num back clip rects:%d, num clip rects:%d\n",
-              *a_num_clip_rects, *a_num_back_clip_rects);
-    *a_back_x = *a_x;
-    *a_back_y = *a_y;
-    *a_w = attrs.width;
-    *a_h = attrs.height;
-
-    is_ok = TRUE;
- out:
-    EPHYR_LOG("leave. index:%d, stamp:%d, x,y:(%d,%d), w,y:(%d,%d)\n",
-              *a_index, *a_stamp, *a_x, *a_y, *a_w, *a_h);
-    free(reply);
-    return is_ok;
-}
-
-Bool
-ephyrDRIGetDeviceInfo(int a_screen,
-                      drm_handle_t * a_frame_buffer,
-                      int *a_fb_origin,
-                      int *a_fb_size,
-                      int *a_fb_stride,
-                      int *a_dev_private_size, void **a_dev_private)
-{
-    Bool is_ok = FALSE;
-    xcb_connection_t *conn = hostx_get_xcbconn ();
-    int screen = hostx_get_screen();
-    xcb_xf86dri_get_device_info_cookie_t cookie;
-    xcb_xf86dri_get_device_info_reply_t *reply;
-
-    EPHYR_RETURN_VAL_IF_FAIL(conn, FALSE);
-    EPHYR_LOG("enter\n");
-    cookie = xcb_xf86dri_get_device_info(conn, screen);
-    reply = xcb_xf86dri_get_device_info_reply(conn, cookie, NULL);
-    if (!reply)
-        goto out;
-    *a_frame_buffer = reply->framebuffer_handle_low;
-    if (sizeof(drm_handle_t) == 8) {
-        int shift = 32;
-        *a_frame_buffer |= ((drm_handle_t)reply->framebuffer_handle_high) << shift;
-    }
-    *a_fb_origin = reply->framebuffer_origin_offset;
-    *a_fb_size = reply->framebuffer_size;
-    *a_fb_stride = reply->framebuffer_stride;
-    *a_dev_private_size = reply->device_private_size;
-    *a_dev_private = calloc(reply->device_private_size, 1);
-    if (!*a_dev_private)
-        goto out;
-    memcpy(*a_dev_private,
-           xcb_xf86dri_get_device_info_device_private(reply),
-           reply->device_private_size);
-    is_ok = TRUE;
-out:
-    free(reply);
-    EPHYR_LOG("leave:%d\n", is_ok);
-    return is_ok;
-}
diff --git a/hw/kdrive/ephyr/ephyrdri.h b/hw/kdrive/ephyr/ephyrdri.h
deleted file mode 100644
index b312e62..0000000
--- a/hw/kdrive/ephyr/ephyrdri.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- *          Authored by Matthew Allum <mallum at openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors:
- *    Dodji Seketeli <dodji at openedhand.com>
- */
-
-#ifndef __EPHYRDRI_H__
-#define __EPHYRDRI_H__
-
-#include <xf86drm.h>
-
-Bool ephyrDRIQueryDirectRenderingCapable(int a_screen, Bool *a_is_capable);
-Bool ephyrDRIOpenConnection(int screen, drm_handle_t * a_sarea,
-                            char **a_bus_id_string);
-Bool ephyrDRIAuthConnection(int a_screen, drm_magic_t a_magic);
-Bool ephyrDRICloseConnection(int a_screen);
-Bool ephyrDRIGetClientDriverName(int a_screen,
-                                 int *a_ddx_driver_major_version,
-                                 int *a_ddx_driver_minor_version,
-                                 int *a_ddx_driver_patch_version,
-                                 char **a_client_driver_name);
-Bool ephyrDRICreateContext(int a_screen,
-                           int a_visual_id,
-                           CARD32 ctx_id, drm_context_t * a_hw_ctx);
-Bool ephyrDRIDestroyContext(int a_screen, int a_context_id);
-Bool ephyrDRICreateDrawable(int a_screen,
-                            int a_drawable, drm_drawable_t * a_hw_drawable);
-Bool ephyrDRIDestroyDrawable(int a_screen, int a_drawable);
-Bool ephyrDRIGetDrawableInfo(int a_screen, int /*Drawable */ a_drawable,
-                             unsigned int *a_index,
-                             unsigned int *a_stamp,
-                             int *a_x,
-                             int *a_y,
-                             int *a_w,
-                             int *a_h,
-                             int *a_num_clip_rects,
-                             drm_clip_rect_t ** a_clip_rects,
-                             int *a_back_x,
-                             int *a_back_y,
-                             int *num_back_clip_rects,
-                             drm_clip_rect_t ** a_back_clip_rects);
-Bool ephyrDRIGetDeviceInfo(int a_screen,
-                           drm_handle_t * a_frame_buffer,
-                           int *a_fb_origin,
-                           int *a_fb_size,
-                           int *a_fb_stride,
-                           int *a_dev_private_size, void **a_dev_private);
-#endif /*__EPHYRDRI_H__*/
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
deleted file mode 100644
index 3703adf..0000000
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ /dev/null
@@ -1,1376 +0,0 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- *          Authored by Matthew Allum <mallum at openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * This file is heavily copied from hw/xfree86/dri/xf86dri.c
- *
- * Authors:
- *    Dodji Seketeli <dodji at openedhand.com>
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-
-#include <string.h>
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#define _XF86DRI_SERVER_
-#include <X11/dri/xf86dri.h>
-#include <X11/dri/xf86driproto.h>
-#include <xcb/xcb.h>
-#include <xcb/shape.h>
-#include <xcb/xf86dri.h>
-#include "misc.h"
-#include "privates.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "servermd.h"
-#include "swaprep.h"
-#include "ephyrdri.h"
-#include "ephyrdriext.h"
-#include "hostx.h"
-#define _HAVE_XALLOC_DECLS
-#include "ephyrlog.h"
-#include "protocol-versions.h"
-
-typedef struct {
-    int foo;
-} EphyrDRIWindowPrivRec;
-typedef EphyrDRIWindowPrivRec *EphyrDRIWindowPrivPtr;
-
-typedef struct {
-    CreateWindowProcPtr CreateWindow;
-    DestroyWindowProcPtr DestroyWindow;
-    MoveWindowProcPtr MoveWindow;
-    PositionWindowProcPtr PositionWindow;
-    ClipNotifyProcPtr ClipNotify;
-} EphyrDRIScreenPrivRec;
-typedef EphyrDRIScreenPrivRec *EphyrDRIScreenPrivPtr;
-
-static int DRIErrorBase;
-
-static Bool ephyrDRIScreenInit(ScreenPtr a_screen);
-static Bool ephyrDRICreateWindow(WindowPtr a_win);
-static Bool ephyrDRIDestroyWindow(WindowPtr a_win);
-static void ephyrDRIMoveWindow(WindowPtr a_win,
-                               int a_x, int a_y,
-                               WindowPtr a_siblings, VTKind a_kind);
-static Bool ephyrDRIPositionWindow(WindowPtr a_win, int x, int y);
-static void ephyrDRIClipNotify(WindowPtr a_win, int a_x, int a_y);
-
-static Bool EphyrMirrorHostVisuals(ScreenPtr a_screen);
-static Bool destroyHostPeerWindow(const WindowPtr a_win);
-static Bool findWindowPairFromLocal(WindowPtr a_local,
-                                    EphyrWindowPair ** a_pair);
-
-static unsigned char DRIReqCode = 0;
-
-static DevPrivateKeyRec ephyrDRIWindowKeyRec;
-
-#define ephyrDRIWindowKey (&ephyrDRIWindowKeyRec)
-static DevPrivateKeyRec ephyrDRIScreenKeyRec;
-
-#define ephyrDRIScreenKey (&ephyrDRIScreenKeyRec)
-
-#define GET_EPHYR_DRI_WINDOW_PRIV(win) ((EphyrDRIWindowPrivPtr) \
-    dixLookupPrivate(&(win)->devPrivates, ephyrDRIWindowKey))
-#define GET_EPHYR_DRI_SCREEN_PRIV(screen) ((EphyrDRIScreenPrivPtr) \
-    dixLookupPrivate(&(screen)->devPrivates, ephyrDRIScreenKey))
-
-static Bool
-ephyrDRIScreenInit(ScreenPtr a_screen)
-{
-    Bool is_ok = FALSE;
-    EphyrDRIScreenPrivPtr screen_priv = NULL;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_screen, FALSE);
-
-    screen_priv = GET_EPHYR_DRI_SCREEN_PRIV(a_screen);
-    EPHYR_RETURN_VAL_IF_FAIL(screen_priv, FALSE);
-
-    screen_priv->CreateWindow = a_screen->CreateWindow;
-    screen_priv->DestroyWindow = a_screen->DestroyWindow;
-    screen_priv->MoveWindow = a_screen->MoveWindow;
-    screen_priv->PositionWindow = a_screen->PositionWindow;
-    screen_priv->ClipNotify = a_screen->ClipNotify;
-
-    a_screen->CreateWindow = ephyrDRICreateWindow;
-    a_screen->DestroyWindow = ephyrDRIDestroyWindow;
-    a_screen->MoveWindow = ephyrDRIMoveWindow;
-    a_screen->PositionWindow = ephyrDRIPositionWindow;
-    a_screen->ClipNotify = ephyrDRIClipNotify;
-
-    is_ok = TRUE;
-
-    return is_ok;
-}
-
-static Bool
-ephyrDRICreateWindow(WindowPtr a_win)
-{
-    Bool is_ok = FALSE;
-    ScreenPtr screen = NULL;
-    EphyrDRIScreenPrivPtr screen_priv = NULL;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_win, FALSE);
-    screen = a_win->drawable.pScreen;
-    EPHYR_RETURN_VAL_IF_FAIL(screen, FALSE);
-    screen_priv = GET_EPHYR_DRI_SCREEN_PRIV(screen);
-    EPHYR_RETURN_VAL_IF_FAIL(screen_priv && screen_priv->CreateWindow, FALSE);
-
-    EPHYR_LOG("enter. win:%p\n", a_win);
-
-    screen->CreateWindow = screen_priv->CreateWindow;
-    is_ok = (*screen->CreateWindow) (a_win);
-    screen->CreateWindow = ephyrDRICreateWindow;
-
-    if (is_ok) {
-        dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
-    }
-    return is_ok;
-}
-
-static Bool
-ephyrDRIDestroyWindow(WindowPtr a_win)
-{
-    Bool is_ok = FALSE;
-    ScreenPtr screen = NULL;
-    EphyrDRIScreenPrivPtr screen_priv = NULL;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_win, FALSE);
-    screen = a_win->drawable.pScreen;
-    EPHYR_RETURN_VAL_IF_FAIL(screen, FALSE);
-    screen_priv = GET_EPHYR_DRI_SCREEN_PRIV(screen);
-    EPHYR_RETURN_VAL_IF_FAIL(screen_priv && screen_priv->DestroyWindow, FALSE);
-
-    screen->DestroyWindow = screen_priv->DestroyWindow;
-    if (screen->DestroyWindow) {
-        is_ok = (*screen->DestroyWindow) (a_win);
-    }
-    screen->DestroyWindow = ephyrDRIDestroyWindow;
-
-    if (is_ok) {
-        EphyrDRIWindowPrivPtr win_priv = GET_EPHYR_DRI_WINDOW_PRIV(a_win);
-
-        if (win_priv) {
-            destroyHostPeerWindow(a_win);
-            free(win_priv);
-            dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
-            EPHYR_LOG("destroyed the remote peer window\n");
-        }
-    }
-    return is_ok;
-}
-
-static void
-ephyrDRIMoveWindow(WindowPtr a_win,
-                   int a_x, int a_y, WindowPtr a_siblings, VTKind a_kind)
-{
-    ScreenPtr screen = NULL;
-    EphyrDRIScreenPrivPtr screen_priv = NULL;
-    EphyrDRIWindowPrivPtr win_priv = NULL;
-    EphyrWindowPair *pair = NULL;
-    EphyrBox geo;
-    int x = 0, y = 0;           /*coords relative to parent window */
-
-    EPHYR_RETURN_IF_FAIL(a_win);
-
-    EPHYR_LOG("enter\n");
-    screen = a_win->drawable.pScreen;
-    EPHYR_RETURN_IF_FAIL(screen);
-    screen_priv = GET_EPHYR_DRI_SCREEN_PRIV(screen);
-    EPHYR_RETURN_IF_FAIL(screen_priv && screen_priv->MoveWindow);
-
-    screen->MoveWindow = screen_priv->MoveWindow;
-    if (screen->MoveWindow) {
-        (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind);
-    }
-    screen->MoveWindow = ephyrDRIMoveWindow;
-
-    EPHYR_LOG("window: %p\n", a_win);
-    if (!a_win->parent) {
-        EPHYR_LOG("cannot move root window\n");
-        return;
-    }
-    win_priv = GET_EPHYR_DRI_WINDOW_PRIV(a_win);
-    if (!win_priv) {
-        EPHYR_LOG("not a DRI peered window\n");
-        return;
-    }
-    if (!findWindowPairFromLocal(a_win, &pair) || !pair) {
-        EPHYR_LOG_ERROR("failed to get window pair\n");
-        return;
-    }
-    /*compute position relative to parent window */
-    x = a_win->drawable.x - a_win->parent->drawable.x;
-    y = a_win->drawable.y - a_win->parent->drawable.y;
-    /*set the geometry to pass to hostx_set_window_geometry */
-    memset(&geo, 0, sizeof(geo));
-    geo.x = x;
-    geo.y = y;
-    geo.width = a_win->drawable.width;
-    geo.height = a_win->drawable.height;
-    hostx_set_window_geometry(pair->remote, &geo);
-}
-
-static Bool
-ephyrDRIPositionWindow(WindowPtr a_win, int a_x, int a_y)
-{
-    Bool is_ok = FALSE;
-    ScreenPtr screen = NULL;
-    EphyrDRIScreenPrivPtr screen_priv = NULL;
-    EphyrDRIWindowPrivPtr win_priv = NULL;
-    EphyrWindowPair *pair = NULL;
-    EphyrBox geo;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_win, FALSE);
-
-    EPHYR_LOG("enter\n");
-    screen = a_win->drawable.pScreen;
-    EPHYR_RETURN_VAL_IF_FAIL(screen, FALSE);
-    screen_priv = GET_EPHYR_DRI_SCREEN_PRIV(screen);
-    EPHYR_RETURN_VAL_IF_FAIL(screen_priv && screen_priv->PositionWindow, FALSE);
-
-    screen->PositionWindow = screen_priv->PositionWindow;
-    if (screen->PositionWindow) {
-        (*screen->PositionWindow) (a_win, a_x, a_y);
-    }
-    screen->PositionWindow = ephyrDRIPositionWindow;
-
-    EPHYR_LOG("window: %p\n", a_win);
-    win_priv = GET_EPHYR_DRI_WINDOW_PRIV(a_win);
-    if (!win_priv) {
-        EPHYR_LOG("not a DRI peered window\n");
-        is_ok = TRUE;
-        goto out;
-    }
-    if (!findWindowPairFromLocal(a_win, &pair) || !pair) {
-        EPHYR_LOG_ERROR("failed to get window pair\n");
-        goto out;
-    }
-    /*set the geometry to pass to hostx_set_window_geometry */
-    memset(&geo, 0, sizeof(geo));
-    geo.x = a_x;
-    geo.y = a_y;
-    geo.width = a_win->drawable.width;
-    geo.height = a_win->drawable.height;
-    hostx_set_window_geometry(pair->remote, &geo);
-    is_ok = TRUE;
-
- out:
-    EPHYR_LOG("leave. is_ok:%d\n", is_ok);
-    /*do cleanup here */
-    return is_ok;
-}
-
-static void
-ephyrDRIClipNotify(WindowPtr a_win, int a_x, int a_y)
-{
-    ScreenPtr screen = NULL;
-    EphyrDRIScreenPrivPtr screen_priv = NULL;
-    EphyrDRIWindowPrivPtr win_priv = NULL;
-    EphyrWindowPair *pair = NULL;
-    EphyrRect *rects = NULL;
-    int i = 0;
-
-    EPHYR_RETURN_IF_FAIL(a_win);
-
-    EPHYR_LOG("enter\n");
-    screen = a_win->drawable.pScreen;
-    EPHYR_RETURN_IF_FAIL(screen);
-    screen_priv = GET_EPHYR_DRI_SCREEN_PRIV(screen);
-    EPHYR_RETURN_IF_FAIL(screen_priv && screen_priv->ClipNotify);
-
-    screen->ClipNotify = screen_priv->ClipNotify;
-    if (screen->ClipNotify) {
-        (*screen->ClipNotify) (a_win, a_x, a_y);
-    }
-    screen->ClipNotify = ephyrDRIClipNotify;
-
-    EPHYR_LOG("window: %p\n", a_win);
-    win_priv = GET_EPHYR_DRI_WINDOW_PRIV(a_win);
-    if (!win_priv) {
-        EPHYR_LOG("not a DRI peered window\n");
-        goto out;
-    }
-    if (!findWindowPairFromLocal(a_win, &pair) || !pair) {
-        EPHYR_LOG_ERROR("failed to get window pair\n");
-        goto out;
-    }
-    rects = calloc(RegionNumRects(&a_win->clipList), sizeof(EphyrRect));
-    for (i = 0; i < RegionNumRects(&a_win->clipList); i++) {
-        memmove(&rects[i],
-                &RegionRects(&a_win->clipList)[i], sizeof(EphyrRect));
-        rects[i].x1 -= a_win->drawable.x;
-        rects[i].x2 -= a_win->drawable.x;
-        rects[i].y1 -= a_win->drawable.y;
-        rects[i].y2 -= a_win->drawable.y;
-    }
-    /*
-     * push the clipping region of this window
-     * to the peer window in the host
-     */
-    hostx_set_window_bounding_rectangles
-        (pair->remote, rects, RegionNumRects(&a_win->clipList));
-
- out:
-    free(rects);
-    rects = NULL;
-
-    EPHYR_LOG("leave.\n");
-    /*do cleanup here */
-}
-
-/**
- * Duplicates a visual of a_screen
- * In screen a_screen, for depth a_depth, find a visual which
- * bitsPerRGBValue and colormap size equal
- * a_bits_per_rgb_values and a_colormap_entries.
- * The ID of that duplicated visual is set to a_new_id.
- * That duplicated visual is then added to the list of visuals
- * of the screen.
- */
-static Bool
-EphyrDuplicateVisual(unsigned int a_screen,
-                     short a_depth,
-                     short a_class,
-                     short a_bits_per_rgb_values,
-                     short a_colormap_entries,
-                     unsigned int a_red_mask,
-                     unsigned int a_green_mask,
-                     unsigned int a_blue_mask, unsigned int a_new_id)
-{
-    Bool is_ok = FALSE, found_visual = FALSE, found_depth = FALSE;
-    ScreenPtr screen = NULL;
-    VisualRec new_visual, *new_visuals = NULL;
-    int i = 0;
-
-    EPHYR_LOG("enter\n");
-    if (a_screen >= screenInfo.numScreens) {
-        EPHYR_LOG_ERROR("bad screen number\n");
-        goto out;
-    }
-    memset(&new_visual, 0, sizeof(VisualRec));
-
-    /*get the screen pointed to by a_screen */
-    screen = screenInfo.screens[a_screen];
-    EPHYR_RETURN_VAL_IF_FAIL(screen, FALSE);
-
-    /*
-     * In that screen, first look for an existing visual that has the
-     * same characteristics as those passed in parameter
-     * to this function and copy it.
-     */
-    for (i = 0; i < screen->numVisuals; i++) {
-        if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values &&
-            screen->visuals[i].ColormapEntries == a_colormap_entries) {
-            /*copy the visual found */
-            memcpy(&new_visual, &screen->visuals[i], sizeof(new_visual));
-            new_visual.vid = a_new_id;
-            new_visual.class = a_class;
-            new_visual.redMask = a_red_mask;
-            new_visual.greenMask = a_green_mask;
-            new_visual.blueMask = a_blue_mask;
-            found_visual = TRUE;
-            EPHYR_LOG("found a visual that matches visual id: %d\n", a_new_id);
-            break;
-        }
-    }
-    if (!found_visual) {
-        EPHYR_LOG("did not find any visual matching %d\n", a_new_id);
-        goto out;
-    }
-    /*
-     * be prepare to extend screen->visuals to add new_visual to it
-     */
-    new_visuals = calloc(screen->numVisuals + 1, sizeof(VisualRec));
-    memmove(new_visuals,
-            screen->visuals, screen->numVisuals * sizeof(VisualRec));
-    memmove(&new_visuals[screen->numVisuals], &new_visual, sizeof(VisualRec));
-    /*
-     * Now, in that same screen, update the screen->allowedDepths member.
-     * In that array, each element represents the visuals applicable to
-     * a given depth. So we need to add an entry matching the new visual
-     * that we are going to add to screen->visuals
-     */
-    for (i = 0; i < screen->numDepths; i++) {
-        VisualID *vids = NULL;
-        DepthPtr cur_depth = NULL;
-
-        /*find the entry matching a_depth */
-        if (screen->allowedDepths[i].depth != a_depth)
-            continue;
-        cur_depth = &screen->allowedDepths[i];
-        /*
-         * extend the list of visual IDs in that entry,
-         * so to add a_new_id in there.
-         */
-        vids = reallocarray(cur_depth->vids,
-                            cur_depth->numVids + 1, sizeof(VisualID));
-        if (!vids) {
-            EPHYR_LOG_ERROR("failed to realloc numids\n");
-            goto out;
-        }
-        vids[cur_depth->numVids] = a_new_id;
-        /*
-         * Okay now commit our change.
-         * Do really update screen->allowedDepths[i]
-         */
-        cur_depth->numVids++;
-        cur_depth->vids = vids;
-        found_depth = TRUE;
-    }
-    if (!found_depth) {
-        EPHYR_LOG_ERROR("failed to update screen[%d]->allowedDepth\n",
-                        a_screen);
-        goto out;
-    }
-    /*
-     * Commit our change to screen->visuals
-     */
-    free(screen->visuals);
-    screen->visuals = new_visuals;
-    screen->numVisuals++;
-    new_visuals = NULL;
-
-    is_ok = TRUE;
- out:
-    free(new_visuals);
-    new_visuals = NULL;
-
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
-
-/**
- * Duplicates the visuals of the host X server.
- * This is necessary to have visuals that have the same
- * ID as those of the host X. It is important to have that for
- * GLX.
- */
-static Bool
-EphyrMirrorHostVisuals(ScreenPtr a_screen)
-{
-    Bool is_ok = FALSE;
-    EphyrHostVisualInfo *visuals = NULL;
-    int nb_visuals = 0, i = 0;
-
-    EPHYR_LOG("enter\n");
-    if (!hostx_get_visuals_info(&visuals, &nb_visuals)) {
-        EPHYR_LOG_ERROR("failed to get host visuals\n");
-        goto out;
-    }
-    for (i = 0; i < nb_visuals; i++) {
-        if (!EphyrDuplicateVisual(a_screen->myNum,
-                                  visuals[i].depth,
-                                  visuals[i].class,
-                                  visuals[i].bits_per_rgb,
-                                  visuals[i].colormap_size,
-                                  visuals[i].red_mask,
-                                  visuals[i].green_mask,
-                                  visuals[i].blue_mask, visuals[i].visualid)) {
-            EPHYR_LOG_ERROR("failed to duplicate host visual %d\n",
-                            (int) visuals[i].visualid);
-        }
-    }
-
-    is_ok = TRUE;
- out:
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
-
-static int
-ProcXF86DRIQueryVersion(register ClientPtr client)
-{
-    xXF86DRIQueryVersionReply rep = {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .majorVersion = SERVER_XF86DRI_MAJOR_VERSION,
-        .minorVersion = SERVER_XF86DRI_MINOR_VERSION,
-        .patchVersion = SERVER_XF86DRI_PATCH_VERSION
-    };
-
-    REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
-
-    EPHYR_LOG("enter\n");
-
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-        swaps(&rep.majorVersion);
-        swaps(&rep.minorVersion);
-        swapl(&rep.patchVersion);
-    }
-    WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), &rep);
-    EPHYR_LOG("leave\n");
-    return Success;
-}
-
-static int
-ProcXF86DRIQueryDirectRenderingCapable(register ClientPtr client)
-{
-    xXF86DRIQueryDirectRenderingCapableReply rep;
-    Bool isCapable;
-
-    REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
-    REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
-
-    EPHYR_LOG("enter\n");
-    if (stuff->screen >= screenInfo.numScreens) {
-        client->errorValue = stuff->screen;
-        return BadValue;
-    }
-
-    if (!ephyrDRIQueryDirectRenderingCapable(stuff->screen, &isCapable)) {
-        return BadValue;
-    }
-
-    if (!client->local || client->swapped)
-        isCapable = 0;
-
-    rep = (xXF86DRIQueryDirectRenderingCapableReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .isCapable = isCapable
-    };
-
-    if (client->swapped) {
-        swaps(&rep.sequenceNumber);
-        swapl(&rep.length);
-    }
-
-    WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply),
-                  &rep);
-    EPHYR_LOG("leave\n");
-
-    return Success;
-}
-
-static int
-ProcXF86DRIOpenConnection(register ClientPtr client)
-{
-    xXF86DRIOpenConnectionReply rep;
-    drm_handle_t hSAREA;
-    char *busIdString = NULL;
-    CARD32 busIdStringLength = 0;
-
-    REQUEST(xXF86DRIOpenConnectionReq);
-    REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
-
-    EPHYR_LOG("enter\n");
-    if (stuff->screen >= screenInfo.numScreens) {
-        client->errorValue = stuff->screen;
-        return BadValue;
-    }
-
-    if (!ephyrDRIOpenConnection(stuff->screen, &hSAREA, &busIdString)) {
-        return BadValue;
-    }
-
-    if (busIdString)
-        busIdStringLength = strlen(busIdString);
-
-    rep = (xXF86DRIOpenConnectionReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) -
-                                 SIZEOF(xGenericReply) +
-                                 pad_to_int32(busIdStringLength)),
-        .hSAREALow = (CARD32) (hSAREA & 0xffffffff),
-#if defined(LONG64) && !defined(__linux__)
-        .hSAREAHigh = (CARD32) (hSAREA >> 32),
-#else
-        .hSAREAHigh = 0,
-#endif
-        .busIdStringLength = busIdStringLength
-    };
-
-    WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), &rep);
-    if (busIdStringLength)
-        WriteToClient(client, busIdStringLength, busIdString);
-    free(busIdString);
-    EPHYR_LOG("leave\n");
-    return Success;
-}
-
-static int
-ProcXF86DRIAuthConnection(register ClientPtr client)
-{
-    xXF86DRIAuthConnectionReply rep;
-
-    REQUEST(xXF86DRIAuthConnectionReq);
-    REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
-
-    EPHYR_LOG("enter\n");
-    if (stuff->screen >= screenInfo.numScreens) {
-        client->errorValue = stuff->screen;
-        return BadValue;
-    }
-
-    rep = (xXF86DRIAuthConnectionReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .authenticated = 1
-    };
-
-    if (!ephyrDRIAuthConnection(stuff->screen, stuff->magic)) {
-        ErrorF("Failed to authenticate %lu\n", (unsigned long) stuff->magic);
-        rep.authenticated = 0;
-    }
-    WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), &rep);
-    EPHYR_LOG("leave\n");
-    return Success;
-}
-
-static int
-ProcXF86DRICloseConnection(register ClientPtr client)
-{
-    REQUEST(xXF86DRICloseConnectionReq);
-    REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
-    EPHYR_LOG("enter\n");
-    if (stuff->screen >= screenInfo.numScreens) {
-        client->errorValue = stuff->screen;
-        return BadValue;
-    }
-
-    /*
-       DRICloseConnection( screenInfo.screens[stuff->screen]);
-     */
-
-    EPHYR_LOG("leave\n");
-    return Success;
-}
-
-static int
-ProcXF86DRIGetClientDriverName(register ClientPtr client)
-{
-    xXF86DRIGetClientDriverNameReply rep =  {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .clientDriverNameLength = 0
-    };
-    char *clientDriverName;
-
-    REQUEST(xXF86DRIGetClientDriverNameReq);
-    REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
-
-    EPHYR_LOG("enter\n");
-    if (stuff->screen >= screenInfo.numScreens) {
-        client->errorValue = stuff->screen;
-        return BadValue;
-    }
-
-    ephyrDRIGetClientDriverName(stuff->screen,
-                                (int *) &rep.ddxDriverMajorVersion,
-                                (int *) &rep.ddxDriverMinorVersion,
-                                (int *) &rep.ddxDriverPatchVersion,
-                                &clientDriverName);
-    if (clientDriverName)
-        rep.clientDriverNameLength = strlen(clientDriverName);
-    rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
-                                SIZEOF(xGenericReply) +
-                                pad_to_int32(rep.clientDriverNameLength));
-
-    WriteToClient(client, sizeof(xXF86DRIGetClientDriverNameReply), &rep);
-    if (rep.clientDriverNameLength)
-        WriteToClient(client, rep.clientDriverNameLength, clientDriverName);
-    EPHYR_LOG("leave\n");
-    return Success;
-}
-
-static int
-ProcXF86DRICreateContext(register ClientPtr client)
-{
-    xXF86DRICreateContextReply rep = {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0
-    };
-    ScreenPtr pScreen;
-    VisualPtr visual;
-    int i = 0;
-
-    REQUEST(xXF86DRICreateContextReq);
-    REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
-
-    EPHYR_LOG("enter\n");
-    if (stuff->screen >= screenInfo.numScreens) {
-        client->errorValue = stuff->screen;
-        return BadValue;
-    }
-
-    pScreen = screenInfo.screens[stuff->screen];
-    visual = pScreen->visuals;
-
-    /* Find the requested X visual */
-    for (i = 0; i < pScreen->numVisuals; i++, visual++)
-        if (visual->vid == stuff->visual)
-            break;
-    if (i == pScreen->numVisuals) {
-        /* No visual found */
-        return BadValue;
-    }
-
-    if (!ephyrDRICreateContext(stuff->screen,
-                               stuff->visual,
-                               stuff->context,
-                               (drm_context_t *) &rep.hHWContext)) {
-        return BadValue;
-    }
-
-    WriteToClient(client, sizeof(xXF86DRICreateContextReply), &rep);
-    EPHYR_LOG("leave\n");
-    return Success;
-}
-
-static int
-ProcXF86DRIDestroyContext(register ClientPtr client)
-{
-    REQUEST(xXF86DRIDestroyContextReq);
-    REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
-    EPHYR_LOG("enter\n");
-
-    if (stuff->screen >= screenInfo.numScreens) {
-        client->errorValue = stuff->screen;
-        return BadValue;
-    }
-
-    if (!ephyrDRIDestroyContext(stuff->screen, stuff->context)) {
-        return BadValue;
-    }
-
-    EPHYR_LOG("leave\n");
-    return Success;
-}
-
-static Bool
-getWindowVisual(const WindowPtr a_win, VisualPtr * a_visual)
-{
-    int i = 0, visual_id = 0;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_win
-                             && a_win->drawable.pScreen
-                             && a_win->drawable.pScreen->visuals, FALSE);
-
-    visual_id = wVisual(a_win);
-    for (i = 0; i < a_win->drawable.pScreen->numVisuals; i++) {
-        if (a_win->drawable.pScreen->visuals[i].vid == visual_id) {
-            *a_visual = &a_win->drawable.pScreen->visuals[i];
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-#define NUM_WINDOW_PAIRS 256
-static EphyrWindowPair window_pairs[NUM_WINDOW_PAIRS];
-
-static Bool
-appendWindowPairToList(WindowPtr a_local, int a_remote)
-{
-    int i = 0;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_local, FALSE);
-
-    EPHYR_LOG("(local,remote):(%p, %d)\n", a_local, a_remote);
-
-    for (i = 0; i < NUM_WINDOW_PAIRS; i++) {
-        if (window_pairs[i].local == NULL) {
-            window_pairs[i].local = a_local;
-            window_pairs[i].remote = a_remote;
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-static Bool
-findWindowPairFromLocal(WindowPtr a_local, EphyrWindowPair ** a_pair)
-{
-    int i = 0;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_pair && a_local, FALSE);
-
-    for (i = 0; i < NUM_WINDOW_PAIRS; i++) {
-        if (window_pairs[i].local == a_local) {
-            *a_pair = &window_pairs[i];
-            EPHYR_LOG("found (%p, %d)\n", (*a_pair)->local, (*a_pair)->remote);
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-Bool
-findWindowPairFromRemote(int a_remote, EphyrWindowPair ** a_pair)
-{
-    int i = 0;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_pair, FALSE);
-
-    for (i = 0; i < NUM_WINDOW_PAIRS; i++) {
-        if (window_pairs[i].remote == a_remote) {
-            *a_pair = &window_pairs[i];
-            EPHYR_LOG("found (%p, %d)\n", (*a_pair)->local, (*a_pair)->remote);
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-static Bool
-createHostPeerWindow(const WindowPtr a_win, int *a_peer_win)
-{
-    Bool is_ok = FALSE;
-    VisualPtr visual = NULL;
-    EphyrBox geo;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_win && a_peer_win, FALSE);
-    EPHYR_RETURN_VAL_IF_FAIL(a_win->drawable.pScreen, FALSE);
-
-    EPHYR_LOG("enter. a_win '%p'\n", a_win);
-    if (!getWindowVisual(a_win, &visual)) {
-        EPHYR_LOG_ERROR("failed to get window visual\n");
-        goto out;
-    }
-    if (!visual) {
-        EPHYR_LOG_ERROR("failed to create visual\n");
-        goto out;
-    }
-    memset(&geo, 0, sizeof(geo));
-    geo.x = a_win->drawable.x;
-    geo.y = a_win->drawable.y;
-    geo.width = a_win->drawable.width;
-    geo.height = a_win->drawable.height;
-    if (!hostx_create_window(a_win->drawable.pScreen->myNum,
-                             &geo, visual->vid, a_peer_win)) {
-        EPHYR_LOG_ERROR("failed to create host peer window\n");
-        goto out;
-    }
-    if (!appendWindowPairToList(a_win, *a_peer_win)) {
-        EPHYR_LOG_ERROR("failed to append window to pair list\n");
-        goto out;
-    }
-    is_ok = TRUE;
- out:
-    EPHYR_LOG("leave:remote win%d\n", *a_peer_win);
-    return is_ok;
-}
-
-static Bool
-destroyHostPeerWindow(const WindowPtr a_win)
-{
-    Bool is_ok = FALSE;
-    EphyrWindowPair *pair = NULL;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_win, FALSE);
-
-    EPHYR_LOG("enter\n");
-
-    if (!findWindowPairFromLocal(a_win, &pair) || !pair) {
-        EPHYR_LOG_ERROR("failed to find peer to local window\n");
-        goto out;
-    }
-    hostx_destroy_window(pair->remote);
-    is_ok = TRUE;
-
- out:
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
-
-static int
-ProcXF86DRICreateDrawable(ClientPtr client)
-{
-    xXF86DRICreateDrawableReply rep = {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0
-    };
-    DrawablePtr drawable = NULL;
-    WindowPtr window = NULL;
-    EphyrWindowPair *pair = NULL;
-    EphyrDRIWindowPrivPtr win_priv = NULL;
-    int rc = 0, remote_win = 0;
-
-    REQUEST(xXF86DRICreateDrawableReq);
-    REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
-
-    EPHYR_LOG("enter\n");
-    if (stuff->screen >= screenInfo.numScreens) {
-        client->errorValue = stuff->screen;
-        return BadValue;
-    }
-
-    rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
-                           DixReadAccess);
-    if (rc != Success)
-        return rc;
-    if (drawable->type != DRAWABLE_WINDOW) {
-        EPHYR_LOG_ERROR("non drawable windows are not yet supported\n");
-        return BadImplementation;
-    }
-    EPHYR_LOG("lookedup drawable %p\n", drawable);
-    window = (WindowPtr) drawable;
-    if (findWindowPairFromLocal(window, &pair) && pair) {
-        remote_win = pair->remote;
-        EPHYR_LOG("found window '%p' paire with remote '%d'\n",
-                  window, remote_win);
-    }
-    else if (!createHostPeerWindow(window, &remote_win)) {
-        EPHYR_LOG_ERROR("failed to create host peer window\n");
-        return BadAlloc;
-    }
-
-    if (!ephyrDRICreateDrawable(stuff->screen,
-                                remote_win,
-                                (drm_drawable_t *) &rep.hHWDrawable)) {
-        EPHYR_LOG_ERROR("failed to create dri drawable\n");
-        return BadValue;
-    }
-
-    win_priv = GET_EPHYR_DRI_WINDOW_PRIV(window);
-    if (!win_priv) {
-        win_priv = calloc(1, sizeof(EphyrDRIWindowPrivRec));
-        if (!win_priv) {
-            EPHYR_LOG_ERROR("failed to allocate window private\n");
-            return BadAlloc;
-        }
-        dixSetPrivate(&window->devPrivates, ephyrDRIWindowKey, win_priv);
-        EPHYR_LOG("paired window '%p' with remote '%d'\n", window, remote_win);
-    }
-
-    WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), &rep);
-    EPHYR_LOG("leave\n");
-    return Success;
-}
-
-static int
-ProcXF86DRIDestroyDrawable(register ClientPtr client)
-{
-    DrawablePtr drawable = NULL;
-    WindowPtr window = NULL;
-    EphyrWindowPair *pair = NULL;
-    int rc = 0;
-
-    REQUEST(xXF86DRIDestroyDrawableReq);
-    REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
-
-    EPHYR_LOG("enter\n");
-    if (stuff->screen >= screenInfo.numScreens) {
-        client->errorValue = stuff->screen;
-        return BadValue;
-    }
-
-    rc = dixLookupDrawable(&drawable,
-                           stuff->drawable, client, 0, DixReadAccess);
-    if (rc != Success)
-        return rc;
-    if (drawable->type != DRAWABLE_WINDOW) {
-        EPHYR_LOG_ERROR("non drawable windows are not yet supported\n");
-        return BadImplementation;
-    }
-    window = (WindowPtr) drawable;
-    if (!findWindowPairFromLocal(window, &pair) && pair) {
-        EPHYR_LOG_ERROR("failed to find pair window\n");
-        return BadImplementation;
-    }
-    if (!ephyrDRIDestroyDrawable(stuff->screen,
-                                 pair->remote /*drawable in host x */ )) {
-        EPHYR_LOG_ERROR("failed to destroy dri drawable\n");
-        return BadImplementation;
-    }
-    pair->local = NULL;
-    pair->remote = 0;
-
-    EPHYR_LOG("leave\n");
-    return Success;
-}
-
-static int
-ProcXF86DRIGetDrawableInfo(register ClientPtr client)
-{
-    xXF86DRIGetDrawableInfoReply rep = {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0
-    };
-    DrawablePtr drawable;
-    WindowPtr window = NULL;
-    EphyrWindowPair *pair = NULL;
-    int X = 0, Y = 0, W = 0, H = 0, backX = 0, backY = 0, rc = 0, i = 0;
-    drm_clip_rect_t *clipRects = NULL;
-    drm_clip_rect_t *backClipRects = NULL;
-
-    REQUEST(xXF86DRIGetDrawableInfoReq);
-    REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
-
-    EPHYR_LOG("enter\n");
-    if (stuff->screen >= screenInfo.numScreens) {
-        client->errorValue = stuff->screen;
-        return BadValue;
-    }
-
-    rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
-                           DixReadAccess);
-    if (rc != Success || !drawable) {
-        EPHYR_LOG_ERROR("could not get drawable\n");
-        return rc;
-    }
-
-    if (drawable->type != DRAWABLE_WINDOW) {
-        EPHYR_LOG_ERROR("non windows type drawables are not yes supported\n");
-        return BadImplementation;
-    }
-    window = (WindowPtr) drawable;
-    memset(&pair, 0, sizeof(pair));
-    if (!findWindowPairFromLocal(window, &pair) || !pair) {
-        EPHYR_LOG_ERROR("failed to find remote peer drawable\n");
-        return BadMatch;
-    }
-    EPHYR_LOG("clip list of xephyr gl drawable:\n");
-    for (i = 0; i < RegionNumRects(&window->clipList); i++) {
-        EPHYR_LOG("x1:%d, y1:%d, x2:%d, y2:%d\n",
-                  RegionRects(&window->clipList)[i].x1,
-                  RegionRects(&window->clipList)[i].y1,
-                  RegionRects(&window->clipList)[i].x2,
-                  RegionRects(&window->clipList)[i].y2);
-    }
-
-    if (!ephyrDRIGetDrawableInfo(stuff->screen,
-                                 pair->remote /*the drawable in hostx */ ,
-                                 (unsigned int *) &rep.drawableTableIndex,
-                                 (unsigned int *) &rep.drawableTableStamp,
-                                 (int *) &X,
-                                 (int *) &Y,
-                                 (int *) &W,
-                                 (int *) &H,
-                                 (int *) &rep.numClipRects,
-                                 &clipRects,
-                                 &backX,
-                                 &backY,
-                                 (int *) &rep.numBackClipRects,
-                                 &backClipRects)) {
-        return BadValue;
-    }
-    EPHYR_LOG("num clip rects:%d, num back clip rects:%d\n",
-              (int) rep.numClipRects, (int) rep.numBackClipRects);
-
-    rep.drawableX = X;
-    rep.drawableY = Y;
-    rep.drawableWidth = W;
-    rep.drawableHeight = H;
-    rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - SIZEOF(xGenericReply));
-
-    rep.backX = backX;
-    rep.backY = backY;
-
-    if (rep.numClipRects) {
-        if (clipRects) {
-            ScreenPtr pScreen = screenInfo.screens[stuff->screen];
-
-            EPHYR_LOG("clip list of host gl drawable:\n");
-            for (i = 0; i < rep.numClipRects; i++) {
-                clipRects[i].x1 = max(clipRects[i].x1, 0);
-                clipRects[i].y1 = max(clipRects[i].y1, 0);
-                clipRects[i].x2 = min(clipRects[i].x2,
-                                      pScreen->width + clipRects[i].x1);
-                clipRects[i].y2 = min(clipRects[i].y2,
-                                      pScreen->width + clipRects[i].y1);
-
-                EPHYR_LOG("x1:%d, y1:%d, x2:%d, y2:%d\n",
-                          clipRects[i].x1, clipRects[i].y1,
-                          clipRects[i].x2, clipRects[i].y2);
-            }
-        }
-        else {
-            rep.numClipRects = 0;
-        }
-    }
-    else {
-        EPHYR_LOG("got zero host gl drawable clipping rects\n");
-    }
-    rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
-    backClipRects = clipRects;
-    rep.numBackClipRects = rep.numClipRects;
-    if (rep.numBackClipRects)
-        rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
-    EPHYR_LOG("num host clip rects:%d\n", (int) rep.numClipRects);
-    EPHYR_LOG("num host back clip rects:%d\n", (int) rep.numBackClipRects);
-
-    rep.length = bytes_to_int32(rep.length);
-
-    WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), &rep);
-
-    if (rep.numClipRects) {
-        WriteToClient(client,
-                      sizeof(drm_clip_rect_t) * rep.numClipRects,
-                      clipRects);
-    }
-
-    if (rep.numBackClipRects) {
-        WriteToClient(client,
-                      sizeof(drm_clip_rect_t) * rep.numBackClipRects,
-                      backClipRects);
-    }
-    free(clipRects);
-    clipRects = NULL;
-
-    EPHYR_LOG("leave\n");
-
-    return Success;
-}
-
-static int
-ProcXF86DRIGetDeviceInfo(register ClientPtr client)
-{
-    xXF86DRIGetDeviceInfoReply rep = {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0
-    };
-    drm_handle_t hFrameBuffer;
-    void *pDevPrivate;
-
-    REQUEST(xXF86DRIGetDeviceInfoReq);
-    REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
-
-    EPHYR_LOG("enter\n");
-    if (stuff->screen >= screenInfo.numScreens) {
-        client->errorValue = stuff->screen;
-        return BadValue;
-    }
-
-    if (!ephyrDRIGetDeviceInfo(stuff->screen,
-                               &hFrameBuffer,
-                               (int *) &rep.framebufferOrigin,
-                               (int *) &rep.framebufferSize,
-                               (int *) &rep.framebufferStride,
-                               (int *) &rep.devPrivateSize, &pDevPrivate)) {
-        return BadValue;
-    }
-
-    rep.hFrameBufferLow = (CARD32) (hFrameBuffer & 0xffffffff);
-#if defined(LONG64) && !defined(__linux__)
-    rep.hFrameBufferHigh = (CARD32) (hFrameBuffer >> 32);
-#else
-    rep.hFrameBufferHigh = 0;
-#endif
-
-    if (rep.devPrivateSize) {
-        rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
-                                    SIZEOF(xGenericReply) +
-                                    pad_to_int32(rep.devPrivateSize));
-    }
-
-    WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), &rep);
-    if (rep.length) {
-        WriteToClient(client, rep.devPrivateSize, pDevPrivate);
-    }
-    EPHYR_LOG("leave\n");
-    return Success;
-}
-
-static int
-ProcXF86DRIDispatch(register ClientPtr client)
-{
-    REQUEST(xReq);
-    EPHYR_LOG("enter\n");
-
-    switch (stuff->data) {
-    case X_XF86DRIQueryVersion:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRIQueryVersion(client);
-    }
-    case X_XF86DRIQueryDirectRenderingCapable:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRIQueryDirectRenderingCapable(client);
-    }
-    }
-
-    if (!client->local)
-        return DRIErrorBase + XF86DRIClientNotLocal;
-
-    switch (stuff->data) {
-    case X_XF86DRIOpenConnection:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRIOpenConnection(client);
-    }
-    case X_XF86DRICloseConnection:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRICloseConnection(client);
-    }
-    case X_XF86DRIGetClientDriverName:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRIGetClientDriverName(client);
-    }
-    case X_XF86DRICreateContext:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRICreateContext(client);
-    }
-    case X_XF86DRIDestroyContext:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRIDestroyContext(client);
-    }
-    case X_XF86DRICreateDrawable:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRICreateDrawable(client);
-    }
-    case X_XF86DRIDestroyDrawable:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRIDestroyDrawable(client);
-    }
-    case X_XF86DRIGetDrawableInfo:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRIGetDrawableInfo(client);
-    }
-    case X_XF86DRIGetDeviceInfo:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRIGetDeviceInfo(client);
-    }
-    case X_XF86DRIAuthConnection:{
-        EPHYR_LOG("leave\n");
-        return ProcXF86DRIAuthConnection(client);
-    }
-        /* {Open,Close}FullScreen are deprecated now */
-    default:{
-        EPHYR_LOG("leave\n");
-        return BadRequest;
-    }
-    }
-}
-
-static int
-SProcXF86DRIQueryVersion(register ClientPtr client)
-{
-    REQUEST(xXF86DRIQueryVersionReq);
-    swaps(&stuff->length);
-    return ProcXF86DRIQueryVersion(client);
-}
-
-static int
-SProcXF86DRIQueryDirectRenderingCapable(register ClientPtr client)
-{
-    REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
-    swaps(&stuff->length);
-    swapl(&stuff->screen);
-    return ProcXF86DRIQueryDirectRenderingCapable(client);
-}
-
-static int
-SProcXF86DRIDispatch(register ClientPtr client)
-{
-    REQUEST(xReq);
-
-    EPHYR_LOG("enter\n");
-    /*
-     * Only local clients are allowed DRI access, but remote clients still need
-     * these requests to find out cleanly.
-     */
-    switch (stuff->data) {
-    case X_XF86DRIQueryVersion:{
-        EPHYR_LOG("leave\n");
-        return SProcXF86DRIQueryVersion(client);
-    }
-    case X_XF86DRIQueryDirectRenderingCapable:{
-        EPHYR_LOG("leave\n");
-        return SProcXF86DRIQueryDirectRenderingCapable(client);
-    }
-    default:{
-        EPHYR_LOG("leave\n");
-        return DRIErrorBase + XF86DRIClientNotLocal;
-    }
-    }
-}
-
-Bool
-ephyrDRIExtensionInit(ScreenPtr a_screen)
-{
-    Bool is_ok = FALSE;
-    ExtensionEntry *extEntry = NULL;
-    EphyrDRIScreenPrivPtr screen_priv = NULL;
-
-    EPHYR_LOG("enter\n");
-    if (!hostx_has_extension(&xcb_xf86dri_id)) {
-        EPHYR_LOG("host does not have DRI extension\n");
-        goto out;
-    }
-    EPHYR_LOG("host X does have DRI extension\n");
-    if (!hostx_has_extension(&xcb_shape_id)) {
-        EPHYR_LOG("host does not have XShape extension\n");
-        goto out;
-    }
-    EPHYR_LOG("host X does have XShape extension\n");
-
-#ifdef XF86DRI_EVENTS
-    EventType = CreateNewResourceType(XF86DRIFreeEvents, "DRIEvents");
-    if (!EventType) {
-        EPHYR_LOG_ERROR("failed to register DRI event resource type\n");
-        goto out;
-    }
-#endif
-
-    if ((extEntry = AddExtension(XF86DRINAME,
-                                 XF86DRINumberEvents,
-                                 XF86DRINumberErrors,
-                                 ProcXF86DRIDispatch,
-                                 SProcXF86DRIDispatch,
-                                 NULL, StandardMinorOpcode))) {
-        DRIReqCode = (unsigned char) extEntry->base;
-        DRIErrorBase = extEntry->errorBase;
-    }
-    else {
-        EPHYR_LOG_ERROR("failed to register DRI extension\n");
-        goto out;
-    }
-    if (!dixRegisterPrivateKey(&ephyrDRIScreenKeyRec, PRIVATE_SCREEN, 0))
-        goto out;
-    if (!dixRegisterPrivateKey(&ephyrDRIWindowKeyRec, PRIVATE_WINDOW, 0))
-        goto out;
-    screen_priv = calloc(1, sizeof(EphyrDRIScreenPrivRec));
-    if (!screen_priv) {
-        EPHYR_LOG_ERROR("failed to allocate screen_priv\n");
-        goto out;
-    }
-    dixSetPrivate(&a_screen->devPrivates, ephyrDRIScreenKey, screen_priv);
-
-    if (!ephyrDRIScreenInit(a_screen)) {
-        EPHYR_LOG_ERROR("ephyrDRIScreenInit() failed\n");
-        goto out;
-    }
-    EphyrMirrorHostVisuals(a_screen);
-    is_ok = TRUE;
- out:
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
diff --git a/hw/kdrive/ephyr/ephyrdriext.h b/hw/kdrive/ephyr/ephyrdriext.h
deleted file mode 100644
index 9755715..0000000
--- a/hw/kdrive/ephyr/ephyrdriext.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- *          Authored by Matthew Allum <mallum at openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors:
- *    Dodji Seketeli <dodji at openedhand.com>
- */
-#ifndef __EPHYRDRIEXT_H__
-#define __EPHYRDRIEXT_H__
-
-typedef struct {
-    WindowPtr local;
-    int remote;
-} EphyrWindowPair;
-
-Bool ephyrDRIExtensionInit(ScreenPtr a_screen);
-
-Bool findWindowPairFromRemote(int a_remote, EphyrWindowPair ** a_pair);
-
-#endif /*__EPHYRDRIEXT_H__*/
diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c
deleted file mode 100644
index c6d1569..0000000
--- a/hw/kdrive/ephyr/ephyrglxext.c
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- *          Authored by Matthew Allum <mallum at openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors:
- *    Dodji Seketeli <dodji at openedhand.com>
- */
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-
-#include <xcb/glx.h>
-#include "extnsionst.h"
-#include "ephyrglxext.h"
-#include "ephyrhostglx.h"
-#define _HAVE_XALLOC_DECLS
-#include "ephyrlog.h"
-#include <GL/glxproto.h>
-#include "glx/glxserver.h"
-#include "glx/indirect_table.h"
-#include "glx/indirect_util.h"
-#include "glx/unpack.h"
-#include "hostx.h"
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-int ephyrGLXQueryVersion(__GLXclientState * cl, GLbyte * pc);
-int ephyrGLXQueryVersionSwap(__GLXclientState * cl, GLbyte * pc);
-int ephyrGLXGetVisualConfigs(__GLXclientState * cl, GLbyte * pc);
-int ephyrGLXGetVisualConfigsSwap(__GLXclientState * cl, GLbyte * pc);
-int ephyrGLXClientInfo(__GLXclientState * cl, GLbyte * pc);
-int ephyrGLXClientInfoSwap(__GLXclientState * cl, GLbyte * pc);
-int ephyrGLXQueryServerString(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXQueryServerStringSwap(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXGetFBConfigsSGIX(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXGetFBConfigsSGIXSwap(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXCreateContext(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXCreateContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXCreateNewContext(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXCreateNewContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXDestroyContext(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXDestroyContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXMakeCurrent(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXMakeCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXMakeCurrentReadSGI(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXMakeCurrentReadSGISwap(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXMakeContextCurrent(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXMakeContextCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXGetString(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXGetStringSwap(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXGetIntegerv(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXGetIntegervSwap(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXIsDirect(__GLXclientState * a_cl, GLbyte * a_pc);
-int ephyrGLXIsDirectSwap(__GLXclientState * a_cl, GLbyte * a_pc);
-
-Bool
-ephyrHijackGLXExtension(void)
-{
-    const void *(*dispatch_functions)[2];
-
-    if (!hostx_has_extension(&xcb_glx_id)) {
-        EPHYR_LOG("host X does not have GLX\n");
-        return FALSE;
-    }
-    EPHYR_LOG("host X does have GLX\n");
-
-    if (!Single_dispatch_info.dispatch_functions) {
-        EPHYR_LOG_ERROR("could not get dispatch functions table\n");
-        return FALSE;
-    }
-    /*
-     * hijack some single entry point dispatch functions
-     */
-    dispatch_functions = Single_dispatch_info.dispatch_functions;
-    EPHYR_RETURN_VAL_IF_FAIL(dispatch_functions, FALSE);
-
-    dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion;
-    dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap;
-
-    dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs;
-    dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap;
-    dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo;
-    dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap;
-
-    dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString;
-    dispatch_functions[X_GLXQueryServerString][1] =
-        ephyrGLXQueryServerStringSwap;
-
-    dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext;
-    dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap;
-
-    dispatch_functions[X_GLXCreateNewContext][0] = ephyrGLXCreateNewContext;
-    dispatch_functions[X_GLXCreateNewContext][1] = ephyrGLXCreateNewContextSwap;
-
-    dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext;
-    dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap;
-
-    dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent;
-    dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap;
-
-    dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect;
-    dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap;
-
-    dispatch_functions[73][0] = ephyrGLXGetString;
-    dispatch_functions[73][1] = ephyrGLXGetStringSwap;
-
-    dispatch_functions[61][0] = ephyrGLXGetIntegerv;
-    dispatch_functions[61][1] = ephyrGLXGetIntegervSwap;
-
-    dispatch_functions[X_GLXMakeContextCurrent][0] =
-        ephyrGLXMakeContextCurrent;
-    dispatch_functions[X_GLXMakeContextCurrent][1] =
-        ephyrGLXMakeContextCurrentSwap;
-
-    /*
-     * hijack some vendor priv entry point dispatch functions
-     */
-    dispatch_functions = VendorPriv_dispatch_info.dispatch_functions;
-    dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX;
-    dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap;
-
-    dispatch_functions[89][0] = ephyrGLXMakeCurrentReadSGI;
-    dispatch_functions[89][1] = ephyrGLXMakeCurrentReadSGISwap;
-
-    EPHYR_LOG("hijacked glx entry points to forward requests to host X\n");
-
-
-    return TRUE;
-}
-
-/*********************
- * implementation of
- * hijacked GLX entry
- * points
- ********************/
-
-int
-ephyrGLXQueryVersion(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    ClientPtr client = a_cl->client;
-    xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
-    xGLXQueryVersionReply reply;
-    int major, minor;
-    int res = BadImplementation;
-
-    EPHYR_LOG("enter\n");
-
-    major = req->majorVersion;
-    minor = req->minorVersion;
-
-    if (!ephyrHostGLXQueryVersion(&major, &minor)) {
-        EPHYR_LOG_ERROR("ephyrHostGLXQueryVersion() failed\n");
-        goto out;
-    }
-    EPHYR_LOG("major:%d, minor:%d\n", major, minor);
-    reply = (xGLXQueryVersionReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .majorVersion = major,
-        .minorVersion = minor
-    };
-
-    if (client->swapped) {
-        __glXSwapQueryVersionReply(client, &reply);
-    }
-    else {
-        WriteToClient(client, sz_xGLXQueryVersionReply, &reply);
-    }
-
-    res = Success;
- out:
-    EPHYR_LOG("leave\n");
-    return res;
-}
-
-int
-ephyrGLXQueryVersionSwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
-
-    __GLX_DECLARE_SWAP_VARIABLES;
-
-    __GLX_SWAP_SHORT(&req->length);
-    __GLX_SWAP_INT(&req->majorVersion);
-    __GLX_SWAP_INT(&req->minorVersion);
-    return ephyrGLXQueryVersion(a_cl, a_pc);
-}
-
-static int
-ephyrGLXGetVisualConfigsReal(__GLXclientState * a_cl,
-                             GLbyte * a_pc, Bool a_do_swap)
-{
-    xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc;
-    ClientPtr client = a_cl->client;
-    xGLXGetVisualConfigsReply reply;
-    int32_t *props_buf = NULL, num_visuals = 0,
-        num_props = 0, res = BadImplementation, i = 0,
-        props_per_visual_size = 0, props_buf_size = 0;
-    __GLX_DECLARE_SWAP_VARIABLES;
-    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-    EPHYR_LOG("enter\n");
-
-    if (!ephyrHostGLXGetVisualConfigs(req->screen,
-                                      &num_visuals,
-                                      &num_props,
-                                      &props_buf_size, &props_buf)) {
-        EPHYR_LOG_ERROR("ephyrHostGLXGetVisualConfigs() failed\n");
-        goto out;
-    }
-    EPHYR_LOG("num_visuals:%d, num_props:%d\n", num_visuals, num_props);
-
-    reply = (xGLXGetVisualConfigsReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = (num_visuals * __GLX_SIZE_CARD32 * num_props) >> 2,
-        .numVisuals = num_visuals,
-        .numProps = num_props
-    };
-
-    if (a_do_swap) {
-        __GLX_SWAP_SHORT(&reply.sequenceNumber);
-        __GLX_SWAP_INT(&reply.length);
-        __GLX_SWAP_INT(&reply.numVisuals);
-        __GLX_SWAP_INT(&reply.numProps);
-        __GLX_SWAP_INT_ARRAY(props_buf, num_props);
-    }
-    WriteToClient(client, sz_xGLXGetVisualConfigsReply, &reply);
-    props_per_visual_size = props_buf_size / num_visuals;
-    for (i = 0; i < num_visuals; i++) {
-        WriteToClient(client,
-                      props_per_visual_size,
-                      (char *) props_buf + i * props_per_visual_size);
-    }
-    res = Success;
-
- out:
-    EPHYR_LOG("leave\n");
-    free(props_buf);
-    props_buf = NULL;
-
-    return res;
-}
-
-static int
-ephyrGLXGetFBConfigsSGIXReal(__GLXclientState * a_cl,
-                             GLbyte * a_pc, Bool a_do_swap)
-{
-    xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) a_pc;
-    ClientPtr client = a_cl->client;
-    xGLXGetVisualConfigsReply reply;
-    int32_t *props_buf = NULL, num_visuals = 0,
-        num_props = 0, res = BadImplementation, i = 0,
-        props_per_visual_size = 0, props_buf_size = 0;
-    __GLX_DECLARE_SWAP_VARIABLES;
-    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
-    EPHYR_LOG("enter\n");
-
-    if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX(req->screen,
-                                                &num_visuals,
-                                                &num_props,
-                                                &props_buf_size, &props_buf)) {
-        EPHYR_LOG_ERROR("ephyrHostGLXGetVisualConfigs() failed\n");
-        goto out;
-    }
-    EPHYR_LOG("num_visuals:%d, num_props:%d\n", num_visuals, num_props);
-
-    reply = (xGLXGetVisualConfigsReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = props_buf_size >> 2,
-        .numVisuals = num_visuals,
-        .numProps = num_props
-    };
-
-    if (a_do_swap) {
-        __GLX_SWAP_SHORT(&reply.sequenceNumber);
-        __GLX_SWAP_INT(&reply.length);
-        __GLX_SWAP_INT(&reply.numVisuals);
-        __GLX_SWAP_INT(&reply.numProps);
-        __GLX_SWAP_INT_ARRAY(props_buf, num_props);
-    }
-    WriteToClient(client, sz_xGLXGetVisualConfigsReply, &reply);
-    props_per_visual_size = props_buf_size / num_visuals;
-    for (i = 0; i < num_visuals; i++) {
-        WriteToClient(client,
-                      props_per_visual_size,
-                      &((char *) props_buf)[i * props_per_visual_size]);
-    }
-    res = Success;
-
- out:
-    EPHYR_LOG("leave\n");
-    free(props_buf);
-    props_buf = NULL;
-
-    return res;
-}
-
-int
-ephyrGLXGetVisualConfigs(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXGetVisualConfigsReal(a_cl, a_pc, FALSE);
-}
-
-int
-ephyrGLXGetVisualConfigsSwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXGetVisualConfigsReal(a_cl, a_pc, TRUE);
-}
-
-int
-ephyrGLXClientInfo(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    int res = BadImplementation;
-    xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
-
-    EPHYR_LOG("enter\n");
-    if (!ephyrHostGLXSendClientInfo(req->major, req->minor, (char *) req + 1)) {
-        EPHYR_LOG_ERROR("failed to send client info to host\n");
-        goto out;
-    }
-    res = Success;
-
- out:
-    EPHYR_LOG("leave\n");
-    return res;
-}
-
-int
-ephyrGLXClientInfoSwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
-
-    __GLX_DECLARE_SWAP_VARIABLES;
-
-    __GLX_SWAP_SHORT(&req->length);
-    __GLX_SWAP_INT(&req->major);
-    __GLX_SWAP_INT(&req->minor);
-    __GLX_SWAP_INT(&req->numbytes);
-
-    return ephyrGLXClientInfo(a_cl, a_pc);
-}
-
-int
-ephyrGLXQueryServerString(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    int res = BadImplementation;
-    ClientPtr client = a_cl->client;
-    xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc;
-    xGLXQueryServerStringReply reply;
-    char *server_string = NULL;
-    int length = 0;
-
-    EPHYR_LOG("enter\n");
-    if (!ephyrHostGLXQueryServerString(req->screen,
-                                       req->name,
-                                       &server_string)) {
-        EPHYR_LOG_ERROR("failed to query string from host\n");
-        goto out;
-    }
-    EPHYR_LOG("string: %s\n", server_string);
-    length = strlen(server_string) + 1;
-    reply = (xGLXQueryServerStringReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = __GLX_PAD(length) >> 2,
-        .n = length
-    };
-
-    WriteToClient(client, sz_xGLXQueryServerStringReply, &reply);
-    WriteToClient(client, (int) (reply.length << 2), server_string);
-
-    res = Success;
-
- out:
-    EPHYR_LOG("leave\n");
-    free(server_string);
-    server_string = NULL;
-
-    return res;
-}
-
-int
-ephyrGLXQueryServerStringSwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    EPHYR_LOG_ERROR("not yet implemented\n");
-    return BadImplementation;
-}
-
-int
-ephyrGLXGetFBConfigsSGIX(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXGetFBConfigsSGIXReal(a_cl, a_pc, FALSE);
-}
-
-int
-ephyrGLXGetFBConfigsSGIXSwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXGetFBConfigsSGIXReal(a_cl, a_pc, TRUE);
-}
-
-static int
-ephyrGLXCreateContextReal(xGLXCreateContextReq * a_req, Bool a_do_swap)
-{
-    int res = BadImplementation;
-    EphyrHostWindowAttributes host_w_attrs;
-
-    __GLX_DECLARE_SWAP_VARIABLES;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_req, BadValue);
-    EPHYR_LOG("enter\n");
-
-    if (a_do_swap) {
-        __GLX_SWAP_SHORT(&a_req->length);
-        __GLX_SWAP_INT(&a_req->context);
-        __GLX_SWAP_INT(&a_req->visual);
-        __GLX_SWAP_INT(&a_req->screen);
-        __GLX_SWAP_INT(&a_req->shareList);
-    }
-
-    EPHYR_LOG("context creation requested. localid:%d, "
-              "screen:%d, visual:%d, direct:%d\n",
-              (int) a_req->context, (int) a_req->screen,
-              (int) a_req->visual, (int) a_req->isDirect);
-
-    memset(&host_w_attrs, 0, sizeof(host_w_attrs));
-    if (!hostx_get_window_attributes(hostx_get_window(a_req->screen),
-                                     &host_w_attrs)) {
-        EPHYR_LOG_ERROR("failed to get host window attrs\n");
-        goto out;
-    }
-
-    EPHYR_LOG("host window visual id: %d\n", host_w_attrs.visualid);
-
-    if (!ephyrHostGLXCreateContext(a_req->screen,
-                                   host_w_attrs.visualid,
-                                   a_req->context,
-                                   a_req->shareList, 0,
-                                   a_req->isDirect, X_GLXCreateContext)) {
-        EPHYR_LOG_ERROR("ephyrHostGLXCreateContext() failed\n");
-        goto out;
-    }
-    res = Success;
- out:
-    EPHYR_LOG("leave\n");
-    return res;
-}
-
-static int
-ephyrGLXCreateNewContextReal(xGLXCreateNewContextReq * a_req, Bool a_do_swap)
-{
-    int res = BadImplementation;
-
-    __GLX_DECLARE_SWAP_VARIABLES;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_req, BadValue);
-    EPHYR_LOG("enter\n");
-
-    if (a_do_swap) {
-        __GLX_SWAP_SHORT(&a_req->length);
-        __GLX_SWAP_INT(&a_req->context);
-        __GLX_SWAP_INT(&a_req->fbconfig);
-        __GLX_SWAP_INT(&a_req->screen);
-        __GLX_SWAP_INT(&a_req->renderType);
-        __GLX_SWAP_INT(&a_req->shareList);
-    }
-
-    EPHYR_LOG("context creation requested. localid:%d, "
-              "screen:%d, fbconfig:%d, renderType:%d, direct:%d\n",
-              (int) a_req->context, (int) a_req->screen,
-              (int) a_req->fbconfig, (int) a_req->renderType,
-              (int) a_req->isDirect);
-
-    if (!ephyrHostGLXCreateContext(a_req->screen,
-                                   a_req->fbconfig,
-                                   a_req->context,
-                                   a_req->shareList, a_req->renderType,
-                                   a_req->isDirect, X_GLXCreateNewContext)) {
-        EPHYR_LOG_ERROR("ephyrHostGLXCreateNewContext() failed\n");
-        goto out;
-    }
-    res = Success;
- out:
-    EPHYR_LOG("leave\n");
-    return res;
-}
-
-int
-ephyrGLXCreateContext(__GLXclientState * cl, GLbyte * pc)
-{
-    xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
-
-    return ephyrGLXCreateContextReal(req, FALSE);
-}
-
-int
-ephyrGLXCreateContextSwap(__GLXclientState * cl, GLbyte * pc)
-{
-    xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
-
-    return ephyrGLXCreateContextReal(req, TRUE);
-}
-
-int
-ephyrGLXCreateNewContext(__GLXclientState * cl, GLbyte * pc)
-{
-    xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
-
-    return ephyrGLXCreateNewContextReal(req, FALSE);
-}
-
-int
-ephyrGLXCreateNewContextSwap(__GLXclientState * cl, GLbyte * pc)
-{
-    xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
-
-    return ephyrGLXCreateNewContextReal(req, TRUE);
-}
-
-static int
-ephyrGLXDestroyContextReal(__GLXclientState * a_cl,
-                           GLbyte * a_pc, Bool a_do_swap)
-{
-    int res = BadImplementation;
-    ClientPtr client = a_cl->client;
-    xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc;
-
-    EPHYR_LOG("enter. id:%d\n", (int) req->context);
-    if (!ephyrHostDestroyContext(req->context)) {
-        EPHYR_LOG_ERROR("ephyrHostDestroyContext() failed\n");
-        client->errorValue = req->context;
-        goto out;
-    }
-    res = Success;
-
- out:
-    EPHYR_LOG("leave\n");
-    return res;
-}
-
-int
-ephyrGLXDestroyContext(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXDestroyContextReal(a_cl, a_pc, FALSE);
-}
-
-int
-ephyrGLXDestroyContextSwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXDestroyContextReal(a_cl, a_pc, TRUE);
-}
-
-static int
-ephyrGLXMakeCurrentReal(__GLXclientState * a_cl, GLXDrawable write,
-                        GLXDrawable read, GLXContextTag ctx,
-                        GLXContextTag old_ctx, Bool a_do_swap)
-{
-    int res = BadImplementation;
-    xGLXMakeCurrentReply reply;
-    DrawablePtr drawableR = NULL, drawableW = NULL;
-    GLXContextTag new_ctx = 0;
-
-    EPHYR_LOG("enter\n");
-    res = dixLookupDrawable(&drawableW, write, a_cl->client, 0, DixReadAccess);
-    EPHYR_RETURN_VAL_IF_FAIL(drawableW, BadValue);
-    EPHYR_RETURN_VAL_IF_FAIL(drawableW->pScreen, BadValue);
-    EPHYR_LOG("screen nummber requested:%d\n", drawableW->pScreen->myNum);
-
-    if (read != write) {
-        res = dixLookupDrawable(&drawableR, read, a_cl->client, 0,
-                                DixReadAccess);
-        EPHYR_RETURN_VAL_IF_FAIL(drawableR, BadValue);
-        EPHYR_RETURN_VAL_IF_FAIL(drawableR->pScreen, BadValue);
-    }
-    else {
-        drawableR = drawableW;
-    }
-
-    if (!ephyrHostGLXMakeCurrent(hostx_get_window(drawableW->pScreen->myNum),
-                                 hostx_get_window(drawableR->pScreen->myNum),
-                                 ctx, old_ctx, (int *) &new_ctx)) {
-        EPHYR_LOG_ERROR("ephyrHostGLXMakeCurrent() failed\n");
-        goto out;
-    }
-    reply = (xGLXMakeCurrentReply) {
-        .type = X_Reply,
-        .sequenceNumber = a_cl->client->sequence,
-        .length = 0,
-        .contextTag = new_ctx
-    };
-    if (a_do_swap) {
-        __GLX_DECLARE_SWAP_VARIABLES;
-        __GLX_SWAP_SHORT(&reply.sequenceNumber);
-        __GLX_SWAP_INT(&reply.length);
-        __GLX_SWAP_INT(&reply.contextTag);
-    }
-    WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, &reply);
-
-    res = Success;
- out:
-    EPHYR_LOG("leave\n");
-    return res;
-}
-
-int
-ephyrGLXMakeCurrent(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
-    return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->drawable,
-                                   req->context, req->oldContextTag, FALSE);
-}
-
-int
-ephyrGLXMakeCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
-    __GLX_DECLARE_SWAP_VARIABLES;
-
-    __GLX_SWAP_INT(&req->drawable);
-    __GLX_SWAP_INT(&req->context);
-    __GLX_SWAP_INT(&req->oldContextTag);
-
-    return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->drawable,
-                                   req->context, req->oldContextTag, TRUE);
-}
-
-int
-ephyrGLXMakeCurrentReadSGI(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) a_pc;
-
-    return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readable,
-                                   req->context, req->oldContextTag, FALSE);
-}
-
-int
-ephyrGLXMakeCurrentReadSGISwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) a_pc;
-    __GLX_DECLARE_SWAP_VARIABLES;
-
-    __GLX_SWAP_INT(&req->drawable);
-    __GLX_SWAP_INT(&req->readable);
-    __GLX_SWAP_INT(&req->context);
-    __GLX_SWAP_INT(&req->oldContextTag);
-
-    return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readable,
-                                   req->context, req->oldContextTag, TRUE);
-}
-
-int
-ephyrGLXMakeContextCurrent(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) a_pc;
-
-    return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readdrawable,
-                                   req->context, req->oldContextTag, FALSE);
-}
-
-int
-ephyrGLXMakeContextCurrentSwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) a_pc;
-    __GLX_DECLARE_SWAP_VARIABLES;
-
-    __GLX_SWAP_INT(&req->drawable);
-    __GLX_SWAP_INT(&req->readdrawable);
-    __GLX_SWAP_INT(&req->context);
-    __GLX_SWAP_INT(&req->oldContextTag);
-
-    return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->readdrawable,
-                                   req->context, req->oldContextTag, TRUE);
-}
-
-static int
-ephyrGLXGetStringReal(__GLXclientState * a_cl, GLbyte * a_pc, Bool a_do_swap)
-{
-    ClientPtr client = NULL;
-    int context_tag = 0, name = 0, res = BadImplementation, length = 0;
-    char *string = NULL;
-
-    __GLX_DECLARE_SWAP_VARIABLES;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_cl && a_pc, BadValue);
-
-    EPHYR_LOG("enter\n");
-
-    client = a_cl->client;
-
-    if (a_do_swap) {
-        __GLX_SWAP_INT(a_pc + 4);
-        __GLX_SWAP_INT(a_pc + __GLX_SINGLE_HDR_SIZE);
-    }
-    context_tag = __GLX_GET_SINGLE_CONTEXT_TAG(a_pc);
-    a_pc += __GLX_SINGLE_HDR_SIZE;
-    name = *(GLenum *) (a_pc + 0);
-    EPHYR_LOG("context_tag:%d, name:%d\n", context_tag, name);
-    if (!ephyrHostGLXGetString(context_tag, name, &string)) {
-        EPHYR_LOG_ERROR("failed to get string from server\n");
-        goto out;
-    }
-    if (string) {
-        length = strlen(string) + 1;
-        EPHYR_LOG("got string:'%s', size:%d\n", string, length);
-    }
-    else {
-        EPHYR_LOG("got string: string (null)\n");
-    }
-    __GLX_BEGIN_REPLY(length);
-    __GLX_PUT_SIZE(length);
-    __GLX_SEND_HEADER();
-    if (a_do_swap) {
-        __GLX_SWAP_REPLY_SIZE();
-        __GLX_SWAP_REPLY_HEADER();
-    }
-    WriteToClient(client, length, string);
-
-    res = Success;
- out:
-    EPHYR_LOG("leave\n");
-    return res;
-}
-
-int
-ephyrGLXGetString(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXGetStringReal(a_cl, a_pc, FALSE);
-}
-
-int
-ephyrGLXGetStringSwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXGetStringReal(a_cl, a_pc, TRUE);
-}
-
-static int
-ephyrGLXGetIntegervReal(__GLXclientState * a_cl, GLbyte * a_pc, Bool a_do_swap)
-{
-    int res = BadImplementation;
-    xGLXSingleReq *const req = (xGLXSingleReq *) a_pc;
-    GLenum int_name;
-    int value = 0;
-    GLint answer_buf_room[200];
-    GLint *buf = NULL;
-
-    EPHYR_LOG("enter\n");
-
-    a_pc += __GLX_SINGLE_HDR_SIZE;
-
-    int_name = *(GLenum *) (a_pc + 0);
-    if (!ephyrHostGetIntegerValue(req->contextTag, int_name, &value)) {
-        EPHYR_LOG_ERROR("ephyrHostGetIntegerValue() failed\n");
-        goto out;
-    }
-    buf = __glXGetAnswerBuffer(a_cl, sizeof(value),
-                               answer_buf_room, sizeof(answer_buf_room), 4);
-
-    if (!buf) {
-        EPHYR_LOG_ERROR("failed to allocate reply buffer\n");
-        res = BadAlloc;
-        goto out;
-    }
-    __glXSendReply(a_cl->client, buf, 1, sizeof(value), GL_FALSE, 0);
-    res = Success;
-
- out:
-    EPHYR_LOG("leave\n");
-    return res;
-}
-
-int
-ephyrGLXGetIntegerv(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXGetIntegervReal(a_cl, a_pc, FALSE);
-}
-
-int
-ephyrGLXGetIntegervSwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXGetIntegervReal(a_cl, a_pc, TRUE);
-}
-
-static int
-ephyrGLXIsDirectReal(__GLXclientState * a_cl, GLbyte * a_pc, Bool a_do_swap)
-{
-    int res = BadImplementation;
-    ClientPtr client = a_cl->client;
-    xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc;
-    xGLXIsDirectReply reply;
-    int is_direct = 0;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_cl && a_pc, FALSE);
-
-    EPHYR_LOG("enter\n");
-
-    if (!ephyrHostIsContextDirect(req->context, (int *) &is_direct)) {
-        EPHYR_LOG_ERROR("ephyrHostIsContextDirect() failed\n");
-        goto out;
-    }
-    reply = (xGLXIsDirectReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .isDirect = is_direct
-    };
-
-    WriteToClient(client, sz_xGLXIsDirectReply, &reply);
-    res = Success;
-
- out:
-    EPHYR_LOG("leave\n");
-    return res;
-}
-
-int
-ephyrGLXIsDirect(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXIsDirectReal(a_cl, a_pc, FALSE);
-}
-
-int
-ephyrGLXIsDirectSwap(__GLXclientState * a_cl, GLbyte * a_pc)
-{
-    return ephyrGLXIsDirectReal(a_cl, a_pc, TRUE);
-}
diff --git a/hw/kdrive/ephyr/ephyrglxext.h b/hw/kdrive/ephyr/ephyrglxext.h
deleted file mode 100644
index 8b4b3a2..0000000
--- a/hw/kdrive/ephyr/ephyrglxext.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- *          Authored by Matthew Allum <mallum at openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors:
- *    Dodji Seketeli <dodji at openedhand.com>
- */
-#ifndef __EPHYR_GLXEXT_H__
-#define __EPHYR_GLXEXT_H__
-
-#include <X11/Xdefs.h>
-Bool ephyrHijackGLXExtension(void);
-
-#endif /*__EPHYR_GLXEXT_H__*/
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
deleted file mode 100644
index 0b98cce..0000000
--- a/hw/kdrive/ephyr/ephyrhostglx.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- *          Authored by Matthew Allum <mallum at openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * a lots of the content of this file has been adapted from the mesa source
- * code.
- * Authors:
- *    Dodji Seketeli <dodji at openedhand.com>
- */
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-
-#include <X11/Xdefs.h>
-#include <X11/Xmd.h>
-#include <GL/glxproto.h>
-#include <xcb/glx.h>
-#include "ephyrhostglx.h"
-#define _HAVE_XALLOC_DECLS
-#include "ephyrlog.h"
-#include "hostx.h"
-
-static int glx_major, glx_minor;
-
-enum VisualConfRequestType {
-    EPHYR_GET_FB_CONFIG,
-    EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
-    EPHYR_GET_VISUAL_CONFIGS
-};
-
-static Bool ephyrHostGLXGetVisualConfigsInternal
-    (enum VisualConfRequestType a_type,
-     xcb_glx_get_visual_configs_reply_t *reply,
-     int32_t a_screen,
-     int32_t *a_num_visuals,
-     int32_t *a_num_props,
-     int32_t *a_props_buf_size,
-     int32_t **a_props_buf);
-
-Bool
-ephyrHostGLXQueryVersion(int *a_major, int *a_minor)
-{
-    Bool is_ok = FALSE;
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    xcb_glx_query_version_cookie_t cookie;
-    xcb_glx_query_version_reply_t *reply;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_major && a_minor, FALSE);
-    EPHYR_LOG("enter\n");
-
-    if (glx_major) {
-        *a_major = glx_major;
-        *a_minor = glx_minor;
-        return TRUE;
-    }
-
-    /* Send the glXQueryVersion request */
-    cookie = xcb_glx_query_version(conn, 2, 1);
-    reply = xcb_glx_query_version_reply(conn, cookie, NULL);
-    if (!reply)
-        goto out;
-    *a_major = reply->major_version;
-    *a_minor = reply->minor_version;
-    free(reply);
-
-    EPHYR_LOG("major:%d, minor:%d\n", *a_major, *a_minor);
-
-    is_ok = TRUE;
- out:
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
-
-Bool
-ephyrHostGLXGetString(int a_context_tag,
-                      int a_string_name,
-                      char **a_string)
-{
-    Bool is_ok = FALSE;
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    xcb_glx_get_string_cookie_t cookie;
-    xcb_glx_get_string_reply_t *reply;
-
-    EPHYR_RETURN_VAL_IF_FAIL(conn && a_string, FALSE);
-
-    EPHYR_LOG("enter\n");
-    cookie = xcb_glx_get_string(conn, a_context_tag, a_string_name);
-    reply = xcb_glx_get_string_reply(conn, cookie, NULL);
-    if (!reply)
-        goto out;
-    *a_string = malloc(reply->n + 1);
-    memcpy(*a_string, xcb_glx_get_string_string(reply), reply->n);
-    (*a_string)[reply->n] = '\0';
-    free(reply);
-    is_ok = TRUE;
-out:
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
-
-Bool ephyrHostGLXQueryServerString(int a_screen_number,
-                                   int a_string_name,
-                                   char **a_string)
-{
-    Bool is_ok = FALSE;
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    int default_screen = hostx_get_screen();
-    xcb_glx_query_server_string_cookie_t cookie;
-    xcb_glx_query_server_string_reply_t *reply;
-
-    EPHYR_RETURN_VAL_IF_FAIL(conn && a_string, FALSE);
-
-    EPHYR_LOG("enter\n");
-    cookie = xcb_glx_query_server_string(conn, default_screen, a_string_name);
-    reply = xcb_glx_query_server_string_reply(conn, cookie, NULL);
-    if (!reply)
-        goto out;
-    *a_string = malloc(reply->str_len + 1);
-    memcpy(*a_string, xcb_glx_query_server_string_string(reply), reply->str_len);
-    (*a_string)[reply->str_len] = '\0';
-    free(reply);
-    is_ok = TRUE;
-out:
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
-
-static Bool
-ephyrHostGLXGetVisualConfigsInternal(enum VisualConfRequestType a_type,
-                                     xcb_glx_get_visual_configs_reply_t *reply,
-                                     int32_t a_screen,
-                                     int32_t * a_num_visuals,
-                                     int32_t * a_num_props,
-                                     int32_t * a_props_buf_size,
-                                     int32_t ** a_props_buf)
-{
-    Bool is_ok = FALSE;
-    int num_props = 0, num_visuals = 0, props_buf_size = 0;
-    int props_per_visual_size = 0;
-    int32_t *props_buf = NULL;
-
-   if (!reply->num_visuals) {
-        EPHYR_LOG_ERROR("screen does not support GL rendering\n");
-        goto out;
-    }
-    num_visuals = reply->num_visuals;
-
-    num_props = reply->num_properties;
-
-    if (a_type != EPHYR_GET_VISUAL_CONFIGS) {
-        num_props *= 2;
-    }
-    props_per_visual_size = num_props * sizeof(uint32_t);
-    props_buf_size = props_per_visual_size * reply->num_visuals;
-    props_buf = malloc(props_buf_size);
-    if (!props_buf)
-        goto out;
-    memcpy(props_buf, xcb_glx_get_visual_configs_property_list(reply),
-           props_buf_size);
-
-    *a_num_visuals = num_visuals;
-    *a_num_props = reply->num_properties;
-    *a_props_buf_size = props_buf_size;
-    *a_props_buf = props_buf;
-    is_ok = TRUE;
-
-out:
-    return is_ok;
-}
-
-Bool
-ephyrHostGLXGetVisualConfigs(int32_t a_screen,
-                             int32_t * a_num_visuals,
-                             int32_t * a_num_props,
-                             int32_t * a_props_buf_size, int32_t ** a_props_buf)
-{
-    Bool is_ok = FALSE;
-    xcb_glx_get_visual_configs_cookie_t cookie;
-    xcb_glx_get_visual_configs_reply_t *reply;
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    int screen = hostx_get_screen();
-
-    EPHYR_LOG("enter\n");
-    cookie = xcb_glx_get_visual_configs(conn, screen);
-    reply = xcb_glx_get_visual_configs_reply(conn, cookie, NULL);
-    if (!reply)
-        goto out;
-    is_ok = ephyrHostGLXGetVisualConfigsInternal
-        (EPHYR_GET_VISUAL_CONFIGS,
-         reply,
-         a_screen,
-         a_num_visuals,
-         a_num_props,
-         a_props_buf_size,
-         a_props_buf);
-
-out:
-    free(reply);
-    EPHYR_LOG("leave:%d\n", is_ok);
-    return is_ok;
-}
-
-Bool
-ephyrHostGLXVendorPrivGetFBConfigsSGIX(int a_screen,
-                                       int32_t * a_num_visuals,
-                                       int32_t * a_num_props,
-                                       int32_t * a_props_buf_size,
-                                       int32_t ** a_props_buf)
-{
-    Bool is_ok=FALSE;
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    int screen = hostx_get_screen();
-    xcb_glx_vendor_private_with_reply_cookie_t cookie;
-    union {
-        xcb_glx_vendor_private_with_reply_reply_t *vprep;
-        xcb_glx_get_visual_configs_reply_t *rep;
-    } reply;
-
-    EPHYR_LOG("enter\n");
-    cookie = xcb_glx_vendor_private_with_reply(conn,
-                                               X_GLXvop_GetFBConfigsSGIX,
-                                               0, 4, (uint8_t *)&screen);
-    reply.vprep = xcb_glx_vendor_private_with_reply_reply(conn, cookie, NULL);
-    if (!reply.vprep)
-        goto out;
-    is_ok = ephyrHostGLXGetVisualConfigsInternal
-        (EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
-         reply.rep,
-         a_screen,
-         a_num_visuals,
-         a_num_props,
-         a_props_buf_size,
-         a_props_buf);
-out:
-    free(reply.vprep);
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
-
-Bool
-ephyrHostGLXSendClientInfo(int32_t a_major, int32_t a_minor,
-                           const char *a_extension_list)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    int size;
-
-    EPHYR_RETURN_VAL_IF_FAIL(conn && a_extension_list, FALSE);
-
-    size = strlen (a_extension_list) + 1;
-    xcb_glx_client_info(conn, a_major, a_minor, size, a_extension_list);
-
-    return TRUE;
-}
-
-Bool
-ephyrHostGLXCreateContext(int a_screen,
-                          int a_generic_id,
-                          int a_context_id,
-                          int a_share_list_ctxt_id,
-                          int a_render_type,
-                          Bool a_direct,
-                          int code)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    Bool is_ok = FALSE;
-    int remote_context_id = 0;
-
-    EPHYR_LOG("enter. screen:%d, generic_id:%d, contextid:%d, rendertype:%d, "
-                 "direct:%d\n", a_screen, a_generic_id, a_context_id,
-                 a_render_type, a_direct);
-
-    if (!hostx_allocate_resource_id_peer(a_context_id, &remote_context_id)) {
-        EPHYR_LOG_ERROR("failed to peer the context id %d host X",
-                        remote_context_id);
-        goto out;
-    }
-
-    switch (code) {
-    case X_GLXCreateContext: {
-        xcb_glx_create_context(conn,
-                               remote_context_id,
-                               a_generic_id,
-                               hostx_get_screen(),
-                               a_share_list_ctxt_id,
-                               a_direct);
-   }
-
-    case X_GLXCreateNewContext: {
-        xcb_glx_create_new_context(conn,
-                                   remote_context_id,
-                                   a_generic_id,
-                                   hostx_get_screen(),
-                                   a_render_type,
-                                   a_share_list_ctxt_id,
-                                   a_direct);
-    }
-
-    default:
-        /* This should never be reached !*/
-        EPHYR_LOG("Internal error! Invalid CreateContext code!\n");
-    }
-
-    is_ok = TRUE;
-
- out:
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
-
-Bool
-ephyrHostDestroyContext(int a_ctxt_id)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    Bool is_ok = FALSE;
-    int remote_ctxt_id = 0;
-
-    EPHYR_LOG("enter:%d\n", a_ctxt_id);
-
-    if (!hostx_get_resource_id_peer(a_ctxt_id, &remote_ctxt_id)) {
-        EPHYR_LOG_ERROR("failed to get remote glx ctxt id\n");
-        goto out;
-    }
-    EPHYR_LOG("host context id:%d\n", remote_ctxt_id);
-
-    xcb_glx_destroy_context(conn, remote_ctxt_id);
-
-    is_ok = TRUE;
-
- out:
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
-
-Bool
-ephyrHostGLXMakeCurrent(int a_drawable, int a_readable,
-                        int a_glx_ctxt_id, int a_old_ctxt_tag, int *a_ctxt_tag)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    Bool is_ok = FALSE;
-    int remote_glx_ctxt_id = 0;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_ctxt_tag, FALSE);
-
-    EPHYR_LOG("enter. drawable:%d, read:%d, context:%d, oldtag:%d\n",
-              a_drawable, a_readable, a_glx_ctxt_id, a_old_ctxt_tag);
-
-    if (!hostx_get_resource_id_peer(a_glx_ctxt_id, &remote_glx_ctxt_id)) {
-        EPHYR_LOG_ERROR("failed to get remote glx ctxt id\n");
-        goto out;
-    }
-
-    /* If both drawables are the same, use the old MakeCurrent request.
-     * Otherwise, if we have GLX 1.3 or higher, use the MakeContextCurrent
-     * request which supports separate read and draw targets.  Failing that,
-     * try the SGI MakeCurrentRead extension.  Logic cribbed from Mesa. */
-    if (a_drawable == a_readable) {
-        xcb_glx_make_current_cookie_t cookie;
-        xcb_glx_make_current_reply_t *reply;
-        cookie = xcb_glx_make_current(conn,
-                                      a_drawable,
-                                      remote_glx_ctxt_id,
-                                      a_old_ctxt_tag);
-        reply = xcb_glx_make_current_reply(conn, cookie, NULL);
-        if (!reply)
-            goto out;
-        *a_ctxt_tag = reply->context_tag;
-        free(reply);
-    }
-    else if (glx_major > 1 || glx_minor >= 3) {
-        xcb_glx_make_context_current_cookie_t cookie;
-        xcb_glx_make_context_current_reply_t *reply;
-        cookie = xcb_glx_make_context_current(conn,
-                                              a_old_ctxt_tag,
-                                              a_drawable,
-                                              a_readable,
-                                              remote_glx_ctxt_id);
-        reply = xcb_glx_make_context_current_reply(conn, cookie, NULL);
-        if (!reply)
-            goto out;
-        *a_ctxt_tag = reply->context_tag;
-        free(reply);
-    }
-    else {
-        xcb_glx_vendor_private_with_reply_cookie_t cookie;
-        xcb_glx_vendor_private_with_reply_reply_t *reply;
-        uint32_t data[3] = {
-            a_drawable, a_readable, remote_glx_ctxt_id,
-        };
-
-        EPHYR_LOG("enter\n");
-        cookie = xcb_glx_vendor_private_with_reply(conn,
-                                                   X_GLXvop_MakeCurrentReadSGI,
-                                                   a_old_ctxt_tag,
-                                                   sizeof(data),
-                                                   (uint8_t *)data);
-        reply = xcb_glx_vendor_private_with_reply_reply(conn, cookie, NULL);
-
-        *a_ctxt_tag = reply->retval;
-
-        free(reply);
-    }
-
-    EPHYR_LOG("context tag:%d\n", *a_ctxt_tag);
-    is_ok = TRUE;
-
- out:
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
-
-Bool
-ephyrHostGetIntegerValue(int a_current_context_tag, int a_int, int *a_val)
-{
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    Bool is_ok = FALSE;
-    int size = 0;
-    xcb_glx_get_integerv_cookie_t cookie;
-    xcb_glx_get_integerv_reply_t *reply;
-
-    EPHYR_RETURN_VAL_IF_FAIL(a_val, FALSE);
-
-    EPHYR_LOG("enter\n");
-    cookie = xcb_glx_get_integerv(conn, a_current_context_tag, a_int);
-    reply = xcb_glx_get_integerv_reply(conn, cookie, NULL);
-    if (!reply)
-        goto out;
-    size = reply->n;
-    if (!size) {
-        EPHYR_LOG_ERROR("X_GLsop_GetIngerv failed\n");
-        goto out;
-    }
-    *a_val = reply->datum;
-    is_ok = TRUE;
-
-out:
-    free(reply);
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
-
-Bool
-ephyrHostIsContextDirect(int a_ctxt_id, int *a_is_direct)
-{
-    Bool is_ok = FALSE;
-    xcb_connection_t *conn = hostx_get_xcbconn();
-    xcb_glx_is_direct_cookie_t cookie;
-    xcb_glx_is_direct_reply_t *reply = NULL;
-    int remote_glx_ctxt_id = 0;
-
-    EPHYR_LOG("enter\n");
-    if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_glx_ctxt_id)) {
-        EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n");
-        goto out;
-    }
-
-    /* Send the glXIsDirect request */
-    cookie = xcb_glx_is_direct(conn, remote_glx_ctxt_id);
-    reply = xcb_glx_is_direct_reply(conn, cookie, NULL);
-    if (!reply) {
-        EPHYR_LOG_ERROR("fail in reading reply from host\n");
-        goto out;
-    }
-    *a_is_direct = reply->is_direct;
-    is_ok = TRUE;
-
-out:
-    free(reply);
-    EPHYR_LOG("leave\n");
-    return is_ok;
-}
diff --git a/hw/kdrive/ephyr/ephyrhostglx.h b/hw/kdrive/ephyr/ephyrhostglx.h
deleted file mode 100644
index f1eec5f..0000000
--- a/hw/kdrive/ephyr/ephyrhostglx.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- *          Authored by Matthew Allum <mallum at openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors:
- *    Dodji Seketeli <dodji at openedhand.com>
- */
-#ifndef __EPHYRHOSTGLX_H__
-#define __EPHYRHOSTGLX_H__
-
-enum EphyrHostGLXGetStringOps {
-    EPHYR_HOST_GLX_UNDEF,
-    EPHYR_HOST_GLX_QueryServerString,
-    EPHYR_HOST_GLX_GetString,
-};
-
-Bool ephyrHostGLXQueryVersion(int *a_maj, int *a_min);
-Bool ephyrHostGLXGetString(int a_context_tag,
-                           int a_string_name,
-                           char **a_string);
-Bool ephyrHostGLXQueryServerString(int a_screen_number,
-                                   int a_string_name,
-                                   char **a_string);
-Bool ephyrHostGLXGetVisualConfigs(int a_screen,
-                                  int32_t * a_num_visuals,
-                                  int32_t * a_num_props,
-                                  int32_t * a_props_buf_size,
-                                  int32_t ** a_props_buf);
-Bool
-
-ephyrHostGLXVendorPrivGetFBConfigsSGIX(int a_screen,
-                                       int32_t * a_num_visuals,
-                                       int32_t * a_num_props,
-                                       int32_t * a_props_buf_size,
-                                       int32_t ** a_props_buf);
-Bool ephyrHostGLXSendClientInfo(int32_t a_major, int32_t a_minor,
-                                const char *a_extension_list);
-Bool ephyrHostGLXCreateContext(int a_screen,
-                               int a_generic_id,
-                               int a_context_id,
-                               int a_share_list_ctxt_id,
-                               int a_render_type,
-                               Bool a_direct,
-                               int code);
-
-Bool ephyrHostDestroyContext(int a_ctxt_id);
-
-Bool ephyrHostGLXMakeCurrent(int a_drawable, int a_readable, int a_glx_ctxt_id,
-                             int a_olg_ctxt_tag, int *a_ctxt_tag);
-
-Bool ephyrHostGetIntegerValue(int a_current_context_tag, int a_int, int *a_val);
-
-Bool ephyrHostIsContextDirect(int a_ctxt_id, int *a_is_direct);
-
-#endif /*__EPHYRHOSTGLX_H__*/
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index d86baf2..6b6c4b1 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -38,9 +38,6 @@ extern Bool kdHasPointer;
 extern Bool kdHasKbd;
 extern Bool ephyr_glamor, ephyr_glamor_gles2;
 
-#ifdef GLXEXT
-extern Bool ephyrNoDRI;
-#endif
 extern Bool ephyrNoXV;
 
 #ifdef KDRIVE_EVDEV
@@ -154,9 +151,6 @@ ddxUseMsg(void)
     ErrorF
         ("-fakexa              Simulate acceleration using software rendering\n");
     ErrorF("-verbosity <level>   Set log verbosity level\n");
-#ifdef GLXEXT
-    ErrorF("-nodri               do not use DRI\n");
-#endif
     ErrorF("-noxv                do not use XV\n");
     ErrorF("-name [name]         define the name in the WM_CLASS property\n");
     ErrorF
@@ -314,13 +308,6 @@ ddxProcessArgument(int argc, char **argv, int i)
             exit(1);
         }
     }
-#ifdef GLXEXT
-    else if (!strcmp(argv[i], "-nodri")) {
-        ephyrNoDRI = TRUE;
-        EPHYR_LOG("no direct rendering enabled\n");
-        return 1;
-    }
-#endif
     else if (!strcmp(argv[i], "-noxv")) {
         ephyrNoXV = TRUE;
         EPHYR_LOG("no XVideo enabled\n");
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 49516bb..ce9faca 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -52,10 +52,6 @@
 #include <xcb/shape.h>
 #include <xcb/xcb_keysyms.h>
 #include <xcb/randr.h>
-#ifdef XF86DRI
-#include <xcb/xf86dri.h>
-#include <xcb/glx.h>
-#endif /* XF86DRI */
 #ifdef GLAMOR
 #include <epoxy/gl.h>
 #include "glamor.h"
@@ -1345,80 +1341,6 @@ out:
     return is_ok;
 }
 
-#ifdef XF86DRI
-typedef struct {
-    int is_valid;
-    int local_id;
-    int remote_id;
-} ResourcePair;
-
-#define RESOURCE_PEERS_SIZE 1024*10
-static ResourcePair resource_peers[RESOURCE_PEERS_SIZE];
-
-int
-hostx_allocate_resource_id_peer(int a_local_resource_id,
-                                int *a_remote_resource_id)
-{
-    int i = 0;
-    ResourcePair *peer = NULL;
-
-    /*
-     * first make sure a resource peer
-     * does not exist already for
-     * a_local_resource_id
-     */
-    for (i = 0; i < RESOURCE_PEERS_SIZE; i++) {
-        if (resource_peers[i].is_valid
-            && resource_peers[i].local_id == a_local_resource_id) {
-            peer = &resource_peers[i];
-            break;
-        }
-    }
-    /*
-     * find one free peer entry, an feed it with
-     */
-    if (!peer) {
-        for (i = 0; i < RESOURCE_PEERS_SIZE; i++) {
-            if (!resource_peers[i].is_valid) {
-                peer = &resource_peers[i];
-                break;
-            }
-        }
-        if (peer) {
-            peer->remote_id = xcb_generate_id(HostX.conn);
-            peer->local_id = a_local_resource_id;
-            peer->is_valid = TRUE;
-        }
-    }
-    if (peer) {
-        *a_remote_resource_id = peer->remote_id;
-        return TRUE;
-    }
-    return FALSE;
-}
-
-int
-hostx_get_resource_id_peer(int a_local_resource_id, int *a_remote_resource_id)
-{
-    int i = 0;
-    ResourcePair *peer = NULL;
-
-    for (i = 0; i < RESOURCE_PEERS_SIZE; i++) {
-        if (resource_peers[i].is_valid
-            && resource_peers[i].local_id == a_local_resource_id) {
-            peer = &resource_peers[i];
-            break;
-        }
-    }
-    if (peer) {
-        *a_remote_resource_id = peer->remote_id;
-        return TRUE;
-    }
-    return FALSE;
-}
-
-#endif                          /* XF86DRI */
-
 #ifdef GLAMOR
 Bool
 ephyr_glamor_init(ScreenPtr screen)
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index d416dae..5e642dc 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -184,20 +184,6 @@ int hostx_set_window_bounding_rectangles(int a_window,
 
 int hostx_has_extension(xcb_extension_t *extension);
 
-#ifdef XF86DRI
-int hostx_lookup_peer_window(void *a_local_window,
-                             int *a_host_peer /*out parameter */ );
-int
-
-hostx_allocate_resource_id_peer(int a_local_resource_id,
-                                int *a_remote_resource_id);
-int
- hostx_get_resource_id_peer(int a_local_resource_id, int *a_remote_resource_id);
-int hostx_has_dri(void);
-
-int hostx_has_glx(void);
-#endif                          /* XF86DRI */
-
 int hostx_get_fd(void);
 
 #endif /*_XLIBS_STUFF_H_*/
commit 953b71270cf12c59c8a836c9be403d07fb01fa22
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>

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 1a48a5863e4bceee6b99c1feda1b2c584ff3657c
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 8 17:41:36 2015 -0500

    xfree86: Remove ancient DRI build instructions
    
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/doc/Makefile.am b/hw/xfree86/doc/Makefile.am
index 1c3620a..392bdfa 100644
--- a/hw/xfree86/doc/Makefile.am
+++ b/hw/xfree86/doc/Makefile.am
@@ -14,5 +14,4 @@ endif ENABLE_DEVEL_DOCS
 EXTRA_DIST =		\
 	Registry	\
 	exa-driver.txt	\
-	README.DRIcomp	\
 	README.modes
diff --git a/hw/xfree86/doc/README.DRIcomp b/hw/xfree86/doc/README.DRIcomp
deleted file mode 100644
index 7388650..0000000
--- a/hw/xfree86/doc/README.DRIcomp
+++ /dev/null
@@ -1,551 +0,0 @@
-                            DRI Compilation Guide
-
-          VA Linux Systems, Inc. Professional Services - Graphics.
-
-                                21 April 2001
-
-1.  Preamble
-
-1.1  Copyright
-
-Copyright 2000-2001 by VA Linux Systems, Inc.  All Rights Reserved.
-
-Permission is granted to make and distribute verbatim copies of this document
-provided the copyright notice and this permission notice are preserved on all
-copies.
-
-1.2  Trademarks
-
-OpenGL is a registered trademark and SGI is a trademark of Silicon Graphics,
-Inc.  Unix is a registered trademark of The Open Group.  The `X' device and X
-Window System are trademarks of The Open Group.  XFree86 is a trademark of
-The XFree86 Project.  Linux is a registered trademark of Linus Torvalds.
-Intel is a registered trademark of Intel Corporation.  3Dlabs, GLINT, and
-Oxygen are either registered trademarks or trademarks of 3Dlabs Inc. Ltd.
-3dfx, Voodoo3, Voodoo4, and Voodoo5 are registered trademarks of 3dfx Inter-
-active, Incorporated.  Matrox is a registered trademark of Matrox Electronic
-Systems Ltd.  ATI Rage and Radeon is a registered trademark of ATI Technolo-
-gies, Inc.  All other trademarks mentioned are the property of their respec-
-tive owners.
-
-2.  Introduction
-
-This document describes how to download, compile and install the DRI.  The
-DRI provides 3D graphics hardware acceleration for the XFree86 project.  This
-information is intended for experienced Linux developers.  Beginners are
-probably better off installing precompiled packages.
-
-Edits, corrections and updates to this document may be mailed to <brian at tung-
-stengraphics.com>.
-
-Last updated on 13 February 2002 by Brian Paul.
-
-3.  Prerequisites
-
-You'll need the following:
-
-   o An installation of XFree86 4.1 or later.  The DRI tree has been pruned
-     down to minimize its size.  But in order to build the DRI tree you need
-     to have recent X header files, etc. already installed.  If you don't
-     have XFree86 4.1 (or later) installed you can probably install it from
-     RPMs (or another package format).  Or, you can download XFree86 as
-     sources and compile/install it yourself.
-
-   o At least 200MB of free disk space.  If you compile for debugging (the -g
-     option) then you'll need about 600MB.
-
-   o GCC compiler and related tools.
-
-   o ssh (secure shell) if you're a DRI developer and don't want to use
-     anonymous CVS download.
-
-   o A 2.4.x Linux Kernel.  See below for details.
-
-   o FreeBSD support is not currently being maintained and may not work.
-
-The DRI 3D drivers generally work on systems with Intel or AMD CPUs.  How-
-ever, limited support for Alpha and PowerPC support is underway.
-
-For 3dfx Voodoo hardware, you'll also need the Glide3 runtime library
-(libglide3-v3.so for Voodoo3 or libglide3-v5.so for Voodoo4/5).  These can be
-downloaded from the DRI website.  You can compile them yourself, but it's
-often a painful process.
-
-For Matrox G200/G400, Intel i810/i830 or ATI Rage128/Radeon hardware, you'll
-also need AGP support in your Linux kernel, either built-in or as a loadable
-module.
-
-4.  Linux Kernel Preparation
-
-Only the Linux 2.4.x kernels are currently supported by the DRI hardware
-drivers.  2.5.x kernels may work, but aren't tested.
-
-Most of the DRI drivers require AGP support and using Intel Pentium III SSE
-optimizations also requires an up-to-date Linux kernel.  Configuring your
-kernel correctly is very important, as features such as SSE optimizations
-will be disabled if your kernel does not support them.  Thus, if you have a
-Pentium III processor, you must configure your kernel for the Pentium III
-processor family.
-
-Building a new Linux kernel can be difficult for beginners but there are
-resources on the Internet to help.  This document assumes experience with
-configuring, building and installing Linux kernels.
-
-Linux kernels can be downloaded from www.kernel.org
-
-Here are the basic steps for kernel setup.
-
-   o Download the needed kernel and put it in /usr/src.  Create a directory
-     for the source and unpack it.  For example:
-
-                    cd /usr/src
-                    rm -f linux
-                    mkdir linux-2.4.x
-                    ln -s linux-2.4.x linux
-                    bzcat linux-2.4.x.tar.bz2 | tar xf -
-
-     It is critical that /usr/src/linux point to your new kernel sources,
-     otherwise the kernel headers will not be used when building the DRI.
-     This will almost certainly cause compilation problems.
-
-   o Read /usr/src/linux/Documentation/Changes.  This file lists the minimum
-     requirements for all software packages required to build the kernel.
-     You must upgrade at least gcc, make, binutils and modutils to at least
-     the versions specified in this file.  The other packages may not be
-     needed.  If you are upgrading from Linux 2.2.x you must upgrade your
-     modutils package for Linux 2.4.x.
-
-   o Configure your kernel.  You might, for example, use make menuconfig and
-     do the following:
-
-        o Go to Code maturity level options
-
-        o Enable Prompt for development and/or incomplete code/drivers
-
-        o hit ESC to return to the top-level menu
-
-        o Go to Processor type and features
-
-        o Select your processor type from Processor Family
-
-        o hit ESC to return to the top-level menu
-
-        o Go to Character devices
-
-        o Disable Direct Rendering Manager (XFree86 DRI support) since we'll
-          use the DRI code from the XFree86/DRI tree and will compile it
-          there.
-
-        o Go to /dev/agpgart (AGP Support) (EXPERIMENTAL) (NEW)
-
-        o Hit SPACE twice to build AGP support into the kernel
-
-        o Enable all chipsets' support for AGP
-
-   o Configure the rest of the kernel as required for your system (i.e. Eth-
-     ernet, SCSI, etc)
-
-   o Exit, saving your kernel configuration.
-
-   o Edit your /etc/lilo.conf file.  Make sure you have an image entry as
-     follows (or similar):
-
-                      image=/boot/vmlinuz
-                            label=linux.2.4.x
-                            read-only
-                            root=/dev/hda1
-
-     The important part is that you have /boot/vmlinuz without a trailing
-     version number.  If this is the first entry in your /etc/lilo.conf AND
-     you haven't set a default, then this will be your default kernel.
-
-   o Compile the new kernel.
-
-                    cd /usr/src/linux-2.4.x
-                    make dep
-                    make bzImage
-                    make modules
-                    make modules_install
-                    make install
-
-     Note that last make command will automatically run lilo for you.
-
-   o Now reboot to use the new kernel.
-
-5.  CPU Architectures
-
-In general, nothing special has to be done to use the DRI on different CPU
-architectures.  There are, however, a few optimizations that are CPU-depen-
-dent.  Mesa will determine at runtime which CPU-dependent optimizations
-should be used and enable them where appropriate.
-
-5.1  Intel Pentium III Features
-
-The Pentium III SSE instructions are used in optimized vertex transformation
-functions in the Mesa-based DRI drivers.  On Linux, SSE requires a recent
-kernel (such as 2.4.0-test11 or later) both at compile time and runtime.
-
-5.2  AMD 3DNow! Features
-
-AMD's 3DNow! instructions are used in optimized vertex transformation func-
-tions in the Mesa-based DRI drivers.  3DNow! is supported in most versions of
-Linux.
-
-5.3  Alpha Features
-
-On newer Alpha processors a significant performance increase can be seen with
-the addition of the -mcpu= option to GCC.  This option is dependent on the
-architecture of the processor.  For example, -mcpu=ev6 will build specifi-
-cally for the EV6 based AXP's, giving both byte and word alignment access to
-the DRI/Mesa drivers.
-
-To enable this optimization edit your xc/config/host.def file and add the
-line:
-
-#define DefaultGcc2AxpOpt -O2 -mcpu=ev6
-
-Additional speed improvements to 3D rendering can be achieved by installing
-Compaq's Math Libraries (CPML) which can be obtained from http://www.sup-
-port.compaq.com/alpha-tools/software/index.html
-
-Once installed, you can add this line to your host.def to build with the CPML
-libraries:
-
-#define UseCompaqMathLibrary YES
-
-The host.def file is explained below.
-
-6.  Downloading the XFree86/DRI CVS Sources
-
-The DRI project is hosted by SourceForge.  The DRI source code, which is a
-subset of the XFree86 source tree, is kept in a CVS repository there.
-
-The DRI CVS sources may be accessed either anonymously or as a registered
-SourceForge user.  It's recommended that you become a registered SourceForge
-user so that you may submit non-anonymous bug reports and can participate in
-the mailing lists.
-
-6.1  Anonymous CVS download:
-
-  1.  Create a directory to store the CVS files:
-
-                       cd ~
-                       mkdir DRI-CVS
-
-      You could put your CVS directory in a different place but we'll use
-      ~/DRI-CVS/ here.
-
-  2.  Check out the CVS sources:
-
-                       cd ~/DRI-CVS
-                       cvs -d:pserver:anonymous at cvs.dri.sourceforge.net:/cvsroot/dri login
-                         (hit ENTER when prompted for a password)
-                       cvs -z3 -d:pserver:anonymous at cvs.dri.sourceforge.net:/cvsroot/dri co xc
-
-      The -z3 flag causes compression to be used in order to reduce the down-
-      load time.
-
-6.2  Registered CVS download:
-
-  1.  Create a directory to store the CVS files:
-
-                       cd ~
-                       mkdir DRI-CVS
-
-      You could put your CVS directory in a different place but we'll use
-      ~/DRI-CVS/ here.
-
-  2.  Set the CVS_RSH environment variable:
-
-                       setenv CVS_RSH ssh      // if using csh or tcsh
-                       export CVS_RSH=ssh      // if using sh or bash
-
-  3.  Check out the CVS sources:
-
-                       cd ~/DRI-CVS
-                       cvs -z3 -d:ext:YOURID at cvs.dri.sourceforge.net:/cvsroot/dri co xc
-
-      Replace YOURID with your CVS login name.  You'll be prompted to enter
-      your sourceforge password.
-
-      The -z3 flag causes compression to be used in order to reduce the down-
-      load time.
-
-6.3  Updating your CVS sources
-
-In the future you'll want to occasionally update your local copy of the DRI
-source code to get the latest changes.  This can be done with:
-
-                cd ~/DRI-CVS
-                cvs -z3 update -dA xc
-
-The -d flag causes any new subdirectories to be created and -A causes most
-recent trunk sources to be fetched, not branch sources.
-
-7.  Mesa
-
-Most of the DRI 3D drivers are based on Mesa (the free implementation of the
-OpenGL API).  The relevant files from Mesa are already included in the
-XFree86/DRI source tree.  There is no need to download or install the Mesa
-source files separately.
-
-Sometimes a newer version of Mesa will be available than the version included
-in XFree86/DRI.  Upgrading Mesa within XFree86/DRI is not always straightfor-
-ward.  It can be an error-prone undertaking, especially for beginners, and is
-not generally recommended.  The DRI developers will upgrade Mesa when appro-
-priate.
-
-8.  Compiling the XFree86/DRI tree
-
-8.1  Make a build tree
-
-Rather than placing object files and library files right in the source tree,
-they're instead put into a parallel build tree.  The build tree is made with
-the lndir command:
-
-                 cd ~/DRI-CVS
-                 ln -s xc XFree40
-                 mkdir build
-                 cd build
-                 lndir -silent -ignorelinks ../XFree40
-
-The build tree will be populated with symbolic links which point back into
-the CVS source tree.
-
-Advanced users may have several build trees for compiling and testing with
-different options.
-
-8.2  Edit the host.def file
-
-The ~/DRI-CVS/build/xc/config/cf/host.def file is used to configure the
-XFree86 build process.  You can change it to customize your build options or
-make adjustments for your particular system configuration
-
-The default host.def file will look something like this:
-
-                 #define DefaultCCOptions -Wall
-     (i386)      #define DefaultGcc2i386Opt -O2
-     (Alpha)     #define DefaultGcc2AxpOpt -O2 -mcpu=ev6 (or similar)
-                 #define LibraryCDebugFlags -O2
-                 #define BuildServersOnly YES
-                 #define XF86CardDrivers vga tdfx mga ati i810
-                 #define LinuxDistribution LinuxRedHat
-                 #define DefaultCCOptions -ansi GccWarningOptions -pipe
-                 #define BuildXF86DRI YES
-                 /* Optionally turn these on for debugging */
-                 /* #define GlxBuiltInTdfx YES */
-                 /* #define GlxBuiltInMga YES */
-                 /* #define GlxBuiltInR128 YES */
-                 /* #define GlxBuiltInRadeon YES */
-                 /* #define DoLoadableServer NO */
-                 #define SharedLibFont NO
-
-The ProjectRoot variable specifies where the XFree86 files will be installed.
-We recommend installing the DRI files over your existing XFree86 installation
-- it's generally safe to do and less error-prone.  This policy is different
-than what we used to recommend.
-
-If XFree86 4.x is not installed in /usr/X11R6/ you'll have to add the follow-
-ing to the host.def file:
-
-                 #define ProjectRoot pathToYourXFree86installation
-
-Note the XF86CardDrivers line to be sure your card's driver is listed.
-
-If you want to enable 3DNow! optimizations in Mesa and the DRI drivers, you
-should add the following:
-
-                 #define MesaUse3DNow YES
-
-You don't have to be using an AMD processor in order to enable this option.
-The DRI will look for 3DNow! support and runtime and only enable it if appli-
-cable.
-
-If you want to enable SSE optimizations in Mesa and the DRI drivers, you must
-upgrade to a Linux 2.4.x kernel.  Mesa will verify that SSE is supported by
-both your processor and your operating system, but to build Mesa inside the
-DRI you need to have the Linux 2.4.x kernel headers in /usr/src/linux.  If
-you enable SSE optimizations with an earlier version of the Linux kernel in
-/usr/src/linux, Mesa will not compile.  You have been warned.  If you do have
-a 2.4.x kernel, you should add the following:
-
-                 #define MesaUseSSE YES
-
-If you want to build the DRM kernel modules as part of the full build pro-
-cess, add the following:
-
-                 #define BuildXF86DRM YES
-
-Otherwise, you'll need to build them separately as described below.
-
-8.3  Compilation
-
-To compile the complete DRI tree:
-
-                 cd ~/DRI-CVS/build/xc/
-                 make World >& world.log
-
-Or if you want to watch the compilation progress:
-
-                 cd ~/DRI-CVS/build/xc/
-                 make World >& world.log &
-                 tail -f world.log
-
-With the default compilation flags it's normal to get a lot of warnings dur-
-ing compilation.
-
-Building will take some time so you may want to go check your email or visit
-slashdot.
-
-WARNING: do not use the -j option with make.  It's reported that it does not
-work with XFree86/DRI.
-
-8.4  Check for compilation errors
-
-Using your text editor, examine world.log for errors by searching for the
-pattern ***.
-
-After fixing the errors, run make World again.  Later, you might just compile
-parts of the source tree but it's important that the whole tree will build
-first.
-
-If you edited your host.def file to enable automatic building of the DRI ker-
-nel module(s), verify that they were built:
-
-               cd ~/DRI-CVS/build/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel
-               ls
-
-Otherwise, build them now by running
-
-               cd ~/DRI-CVS/build/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel
-               make -f Makefile.linux
-
-For the 3dfx Voodoo, you should see tdfx.o.  For the Matrox G200/G400, you
-should see mga.o.  For the ATI Rage 128, you should see r128.o.  For the ATI
-Radeon, you should see radeon.o.  For the Intel i810, you should see i810.o.
-
-If the DRI kernel module(s) failed to build you should verify that you're
-using the right version of the Linux kernel.  The most recent kernels are not
-always supported.
-
-If your build machine is running a different version of the kernel than your
-target machine (i.e. 2.2.x vs. 2.4.x), make will select the wrong kernel
-source tree. This can be fixed by explicitly setting the value of LINUXDIR.
-If the path to your kernel source is /usr/src/linux-2.4.x,
-
-               cd ~/DRI-CVS/build/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel
-               make -f Makefile.linux LINUXDIR=/usr/src/linux-2.4.x
-
-or alternatively, edit Makefile.linux to set LINUXDIR before the ifndef LIN-
-UXDIR line.
-
-8.5  DRI kernel module installation
-
-The DRI kernel modules will be in ~/DRI-CVS/build/xc/pro-
-grams/Xserver/hw/xfree86/os-support/linux/drm/kernel/.
-
-To load the appropriate DRM module in your running kernel you can either use
-ismod and restart your X server or copy the kernel module to /lib/mod-
-ules/2.4.x/kernel/drivers/char/drm/ then run depmod and restart your X
-server.
-
-Make sure you first unload any older DRI kernel modules that might be already
-loaded.
-
-Note that some DRM modules require that the agpgart module be loaded first.
-
-9.  Normal Installation and Configuration
-
-Most users will want to install the new X server and use it in place of their
-old X server.  This section explains how to do that.
-
-Developers, on the other hand, may just want to test the X server without
-actually installing it as their default server.  If you want to do that, skip
-to the next section.
-
-9.1  Installation
-
-Here are the installation commands:
-
-                su
-                cd ~/DRI-CVS/build/xc
-                make install
-
-9.2  Update the XF86Config File
-
-You may need to edit your XF86Config file to enable the DRI.  The config file
-is usually installed as /etc/X11/XF86Config-4.  See the DRI User Guide for
-details, but basically, you need to load the "glx" and "dri" modules and add
-a "DRI" section.
-
-On the DRI web site, in the resources section, you'll find example XF86Config
-files for a number of graphics cards.  These configuration files also setup
-DRI options so it's highly recommended that you look at these examples.
-
-The XFree86 4.x server can generate a basic configuration file itself.  Sim-
-ply do this:
-
-                  cd /usr/X11R6/bin
-                  ./XFree86 -configure
-
-A file named /root/XF86Config.new will be created.  It should allow you to
-try your X server but you'll almost certainly have to edit it.  For example,
-you should add HorizSync and VertRefresh options to the Monitor section and
-Modes options to the Screen section.  Also, the ModulePath option in the
-Files section should be set to /usr/X11R6/lib/modules.
-
-9.3  Start the New X Server
-
-The new X server should be ready to use now.  Start your X server in your
-usual manner.  Often times the startx command is used:
-
-                  startx
-
-10.  Testing the Server Without Installing It
-
-As mentioned at the start of section 9, developers may want to simply run the
-X server without installing it.  This can save some time and allow you to
-keep a number of X servers available for testing.
-
-10.1  Configuration
-
-As described in the preceding section, you'll need to create a configuration
-file for the new server.  Put the XF86Config file in your ~/DRI-
-CVS/build/xc/programs/Xserver directory.
-
-Be sure the ModulePath option in your XF86Config file is set correctly.
-
-10.2  A Startup Script
-
-A simple shell script can be used to start the X server.  Here's an example.
-
-             #!/bin/sh
-             export DISPLAY=:0
-             ./XFree86 -xf86config XF86Config & \
-             sleep 2
-             fvwm2 &
-             xset b off
-             xmodmap -e "clear mod4"
-             xsetroot -solid "#00306f"
-             xterm -geometry 80x40+0+0
-
-You might name this script start-dri.  Put it in your ~/DRI-CVS/build/xc/pro-
-grams/Xserver directory.
-
-To test the server run the script:
-
-                  cd ~/DRI-CVS/build/xc/programs/Xserver
-                  ./start-dri
-
-For debugging, you may also want to capture the log messages printed by the
-server in a file.  If you're using the C-shell:
-
-                  ./start-dri >& log
-
-11.  Where To Go From Here
-
-At this point your X server should be up and running with hardware-acceler-
-ated direct rendering.  Please read the DRI User Guide for information about
-trouble shooting and how to use the DRI-enabled X server for 3D applications.
-
-     Generated from XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DRIcomp.sgml,v 1.19 dawes Exp $
commit d8ecbe563991cc689e95a8cb9d510e920eaceea0
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>

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 50ca286d79f6304b972ea74487308e7794a170fb
Author: Timo Aaltonen <tjaalton at ubuntu.com>
Date:   Wed Jan 27 14:18:50 2016 +0200

    dri2: Sync i915_pci_ids.h and i965_pci_ids.h from mesa
    
    Adds Skylake, Kabylake and Broxton allowing them to use
    modesetting + glamor with dri2.
    
    Signed-off-by: Timo Aaltonen <timo.aaltonen at canonical.com>
    Reviewed-by: Andreas Boll <andreas.boll.dev at gmail.com>

diff --git a/hw/xfree86/dri2/pci_ids/i915_pci_ids.h b/hw/xfree86/dri2/pci_ids/i915_pci_ids.h
index 7d51975..1c43c8e 100644
--- a/hw/xfree86/dri2/pci_ids/i915_pci_ids.h
+++ b/hw/xfree86/dri2/pci_ids/i915_pci_ids.h
@@ -11,5 +11,5 @@ CHIPSET(0x27AE, I945_GME, "Intel(R) 945GME")
 CHIPSET(0x29B2, Q35_G,    "Intel(R) Q35")
 CHIPSET(0x29C2, G33_G,    "Intel(R) G33")
 CHIPSET(0x29D2, Q33_G,    "Intel(R) Q33")
-CHIPSET(0xA011, IGD_GM,   "Intel(R) IGD")
-CHIPSET(0xA001, IGD_G,    "Intel(R) IGD")
+CHIPSET(0xA011, PNV_GM,   "Intel(R) Pineview M")
+CHIPSET(0xA001, PNV_G,    "Intel(R) Pineview")
diff --git a/hw/xfree86/dri2/pci_ids/i965_pci_ids.h b/hw/xfree86/dri2/pci_ids/i965_pci_ids.h
index 2e04301..5139e27 100644
--- a/hw/xfree86/dri2/pci_ids/i965_pci_ids.h
+++ b/hw/xfree86/dri2/pci_ids/i965_pci_ids.h
@@ -109,7 +109,55 @@ CHIPSET(0x162A, bdw_gt3, "Intel(R) Iris Pro P6300 (Broadwell GT3e)")
 CHIPSET(0x162B, bdw_gt3, "Intel(R) Iris 6100 (Broadwell GT3)")
 CHIPSET(0x162D, bdw_gt3, "Intel(R) Broadwell GT3")
 CHIPSET(0x162E, bdw_gt3, "Intel(R) Broadwell GT3")
-CHIPSET(0x22B0, chv,     "Intel(R) Cherryview")
-CHIPSET(0x22B1, chv,     "Intel(R) Cherryview")
-CHIPSET(0x22B2, chv,     "Intel(R) Cherryview")
-CHIPSET(0x22B3, chv,     "Intel(R) Cherryview")
+CHIPSET(0x1902, skl_gt1, "Intel(R) HD Graphics 510 (Skylake GT1)")
+CHIPSET(0x1906, skl_gt1, "Intel(R) HD Graphics 510 (Skylake GT1)")
+CHIPSET(0x190A, skl_gt1, "Intel(R) Skylake GT1")
+CHIPSET(0x190E, skl_gt1, "Intel(R) Skylake GT1")
+CHIPSET(0x1912, skl_gt2, "Intel(R) HD Graphics 530 (Skylake GT2)")
+CHIPSET(0x1913, skl_gt2, "Intel(R) Skylake GT2f")
+CHIPSET(0x1915, skl_gt2, "Intel(R) Skylake GT2f")
+CHIPSET(0x1916, skl_gt2, "Intel(R) HD Graphics 520 (Skylake GT2)")
+CHIPSET(0x1917, skl_gt2, "Intel(R) Skylake GT2f")
+CHIPSET(0x191A, skl_gt2, "Intel(R) Skylake GT2")
+CHIPSET(0x191B, skl_gt2, "Intel(R) HD Graphics 530 (Skylake GT2)")
+CHIPSET(0x191D, skl_gt2, "Intel(R) HD Graphics P530 (Skylake GT2)")
+CHIPSET(0x191E, skl_gt2, "Intel(R) HD Graphics 515 (Skylake GT2)")
+CHIPSET(0x1921, skl_gt2, "Intel(R) Skylake GT2")
+CHIPSET(0x1923, skl_gt3, "Intel(R) Iris Graphics 540 (Skylake GT3e)")
+CHIPSET(0x1926, skl_gt3, "Intel(R) HD Graphics 535 (Skylake GT3)")
+CHIPSET(0x1927, skl_gt3, "Intel(R) Iris Graphics 550 (Skylake GT3e)")
+CHIPSET(0x192A, skl_gt4, "Intel(R) Skylake GT4")
+CHIPSET(0x192B, skl_gt3, "Intel(R) Iris Graphics (Skylake GT3fe)")
+CHIPSET(0x1932, skl_gt4, "Intel(R) Skylake GT4")
+CHIPSET(0x193A, skl_gt4, "Intel(R) Skylake GT4")
+CHIPSET(0x193B, skl_gt4, "Intel(R) Skylake GT4")
+CHIPSET(0x193D, skl_gt4, "Intel(R) Skylake GT4")
+CHIPSET(0x5902, kbl_gt1, "Intel(R) Kabylake GT1")
+CHIPSET(0x5906, kbl_gt1, "Intel(R) Kabylake GT1")
+CHIPSET(0x590A, kbl_gt1, "Intel(R) Kabylake GT1")
+CHIPSET(0x590B, kbl_gt1, "Intel(R) Kabylake GT1")
+CHIPSET(0x590E, kbl_gt1, "Intel(R) Kabylake GT1")
+CHIPSET(0x5913, kbl_gt1_5, "Intel(R) Kabylake GT1.5")
+CHIPSET(0x5915, kbl_gt1_5, "Intel(R) Kabylake GT1.5")
+CHIPSET(0x5917, kbl_gt1_5, "Intel(R) Kabylake GT1.5")
+CHIPSET(0x5912, kbl_gt2, "Intel(R) Kabylake GT2")
+CHIPSET(0x5916, kbl_gt2, "Intel(R) Kabylake GT2")
+CHIPSET(0x591A, kbl_gt2, "Intel(R) Kabylake GT2")
+CHIPSET(0x591B, kbl_gt2, "Intel(R) Kabylake GT2")
+CHIPSET(0x591D, kbl_gt2, "Intel(R) Kabylake GT2")
+CHIPSET(0x591E, kbl_gt2, "Intel(R) Kabylake GT2")
+CHIPSET(0x5921, kbl_gt2, "Intel(R) Kabylake GT2F")
+CHIPSET(0x5926, kbl_gt3, "Intel(R) Kabylake GT3")
+CHIPSET(0x592A, kbl_gt3, "Intel(R) Kabylake GT3")
+CHIPSET(0x592B, kbl_gt3, "Intel(R) Kabylake GT3")
+CHIPSET(0x5932, kbl_gt4, "Intel(R) Kabylake GT4")
+CHIPSET(0x593A, kbl_gt4, "Intel(R) Kabylake GT4")
+CHIPSET(0x593B, kbl_gt4, "Intel(R) Kabylake GT4")
+CHIPSET(0x593D, kbl_gt4, "Intel(R) Kabylake GT4")
+CHIPSET(0x22B0, chv,     "Intel(R) HD Graphics (Cherryview)")
+CHIPSET(0x22B1, chv,     "Intel(R) HD Graphics (Cherryview)")
+CHIPSET(0x22B2, chv,     "Intel(R) HD Graphics (Cherryview)")
+CHIPSET(0x22B3, chv,     "Intel(R) HD Graphics (Cherryview)")
+CHIPSET(0x0A84, bxt,     "Intel(R) HD Graphics (Broxton)")
+CHIPSET(0x1A84, bxt,     "Intel(R) HD Graphics (Broxton)")
+CHIPSET(0x5A84, bxt,     "Intel(R) HD Graphics (Broxton)")
commit bf23db42a4e5943129501223a47b48884cdeb62f
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Jan 27 11:50:13 2016 -0500

    modesetting: Require sufficiently new libdrm
    
    Bugzilla: https://bugs.freedesktop.org/93883
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>

diff --git a/configure.ac b/configure.ac
index ac3bb64..312fc69 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2035,8 +2035,7 @@ if test "x$XORG" = xyes; then
 
 	if test "x$DRM" = xyes; then
 		dnl 2.4.46 is required for cursor hotspot support.
-		PKG_CHECK_EXISTS(libdrm >= 2.4.46)
-		XORG_DRIVER_MODESETTING=yes
+		PKG_CHECK_EXISTS(libdrm >= 2.4.46, XORG_DRIVER_MODESETTING=yes, XORG_DRIVER_MODESETTING=no)
 	fi
 
 	AC_SUBST([XORG_LIBS])
commit 6978c8ee666a9224213173e7680e2d71b1094bab
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>

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index c357217..7f6fb9a 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 79c3925532bc0d098c9a4da6d5117bdada56e0af
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>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index ea0443d..4bcd3ce 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -738,6 +738,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);
@@ -798,12 +807,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 98c3504dcfcec227b9c7798a0bd287941cec0691
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>

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 564d9f0f8c17bb3c13aa3ca36da7825454dc5de3
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>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 25967b6..e9c1d9e 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -579,9 +579,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 a4e0655..a73e9ef 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -66,6 +66,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 e6754dcb59ee21abb42421a28f4e467295584f67
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>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index d4f3be2..25967b6 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -599,6 +599,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 5042b0652b9fe5fed57a233880c3429ba390d86d
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>

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 1fd82c764d5b24107e60f2173e30e5d24a2f2667
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Jan 19 02:01:09 2016 +0000

    glamor: don't do copy if we have 0 boxes to copy.
    
    This happens if you run twm + mplayer + xclock and drag
    the clock over the mplayer. If we don't catch it, we cause
    an illegal draw elements command to be passed to GL.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index 028acf2..1adfba0 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -640,6 +640,9 @@ glamor_copy(DrawablePtr src,
             Pixel bitplane,
             void *closure)
 {
+    if (nbox == 0)
+	return;
+
     if (glamor_copy_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure))
         return;
     glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
commit e7308b6c77561df44c04f81509f8ada678705d94
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>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 0b5ebef..d4f3be2 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -576,6 +576,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 cab14a9a08ff06bc4cbef79c7be8f1d07c07ebf9
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>

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 510c8605641803f1f5b5d2de6d3bb422b148e0e7
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jan 21 11:30:15 2016 -0800

    glamor: Fix copy-like Render operations between 15 and 16 depth.
    
    Reading and writing to 16-depth pixmaps using PICT_x1r5g5b5 ends up
    failing, unless you're doing a straight copy at the same bpp where the
    misinterpretation matches on both sides.
    
    Fixes rendercheck/blend/over and renderhceck/blend/src in piglit.
    
    Please cherry-pick this to active stable branches.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index d8574ec..92b6b0c 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -512,6 +512,14 @@ 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;
 
commit bc415fb1e0031ad23bda6e9c3f4664532876a0e5
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Jan 20 15:43:10 2016 -0500

    glx: Fix GLX_EXT_create_context_es2_profile support
    
    As of v4 of this extension, any GLES version number may be requested (to
    enable GLES3 and later). To comply with this, simply remove the API
    version checks and leave it to the DRI driver to validate. This happens
    to also enable using GLES1 in direct contexts, so if that's the dire
    situation you find yourself in, your client driver at least stands a
    chance of working.
    
    v4 also specifies that both extension strings should be advertised for
    compatibility with clients written against v1 of the extension spec, so
    add the es_profile bit to the extension list and enable it whenever we
    would enable es2_profile.
    
    Reviewed-by: Ilia Mirkin <imirkin at alum.mit.edu>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/createcontext.c b/glx/createcontext.c
index d06bc1f..9157e2f 100644
--- a/glx/createcontext.c
+++ b/glx/createcontext.c
@@ -254,36 +254,17 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
      *        GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; has more than one of
      *        these bits set; or if the implementation does not support the
      *        requested profile, then GLXBadProfileARB is generated."
+     *
+     * The GLX_EXT_create_context_es2_profile spec doesn't exactly say what
+     * is supposed to happen if an invalid version is set, but it doesn't
+     * much matter as support for GLES contexts is only defined for direct
+     * contexts (at the moment anyway) so we can leave it up to the driver
+     * to validate.
      */
     switch (profile) {
     case GLX_CONTEXT_CORE_PROFILE_BIT_ARB:
     case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
-        break;
     case GLX_CONTEXT_ES2_PROFILE_BIT_EXT:
-        /* The GLX_EXT_create_context_es2_profile spec says:
-         *
-         *     "... If the version requested is 2.0, and the
-         *     GLX_CONTEXT_ES2_PROFILE_BIT_EXT bit is set in the
-         *     GLX_CONTEXT_PROFILE_MASK_ARB attribute (see below), then the
-         *     context returned will implement OpenGL ES 2.0."
-         *
-         * It also says:
-         *
-         *     "* If attribute GLX_CONTEXT_PROFILE_MASK_ARB has no bits set;
-         *        has any bits set other than
-         *        GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
-         *        GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, or
-         *        GLX_CONTEXT_ES2_PROFILE_BIT_EXT; has more than one of these
-         *        bits set; or if the implementation does not supported the
-         *        requested profile, then GLXBadProfileARB is generated."
-         *
-         * It does not specifically say what is supposed to happen if
-         * GLX_CONTEXT_ES2_PROFILE_BIT_EXT is set but the version requested is
-         * not 2.0.  We choose to generate GLXBadProfileARB as this matches
-         * NVIDIA's behavior.
-         */
-        if (major_version != 2 || minor_version != 0)
-            return __glXError(GLXBadProfileARB);
         break;
     default:
         return __glXError(GLXBadProfileARB);
diff --git a/glx/extension_string.c b/glx/extension_string.c
index e881d21..cf90146 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -80,6 +80,7 @@ static const struct extension_info known_glx_extensions[] = {
     { GLX(ARB_framebuffer_sRGB),        VER(0,0), N, },
     { GLX(ARB_multisample),             VER(1,4), Y, },
 
+    { GLX(EXT_create_context_es_profile), VER(0,0), N, },
     { 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, },
diff --git a/glx/extension_string.h b/glx/extension_string.h
index bac7b06..ffaab07 100644
--- a/glx/extension_string.h
+++ b/glx/extension_string.h
@@ -43,6 +43,7 @@ enum {
     ARB_fbconfig_float_bit,
     ARB_framebuffer_sRGB_bit,
     ARB_multisample_bit,
+    EXT_create_context_es_profile_bit,
     EXT_create_context_es2_profile_bit,
     EXT_import_context_bit,
     EXT_texture_from_pixmap_bit,
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 6fb3d92..89ad808 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -864,11 +864,13 @@ initializeExtensions(__GLXDRIscreen * screen)
         __glXEnableExtension(screen->glx_enable_bits,
                              "GLX_ARB_create_context_profile");
         __glXEnableExtension(screen->glx_enable_bits,
+                             "GLX_EXT_create_context_es_profile");
+        __glXEnableExtension(screen->glx_enable_bits,
                              "GLX_EXT_create_context_es2_profile");
         LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_create_context\n");
         LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_create_context_profile\n");
         LogMessage(X_INFO,
-                   "AIGLX: enabled GLX_EXT_create_context_es2_profile\n");
+                   "AIGLX: enabled GLX_EXT_create_context_es{,2}_profile\n");
     }
 
     if (DRI2HasSwapControl(pScreen)) {
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index e8e53bf..be00f5f 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -405,6 +405,8 @@ initializeExtensions(__GLXDRIscreen * screen)
         __glXEnableExtension(screen->glx_enable_bits,
                              "GLX_ARB_create_context_profile");
         __glXEnableExtension(screen->glx_enable_bits,
+                             "GLX_EXT_create_context_es_profile");
+        __glXEnableExtension(screen->glx_enable_bits,
                              "GLX_EXT_create_context_es2_profile");
     }
 
commit 49aa5e3ea4eecea0562c05a4e52962985a56e510
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>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 81aba2d..0b5ebef 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -574,6 +574,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 d99204fb5e09ce7be36485d4226f7ad6d6eb24cc
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>

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 5582ad1b9b29934498cf3fef305d3a988130cd52
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>

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);
commit 25eca80265654cfbf8768024e027426fedeb0918
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Fri Jan 15 18:22:21 2016 +0900

    present: Handle wraparound when comparing MSC values
    
    When a window moves from one CRTC to another, present_window_to_crtc_msc
    updates window_priv->msc_offset according to the delta between the
    current MSC values of the old and new CRTC:
    
                window_priv->msc_offset += new_msc - old_msc;
    
    window_priv->msc_offset is initially 0, so if new_msc < old_msc,
    window_priv->msc_offset wraps around and becomes a large number. If the
    window_msc parameter passed in is small (in particular if it's 0, such as
    is the case when the client just wants to know the current window MSC
    value), the returned CRTC MSC value may still be a large number. In that
    case, the existing MSC comparisons in pixmap_present weren't working as
    intended, resulting in scheduling a wait far into the future when the
    target MSC had actually already passed. This would result in the client
    (e.g. the Chromium browser) hanging when moving its window between CRTCs.
    
    In order to fix this, introduce msc_is_(equal_or_)after helper functions
    which take the wraparound into account for comparing two MSC values.
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Martin Peres <martin.peres at linux.intel.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/present/present.c b/present/present.c
index 66e0f21..8cf3b6f 100644
--- a/present/present.c
+++ b/present/present.c
@@ -717,6 +717,28 @@ 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,
@@ -771,14 +793,14 @@ present_pixmap(WindowPtr window,
 
     /* Adjust target_msc to match modulus
      */
-    if (crtc_msc >= target_msc) {
+    if (msc_is_equal_or_after(crtc_msc, target_msc)) {
         if (divisor != 0) {
             target_msc = crtc_msc - (crtc_msc % divisor) + remainder;
             if (options & PresentOptionAsync) {
-                if (target_msc < crtc_msc)
+                if (msc_is_after(crtc_msc, target_msc))
                     target_msc += divisor;
             } else {
-                if (target_msc <= crtc_msc)
+                if (msc_is_equal_or_after(crtc_msc, target_msc))
                     target_msc += divisor;
             }
         } else {
@@ -864,7 +886,7 @@ present_pixmap(WindowPtr window,
     if (pixmap != NULL &&
         !(options & PresentOptionCopy) &&
         screen_priv->info) {
-        if (target_msc > crtc_msc &&
+        if (msc_is_after(target_msc, crtc_msc) &&
             present_check_flip (target_crtc, window, pixmap, TRUE, valid, x_off, y_off))
         {
             vblank->flip = TRUE;
@@ -897,7 +919,7 @@ present_pixmap(WindowPtr window,
 
     xorg_list_add(&vblank->event_queue, &present_exec_queue);
     vblank->queued = TRUE;
-    if (target_msc > crtc_msc) {
+    if (msc_is_after(target_msc, crtc_msc)) {
         ret = present_queue_vblank(screen, target_crtc, vblank->event_id, target_msc);
         if (ret == Success)
             return Success;
commit 1db6de7b6a6ee240eb50a13fe1fa1e135d7cb93b
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Jan 12 15:42:47 2016 +0900

    glamor: Disable debugging messages other than GL API errors
    
    According to Nicolai Hähnle, the relevant specification says "All
    messages are initially enabled unless their assigned severity is
    DEBUG_SEVERITY_LOW", so we need to explicitly disable the messages we
    don't want to get. Failing that, we were accidentally logging e.g.
    shader stats intended for shader-db.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93659
    Tested-by: Laurent Carlier <lordheavym at gmail.com>
    Reviewed-by: Emil Velikov <emil.l.velikov at gmail.com>
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 116d10c..81aba2d 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -393,6 +393,9 @@ glamor_setup_debug_output(ScreenPtr screen)
         return;
 
     glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+    /* Disable debugging messages other than GL API errors */
+    glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL,
+                          GL_FALSE);
     glDebugMessageControl(GL_DEBUG_SOURCE_API,
                           GL_DEBUG_TYPE_ERROR,
                           GL_DONT_CARE,
commit 8116fd8a760b5935645def1b2c3b155c05927850
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Jan 12 14:19:24 2016 +1000

    glamor: store old fonts in double width textures.
    
    There is a problem with some fonts that the height necessary
    to store the font is greater than the max texture size, which
    causes a fallback to occur. We can avoid this by storing two
    macro columns side-by-side in the texture and adjusting
    the calculations to suit.
    
    This fixes
    xfd -fn -*-*-*-*-*-*-*-*-*-*-*-*-*-*
    falling back here, when it picks
    -arabic-newspaper-medium-r-normal--32-246-100-100-p-137-iso10646-1
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/glamor/glamor_font.c b/glamor/glamor_font.c
index 9b0dbd1..637e0dc 100644
--- a/glamor/glamor_font.c
+++ b/glamor/glamor_font.c
@@ -77,8 +77,19 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
     glamor_font->glyph_width_bytes = glyph_width_bytes;
     glamor_font->glyph_height = glyph_height;
 
-    overall_width = glyph_width_bytes * num_cols;
-    overall_height = glyph_height * num_rows;
+    /*
+     * Layout the font two blocks of columns wide.
+     * This avoids a problem with some fonts that are too high to fit.
+     */
+    glamor_font->row_width = glyph_width_bytes * num_cols;
+
+    if (num_rows > 1) {
+       overall_width = glamor_font->row_width * 2;
+       overall_height = glyph_height * ((num_rows + 1) / 2);
+    } else {
+       overall_width = glamor_font->row_width;
+       overall_height = glyph_height;
+    }
 
     if (overall_width > glamor_priv->max_fbo_size ||
         overall_height > glamor_priv->max_fbo_size) {
@@ -117,11 +128,17 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
             (*font->get_glyphs)(font, 1, c, TwoD16Bit, &count, &glyph);
 
             if (count) {
-                char *dst = bits + row * glyph_height * overall_width +
-                    col * glyph_width_bytes;
+                char *dst;
                 char *src = glyph->bits;
                 unsigned y;
 
+                dst = bits;
+                /* get offset of start of first row */
+                dst += (row / 2) * glyph_height * overall_width;
+                /* add offset into second row */
+                dst += (row & 1) ? glamor_font->row_width : 0;
+
+                dst += col * glyph_width_bytes;
                 for (y = 0; y < GLYPHHEIGHTPIXELS(glyph); y++) {
                     memcpy(dst, src, GLYPHWIDTHBYTES(glyph));
                     dst += overall_width;
diff --git a/glamor/glamor_font.h b/glamor/glamor_font.h
index 36d2062..4d41e01 100644
--- a/glamor/glamor_font.h
+++ b/glamor/glamor_font.h
@@ -30,7 +30,7 @@ typedef struct {
     CARD8       default_col;
 
     GLuint      texture_id;
-
+    GLuint      row_width;
     CARD16      glyph_width_bytes;
     CARD16      glyph_width_pixels;
     CARD16      glyph_height;
diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
index 81a22a5..429f53b 100644
--- a/glamor/glamor_text.c
+++ b/glamor/glamor_text.c
@@ -142,7 +142,7 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
             int     height = GLYPHHEIGHTPIXELS(ci);
             int     tx, ty = 0;
             int     row = 0, col;
-
+            int     second_row = 0;
             x += ci->metrics.characterWidth;
 
             if (sixteen) {
@@ -153,8 +153,10 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
                     row = chars[0];
                     col = chars[1];
                 }
-                if (FONTLASTROW(font) != 0)
-                    ty = (row - firstRow) * glyph_spacing_y;
+                if (FONTLASTROW(font) != 0) {
+                    ty = ((row - firstRow) / 2) * glyph_spacing_y;
+                    second_row = (row - firstRow) & 1;
+                }
                 else
                     col += row << 8;
             } else {
@@ -165,6 +167,8 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
             }
 
             tx = (col - firstCol) * glyph_spacing_x;
+            /* adjust for second row layout */
+            tx += second_row * glamor_font->row_width * 8;
 
             v[ 0] = x1;
             v[ 1] = y1;
commit 64081d0eacf3e53a029b8e8b63096cc153e98549
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Jan 11 17:02:57 2016 +1000

    glamor: fallback if font is too large for FBO size.
    
    running xfontsel on haswell here, with a max texture size
    of 8kx8k, one font wants 9711 height. This fallsback to
    sw in this case.
    
    A proper solution probably involves using an array texture.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/glamor/glamor_font.c b/glamor/glamor_font.c
index 6753d50..9b0dbd1 100644
--- a/glamor/glamor_font.c
+++ b/glamor/glamor_font.c
@@ -80,6 +80,11 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
     overall_width = glyph_width_bytes * num_cols;
     overall_height = glyph_height * num_rows;
 
+    if (overall_width > glamor_priv->max_fbo_size ||
+        overall_height > glamor_priv->max_fbo_size) {
+        /* fallback if we don't fit inside a texture */
+        return NULL;
+    }
     bits = malloc(overall_width * overall_height);
     if (!bits)
         return NULL;
commit 6dcb73375e0ce389315d55587623eb84e9d13543
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Jan 6 10:03:23 2016 -0500

    os: Failure to remove a non-existent log file is not an error
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/os/log.c b/os/log.c
index 6168d59..91e55a5 100644
--- a/os/log.c
+++ b/os/log.c
@@ -218,7 +218,7 @@ LogFilePrep(const char *fname, const char *backup, const char *idstring)
         }
     }
     else {
-        if (remove(logFileName) != 0) {
+        if (remove(logFileName) != 0 && errno != ENOENT) {
             FatalError("Cannot remove old log file \"%s\": %s\n",
                        logFileName, strerror(errno));
         }
commit 862cbf4c870c9ed913206c6ef4988bdb470e1c39
Author: Thomas Klausner <wiz at NetBSD.org>
Date:   Wed Nov 11 13:32:05 2015 +0100

    Fix build when XSERVER_PLATFORM_BUS is not defined.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Thomas Klausner <wiz at NetBSD.org>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index e53d3d4..8f60eae 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -90,6 +90,10 @@ static const struct pci_id_match ms_device_match[] = {
 };
 #endif
 
+#ifndef XSERVER_PLATFORM_BUS
+struct xf86_platform_device;
+#endif
+
 #ifdef XSERVER_PLATFORM_BUS
 static Bool ms_platform_probe(DriverPtr driver,
                               int entity_num, int flags,
commit 63f83d1b7f496d05b409352749cdb6674d71cf80
Author: Thomas Klausner <wiz at NetBSD.org>
Date:   Tue Jan 5 12:51:41 2016 -0500

    Fix uninitialized variable warnings reported by clang
    
    v2: Move initializing pos into the first clause of the for statement. We
    have to keep this macro equivalent to a plain for statement from the
    user's perspective, otherwise callers need to {} things to keep control
    flow correct. [ajax]
    
    Signed-off-by: Thomas Klausner <wiz at NetBSD.org>
    Acked-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/include/list.h b/include/list.h
index 39f1985..3f0574d 100644
--- a/include/list.h
+++ b/include/list.h
@@ -304,8 +304,9 @@ xorg_list_is_empty(struct xorg_list *head)
  * @param member Member name of the struct xorg_list in the list elements.
  *
  */
-#define xorg_list_for_each_entry(pos, head, member)				\
-    for (pos = __container_of((head)->next, pos, member);		\
+#define xorg_list_for_each_entry(pos, head, member)			\
+    for (pos = NULL,                                                    \
+         pos = __container_of((head)->next, pos, member);		\
 	 &pos->member != (head);					\
 	 pos = __container_of(pos->member.next, pos, member))
 
@@ -317,7 +318,8 @@ xorg_list_is_empty(struct xorg_list *head)
  * See xorg_list_for_each_entry for more details.
  */
 #define xorg_list_for_each_entry_safe(pos, tmp, head, member)		\
-    for (pos = __container_of((head)->next, pos, member),		\
+    for (pos = NULL,                                                    \
+         pos = __container_of((head)->next, pos, member),		\
 	 tmp = __container_of(pos->member.next, pos, member);		\
 	 &pos->member != (head);					\
 	 pos = tmp, tmp = __container_of(pos->member.next, tmp, member))
commit ba71b69f94f00a6f6910597185610668e79c10be
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Jan 1 17:34:41 2016 -0800

    Avoid segfault in CloseWellKnownConnections when using -displayfd
    
    When -displayfd is looping through the possible display ids to use,
    if it can't open all the listening sockets for one (say when :0 is
    already in use), it calls CloseWellKnownConnections to close all
    the ListenTransConns entries before the point that ListenTransFds
    was allocated & initialized, so CloseWellKnownConnections would
    segfault trying to read entries from a NULL ListenTransFds pointer.
    
    Introduced by commit 7b02f0b8
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/os/connection.c b/os/connection.c
index 8e75139..2a4fc8d 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -523,7 +523,8 @@ CloseWellKnownConnections(void)
         if (ListenTransConns[i] != NULL) {
             _XSERVTransClose(ListenTransConns[i]);
             ListenTransConns[i] = NULL;
-            RemoveNotifyFd(ListenTransFds[i]);
+            if (ListenTransFds != NULL)
+                RemoveNotifyFd(ListenTransFds[i]);
         }
     }
     ListenTransCount = 0;
commit edcb6426f20c3be5dd5f50b76a686754aef2f64e
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Jan 1 18:11:14 2016 -0800

    Use unique logfile names when starting server with -displayfd
    
    Fixes https://bugs.freedesktop.org/show_bug.cgi?id=93212
    
    Previously all X servers started with -displayfd would overwrite
    Xorg.0.log - now a temporary name of Xorg.pid-<pid>.log is used
    until after -displayfd finds an open display - then it is renamed
    to the traditional Xorg.<display>.log name.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/include/os.h b/include/os.h
index e7c1936..461d5d6 100644
--- a/include/os.h
+++ b/include/os.h
@@ -626,6 +626,8 @@ typedef enum {
 
 extern _X_EXPORT const char *
 LogInit(const char *fname, const char *backup);
+extern void
+LogSetDisplay(void);
 extern _X_EXPORT void
 LogClose(enum ExitCode error);
 extern _X_EXPORT Bool
diff --git a/os/connection.c b/os/connection.c
index 8d866f6..8e75139 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -431,6 +431,7 @@ CreateWellKnownSockets(void)
             FatalError("Failed to find a socket to listen on");
         snprintf(dynamic_display, sizeof(dynamic_display), "%d", i);
         display = dynamic_display;
+        LogSetDisplay();
     }
 
     ListenTransFds = xallocarray(ListenTransCount, sizeof (int));
diff --git a/os/log.c b/os/log.c
index 3db5c53..6168d59 100644
--- a/os/log.c
+++ b/os/log.c
@@ -85,6 +85,7 @@ OR PERFORMANCE OF THIS SOFTWARE.
 #include <sys/stat.h>
 #include <stdarg.h>
 #include <stdlib.h>             /* for malloc() */
+#include <errno.h>
 
 #include "input.h"
 #include "site.h"
@@ -181,16 +182,64 @@ strlen_sigsafe(const char *s)
 }
 
 /*
+ * LogFilePrep is called to setup files for logging, including getting
+ * an old file out of the way, but it doesn't actually open the file,
+ * since it may be used for renaming a file we're already logging to.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+
+static char *
+LogFilePrep(const char *fname, const char *backup, const char *idstring)
+{
+    char *logFileName = NULL;
+
+    if (asprintf(&logFileName, fname, idstring) == -1)
+        FatalError("Cannot allocate space for the log file name\n");
+
+    if (backup && *backup) {
+        struct stat buf;
+
+        if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) {
+            char *suffix;
+            char *oldLog;
+
+            if ((asprintf(&suffix, backup, idstring) == -1) ||
+                (asprintf(&oldLog, "%s%s", logFileName, suffix) == -1)) {
+                FatalError("Cannot allocate space for the log file name\n");
+            }
+            free(suffix);
+
+            if (rename(logFileName, oldLog) == -1) {
+                FatalError("Cannot move old log file \"%s\" to \"%s\"\n",
+                           logFileName, oldLog);
+            }
+            free(oldLog);
+        }
+    }
+    else {
+        if (remove(logFileName) != 0) {
+            FatalError("Cannot remove old log file \"%s\": %s\n",
+                       logFileName, strerror(errno));
+        }
+    }
+
+    return logFileName;
+}
+#pragma GCC diagnostic pop
+
+/*
  * LogInit is called to start logging to a file.  It is also called (with
  * NULL arguments) when logging to a file is not wanted.  It must always be
  * called, otherwise log messages will continue to accumulate in a buffer.
  *
  * %s, if present in the fname or backup strings, is expanded to the display
- * string.
+ * string (or to a string containing the pid if the display is not yet set).
  */
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+static char *saved_log_fname;
+static char *saved_log_backup;
+static char *saved_log_tempname;
 
 const char *
 LogInit(const char *fname, const char *backup)
@@ -198,30 +247,22 @@ LogInit(const char *fname, const char *backup)
     char *logFileName = NULL;
 
     if (fname && *fname) {
-        if (asprintf(&logFileName, fname, display) == -1)
-            FatalError("Cannot allocate space for the log file name\n");
-
-        if (backup && *backup) {
-            struct stat buf;
-
-            if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) {
-                char *suffix;
-                char *oldLog;
-
-                if ((asprintf(&suffix, backup, display) == -1) ||
-                    (asprintf(&oldLog, "%s%s", logFileName, suffix) == -1))
-                    FatalError("Cannot allocate space for the log file name\n");
-                free(suffix);
-                if (rename(logFileName, oldLog) == -1) {
-                    FatalError("Cannot move old log file \"%s\" to \"%s\"\n",
-                               logFileName, oldLog);
-                }
-                free(oldLog);
-            }
-        }
-        else {
-            unlink(logFileName);
-        }
+        if (displayfd != -1) {
+            /* Display isn't set yet, so we can't use it in filenames yet. */
+            char pidstring[32];
+            snprintf(pidstring, sizeof(pidstring), "pid-%ld",
+                     (unsigned long) getpid());
+            logFileName = LogFilePrep(fname, backup, pidstring);
+            saved_log_tempname = logFileName;
+
+            /* Save the patterns for use when the display is named. */
+            saved_log_fname = strdup(fname);
+            if (backup == NULL)
+                saved_log_backup = NULL;
+            else
+                saved_log_backup = strdup(backup);
+        } else
+            logFileName = LogFilePrep(fname, backup, display);
         if ((logFile = fopen(logFileName, "w")) == NULL)
             FatalError("Cannot open log file \"%s\"\n", logFileName);
         setvbuf(logFile, NULL, _IONBF, 0);
@@ -251,7 +292,36 @@ LogInit(const char *fname, const char *backup)
 
     return logFileName;
 }
-#pragma GCC diagnostic pop
+
+void
+LogSetDisplay(void)
+{
+    if (saved_log_fname) {
+        char *logFileName;
+
+        logFileName = LogFilePrep(saved_log_fname, saved_log_backup, display);
+
+        if (rename(saved_log_tempname, logFileName) == 0) {
+            LogMessageVerb(X_PROBED, 0,
+                           "Log file renamed from \"%s\" to \"%s\"\n",
+                           saved_log_tempname, logFileName);
+
+            if (strlen(saved_log_tempname) >= strlen(logFileName))
+                strncpy(saved_log_tempname, logFileName,
+                        strlen(saved_log_tempname));
+        }
+        else {
+            ErrorF("Failed to rename log file \"%s\" to \"%s\": %s\n",
+                   saved_log_tempname, logFileName, strerror(errno));
+        }
+
+        /* free newly allocated string - can't free old one since existing
+           pointers to it may exist in DDX callers. */
+        free(logFileName);
+        free(saved_log_fname);
+        free(saved_log_backup);
+    }
+}
 
 void
 LogClose(enum ExitCode error)
commit fe8562f5316d8c74ca074ad145295c65ddff5fc2
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Jan 1 18:10:08 2016 -0800

    modesetting should not reference gbm when it's not defined
    
    Fixes build errors of:
    present.c: In function 'ms_do_pageflip':
    present.c:410:17: error: 'drmmode_bo' has no member named 'gbm'
         new_front_bo.gbm = glamor_gbm_bo_from_pixmap(screen, new_front);
                     ^
    present.c:412:22: error: 'drmmode_bo' has no member named 'gbm'
         if (!new_front_bo.gbm) {
                          ^
    present.c: In function 'ms_present_check_flip':
    present.c:536:36: error: 'drmmode_bo' has no member named 'gbm'
             if (drmmode_crtc->rotate_bo.gbm)
                                        ^
    Introduced by commit 13c7d53d
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index bb2976b..d65c8c8 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -398,6 +398,9 @@ ms_do_pageflip(ScreenPtr screen,
                int ref_crtc_vblank_pipe,
                Bool async)
 {
+#ifndef GLAMOR_HAS_GBM
+    return FALSE;
+#else
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     modesettingPtr ms = modesettingPTR(scrn);
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -505,6 +508,7 @@ error_out:
         flipdata->flip_count--;
 
     return FALSE;
+#endif /* GLAMOR_HAS_GBM */
 }
 
 /*
@@ -533,8 +537,10 @@ ms_present_check_flip(RRCrtcPtr crtc,
         drmmode_crtc_private_ptr drmmode_crtc = config->crtc[i]->driver_private;
 
         /* Don't do pageflipping if CRTCs are rotated. */
+#ifdef GLAMOR_HAS_GBM
         if (drmmode_crtc->rotate_bo.gbm)
             return FALSE;
+#endif
 
         if (ms_crtc_on(config->crtc[i]))
             num_crtcs_on++;
commit 792176417f7e62a99c4f07801f74f804d6080de2
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Jan 5 12:03:54 2016 -0500

    Revert "Fix uninitialized variable warnings reported by clang"
    
    Crashes at startup:
    
    dmt:~/git/xserver% ./hw/kdrive/ephyr/Xephyr :1
    (EE) Backtrace:
    (EE) 0: ./hw/kdrive/ephyr/Xephyr (OsSigHandler+0x29) [0x47c8f9]
    (EE) 1: /lib64/libc.so.6 (__restore_rt+0x0) [0x7f38d4de6b1f]
    (EE) 2: ./hw/kdrive/ephyr/Xephyr (InitNotifyFds+0x17) [0x478697]
    (EE) 3: ./hw/kdrive/ephyr/Xephyr (OsInit+0x1e) [0x47c99e]
    (EE) 4: ./hw/kdrive/ephyr/Xephyr (dix_main+0x11c) [0x446efc]
    (EE) 5: /lib64/libc.so.6 (__libc_start_main+0xf0) [0x7f38d4dd2580]
    (EE) 6: ./hw/kdrive/ephyr/Xephyr (_start+0x29) [0x427099]
    (EE) 7: ? (?+0x29) [0x29]
    (EE)
    (EE) Segmentation fault at address 0x0
    
    This reverts commit a221d4737c167589da44595c795d54f2c36b439a.

diff --git a/include/list.h b/include/list.h
index 1accf10..39f1985 100644
--- a/include/list.h
+++ b/include/list.h
@@ -304,8 +304,7 @@ xorg_list_is_empty(struct xorg_list *head)
  * @param member Member name of the struct xorg_list in the list elements.
  *
  */
-#define xorg_list_for_each_entry(pos, head, member)			\
-    pos = NULL;								\
+#define xorg_list_for_each_entry(pos, head, member)				\
     for (pos = __container_of((head)->next, pos, member);		\
 	 &pos->member != (head);					\
 	 pos = __container_of(pos->member.next, pos, member))
@@ -318,7 +317,6 @@ xorg_list_is_empty(struct xorg_list *head)
  * See xorg_list_for_each_entry for more details.
  */
 #define xorg_list_for_each_entry_safe(pos, tmp, head, member)		\
-    pos = NULL;								\
     for (pos = __container_of((head)->next, pos, member),		\
 	 tmp = __container_of(pos->member.next, pos, member);		\
 	 &pos->member != (head);					\
commit a221d4737c167589da44595c795d54f2c36b439a
Author: Thomas Klausner <wiz at NetBSD.org>
Date:   Wed Dec 16 08:36:24 2015 +0100

    Fix uninitialized variable warnings reported by clang
    
    Signed-off-by: Thomas Klausner <wiz at NetBSD.org>
    Acked-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/include/list.h b/include/list.h
index 39f1985..1accf10 100644
--- a/include/list.h
+++ b/include/list.h
@@ -304,7 +304,8 @@ xorg_list_is_empty(struct xorg_list *head)
  * @param member Member name of the struct xorg_list in the list elements.
  *
  */
-#define xorg_list_for_each_entry(pos, head, member)				\
+#define xorg_list_for_each_entry(pos, head, member)			\
+    pos = NULL;								\
     for (pos = __container_of((head)->next, pos, member);		\
 	 &pos->member != (head);					\
 	 pos = __container_of(pos->member.next, pos, member))
@@ -317,6 +318,7 @@ xorg_list_is_empty(struct xorg_list *head)
  * See xorg_list_for_each_entry for more details.
  */
 #define xorg_list_for_each_entry_safe(pos, tmp, head, member)		\
+    pos = NULL;								\
     for (pos = __container_of((head)->next, pos, member),		\
 	 tmp = __container_of(pos->member.next, pos, member);		\
 	 &pos->member != (head);					\
commit f3593918a0507cc080875788b2776ebe4f57c694
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Dec 16 09:21:39 2015 +1000

    xfree86: move check for driver->PreInit up
    
    No real change, but if the driver is broken and doesn't provide a PreInit
    function, then we don't need to worry about logind.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 2dca130..a9ce62a 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -860,6 +860,17 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
         goto unwind;
     }
 
+    xf86Msg(X_INFO, "Using input driver '%s' for '%s'\n", drv->driverName,
+            pInfo->name);
+
+    if (!drv->PreInit) {
+        xf86Msg(X_ERROR,
+                "Input driver `%s' has no PreInit function (ignoring)\n",
+                drv->driverName);
+        rval = BadImplementation;
+        goto unwind;
+    }
+
     path = xf86CheckStrOption(pInfo->options, "Device", NULL);
     if (path && pInfo->major == 0 && pInfo->minor == 0)
         xf86stat(path, &pInfo->major, &pInfo->minor);
@@ -887,17 +898,6 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
 
     free(path);
 
-    xf86Msg(X_INFO, "Using input driver '%s' for '%s'\n", drv->driverName,
-            pInfo->name);
-
-    if (!drv->PreInit) {
-        xf86Msg(X_ERROR,
-                "Input driver `%s' has no PreInit function (ignoring)\n",
-                drv->driverName);
-        rval = BadImplementation;
-        goto unwind;
-    }
-
     xf86AddInput(drv, pInfo);
 
     rval = drv->PreInit(drv, pInfo, 0);
commit fc4fbe8224fdc8d7774120b6e978c652a70a50ee
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Dec 11 09:31:30 2015 +1000

    xfree86: add NoMatchFoo directives for InputClass sections
    
    InputClass sections use various MatchFoo directives to decide which device to
    apply to. This usually works fine for specific snippets but has drawbacks for
    snippets that apply more generally to a multitude of devices.
    
    This patch adds a NoMatchFoo directive to negate a match, thus allowing
    snippets that only apply if a given condition is not set. Specifically, this
    allows for more flexible fallback driver matching, it is now possible to use a
    snippet that says "assign driver foo, but only if driver bar wasn't already
    assigned to it". For example:
    
    Section "InputClass"
       Identifier "libinput for tablets"
       MatchIsTablet "true"
       NoMatchDriver "wacom"
       Driver "libinput"
    EndSection
    
    The above only assigns libinput to tablet devices if wacom isn't already
    assigned to this device, making it possible to select a specific driver by
    installing/uninstalling it.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index c56a2b9..2dca130 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -540,21 +540,24 @@ MatchAttrToken(const char *attr, struct xorg_list *patterns,
     if (xorg_list_is_empty(patterns))
         return TRUE;
 
-    /* If there are patterns but no attribute, reject the match */
-    if (!attr)
-        return FALSE;
-
     /*
-     * Otherwise, iterate the list of patterns ensuring each entry has a
+     * Iterate the list of patterns ensuring each entry has a
      * match. Each list entry is a separate Match line of the same type.
      */
     xorg_list_for_each_entry(group, patterns, entry) {
         char *const *cur;
-        Bool match = FALSE;
+        Bool is_negated = group->is_negated;
+        Bool match = is_negated;
+
+        /* If there's a pattern but no attribute, we reject the match for a
+         * MatchFoo directive, and accept it for a NoMatchFoo directive
+         */
+        if (!attr)
+            return is_negated;
 
         for (cur = group->values; *cur; cur++)
             if ((*compare) (attr, *cur) == 0) {
-                match = TRUE;
+                match = !is_negated;
                 break;
             }
         if (!match)
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
index 08eb7a9..d794df4 100644
--- a/hw/xfree86/man/xorg.conf.man
+++ b/hw/xfree86/man/xorg.conf.man
@@ -1092,6 +1092,7 @@ attribute. For example:
 .B  "    # either gizmo or gadget
 .B  "    MatchProduct \*qexample\*q
 .B  "    MatchProduct \*qgizmo|gadget\*q
+.B  "    NoMatchDriver \*qdrivername\*q
 .I  "    ..."
 .B  "EndSection"
 .fi
@@ -1160,6 +1161,20 @@ if no named
 .B ServerLayout
 sections have been found.
 .PP
+The above directives have equivalents for negative matching with the
+.B NoMatchProduct,
+.B NoMatchVendor,
+.B NoMatchDevicePath,
+.B NoMatchOS,
+.B NoMatchPnPID,
+.B NoMatchUSBID,
+.B NoMatchDriver,
+.B NoMatchTag,
+and
+.B NoMatchLayout
+directives. These NoMatch directives match if the subsequent match is not
+met by the device.
+.PP
 The second type of entry is used to match device types. These entries take a
 boolean argument similar to
 .B Option
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index 2b68aaa..5d3b59c 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -55,6 +55,15 @@ xf86ConfigSymTabRec InputClassTab[] = {
     {MATCH_IS_TABLET, "matchistablet"},
     {MATCH_IS_TOUCHPAD, "matchistouchpad"},
     {MATCH_IS_TOUCHSCREEN, "matchistouchscreen"},
+    {NOMATCH_PRODUCT, "nomatchproduct"},
+    {NOMATCH_VENDOR, "nomatchvendor"},
+    {NOMATCH_DEVICE_PATH, "nomatchdevicepath"},
+    {NOMATCH_OS, "nomatchos"},
+    {NOMATCH_PNPID, "nomatchpnpid"},
+    {NOMATCH_USBID, "nomatchusbid"},
+    {NOMATCH_DRIVER, "nomatchdriver"},
+    {NOMATCH_TAG, "nomatchtag"},
+    {NOMATCH_LAYOUT, "nomatchlayout"},
     {-1, ""},
 };
 
@@ -138,13 +147,19 @@ xf86freeInputClassList(XF86ConfInputClassPtr ptr)
 
 #define TOKEN_SEP "|"
 
+enum MatchType {
+    MATCH_NORMAL,
+    MATCH_NEGATED,
+};
+
 static void
-add_group_entry(struct xorg_list *head, char **values)
+add_group_entry(struct xorg_list *head, char **values, enum MatchType type)
 {
     xf86MatchGroup *group;
 
     group = malloc(sizeof(*group));
     if (group) {
+        group->is_negated = (type == MATCH_NEGATED);
         group->values = values;
         xorg_list_add(&group->entry, head);
     }
@@ -155,6 +170,7 @@ xf86parseInputClassSection(void)
 {
     int has_ident = FALSE;
     int token;
+    enum MatchType matchtype;
 
     parsePrologue(XF86ConfInputClassPtr, XF86ConfInputClassRec)
 
@@ -170,6 +186,8 @@ xf86parseInputClassSection(void)
     xorg_list_init(&ptr->match_layout);
 
     while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
+        matchtype = MATCH_NORMAL;
+
         switch (token) {
         case COMMENT:
             ptr->comment = xf86addComment(ptr->comment, xf86_lex_val.str);
@@ -195,65 +213,103 @@ xf86parseInputClassSection(void)
         case OPTION:
             ptr->option_lst = xf86parseOption(ptr->option_lst);
             break;
+        case NOMATCH_PRODUCT:
+            matchtype = MATCH_NEGATED;
+            /* fallthrough */
         case MATCH_PRODUCT:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchProduct");
             add_group_entry(&ptr->match_product,
-                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
+                            matchtype);
             free(xf86_lex_val.str);
             break;
+        case NOMATCH_VENDOR:
+            matchtype = MATCH_NEGATED;
+            /* fallthrough */
         case MATCH_VENDOR:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchVendor");
             add_group_entry(&ptr->match_vendor,
-                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
+                            matchtype);
             free(xf86_lex_val.str);
             break;
+        case NOMATCH_DEVICE_PATH:
+            matchtype = MATCH_NEGATED;
+            /* fallthrough */
         case MATCH_DEVICE_PATH:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchDevicePath");
             add_group_entry(&ptr->match_device,
-                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
+                            matchtype);
             free(xf86_lex_val.str);
             break;
+        case NOMATCH_OS:
+            matchtype = MATCH_NEGATED;
+            /* fallthrough */
         case MATCH_OS:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchOS");
-            add_group_entry(&ptr->match_os, xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+            add_group_entry(&ptr->match_os, xstrtokenize(xf86_lex_val.str,
+                                                         TOKEN_SEP),
+                            matchtype);
             free(xf86_lex_val.str);
             break;
+        case NOMATCH_PNPID:
+            matchtype = MATCH_NEGATED;
+            /* fallthrough */
         case MATCH_PNPID:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchPnPID");
             add_group_entry(&ptr->match_pnpid,
-                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
+                            matchtype);
             free(xf86_lex_val.str);
             break;
+        case NOMATCH_USBID:
+            matchtype = MATCH_NEGATED;
+            /* fallthrough */
         case MATCH_USBID:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchUSBID");
             add_group_entry(&ptr->match_usbid,
-                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
+                            matchtype);
             free(xf86_lex_val.str);
             break;
+        case NOMATCH_DRIVER:
+            matchtype = MATCH_NEGATED;
+            /* fallthrough */
         case MATCH_DRIVER:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchDriver");
             add_group_entry(&ptr->match_driver,
-                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
+                            matchtype);
             free(xf86_lex_val.str);
             break;
+        case NOMATCH_TAG:
+            matchtype = MATCH_NEGATED;
+            /* fallthrough */
         case MATCH_TAG:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchTag");
-            add_group_entry(&ptr->match_tag, xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+            add_group_entry(&ptr->match_tag, xstrtokenize(xf86_lex_val.str,
+                                                          TOKEN_SEP),
+                            matchtype);
             free(xf86_lex_val.str);
             break;
+        case NOMATCH_LAYOUT:
+            matchtype = MATCH_NEGATED;
+            /* fallthrough */
         case MATCH_LAYOUT:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchLayout");
             add_group_entry(&ptr->match_layout,
-                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP),
+                            matchtype);
             free(xf86_lex_val.str);
             break;
         case MATCH_IS_KEYBOARD:
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index b3a50e5..a038f9e 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -306,6 +306,7 @@ typedef struct {
 typedef struct {
     struct xorg_list entry;
     char **values;
+    Bool is_negated;
 } xf86MatchGroup;
 
 typedef struct {
diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
index bbd6b90..f955af0 100644
--- a/hw/xfree86/parser/xf86tokens.h
+++ b/hw/xfree86/parser/xf86tokens.h
@@ -286,7 +286,17 @@ typedef enum {
     MATCH_IS_JOYSTICK,
     MATCH_IS_TABLET,
     MATCH_IS_TOUCHPAD,
-    MATCH_IS_TOUCHSCREEN
+    MATCH_IS_TOUCHSCREEN,
+
+    NOMATCH_PRODUCT,
+    NOMATCH_VENDOR,
+    NOMATCH_DEVICE_PATH,
+    NOMATCH_OS,
+    NOMATCH_PNPID,
+    NOMATCH_USBID,
+    NOMATCH_DRIVER,
+    NOMATCH_TAG,
+    NOMATCH_LAYOUT,
 } ParserTokens;
 
 #endif                          /* _xf86_tokens_h */
commit eb671b804e902011ba901d0833a215799177bad0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Dec 11 07:26:02 2015 +1000

    xfree86: whitespace fix
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index 29bd9fa..2b68aaa 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -158,8 +158,8 @@ xf86parseInputClassSection(void)
 
     parsePrologue(XF86ConfInputClassPtr, XF86ConfInputClassRec)
 
-        /* Initialize MatchGroup lists */
-        xorg_list_init(&ptr->match_product);
+    /* Initialize MatchGroup lists */
+    xorg_list_init(&ptr->match_product);
     xorg_list_init(&ptr->match_vendor);
     xorg_list_init(&ptr->match_device);
     xorg_list_init(&ptr->match_os);
commit 3d68d1f26709ecb5ce22a9baa0d3d8162574ed6a
Author: Siim Põder <siim at p6drad-teel.net>
Date:   Mon Jun 8 22:14:12 2015 +0000

    vfb: add randr support (v2)
    
    The motivation for getting this is chrome remote desktop that runs under
    Xvfb and wants to use RANDR to adjust screen size according to the
    remote desktop client screen size. Apparently there are other use cases
    as well, the bug mentions gnome-settings-daemon testing.
    
    [ajax: massaged commit message]
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=26391
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Lambros Lambrou <lambroslambrou at google.com>
    Signed-off-by: Mike Frysinger <vapier at gentoo.org>
    Signed-off-by: Michal Srb <msrb at suse.com>
    Signed-off-by: Siim Põder <siim at p6drad-teel.net>

diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index 8b867e3..9e8dd7a 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -66,6 +66,7 @@ from The Open Group.
 #include "dix.h"
 #include "miline.h"
 #include "glx_extinit.h"
+#include "randrstr.h"
 
 #define VFB_DEFAULT_WIDTH      1280
 #define VFB_DEFAULT_HEIGHT     1024
@@ -739,6 +740,125 @@ vfbCloseScreen(ScreenPtr pScreen)
 }
 
 static Bool
+vfbRROutputValidateMode(ScreenPtr           pScreen,
+                        RROutputPtr         output,
+                        RRModePtr           mode)
+{
+    rrScrPriv(pScreen);
+
+    if (pScrPriv->minWidth <= mode->mode.width &&
+        pScrPriv->maxWidth >= mode->mode.width &&
+        pScrPriv->minHeight <= mode->mode.height &&
+        pScrPriv->maxHeight >= mode->mode.height)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+static Bool
+vfbRRScreenSetSize(ScreenPtr  pScreen,
+                   CARD16     width,
+                   CARD16     height,
+                   CARD32     mmWidth,
+                   CARD32     mmHeight)
+{
+    // Prevent screen updates while we change things around
+    SetRootClip(pScreen, FALSE);
+
+    pScreen->width = width;
+    pScreen->height = height;
+    pScreen->mmWidth = mmWidth;
+    pScreen->mmHeight = mmHeight;
+
+    // Restore the ability to update screen, now with new dimensions
+    SetRootClip(pScreen, TRUE);
+
+    RRScreenSizeNotify (pScreen);
+    RRTellChanged(pScreen);
+
+    return TRUE;
+}
+
+static Bool
+vfbRRCrtcSet(ScreenPtr pScreen,
+             RRCrtcPtr crtc,
+             RRModePtr mode,
+             int       x,
+             int       y,
+             Rotation  rotation,
+             int       numOutput,
+             RROutputPtr *outputs)
+{
+  return RRCrtcNotify(crtc, mode, x, y, rotation, NULL, numOutput, outputs);
+}
+
+static Bool
+vfbRRGetInfo(ScreenPtr pScreen, Rotation *rotations)
+{
+    return TRUE;
+}
+
+static Bool
+vfbRandRInit(ScreenPtr pScreen)
+{
+    rrScrPrivPtr pScrPriv;
+#if RANDR_12_INTERFACE
+    RRModePtr  mode;
+    RRCrtcPtr  crtc;
+    RROutputPtr        output;
+    xRRModeInfo modeInfo;
+    char       name[64];
+#endif
+
+    if (!RRScreenInit (pScreen))
+       return FALSE;
+    pScrPriv = rrGetScrPriv(pScreen);
+    pScrPriv->rrGetInfo = vfbRRGetInfo;
+#if RANDR_12_INTERFACE
+    pScrPriv->rrCrtcSet = vfbRRCrtcSet;
+    pScrPriv->rrScreenSetSize = vfbRRScreenSetSize;
+    pScrPriv->rrOutputSetProperty = NULL;
+#if RANDR_13_INTERFACE
+    pScrPriv->rrOutputGetProperty = NULL;
+#endif
+    pScrPriv->rrOutputValidateMode = vfbRROutputValidateMode;
+    pScrPriv->rrModeDestroy = NULL;
+
+    RRScreenSetSizeRange (pScreen,
+                         1, 1,
+                         pScreen->width, pScreen->height);
+
+    sprintf (name, "%dx%d", pScreen->width, pScreen->height);
+    memset (&modeInfo, '\0', sizeof (modeInfo));
+    modeInfo.width = pScreen->width;
+    modeInfo.height = pScreen->height;
+    modeInfo.nameLength = strlen (name);
+
+    mode = RRModeGet (&modeInfo, name);
+    if (!mode)
+       return FALSE;
+
+    crtc = RRCrtcCreate (pScreen, NULL);
+    if (!crtc)
+       return FALSE;
+
+    output = RROutputCreate (pScreen, "screen", 6, NULL);
+    if (!output)
+       return FALSE;
+    if (!RROutputSetClones (output, NULL, 0))
+       return FALSE;
+    if (!RROutputSetModes (output, &mode, 1, 0))
+       return FALSE;
+    if (!RROutputSetCrtcs (output, &crtc, 1))
+       return FALSE;
+    if (!RROutputSetConnection (output, RR_Connected))
+       return FALSE;
+    RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, NULL, 1, &output);
+#endif
+    return TRUE;
+}
+
+static Bool
 vfbScreenInit(ScreenPtr pScreen, int argc, char **argv)
 {
     vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
@@ -811,6 +931,9 @@ vfbScreenInit(ScreenPtr pScreen, int argc, char **argv)
     if (!ret)
         return FALSE;
 
+    if (!vfbRandRInit(pScreen))
+       return FALSE;
+
     pScreen->InstallColormap = vfbInstallColormap;
 
     pScreen->SaveScreen = vfbSaveScreen;
commit e98b36bc69d805ab52aba95b070a614427d46e05
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 8 16:22:16 2015 -0500

    randr: Silence unused variable warning
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index ec26fcd..566a3db 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -383,7 +383,6 @@ rrDestroySharedPixmap(RRCrtcPtr crtc, PixmapPtr pPixmap) {
 void
 RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
 {
-    ScreenPtr master = crtc->pScreen->current_master;
     rrScrPriv(crtc->pScreen);
 
     pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL);
commit 8c49c883dc196ea57e3f64425c2a5b0a8ce3ba75
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 8 15:08:34 2015 -0500

    sync: Don't allow creating a system counter before sync is initialized
    
    It probably doesn't work very well since there's other extension setup
    we're not doing on this path, and in any event it's not a thing that
    happens currently.
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/Xext/sync.c b/Xext/sync.c
index 4140561..4c59fea 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -984,20 +984,7 @@ SyncCreateSystemCounter(const char *name,
                         SyncSystemCounterBracketValues BracketValues
     )
 {
-    SyncCounter *pCounter;
-
-    /* this function may be called before SYNC has been initialized, so we
-     * have to make sure RTCounter is created.
-     */
-    if (RTCounter == 0) {
-        RTCounter = CreateNewResourceType(FreeCounter, "SyncCounter");
-        if (RTCounter == 0) {
-            return NULL;
-        }
-        xorg_list_init(&SysCounterList);
-    }
-
-    pCounter = SyncCreateCounter(NULL, FakeClientID(0), initial);
+    SyncCounter *pCounter = SyncCreateCounter(NULL, FakeClientID(0), initial);
 
     if (pCounter) {
         SysCounterInfo *psci;
@@ -2501,10 +2488,8 @@ SyncExtensionInit(void)
     for (s = 0; s < screenInfo.numScreens; s++)
         miSyncSetup(screenInfo.screens[s]);
 
-    if (RTCounter == 0) {
-        RTCounter = CreateNewResourceType(FreeCounter, "SyncCounter");
-        xorg_list_init(&SysCounterList);
-    }
+    RTCounter = CreateNewResourceType(FreeCounter, "SyncCounter");
+    xorg_list_init(&SysCounterList);
     RTAlarm = CreateNewResourceType(FreeAlarm, "SyncAlarm");
     RTAwait = CreateNewResourceType(FreeAwait, "SyncAwait");
     RTFence = CreateNewResourceType(FreeFence, "SyncFence");
commit b5f04a79df8b5aab8b558461261d14721f0b3e41
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 8 15:56:17 2015 -0500

    glxproxy: Silence shadowed-variable warnings
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/dmx/glxProxy/glxsingle.c b/hw/dmx/glxProxy/glxsingle.c
index 79d426b..e254936 100644
--- a/hw/dmx/glxProxy/glxsingle.c
+++ b/hw/dmx/glxProxy/glxsingle.c
@@ -804,9 +804,8 @@ __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc)
     int win_y1, win_y2;
     int ebits, rowsize;
 
-    __GLX_DECLARE_SWAP_VARIABLES;
-
     if (client->swapped) {
+        __GLX_DECLARE_SWAP_VARIABLES;
         __GLX_SWAP_INT(&req->contextTag);
     }
 
@@ -834,6 +833,7 @@ __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc)
     lsbFirst = *(GLboolean *) (pc + 25);
 
     if (client->swapped) {
+        __GLX_DECLARE_SWAP_VARIABLES;
         __GLX_SWAP_INT(&x);
         __GLX_SWAP_INT(&y);
         __GLX_SWAP_INT(&width);
@@ -1017,6 +1017,7 @@ __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc)
     };
 
     if (client->swapped) {
+        __GLX_DECLARE_SWAP_VARIABLES;
         __GLX_SWAP_SHORT(&reply.sequenceNumber);
         __GLX_SWAP_INT(&reply.length);
     }
commit 18729a211a5fdd4f733e44eded754a0e6210b687
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 8 15:53:35 2015 -0500

    glxproxy: Silence set-but-unused-variable warnings
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/dmx/glxProxy/render2swap.c b/hw/dmx/glxProxy/render2swap.c
index 166ec88..146476c 100644
--- a/hw/dmx/glxProxy/render2swap.c
+++ b/hw/dmx/glxProxy/render2swap.c
@@ -67,7 +67,7 @@ void
 __glXDispSwap_Map1f(GLbyte * pc)
 {
     GLint order, k;
-    GLfloat u1, u2, *points;
+    GLfloat *points;
     GLenum target;
     GLint compsize;
 
@@ -81,8 +81,6 @@ __glXDispSwap_Map1f(GLbyte * pc)
 
     target = *(GLenum *) (pc + 0);
     order = *(GLint *) (pc + 12);
-    u1 = *(GLfloat *) (pc + 4);
-    u2 = *(GLfloat *) (pc + 8);
     points = (GLfloat *) (pc + 16);
     k = __glEvalComputeK(target);
 
@@ -100,8 +98,8 @@ __glXDispSwap_Map1f(GLbyte * pc)
 void
 __glXDispSwap_Map2f(GLbyte * pc)
 {
-    GLint uorder, vorder, ustride, vstride, k;
-    GLfloat u1, u2, v1, v2, *points;
+    GLint uorder, vorder, k;
+    GLfloat *points;
     GLenum target;
     GLint compsize;
 
@@ -119,15 +117,9 @@ __glXDispSwap_Map2f(GLbyte * pc)
     target = *(GLenum *) (pc + 0);
     uorder = *(GLint *) (pc + 12);
     vorder = *(GLint *) (pc + 24);
-    u1 = *(GLfloat *) (pc + 4);
-    u2 = *(GLfloat *) (pc + 8);
-    v1 = *(GLfloat *) (pc + 16);
-    v2 = *(GLfloat *) (pc + 20);
     points = (GLfloat *) (pc + 28);
 
     k = __glEvalComputeK(target);
-    ustride = vorder * k;
-    vstride = k;
 
     if (vorder <= 0 || uorder <= 0 || k < 0) {
         /* Erroneous command. */
@@ -145,7 +137,7 @@ __glXDispSwap_Map1d(GLbyte * pc)
 {
     GLint order, k, compsize;
     GLenum target;
-    GLdouble u1, u2, *points;
+    GLdouble u1, u2;
 
     __GLX_DECLARE_SWAP_VARIABLES;
     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
@@ -177,21 +169,15 @@ __glXDispSwap_Map1d(GLbyte * pc)
          ** the data in the process
          */
         __GLX_MEM_COPY(pc - 4, pc, compsize * 8);
-        points = (GLdouble *) (pc - 4);
     }
-    else {
-        points = (GLdouble *) pc;
-    }
-#else
-    points = (GLdouble *) pc;
 #endif
 }
 
 void
 __glXDispSwap_Map2d(GLbyte * pc)
 {
-    GLdouble u1, u2, v1, v2, *points;
-    GLint uorder, vorder, ustride, vstride, k, compsize;
+    GLdouble u1, u2, v1, v2;
+    GLint uorder, vorder, k, compsize;
     GLenum target;
 
     __GLX_DECLARE_SWAP_VARIABLES;
@@ -222,8 +208,6 @@ __glXDispSwap_Map2d(GLbyte * pc)
     __GLX_GET_DOUBLE(v2, pc + 24);
     __GLX_SWAP_DOUBLE_ARRAY(pc + 44, compsize);
     pc += 44;
-    ustride = vorder * k;
-    vstride = k;
 
 #ifdef __GLX_ALIGN64
     if (((unsigned long) pc) & 7) {
@@ -232,13 +216,7 @@ __glXDispSwap_Map2d(GLbyte * pc)
          ** the data in the process
          */
         __GLX_MEM_COPY(pc - 4, pc, compsize * 8);
-        points = (GLdouble *) (pc - 4);
-    }
-    else {
-        points = (GLdouble *) pc;
     }
-#else
-    points = (GLdouble *) pc;
 #endif
 }
 
diff --git a/hw/dmx/glxProxy/renderpixswap.c b/hw/dmx/glxProxy/renderpixswap.c
index 32df0d5..6557a8f 100644
--- a/hw/dmx/glxProxy/renderpixswap.c
+++ b/hw/dmx/glxProxy/renderpixswap.c
@@ -380,12 +380,9 @@ __glXDispSwap_SeparableFilter2D(GLbyte * pc)
 {
     __GLXdispatchConvolutionFilterHeader *hdr =
         (__GLXdispatchConvolutionFilterHeader *) pc;
-    GLint hdrlen;
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    hdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_HDR_SIZE);
-
     __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
     __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
     __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
commit bc996fa4e3c06f65eafe0a88ef491dbf01f31422
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 8 16:04:44 2015 -0500

    dmx: Run 'doxygen -u' to upgrade the doxygen config file
    
    Also change the dot font setting back to the default of Helvetica as
    doxygen no longer ships FreeSans.
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/dmx/doxygen/doxygen.conf.in b/hw/dmx/doxygen/doxygen.conf.in
index 3dbb27e..d709c9b 100644
--- a/hw/dmx/doxygen/doxygen.conf.in
+++ b/hw/dmx/doxygen/doxygen.conf.in
@@ -1,96 +1,129 @@
-# Doxyfile 1.6.2
+# Doxyfile 1.8.10
 
 # This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
+# doxygen (www.doxygen.org) for a project.
 #
-# All text after a hash (#) is considered a comment and will be ignored
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
 # The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
 
 #---------------------------------------------------------------------------
 # Project related configuration options
 #---------------------------------------------------------------------------
 
 # This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the
-# iconv built into libc) for the transcoding. See
-# http://www.gnu.org/software/libiconv for the list of possible encodings.
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
 
 DOXYFILE_ENCODING      = UTF-8
 
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
 
 PROJECT_NAME           = "Distributed Multihead X"
 
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
 
 PROJECT_NUMBER         = "@PACKAGE_VERSION@"
 
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
 
 OUTPUT_DIRECTORY       =
 
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
 
 CREATE_SUBDIRS         = NO
 
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
 # The OUTPUT_LANGUAGE tag is used to specify the language in which all
 # documentation generated by doxygen is written. Doxygen will use this
 # information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
-# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
-# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
 
 OUTPUT_LANGUAGE        = English
 
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
 
 BRIEF_MEMBER_DESC      = YES
 
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
 # brief descriptions will be completely suppressed.
+# The default value is: YES.
 
 REPEAT_BRIEF           = YES
 
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
 
 ABBREVIATE_BRIEF       =
 
 # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
+# doxygen will generate a detailed section even if there is only a brief
 # description.
+# The default value is: NO.
 
 ALWAYS_DETAILED_SEC    = YES
 
@@ -98,528 +131,699 @@ ALWAYS_DETAILED_SEC    = YES
 # inherited members of a class in the documentation of that class as if those
 # members were ordinary class members. Constructors, destructors and assignment
 # operators of the base classes will not be shown.
+# The default value is: NO.
 
 INLINE_INHERITED_MEMB  = NO
 
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
 
 FULL_PATH_NAMES        = NO
 
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
 
 STRIP_FROM_PATH        =
 
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
 
 STRIP_FROM_INC_PATH    =
 
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
 
 SHORT_NAMES            = NO
 
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like regular Qt-style comments
-# (thus requiring an explicit @brief command for a brief description.)
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
 
 JAVADOC_AUTOBRIEF      = NO
 
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
-# interpret the first line (until the first dot) of a Qt-style
-# comment as the brief description. If set to NO, the comments
-# will behave just like regular Qt-style comments (thus requiring
-# an explicit \brief command for a brief description.)
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
 
 QT_AUTOBRIEF           = NO
 
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
 
 MULTILINE_CPP_IS_BRIEF = NO
 
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
 
 INHERIT_DOCS           = YES
 
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
 
 SEPARATE_MEMBER_PAGES  = NO
 
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
 
 TAB_SIZE               = 8
 
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
 
 ALIASES                =
 
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
 
 OPTIMIZE_OUTPUT_FOR_C  = YES
 
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
-# sources only. Doxygen will then generate output that is more tailored for
-# Java. For instance, namespaces will be presented as packages, qualified
-# scopes will look different, etc.
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
 
 OPTIMIZE_OUTPUT_JAVA   = NO
 
 # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources only. Doxygen will then generate output that is more tailored for
-# Fortran.
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
 
 OPTIMIZE_FOR_FORTRAN   = NO
 
 # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for
-# VHDL.
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
 
 OPTIMIZE_OUTPUT_VHDL   = NO
 
-# Doxygen selects the parser to use depending on the extension of the files it parses.
-# With this tag you can assign which parser to use for a given extension.
-# Doxygen has a built-in mapping, but you can override or extend it using this tag.
-# The format is ext=language, where ext is a file extension, and language is one of
-# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
-# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
-# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
-# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
 
 EXTENSION_MAPPING      =
 
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
 # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should
-# set this tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
-# func(std::string) {}). This also make the inheritance and collaboration
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
 # diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
 
 BUILTIN_STL_SUPPORT    = NO
 
 # If you use Microsoft's C++/CLI language, you should set this option to YES to
 # enable parsing support.
+# The default value is: NO.
 
 CPP_CLI_SUPPORT        = NO
 
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
-# Doxygen will parse them like normal C++ but will assume all classes use public
-# instead of private inheritance when no explicit protection keyword is present.
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
 
 SIP_SUPPORT            = NO
 
-# For Microsoft's IDL there are propget and propput attributes to indicate getter
-# and setter methods for a property. Setting this option to YES (the default)
-# will make doxygen to replace the get and set methods by a property in the
-# documentation. This will only work if the methods are indeed getting or
-# setting a simple type. If this is not the case, or you want to show the
-# methods anyway, you should set this option to NO.
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
 
 IDL_PROPERTY_SUPPORT   = YES
 
 # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
+# tag is set to YES then doxygen will reuse the documentation of the first
 # member in the group (if any) for the other members of the group. By default
 # all members of a group must be documented explicitly.
+# The default value is: NO.
 
 DISTRIBUTE_GROUP_DOC   = NO
 
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
 
 SUBGROUPING            = YES
 
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
-# is documented as struct, union, or enum with the name of the typedef. So
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
 # typedef struct TypeS {} TypeT, will appear in the documentation as a struct
 # with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically
-# be useful for C code in case the coding convention dictates that all compound
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
 # types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
 
 TYPEDEF_HIDES_STRUCT   = NO
 
-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
-# determine which symbols to keep in memory and which to flush to disk.
-# When the cache is full, less often used symbols will be written to disk.
-# For small to medium size projects (<1000 input files) the default value is
-# probably good enough. For larger projects a too small cache size can cause
-# doxygen to be busy swapping symbols to and from disk most of the time
-# causing a significant performance penality.
-# If the system has enough physical memory increasing the cache will improve the
-# performance by keeping more symbols in memory. Note that the value works on
-# a logarithmic scale so increasing the size by one will rougly double the
-# memory usage. The cache size is given by this formula:
-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
-# corresponding to a cache size of 2^16 = 65536 symbols
-
-SYMBOL_CACHE_SIZE      = 0
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
 
 #---------------------------------------------------------------------------
 # Build related configuration options
 #---------------------------------------------------------------------------
 
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
 
 EXTRACT_ALL            = YES
 
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
 
 EXTRACT_PRIVATE        = NO
 
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
 
 EXTRACT_STATIC         = YES
 
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
 
 EXTRACT_LOCAL_CLASSES  = YES
 
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
 
 EXTRACT_LOCAL_METHODS  = NO
 
 # If this flag is set to YES, the members of anonymous namespaces will be
 # extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base
-# name of the file that contains the anonymous namespace. By default
-# anonymous namespace are hidden.
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
 
 EXTRACT_ANON_NSPACES   = NO
 
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
 
 HIDE_UNDOC_MEMBERS     = YES
 
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
 
 HIDE_UNDOC_CLASSES     = NO
 
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
 
 HIDE_FRIEND_COMPOUNDS  = NO
 
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
 
 HIDE_IN_BODY_DOCS      = NO
 
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
 
 INTERNAL_DOCS          = NO
 
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
 # allowed. This is useful if you have classes or files whose names only differ
 # in case and if your file system supports case sensitive file names. Windows
 # and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
 
 CASE_SENSE_NAMES       = YES
 
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
 
 HIDE_SCOPE_NAMES       = NO
 
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
 
 SHOW_INCLUDE_FILES     = YES
 
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
-# will list include files with double quotes in the documentation
-# rather than with sharp brackets.
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
 
 FORCE_LOCAL_INCLUDES   = NO
 
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
 
 INLINE_INFO            = YES
 
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
 
 SORT_MEMBER_DOCS       = YES
 
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
 
 SORT_BRIEF_DOCS        = NO
 
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
 
 SORT_MEMBERS_CTORS_1ST = NO
 
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
-# hierarchy of group names into alphabetical order. If set to NO (the default)
-# the group names will appear in their defined order.
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
 
 SORT_GROUP_NAMES       = NO
 
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
 # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
 
 SORT_BY_SCOPE_NAME     = NO
 
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
 
 GENERATE_TODOLIST      = YES
 
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
 
 GENERATE_TESTLIST      = YES
 
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
 
 GENERATE_BUGLIST       = YES
 
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
 
 GENERATE_DEPRECATEDLIST= YES
 
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
 
 ENABLED_SECTIONS       =
 
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
 
 MAX_INITIALIZER_LINES  = 30
 
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
 # list will mention the files that were used to generate the documentation.
+# The default value is: YES.
 
 SHOW_USED_FILES        = YES
 
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES       = NO
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
-# This will remove the Files entry from the Quick Index and from the
-# Folder Tree View (if specified). The default is YES.
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
 
 SHOW_FILES             = YES
 
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
-# Namespaces page.
-# This will remove the Namespaces entry from the Quick Index
-# and from the Folder Tree View (if specified). The default is YES.
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
 
 SHOW_NAMESPACES        = YES
 
 # The FILE_VERSION_FILTER tag can be used to specify a program or script that
 # doxygen should invoke to get the current version for each file (typically from
 # the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the program writes to standard output
-# is used as the file version. See the manual for examples.
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
 
 FILE_VERSION_FILTER    =
 
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
-# doxygen. The layout file controls the global structure of the generated output files
-# in an output format independent way. The create the layout file that represents
-# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
-# file name after the option, if omitted DoxygenLayout.xml will be used as the name
-# of the layout file.
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
 
 LAYOUT_FILE            =
 
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         =
+
 #---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
+# Configuration options related to warning and progress messages
 #---------------------------------------------------------------------------
 
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
 
 QUIET                  = YES
 
 # The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
 
 WARNINGS               = YES
 
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
 
 WARN_IF_UNDOCUMENTED   = YES
 
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
 
 WARN_IF_DOC_ERROR      = YES
 
-# This WARN_NO_PARAMDOC option can be abled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
 
 WARN_NO_PARAMDOC       = NO
 
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
 
 WARN_FORMAT            = "$file:$line: $text"
 
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
 
 WARN_LOGFILE           =
 
 #---------------------------------------------------------------------------
-# configuration options related to the input files
+# Configuration options related to the input files
 #---------------------------------------------------------------------------
 
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
 
 INPUT                  = @srcdir@/.. \
                          @srcdir@/../input \
                          @srcdir@/../config
 
 # This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
-# also the default input encoding. Doxygen uses libiconv (or the iconv built
-# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
-# the list of possible encodings.
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
 
 INPUT_ENCODING         = UTF-8
 
 # If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
+# *.vhdl, *.ucf, *.qsf, *.as and *.js.
 
 FILE_PATTERNS          =
 
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
 
 RECURSIVE              = NO
 
-# The EXCLUDE tag can be used to specify files and/or directories that should
+# The EXCLUDE tag can be used to specify files and/or directories that should be
 # excluded from the INPUT source files. This way you can easily exclude a
 # subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
 
 EXCLUDE                = @srcdir@/../config/parser.c \
                          @srcdir@/../config/parser.h \
                          @srcdir@/../config/scanner.c
 
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
 # from the input.
+# The default value is: NO.
 
 EXCLUDE_SYMLINKS       = YES
 
 # If the value of the INPUT tag contains directories, you can use the
 # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
-# for example use the pattern */test/*
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
 
 EXCLUDE_PATTERNS       = atKeynames.h \
                          Canvas*.*
@@ -629,624 +833,1122 @@ EXCLUDE_PATTERNS       = atKeynames.h \
 # output. The symbol name can be a fully qualified name, a word, or if the
 # wildcard * is used, a substring. Examples: ANamespace, AClass,
 # AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
 
 EXCLUDE_SYMBOLS        =
 
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
 
 EXAMPLE_PATH           =
 
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
 
 EXAMPLE_PATTERNS       =
 
 # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
 
 EXAMPLE_RECURSIVE      = NO
 
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
 
 IMAGE_PATH             =
 
 # The INPUT_FILTER tag can be used to specify a program that doxygen should
 # invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output.
-# If FILTER_PATTERNS is specified, this tag will be
-# ignored.
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
 
 INPUT_FILTER           =
 
 # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis.
-# Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match.
-# The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
 
 FILTER_PATTERNS        =
 
 # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
 
 FILTER_SOURCE_FILES    = NO
 
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
 #---------------------------------------------------------------------------
-# configuration options related to source browsing
+# Configuration options related to source browsing
 #---------------------------------------------------------------------------
 
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
 
 SOURCE_BROWSER         = NO
 
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
 
 INLINE_SOURCES         = NO
 
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
 
 STRIP_CODE_COMMENTS    = YES
 
-# If the REFERENCED_BY_RELATION tag is set to YES
-# then for each documented function all documented
-# functions referencing it will be listed.
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
 
 REFERENCED_BY_RELATION = YES
 
-# If the REFERENCES_RELATION tag is set to YES
-# then for each documented function all documented entities
-# called/used by that function will be listed.
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
 
 REFERENCES_RELATION    = YES
 
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.
-# Otherwise they will link to the documentation.
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
 
 REFERENCES_LINK_SOURCE = YES
 
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
-# will need version 4.8.6 or higher.
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
 
 USE_HTAGS              = NO
 
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
 
 VERBATIM_HEADERS       = YES
 
 #---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
+# Configuration options related to the alphabetical class index
 #---------------------------------------------------------------------------
 
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
 
 ALPHABETICAL_INDEX     = YES
 
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
 
 COLS_IN_ALPHA_INDEX    = 5
 
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
 
 IGNORE_PREFIX          =
 
 #---------------------------------------------------------------------------
-# configuration options related to the HTML output
+# Configuration options related to the HTML output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
 
 GENERATE_HTML          = YES
 
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 HTML_OUTPUT            = html
 
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 HTML_FILE_EXTENSION    = .html
 
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
 # standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 HTML_HEADER            =
 
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 HTML_FOOTER            = @srcdir@/footer.html
 
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 HTML_STYLESHEET        =
 
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting
-# this to NO can help when comparing the output of multiple runs.
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 HTML_TIMESTAMP         = NO
 
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS     = YES
-
 # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
 # documentation will contain sections that can be hidden and shown after the
-# page has loaded. For this to work a browser that supports
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 HTML_DYNAMIC_SECTIONS  = NO
 
-# If the GENERATE_DOCSET tag is set to YES, additional index files
-# will be generated that can be used as input for Apple's Xcode 3
-# integrated development environment, introduced with OSX 10.5 (Leopard).
-# To create a documentation set, doxygen will generate a Makefile in the
-# HTML output directory. Running make will produce the docset in that
-# directory and running "make install" will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
-# it at startup.
-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 GENERATE_DOCSET        = NO
 
-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
-# feed. A documentation feed provides an umbrella under which multiple
-# documentation sets from a single provider (such as a company or product suite)
-# can be grouped.
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
 
 DOCSET_FEEDNAME        = "Doxygen generated docs"
 
-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
-# should uniquely identify the documentation set bundle. This should be a
-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
-# will append .docset to the name.
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
 
 DOCSET_BUNDLE_ID       = org.doxygen.Project
 
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
-# of the generated HTML documentation.
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 GENERATE_HTMLHELP      = NO
 
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
 # written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
 CHM_FILE               =
 
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
 HHC_LOCATION           =
 
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
 GENERATE_CHI           = NO
 
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
-# is used to encode HtmlHelp index (hhk), content (hhc) and project file
-# content.
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
 CHM_INDEX_ENCODING     =
 
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
 BINARY_TOC             = NO
 
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
 TOC_EXPAND             = NO
 
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
-# are set, an additional index file will be generated that can be used as input for
-# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
-# HTML documentation.
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 GENERATE_QHP           = NO
 
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
-# be used to specify the file name of the resulting .qch file.
-# The path specified is relative to the HTML output folder.
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
 
 QCH_FILE               =
 
-# The QHP_NAMESPACE tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#namespace
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
 
 QHP_NAMESPACE          = org.doxygen.Project
 
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
 
 QHP_VIRTUAL_FOLDER     = doc
 
-# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
-# For more information please see
-# http://doc.trolltech.com/qthelpproject.html#custom-filters
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
 
 QHP_CUST_FILTER_NAME   =
 
-# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
-# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
 
 QHP_CUST_FILTER_ATTRS  =
 
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
-# filter section matches.
-# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
 
 QHP_SECT_FILTER_ATTRS  =
 
-# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
-# be used to specify the location of Qt's qhelpgenerator.
-# If non-empty doxygen will try to run qhelpgenerator on the generated
-# .qhp file.
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
 
 QHG_LOCATION           =
 
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
-#  will be generated, which together with the HTML files, form an Eclipse help
-#  plugin. To install this plugin and make it available under the help contents
-# menu in Eclipse, the contents of the directory containing the HTML and XML
-# files needs to be copied into the plugins directory of eclipse. The name of
-# the directory within the plugins directory should be the same as
-# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears.
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 GENERATE_ECLIPSEHELP   = NO
 
-# A unique identifier for the eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have
-# this name.
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
 
 ECLIPSE_DOC_ID         = org.doxygen.Project
 
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 DISABLE_INDEX          = NO
 
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE   = 4
-
 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information.
-# If the tag value is set to YES, a side panel will be generated
-# containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
-# Windows users are probably better off using the HTML help feature.
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 GENERATE_TREEVIEW      = YES
 
-# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
-# and Class Hierarchy pages using a tree view instead of an ordered list.
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
-USE_INLINE_TREES       = NO
+ENUM_VALUES_PER_LINE   = 4
 
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 TREEVIEW_WIDTH         = 250
 
-# Use this tag to change the font size of Latex formulas included
-# as images in the HTML documentation. The default is 10. Note that
-# when you change the font size after a successful doxygen run you need
-# to manually remove any form_*.png images from the HTML output directory
-# to force them to be regenerated.
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 FORMULA_FONTSIZE       = 10
 
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
-# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should
-# typically be disabled. For large projects the javascript based search engine
-# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
 
 SEARCHENGINE           = NO
 
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index
-# file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup
-# and does not have live searching capabilities.
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
 
 SERVER_BASED_SEARCH    = NO
 
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  =
+
 #---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
+# Configuration options related to the LaTeX output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
 
 GENERATE_LATEX         = NO
 
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 LATEX_OUTPUT           = latex
 
 # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-# Note that when enabling USE_PDFLATEX this option is only used for
-# generating bitmaps for formulas in the HTML output, but not in the
-# Makefile that is written to the output directory.
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 LATEX_CMD_NAME         = latex
 
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 MAKEINDEX_CMD_NAME     = makeindex
 
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 COMPACT_LATEX          = NO
 
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 PAPER_TYPE             = a4wide
 
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 EXTRA_PACKAGES         =
 
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 LATEX_HEADER           =
 
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 PDF_HYPERLINKS         = NO
 
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
 # higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 USE_PDFLATEX           = NO
 
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 LATEX_BATCHMODE        = NO
 
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 LATEX_HIDE_INDICES     = NO
 
-# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
 
 LATEX_SOURCE_CODE      = NO
 
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP        = NO
+
 #---------------------------------------------------------------------------
-# configuration options related to the RTF output
+# Configuration options related to the RTF output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
 
 GENERATE_RTF           = NO
 
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
 
 RTF_OUTPUT             = rtf
 
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
 
 COMPACT_RTF            = NO
 
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
 
 RTF_HYPERLINKS         = NO
 
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
 
 RTF_STYLESHEET_FILE    =
 
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
 
 RTF_EXTENSIONS_FILE    =
 
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
 #---------------------------------------------------------------------------
-# configuration options related to the man page output
+# Configuration options related to the man page output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
 
 GENERATE_MAN           = NO
 
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
 
 MAN_OUTPUT             = man
 
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
 
 MAN_EXTENSION          = .3
 
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
 
 MAN_LINKS              = NO
 
 #---------------------------------------------------------------------------
-# configuration options related to the XML output
+# Configuration options related to the XML output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
 
 GENERATE_XML           = NO
 
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
 
 XML_OUTPUT             = xml
 
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
 
-XML_SCHEMA             =
+XML_PROGRAMLISTING     = YES
 
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
 
-XML_DTD                =
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
 
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
+GENERATE_DOCBOOK       = NO
 
-XML_PROGRAMLISTING     = YES
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
 
 #---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
+# Configuration options for the AutoGen Definitions output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
 
 GENERATE_AUTOGEN_DEF   = NO
 
 #---------------------------------------------------------------------------
-# configuration options related to the Perl module output
+# Configuration options related to the Perl module output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
 
 GENERATE_PERLMOD       = NO
 
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
 
 PERLMOD_LATEX          = NO
 
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader.
-# This is useful
-# if you want to understand what is going on.
-# On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
 
 PERLMOD_PRETTY         = YES
 
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
 
 PERLMOD_MAKEVAR_PREFIX =
 
@@ -1254,113 +1956,132 @@ PERLMOD_MAKEVAR_PREFIX =
 # Configuration options related to the preprocessor
 #---------------------------------------------------------------------------
 
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
 
 ENABLE_PREPROCESSING   = YES
 
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
 MACRO_EXPANSION        = NO
 
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_DEFINED tags.
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
 EXPAND_ONLY_PREDEF     = NO
 
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
 SEARCH_INCLUDES        = YES
 
 # The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
 
 INCLUDE_PATH           =
 
 # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
 # patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
 INCLUDE_FILE_PATTERNS  =
 
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
 PREDEFINED             = SHAPE \
                          RENDER \
                          XKB \
                          XINPUT
 
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
 EXPAND_AS_DEFINED      =
 
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse
-# the parser if not removed.
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
 SKIP_FUNCTION_MACROS   = YES
 
 #---------------------------------------------------------------------------
-# Configuration::additions related to external references
+# Configuration options related to external references
 #---------------------------------------------------------------------------
 
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-#
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
 # TAGFILES = file1 file2 ...
 # Adding location for the tag files is done as follows:
-#
 # TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
 
 TAGFILES               =
 
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
 
 GENERATE_TAGFILE       =
 
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
 
 ALLEXTERNALS           = NO
 
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
 
 EXTERNAL_GROUPS        = YES
 
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
 # The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
 
 PERL_PATH              = /usr/bin/perl
 
@@ -1368,192 +2089,312 @@ PERL_PATH              = /usr/bin/perl
 # Configuration options related to the dot tool
 #---------------------------------------------------------------------------
 
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option is superseded by the HAVE_DOT option below. This is only a
-# fallback. It is recommended to install and use dot, since it yields more
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
 # powerful graphs.
+# The default value is: YES.
 
 CLASS_DIAGRAMS         = YES
 
 # You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see
-# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
 # documentation. The MSCGEN_PATH tag allows you to specify the directory where
 # the mscgen tool resides. If left empty the tool is assumed to be found in the
 # default search path.
 
 MSCGEN_PATH            =
 
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
 
 HIDE_UNDOC_RELATIONS   = YES
 
 # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
 
 HAVE_DOT               = NO
 
-# By default doxygen will write a font called FreeSans.ttf to the output
-# directory and reference it in all dot files that doxygen generates. This
-# font does not include all possible unicode characters however, so when you need
-# these (or just want a differently looking font) you can specify the font name
-# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
-# which can be done by putting it in a standard location or by setting the
-# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
-# containing the font.
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
 
-DOT_FONTNAME           = FreeSans
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
-# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
-# The default size is 10pt.
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 DOT_FONTSIZE           = 10
 
-# By default doxygen will tell dot to use the output directory to look for the
-# FreeSans.ttf font (which doxygen will put there itself). If you specify a
-# different font using DOT_FONTNAME you can set the path where dot
-# can find it using this tag.
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 DOT_FONTPATH           =
 
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 CLASS_GRAPH            = YES
 
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 COLLABORATION_GRAPH    = YES
 
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 GROUP_GRAPHS           = YES
 
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
 # collaboration diagrams in a style similar to the OMG's Unified Modeling
 # Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 UML_LOOK               = NO
 
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 TEMPLATE_RELATIONS     = YES
 
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 INCLUDE_GRAPH          = YES
 
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 INCLUDED_BY_GRAPH      = YES
 
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then
-# doxygen will generate a call dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable call graphs
-# for selected functions only using the \callgraph command.
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 CALL_GRAPH             = NO
 
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
-# doxygen will generate a caller dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable caller
-# graphs for selected functions only using the \callergraph command.
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 CALLER_GRAPH           = NO
 
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 GRAPHICAL_HIERARCHY    = YES
 
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 DIRECTORY_GRAPH        = YES
 
 # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 DOT_IMAGE_FORMAT       = gif
 
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
 # found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 DOT_PATH               =
 
 # The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 DOTFILE_DIRS           =
 
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
-# nodes that will be shown in the graph. If the number of nodes in a graph
-# becomes larger than this value, doxygen will truncate the graph, which is
-# visualized by representing a node as a red box. Note that doxygen if the
-# number of direct children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
-# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 DOT_GRAPH_MAX_NODES    = 50
 
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that the size of a graph can be further restricted by
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
 # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 MAX_DOT_GRAPH_DEPTH    = 0
 
 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not
-# seem to support this out of the box. Warning: Depending on the platform used,
-# enabling this option may lead to badly anti-aliased labels on the edges of
-# a graph (i.e. they become hard to read).
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 DOT_TRANSPARENT        = NO
 
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
 # files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 DOT_MULTI_TARGETS      = YES
 
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 GENERATE_LEGEND        = YES
 
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
 
 DOT_CLEANUP            = YES
commit a55e0bc56fd8f9da8f066dc344af19535dd092ca
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 8 16:00:19 2015 -0500

    dmx: Silence unused variable warning in dmxcompat
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/dmx/config/dmxcompat.c b/hw/dmx/config/dmxcompat.c
index 107991a..6d31b53 100644
--- a/hw/dmx/config/dmxcompat.c
+++ b/hw/dmx/config/dmxcompat.c
@@ -123,7 +123,6 @@ dmxVDLRead(const char *filename)
     DMXConfigSubPtr sub = NULL;
     DMXConfigDisplayPtr display = NULL;
     DMXConfigFullDimPtr fdim = NULL;
-    int vcount = 0;
     int dcount = 0;
     int icount = 0;
     int x, y, xoff, yoff, xorig, yorig;
@@ -167,7 +166,6 @@ dmxVDLRead(const char *filename)
             state = virtualCount;
             break;
         case virtualCount:
-            vcount = dmxVDLCount(buf);
             state = virtualEntry;
             break;
         case virtualEntry:
commit 2730ccb803c55af74dbdd1bfd982fc23e643554d
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 8 15:37:12 2015 -0500

    dmx: Silence lex/yacc-related config parser warnings
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/dmx/config/dmxconfig.c b/hw/dmx/config/dmxconfig.c
index 1d10ec0..c1a9e1c 100644
--- a/hw/dmx/config/dmxconfig.c
+++ b/hw/dmx/config/dmxconfig.c
@@ -48,7 +48,7 @@
 #include "dmxstat.h"
 #include "parser.h"
 
-extern int yyparse(void);
+extern int yydebug;
 extern FILE *yyin;
 
 static char *dmxXkbRules;
diff --git a/hw/dmx/config/dmxparse.h b/hw/dmx/config/dmxparse.h
index cc2f0eb..a64b36f 100644
--- a/hw/dmx/config/dmxparse.h
+++ b/hw/dmx/config/dmxparse.h
@@ -200,8 +200,6 @@ typedef struct _DMXConfigEntry {
 
 extern DMXConfigEntryPtr dmxConfigEntry;
 
-extern int yylex(void);
-extern int yydebug;
 extern void yyerror(const char *message);
 
 extern void dmxConfigLog(const char *format, ...) _X_ATTRIBUTE_PRINTF(1,0);
diff --git a/hw/dmx/config/dmxtodmx.c b/hw/dmx/config/dmxtodmx.c
index 6634209..5a1a0b4 100644
--- a/hw/dmx/config/dmxtodmx.c
+++ b/hw/dmx/config/dmxtodmx.c
@@ -38,6 +38,7 @@
 #include "dmxcompat.h"
 
 extern int yyparse(void);
+extern int yydebug;
 extern FILE *yyin;
 
 int
diff --git a/hw/dmx/config/parser.y b/hw/dmx/config/parser.y
index ac24410..fa041a1 100644
--- a/hw/dmx/config/parser.y
+++ b/hw/dmx/config/parser.y
@@ -44,6 +44,7 @@
 #define YYERROR_VERBOSE
 #define YY_USE_PROTOS
 
+extern int yylex(void);
 DMXConfigEntryPtr dmxConfigEntry = NULL;
 #define APPEND(type, h, t)                 \
 {                                          \
diff --git a/hw/dmx/config/scanner.l b/hw/dmx/config/scanner.l
index e527d6d..3688fd7 100644
--- a/hw/dmx/config/scanner.l
+++ b/hw/dmx/config/scanner.l
@@ -84,10 +84,12 @@ param           return gettoken(T_PARAM, yytext, yyleng);
 %%
 int yywrap(void)
 {
+    (void) &yyunput;
+    (void) &input;
     return 1;
 }
 
-void yyerror(const char *message)
+_X_NORETURN void yyerror(const char *message)
 {
     const char *pt, *end;
     struct _entry {
@@ -109,7 +111,7 @@ void yyerror(const char *message)
     };
     
     fprintf(stderr, "parse error on line %d at token \"%*.*s\"\n",
-            lineno, yyleng, yyleng, yytext);
+            lineno, (int)yyleng, (int)yyleng, yytext);
     end = message + strlen(message);
     for (pt = message; *pt; pt++) {
         if (pt[0] == 'T' && pt[1] == '_') {
diff --git a/hw/dmx/config/xdmxconfig.c b/hw/dmx/config/xdmxconfig.c
index 0540d01..49e4b54 100644
--- a/hw/dmx/config/xdmxconfig.c
+++ b/hw/dmx/config/xdmxconfig.c
@@ -53,6 +53,7 @@
 #include "dmxlog.h"
 
 extern int yyparse(void);
+extern int yydebug;
 extern FILE *yyin;
 
 #define DMX_INFO "xdmxconfig v0.9\nCopyright 2002 Red Hat Inc.\n"
commit 718223d27452862eedcf1bee6278eae6040d45ea
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Thu Dec 3 08:05:59 2015 -0200

    systemd-logind.c: don't parse VT settings for non-seat0 X servers
    
    Since non-seat0 X servers no longer touch VTs, I believe these settings
    are unnecessary.
    
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c
index 2612d9e..13784d1 100644
--- a/hw/xfree86/os-support/linux/systemd-logind.c
+++ b/hw/xfree86/os-support/linux/systemd-logind.c
@@ -38,6 +38,7 @@
 #include "xf86.h"
 #include "xf86platformBus.h"
 #include "xf86Xinput.h"
+#include "globals.h"
 
 #include "systemd-logind.h"
 
@@ -615,7 +616,7 @@ static struct dbus_core_hook core_hook = {
 int
 systemd_logind_init(void)
 {
-    if (linux_parse_vt_settings(TRUE) && !linux_get_keeptty()) {
+    if (!ServerIsNotSeat0() && linux_parse_vt_settings(TRUE) && !linux_get_keeptty()) {
         LogMessage(X_INFO,
             "systemd-logind: logind integration requires -keeptty and "
             "-keeptty was not provided, disabling logind integration\n");
commit 7c0ba32ddd5f1d5c65279365fa307dec3433caf3
Author: Bob Ham <bob.ham at collabora.com>
Date:   Fri Dec 4 12:30:47 2015 +0000

    xserver: Fix configure.ac check for libsystemd/-daemon
    
    The configure script looks for the libsystemd-daemon pkg-config
    module.  If the configure script finds it, the script will add
    libsystemd-daemon to a list of modules which are used to consolidate
    CFLAGS and LIBS.
    
    The check for libsystemd-daemon was altered to fallback to libsystemd
    if libsystemd-daemon was not found (libsystemd-daemon was brought into
    libsystemd).  Unfortunately, the configure script still adds
    "libsystemd-daemon" to the list of modules to consolidate, instead of
    "libsystemd".  With this patch, we set a variable depending on which
    pkg-config module is found and add that to the module list instead.
    
    Changes since v1:
    - Rearranged logic so that we do a versioned check for libsystemd
      first, then look for libsystemd-daemon.
    - Cleaned up the check a bit, only performing the module checks if we
      don't have --with-systemd-daemon=no, in a similar style to
      --with-dtrace.
    - Changed the variable name to LIBSYSTEMD_DAEMON as per feedback.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Bob Ham <bob.ham at collabora.com>

diff --git a/configure.ac b/configure.ac
index 2e38efa..ac3bb64 100644
--- a/configure.ac
+++ b/configure.ac
@@ -832,23 +832,26 @@ REQUIRED_MODULES="$FIXESPROTO $DAMAGEPROTO $XCMISCPROTO $XTRANS $BIGREQSPROTO $S
 
 dnl systemd socket activation
 dnl activate the code in libxtrans that grabs systemd's socket fds
+dnl libsystemd-daemon was moved into libsystemd in version 209
+LIBSYSTEMD="libsystemd >= 209"
 AC_ARG_WITH([systemd-daemon],
 	AS_HELP_STRING([--with-systemd-daemon],
 		[support systemd socket activation (default: auto)]),
 	[WITH_SYSTEMD_DAEMON=$withval], [WITH_SYSTEMD_DAEMON=auto])
-PKG_CHECK_MODULES([SYSTEMD_DAEMON], [libsystemd-daemon],
-                  [HAVE_SYSTEMD_DAEMON=yes],
-                  [PKG_CHECK_MODULES([SYSTEMD_DAEMON], [libsystemd],
-                                     [HAVE_SYSTEMD_DAEMON=yes], [HAVE_SYSTEMD_DAEMON=no])])
-if test "x$WITH_SYSTEMD_DAEMON" = xauto; then
-	WITH_SYSTEMD_DAEMON="$HAVE_SYSTEMD_DAEMON"
-fi
-if test "x$WITH_SYSTEMD_DAEMON" = xyes; then
-	if test "x$HAVE_SYSTEMD_DAEMON" = xno; then
+if test "x$WITH_SYSTEMD_DAEMON" = "xyes" -o "x$WITH_SYSTEMD_DAEMON" = "xauto" ; then
+	PKG_CHECK_MODULES([SYSTEMD_DAEMON], [$LIBSYSTEMD],
+			  [HAVE_SYSTEMD_DAEMON=yes;
+			   LIBSYSTEMD_DAEMON="$LIBSYSTEMD"],
+			  [PKG_CHECK_MODULES([SYSTEMD_DAEMON], [libsystemd-daemon],
+					     [HAVE_SYSTEMD_DAEMON=yes;
+					      LIBSYSTEMD_DAEMON=libsystemd-daemon],
+					     [HAVE_SYSTEMD_DAEMON=no])])
+	if test "x$HAVE_SYSTEMD_DAEMON" = xyes; then
+		AC_DEFINE(HAVE_SYSTEMD_DAEMON, 1, [Define to 1 if libsystemd-daemon is available])
+		REQUIRED_LIBS="$REQUIRED_LIBS $LIBSYSTEMD_DAEMON"
+	elif test "x$WITH_SYSTEMD_DAEMON" = xyes; then
 		AC_MSG_ERROR([systemd support requested but no library has been found])
 	fi
-	AC_DEFINE(HAVE_SYSTEMD_DAEMON, 1, [Define to 1 if libsystemd-daemon is available])
-	REQUIRED_LIBS="$REQUIRED_LIBS libsystemd-daemon"
 fi
 AM_CONDITIONAL([HAVE_SYSTEMD_DAEMON], [test "x$HAVE_SYSTEMD_DAEMON" = "xyes"])
 
commit 530d3e5ca0a02039b04ec6a677bbb4e05b78e5f4
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Dec 3 17:04:09 2015 +0900

    prime: Damage full destination rectangle when we start dirty tracking
    
    This makes sure that the destination pixmap contents will be fully
    initialized. Without this, a PRIME output starts out with garbage.
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/dix/pixmap.c b/dix/pixmap.c
index 05aebc4..11d83fe 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -173,6 +173,9 @@ PixmapStartDirtyTracking(PixmapPtr src,
 {
     ScreenPtr screen = src->drawable.pScreen;
     PixmapDirtyUpdatePtr dirty_update;
+    RegionPtr damageregion;
+    RegionRec dstregion;
+    BoxRec box;
 
     dirty_update = calloc(1, sizeof(PixmapDirtyUpdateRec));
     if (!dirty_update)
@@ -205,6 +208,24 @@ PixmapStartDirtyTracking(PixmapPtr src,
         return FALSE;
     }
 
+    /* Damage destination rectangle so that the destination pixmap contents
+     * will get fully initialized
+     */
+    box.x1 = dirty_update->x;
+    box.y1 = dirty_update->y;
+    if (dirty_update->rotation == RR_Rotate_90 ||
+        dirty_update->rotation == RR_Rotate_270) {
+        box.x2 = dirty_update->x + slave_dst->drawable.height;
+        box.y2 = dirty_update->y + slave_dst->drawable.width;
+    } else {
+        box.x2 = dirty_update->x + slave_dst->drawable.width;
+        box.y2 = dirty_update->y + slave_dst->drawable.height;
+    }
+    RegionInit(&dstregion, &box, 1);
+    damageregion = DamageRegion(dirty_update->damage);
+    RegionUnion(damageregion, damageregion, &dstregion);
+    RegionUninit(&dstregion);
+
     DamageRegister(&src->drawable, dirty_update->damage);
     xorg_list_add(&dirty_update->ent, &screen->pixmap_dirty_list);
     return TRUE;
commit 2a52c06e235bd79f91851121f53f7c1808fde321
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Dec 7 17:03:02 2015 -0500

    x86emu: Squash a warning
    
    Apologies, should have caught this one when applying the previous x86emu
    patch.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/x86emu/ops.c b/hw/xfree86/x86emu/ops.c
index 551dca7..210f8ce 100644
--- a/hw/xfree86/x86emu/ops.c
+++ b/hw/xfree86/x86emu/ops.c
@@ -12078,7 +12078,7 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
             break;
         case 2:                /* call word ptr ... */
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                destreg = DECODE_RM_LONG_REGISTER(rl);
+                destreg = (u16 *)DECODE_RM_LONG_REGISTER(rl);
                 DECODE_PRINTF("\n");
                 TRACE_AND_STEP();
                 push_long(M.x86.R_EIP);
commit 59b618227ebd024e57720aaaea17596953f5b80e
Author: Julian Pidancet <julian.pidancet at gmail.com>
Date:   Sun Jul 1 18:49:25 2012 +0100

    x86emu: Correctly handle 0x66 prefix for some instructions
    
    (Sorry for double posting)
    
    I repost this patch because I havn't got any replies from maintainers
    since I posted the initial patch back in March.
    
    Some instructions are not emulated correctly by x86emu when they
    are prefixed by the 0x66 opcode.
    I've identified problems in the emulation of these intructions: ret,
    enter, leave, iret and some forms of call.
    
    Most of the time, the problem is that these instructions should push or
    pop 32-bit values to/from the stack, instead of 16bit, when they are
    prefixed by the 0x66 special opcode.
    
    The SeaBIOS project aims to produce a complete legacy BIOS
    implementation as well as a VGA option ROM, entirely written in C and
    using the GCC compiler.
    
    In 16bit code produced by the GCC compiler, the 0x66 prefix is used
    almost everywhere. This patch is necessary to allow the SeaBIOS VGA
    option ROM to function with Xorg when using the vesa driver.
    
    SeaBIOS currently use postprocessing on the ROM assembly output to
    replace the affected instruction with alternative unaffected instructions.
    This is obviously not very elegant, and this fix in x86emu would be
    more appropriate.
    
    v2: - Decrement BP instead of EBP in accordance with the Intel Manual
        - Assign EIP instead of IP when poping the return address from the
        stack in 32-bit operand size mode in ret_far_IMM, ret_far, and iret
        - When poping EFLAGS from the stack in iret in 32-bit operand size
        mode, apply some mask to preserve Read-only flags.
    
    v3: - Rebase
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Julian Pidancet <julian.pidancet at gmail.com>

diff --git a/hw/xfree86/x86emu/ops.c b/hw/xfree86/x86emu/ops.c
index 853792e..551dca7 100644
--- a/hw/xfree86/x86emu/ops.c
+++ b/hw/xfree86/x86emu/ops.c
@@ -8949,7 +8949,11 @@ x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
     DECODE_PRINTF2("%x\n", imm);
     RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
     TRACE_AND_STEP();
-    M.x86.R_IP = pop_word();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EIP = pop_long();
+    } else {
+        M.x86.R_IP = pop_word();
+    }
     M.x86.R_SP += imm;
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();
@@ -8966,7 +8970,11 @@ x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
     DECODE_PRINTF("RET\n");
     RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
     TRACE_AND_STEP();
-    M.x86.R_IP = pop_word();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EIP = pop_long();
+    } else {
+        M.x86.R_IP = pop_word();
+    }
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();
 }
@@ -9259,8 +9267,13 @@ x86emuOp_enter(u8 X86EMU_UNUSED(op1))
     frame_pointer = M.x86.R_SP;
     if (nesting > 0) {
         for (i = 1; i < nesting; i++) {
-            M.x86.R_BP -= 2;
-            push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                M.x86.R_BP -= 4;
+                push_long(fetch_data_long_abs(M.x86.R_SS, M.x86.R_BP));
+            } else {
+                M.x86.R_BP -= 2;
+                push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
+            }
         }
         push_word(frame_pointer);
     }
@@ -9281,7 +9294,11 @@ x86emuOp_leave(u8 X86EMU_UNUSED(op1))
     DECODE_PRINTF("LEAVE\n");
     TRACE_AND_STEP();
     M.x86.R_SP = M.x86.R_BP;
-    M.x86.R_BP = pop_word();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EBP = pop_long();
+    } else {
+        M.x86.R_BP = pop_word();
+    }
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();
 }
@@ -9301,8 +9318,13 @@ x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
     DECODE_PRINTF2("%x\n", imm);
     RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
     TRACE_AND_STEP();
-    M.x86.R_IP = pop_word();
-    M.x86.R_CS = pop_word();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EIP = pop_long();
+        M.x86.R_CS = pop_long() & 0xffff;
+    } else {
+        M.x86.R_IP = pop_word();
+        M.x86.R_CS = pop_word();
+    }
     M.x86.R_SP += imm;
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();
@@ -9319,8 +9341,13 @@ x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
     DECODE_PRINTF("RETF\n");
     RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
     TRACE_AND_STEP();
-    M.x86.R_IP = pop_word();
-    M.x86.R_CS = pop_word();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EIP = pop_long();
+        M.x86.R_CS = pop_long() & 0xffff;
+    } else {
+        M.x86.R_IP = pop_word();
+        M.x86.R_CS = pop_word();
+    }
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();
 }
@@ -9421,9 +9448,15 @@ x86emuOp_iret(u8 X86EMU_UNUSED(op1))
 
     TRACE_AND_STEP();
 
-    M.x86.R_IP = pop_word();
-    M.x86.R_CS = pop_word();
-    M.x86.R_FLG = pop_word();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EIP = pop_long();
+        M.x86.R_CS = pop_long() & 0xffff;
+        M.x86.R_EFLG = (pop_long() & 0x257FD5) | (M.x86.R_EFLG & 0x1A0000);
+    } else {
+        M.x86.R_IP = pop_word();
+        M.x86.R_CS = pop_word();
+        M.x86.R_FLG = pop_word();
+    }
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();
 }
@@ -11740,19 +11773,36 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
             }
             break;
         case 2:                /* call word ptr ... */
-            destval = fetch_data_word(destoffset);
-            TRACE_AND_STEP();
-            push_word(M.x86.R_IP);
-            M.x86.R_IP = destval;
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
             break;
         case 3:                /* call far ptr ... */
-            destval = fetch_data_word(destoffset);
-            destval2 = fetch_data_word(destoffset + 2);
-            TRACE_AND_STEP();
-            push_word(M.x86.R_CS);
-            M.x86.R_CS = destval2;
-            push_word(M.x86.R_IP);
-            M.x86.R_IP = destval;
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                destval2 = fetch_data_word(destoffset + 4);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                destval2 = fetch_data_word(destoffset + 2);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
             break;
         case 4:                /* jmp word ptr ... */
             destval = fetch_data_word(destoffset);
@@ -11825,19 +11875,36 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
             }
             break;
         case 2:                /* call word ptr ... */
-            destval = fetch_data_word(destoffset);
-            TRACE_AND_STEP();
-            push_word(M.x86.R_IP);
-            M.x86.R_IP = destval;
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
             break;
         case 3:                /* call far ptr ... */
-            destval = fetch_data_word(destoffset);
-            destval2 = fetch_data_word(destoffset + 2);
-            TRACE_AND_STEP();
-            push_word(M.x86.R_CS);
-            M.x86.R_CS = destval2;
-            push_word(M.x86.R_IP);
-            M.x86.R_IP = destval;
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                destval2 = fetch_data_word(destoffset + 4);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                destval2 = fetch_data_word(destoffset + 2);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
             break;
         case 4:                /* jmp word ptr ... */
             destval = fetch_data_word(destoffset);
@@ -11910,19 +11977,36 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
             }
             break;
         case 2:                /* call word ptr ... */
-            destval = fetch_data_word(destoffset);
-            TRACE_AND_STEP();
-            push_word(M.x86.R_IP);
-            M.x86.R_IP = destval;
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
             break;
         case 3:                /* call far ptr ... */
-            destval = fetch_data_word(destoffset);
-            destval2 = fetch_data_word(destoffset + 2);
-            TRACE_AND_STEP();
-            push_word(M.x86.R_CS);
-            M.x86.R_CS = destval2;
-            push_word(M.x86.R_IP);
-            M.x86.R_IP = destval;
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                destval2 = fetch_data_word(destoffset + 4);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                destval2 = fetch_data_word(destoffset + 2);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
             break;
         case 4:                /* jmp word ptr ... */
             destval = fetch_data_word(destoffset);
@@ -11993,11 +12077,19 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
             }
             break;
         case 2:                /* call word ptr ... */
-            destreg = DECODE_RM_WORD_REGISTER(rl);
-            DECODE_PRINTF("\n");
-            TRACE_AND_STEP();
-            push_word(M.x86.R_IP);
-            M.x86.R_IP = *destreg;
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destreg = DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = *destreg;
+            } else {
+                destreg = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = *destreg;
+            }
             break;
         case 3:                /* jmp far ptr ... */
             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
commit 72f0724cdc65dc9abbbf70b9feb6cce7c2b9f8a0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Feb 8 09:47:42 2015 +0000

    present: Do not replace Pixmaps on redirected Window on unflip
    
    When unflipping, we may find that our flip window has been redirected.
    If we replace the redirected Window with the Screen Pixmap we then have
    mutliple fullscreen Windows believing that their own the Screen Pixmap -
    multiple fullscreen Windows that are being flipped by Clients, and so
    continue to flip causing popping between e.g. the compositor and the
    game.
    
    [ajax: Fix up present_execute() hunk to account for changes introduced
    in fe07ec19e212a68076560d243a2a935c54589068]
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/present/present.c b/present/present.c
index c55a56e..66e0f21 100644
--- a/present/present.c
+++ b/present/present.c
@@ -374,12 +374,17 @@ present_set_tree_pixmap_visit(WindowPtr window, void *data)
 }
 
 static void
-present_set_tree_pixmap(WindowPtr window, PixmapPtr pixmap)
+present_set_tree_pixmap(WindowPtr window,
+                        PixmapPtr expected,
+                        PixmapPtr pixmap)
 {
     struct pixmap_visit visit;
     ScreenPtr           screen = window->drawable.pScreen;
 
     visit.old = (*screen->GetWindowPixmap)(window);
+    if (expected && visit.old != expected)
+        return;
+
     visit.new = pixmap;
     if (visit.old == visit.new)
         return;
@@ -390,6 +395,7 @@ 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.
@@ -397,10 +403,11 @@ present_set_abort_flip(ScreenPtr screen)
 
     if (screen_priv->flip_window)
         present_set_tree_pixmap(screen_priv->flip_window,
-                                  (*screen->GetScreenPixmap)(screen));
+                                screen_priv->flip_pixmap,
+                                pixmap);
 
     if (screen->root)
-        present_set_tree_pixmap(screen->root, (*screen->GetScreenPixmap)(screen));
+        present_set_tree_pixmap(screen->root, NULL, pixmap);
 
     screen_priv->flip_pending->abort_flip = TRUE;
 }
@@ -414,10 +421,12 @@ present_unflip(ScreenPtr screen)
     assert (!screen_priv->unflip_event_id);
     assert (!screen_priv->flip_pending);
 
-    if (screen_priv->flip_window)
-        present_set_tree_pixmap(screen_priv->flip_window, pixmap);
+    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, pixmap);
+    present_set_tree_pixmap(screen->root, NULL, pixmap);
 
     /* Update the screen pixmap with the current flip pixmap contents
      */
@@ -644,9 +653,10 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
                  */
                 if (screen_priv->flip_window && screen_priv->flip_window != window)
                     present_set_tree_pixmap(screen_priv->flip_window,
-                                              (*screen->GetScreenPixmap)(screen));
-                present_set_tree_pixmap(vblank->window, vblank->pixmap);
-                present_set_tree_pixmap(screen->root, vblank->pixmap);
+                                            screen_priv->flip_pixmap,
+                                            (*screen->GetScreenPixmap)(screen));
+                present_set_tree_pixmap(vblank->window, NULL, vblank->pixmap);
+                present_set_tree_pixmap(screen->root, NULL, vblank->pixmap);
 
                 /* Report update region as damaged
                  */
commit 180b09912c0d2c4a43b5a08678bcad4b818924c7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Feb 8 09:47:41 2015 +0000

    present: When cancelling a pending synchronous flip, requeue it
    
    The vblank event request for a synchronous flip is scheduled for the
    vblank before the target flip msc (so that the flip itself appears at
    the right frame). If we cancel that flip and so wish to schedule a
    copy instead, that copy needs to be postponed by a frame in order for it
    be performed at the requested time.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/present/present.c b/present/present.c
index 7af6bb7..c55a56e 100644
--- a/present/present.c
+++ b/present/present.c
@@ -549,8 +549,13 @@ present_check_flip_window (WindowPtr window)
 
     /* Now check any queued vblanks */
     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))
+        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) {
+                vblank->requeue = TRUE;
+                vblank->target_msc++;
+            }
+        }
     }
 }
 
@@ -584,6 +589,15 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
     uint8_t                     mode;
 
+    if (vblank->requeue) {
+        vblank->requeue = FALSE;
+        if (Success == present_queue_vblank(screen,
+                                            vblank->crtc,
+                                            vblank->event_id,
+                                            vblank->target_msc))
+            return;
+    }
+
     if (vblank->wait_fence) {
         if (!present_fence_check_triggered(vblank->wait_fence)) {
             present_fence_set_callback(vblank->wait_fence, present_wait_fence_triggered, vblank);
diff --git a/present/present_priv.h b/present/present_priv.h
index d007fdb..0d16cfa 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -70,6 +70,7 @@ struct present_vblank {
     present_notify_ptr  notifies;
     int                 num_notifies;
     Bool                queued;         /* on present_exec_queue */
+    Bool                requeue;        /* on queue, but target_msc has changed */
     Bool                flip;           /* planning on using flip */
     Bool                flip_ready;     /* wants to flip, but waiting for previous flip or unflip */
     Bool                sync_flip;      /* do flip synchronous to vblank */
commit b2d55338f6b8f43ebcb49994abad123a797248cf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Feb 8 09:47:40 2015 +0000

    present: Requery pending flips with the right sync_flip mode
    
    When verifying whether a pending flip is still valid, we need to pass
    down the orignal sync_flip mode (e.g. if the driver only supports sync
    flips, verifying a async flip will falsely fail).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/present/present.c b/present/present.c
index beb01dc..7af6bb7 100644
--- a/present/present.c
+++ b/present/present.c
@@ -453,6 +453,7 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     screen_priv->flip_window = vblank->window;
     screen_priv->flip_serial = vblank->serial;
     screen_priv->flip_pixmap = vblank->pixmap;
+    screen_priv->flip_sync = vblank->sync_flip;
     screen_priv->flip_idle_fence = vblank->idle_fence;
 
     vblank->pixmap = NULL;
@@ -541,14 +542,14 @@ present_check_flip_window (WindowPtr window)
          * Check current flip
          */
         if (window == screen_priv->flip_window) {
-            if (!present_check_flip(screen_priv->flip_crtc, window, screen_priv->flip_pixmap, FALSE, NULL, 0, 0))
+            if (!present_check_flip(screen_priv->flip_crtc, window, screen_priv->flip_pixmap, screen_priv->flip_sync, NULL, 0, 0))
                 present_unflip(screen);
         }
     }
 
     /* Now check any queued vblanks */
     xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
-        if (vblank->queued && vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, FALSE, NULL, 0, 0))
+        if (vblank->queued && vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, vblank->sync_flip, NULL, 0, 0))
             vblank->flip = FALSE;
     }
 }
diff --git a/present/present_priv.h b/present/present_priv.h
index 996292e..d007fdb 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -93,6 +93,7 @@ typedef struct present_screen_priv {
     uint32_t                    flip_serial;
     PixmapPtr                   flip_pixmap;
     present_fence_ptr           flip_idle_fence;
+    Bool                        flip_sync;
 
     present_screen_info_ptr     info;
 } present_screen_priv_rec, *present_screen_priv_ptr;
commit 548a3d5fd69bb059bbaf26ededdc94c212712cd7
Author: Dave Airlie <airlied at gmail.com>
Date:   Mon Nov 16 09:05:27 2015 +1000

    modesetting: create entities for pci and old probe. (v2)
    
    This moves the code from the platform case into
    a common function, and calls that from the
    other two.
    
    v2: Emil convinced me we don't need to lookup pEnt
    here, so let's not bother.
    
    Reported-by: Mark Kettenis <mark.kettenis at xs4all.nl>
    Reviewed-by: Mark Kettenis <kettenis at openbsd.org>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 00f966c..e53d3d4 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -330,6 +330,25 @@ ms_setup_scrn_hooks(ScrnInfoPtr scrn)
     scrn->ValidMode = ValidMode;
 }
 
+static void
+ms_setup_entity(ScrnInfoPtr scrn, int entity_num)
+{
+    DevUnion *pPriv;
+
+    xf86SetEntitySharable(entity_num);
+
+    if (ms_entity_index == -1)
+        ms_entity_index = xf86AllocateEntityPrivateIndex();
+
+    pPriv = xf86GetEntityPrivate(entity_num,
+                                 ms_entity_index);
+
+    xf86SetEntityInstanceForScreen(scrn, entity_num, xf86GetNumEntityInstances(entity_num) - 1);
+
+    if (!pPriv->ptr)
+        pPriv->ptr = xnfcalloc(sizeof(modesettingEntRec), 1);
+}
+
 #if XSERVER_LIBPCIACCESS
 static Bool
 ms_pci_probe(DriverPtr driver,
@@ -353,6 +372,8 @@ ms_pci_probe(DriverPtr driver,
                        dev->bus, dev->domain, dev->dev, dev->func);
             xf86DrvMsg(scrn->scrnIndex, X_INFO,
                        "using %s\n", devpath ? devpath : "default device");
+
+            ms_setup_entity(scrn, entity_num);
         }
         else
             scrn = NULL;
@@ -385,25 +406,7 @@ ms_platform_probe(DriverPtr driver,
         xf86DrvMsg(scrn->scrnIndex, X_INFO,
                    "using drv %s\n", path ? path : "default device");
 
-        {
-            DevUnion *pPriv;
-            EntityInfoPtr pEnt;
-
-            xf86SetEntitySharable(entity_num);
-
-            if (ms_entity_index == -1)
-                ms_entity_index = xf86AllocateEntityPrivateIndex();
-
-            pEnt = xf86GetEntityInfo(entity_num);
-            pPriv = xf86GetEntityPrivate(pEnt->index,
-                                         ms_entity_index);
-
-            xf86SetEntityInstanceForScreen(scrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1);
-
-            if (!pPriv->ptr)
-                pPriv->ptr = xnfcalloc(sizeof(modesettingEntRec), 1);
-        }
-
+        ms_setup_entity(scrn, entity_num);
     }
 
     return scrn != NULL;
@@ -432,13 +435,12 @@ Probe(DriverPtr drv, int flags)
     }
 
     for (i = 0; i < numDevSections; i++) {
-
+        int entity_num;
         dev = xf86FindOptionValue(devSections[i]->options, "kmsdev");
         if (probe_hw(dev, NULL)) {
-            int entity;
 
-            entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE);
-            scrn = xf86ConfigFbEntity(scrn, 0, entity, NULL, NULL, NULL, NULL);
+            entity_num = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE);
+            scrn = xf86ConfigFbEntity(scrn, 0, entity_num, NULL, NULL, NULL, NULL);
         }
 
         if (scrn) {
@@ -448,6 +450,7 @@ Probe(DriverPtr drv, int flags)
 
             xf86DrvMsg(scrn->scrnIndex, X_INFO,
                        "using %s\n", dev ? dev : "default device");
+            ms_setup_entity(scrn, entity_num);
         }
     }
 
commit 771016f0705909c908917b4ccaeafc950ba93c05
Author: Dave Airlie <airlied at gmail.com>
Date:   Mon Nov 16 09:05:26 2015 +1000

    modesetting: drop platform_dev pointer.
    
    This isn't used anywhere, so no point storing it until we need it.
    
    Reviewed-by: Mark Kettenis <kettenis at openbsd.org>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 80abcdf..00f966c 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -388,7 +388,6 @@ ms_platform_probe(DriverPtr driver,
         {
             DevUnion *pPriv;
             EntityInfoPtr pEnt;
-            modesettingEntPtr pMSEnt;
 
             xf86SetEntitySharable(entity_num);
 
@@ -401,13 +400,8 @@ ms_platform_probe(DriverPtr driver,
 
             xf86SetEntityInstanceForScreen(scrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1);
 
-            if (!pPriv->ptr) {
+            if (!pPriv->ptr)
                 pPriv->ptr = xnfcalloc(sizeof(modesettingEntRec), 1);
-                pMSEnt = pPriv->ptr;
-            } else {
-                pMSEnt = pPriv->ptr;
-            }
-            pMSEnt->platform_dev = dev;
         }
 
     }
diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index 14137c1..5e1c5d9 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -61,9 +61,6 @@ typedef struct
     unsigned long fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */
     int fd_wakeup_ref;
     unsigned int assigned_crtcs;
-#ifdef XSERVER_PLATFORM_BUS
-    struct xf86_platform_device *platform_dev;
-#endif
 } modesettingEntRec, *modesettingEntPtr;
 
 typedef void (*ms_drm_handler_proc)(uint64_t frame,
commit 19b0249a5e07b9fc008e5d8709d7e489874415de
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Mon Nov 16 11:06:57 2015 +0100

    Xorg.wrap: activate libdrm based detection for KMS drivers
    
    Xorg.wrap includes code guarded with WITH_LIBDRM for detecting KMS drivers.
    Unfortunately it is never activated since code missed to include file
    which defines WITH_LIBDRM.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92894
    Signed-off-by: Arkadiusz Miśkiewicz <arekm at maven.pl>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/xorg-wrapper.c b/hw/xfree86/xorg-wrapper.c
index 4c37cfc..d930962 100644
--- a/hw/xfree86/xorg-wrapper.c
+++ b/hw/xfree86/xorg-wrapper.c
@@ -24,6 +24,7 @@
  */
 
 #include "dix-config.h"
+#include "xorg-config.h"
 
 #include <errno.h>
 #include <fcntl.h>
commit 5bccde749db93296b7784e4cdc5e54c4443656c1
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Dec 2 18:21:12 2015 +0900

    randr: Stop dirty tracking for shared pixmap being destroyed
    
    Otherwise, we leave a dangling reference to the destroyed pixmap in the
    master screen's pixmap_dirty_list.
    
    Fixes regression from commit cf5d6414 ("randr: Factor out shared pixmap
    destruction").
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 8d9c5bb..ec26fcd 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -363,13 +363,18 @@ RRComputeContiguity(ScreenPtr pScreen)
 
 static void
 rrDestroySharedPixmap(RRCrtcPtr crtc, PixmapPtr pPixmap) {
-    if (crtc->pScreen->current_master && pPixmap->master_pixmap) {
+    ScreenPtr master = crtc->pScreen->current_master;
+
+    if (master && pPixmap->master_pixmap) {
+        PixmapPtr mscreenpix = master->GetScreenPixmap(master);
+
+        master->StopPixmapTracking(mscreenpix, pPixmap);
         /*
          * Unref the pixmap twice: once for the original reference, and once
          * for the reference implicitly added by PixmapShareToSlave.
          */
-        crtc->pScreen->current_master->DestroyPixmap(pPixmap->master_pixmap);
-        crtc->pScreen->current_master->DestroyPixmap(pPixmap->master_pixmap);
+        master->DestroyPixmap(pPixmap->master_pixmap);
+        master->DestroyPixmap(pPixmap->master_pixmap);
     }
 
     crtc->pScreen->DestroyPixmap(pPixmap);
commit 2e3d9623ae3f562f81e513cb183ca1b1b68f279c
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Dec 2 10:42:36 2015 -0500

    Revert "hw/xfree86: Use NotifyFd for device and other input fd wakeups"
    
    Reported to break libinput:
    
    http://lists.freedesktop.org/archives/xorg-devel/2015-December/048091.html
    
    This reverts commit 1df07dc36ca145c59f51176d9ab2651112506d75.

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 2db6e5b..709afd6 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -101,6 +101,8 @@ Bool VTSwitchEnabled = TRUE;    /* Allows run-time disabling for
                                  switches when using the DRI
                                  automatic full screen mode.*/
 
+extern fd_set EnabledDevices;
+
 #ifdef XF86PM
 extern void (*xf86OSPMClose) (void);
 #endif
@@ -245,6 +247,45 @@ xf86ProcessActionEvent(ActionEvent action, void *arg)
 void
 xf86Wakeup(void *blockData, int err, void *pReadmask)
 {
+    fd_set *LastSelectMask = (fd_set *) pReadmask;
+    fd_set devicesWithInput;
+    InputInfoPtr pInfo;
+
+    if (err >= 0) {
+
+        XFD_ANDSET(&devicesWithInput, LastSelectMask, &EnabledDevices);
+        if (XFD_ANYSET(&devicesWithInput)) {
+            pInfo = xf86InputDevs;
+            while (pInfo) {
+                if (pInfo->read_input && pInfo->fd >= 0 &&
+                    (FD_ISSET(pInfo->fd, &devicesWithInput) != 0)) {
+                    OsBlockSIGIO();
+
+                    /*
+                     * Remove the descriptior from the set because more than one
+                     * device may share the same file descriptor.
+                     */
+                    FD_CLR(pInfo->fd, &devicesWithInput);
+
+                    pInfo->read_input(pInfo);
+                    OsReleaseSIGIO();
+                }
+                pInfo = pInfo->next;
+            }
+        }
+    }
+
+    if (err >= 0) {             /* we don't want the handlers called if select() */
+        IHPtr ih, ih_tmp;       /* returned with an error condition, do we?      */
+
+        nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next) {
+            if (ih->enabled && ih->fd >= 0 && ih->ihproc &&
+                (FD_ISSET(ih->fd, ((fd_set *) pReadmask)) != 0)) {
+                ih->ihproc(ih->fd, ih->data);
+            }
+        }
+    }
+
     if (xf86VTSwitchPending())
         xf86VTSwitch();
 }
@@ -264,15 +305,6 @@ xf86SigioReadInput(int fd, void *closure)
     errno = errno_save;
 }
 
-static void
-xf86NotifyReadInput(int fd, int ready, void *closure)
-{
-    InputInfoPtr pInfo = closure;
-    OsBlockSIGIO();
-    pInfo->read_input(pInfo);
-    OsReleaseSIGIO();
-}
-
 /*
  * xf86AddEnabledDevice --
  *
@@ -282,7 +314,6 @@ xf86AddEnabledDevice(InputInfoPtr pInfo)
 {
     if (!xf86InstallSIGIOHandler(pInfo->fd, xf86SigioReadInput, pInfo)) {
         AddEnabledDevice(pInfo->fd);
-        SetNotifyFd(pInfo->fd, xf86NotifyReadInput, X_NOTIFY_READ, pInfo);
     }
 }
 
@@ -295,7 +326,6 @@ xf86RemoveEnabledDevice(InputInfoPtr pInfo)
 {
     if (!xf86RemoveSIGIOHandler(pInfo->fd)) {
         RemoveEnabledDevice(pInfo->fd);
-        RemoveNotifyFd(pInfo->fd);
     }
 }
 
@@ -606,16 +636,6 @@ xf86VTSwitch(void)
 
 /* Input handler registration */
 
-static void
-xf86InputHandlerNotify(int fd, int ready, void *data)
-{
-    IHPtr       ih = data;
-
-    if (ih->enabled && ih->fd >= 0 && ih->ihproc) {
-        ih->ihproc(ih->fd, ih->data);
-    }
-}
-
 static void *
 addInputHandler(int fd, InputHandlerProc proc, void *data)
 {
@@ -633,11 +653,6 @@ addInputHandler(int fd, InputHandlerProc proc, void *data)
     ih->data = data;
     ih->enabled = TRUE;
 
-    if (!SetNotifyFd(fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih)) {
-        free(ih);
-        return NULL;
-    }
-
     ih->next = InputHandlers;
     InputHandlers = ih;
 
commit 7b02f0b87ec2fa0cc5a65307a1fd55c671cec884
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:17 2015 -0800

    os: Use NotifyFd interface for listen descriptors
    
    Replace the custom path for dealing with new incoming connections with
    the general-purpose NotifyFd API.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/os.h b/include/os.h
index aed2e2f..e7c1936 100644
--- a/include/os.h
+++ b/include/os.h
@@ -139,9 +139,6 @@ extern _X_EXPORT const char *ClientAuthorized(ClientPtr /*client */ ,
                                               unsigned int /*string_n */ ,
                                               char * /*auth_string */ );
 
-extern _X_EXPORT Bool EstablishNewConnections(ClientPtr clientUnused,
-                                              void *closure);
-
 extern _X_EXPORT void CheckConnections(void);
 
 extern _X_EXPORT void CloseDownConnection(ClientPtr /*client */ );
diff --git a/os/WaitFor.c b/os/WaitFor.c
index b579e1b..e839d61 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -311,10 +311,6 @@ WaitForSomething(int *pClientsReady)
 
             XFD_ANDSET(&devicesReadable, &LastSelectMask, &EnabledDevices);
             XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients);
-            XFD_ANDSET(&tmp_set, &LastSelectMask, &WellKnownConnections);
-            if (XFD_ANYSET(&tmp_set))
-                QueueWorkProc(EstablishNewConnections, NULL,
-                              (void *) &LastSelectMask);
 
             XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds);
             if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady)
diff --git a/os/connection.c b/os/connection.c
index 4da01a6..8d866f6 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -121,7 +121,6 @@ SOFTWARE.
 
 static int lastfdesc;           /* maximum file descriptor */
 
-fd_set WellKnownConnections;    /* Listener mask */
 fd_set EnabledDevices;          /* mask for input devices that are on */
 fd_set NotifyReadFds;           /* mask for other file descriptors */
 fd_set NotifyWriteFds;          /* mask for other write file descriptors */
@@ -154,6 +153,9 @@ static fd_set SavedAllSockets;
 static fd_set SavedClientsWithInput;
 int GrabInProgress = 0;
 
+static void
+QueueNewConnections(int curconn, int ready, void *data);
+
 #if !defined(WIN32)
 int *ConnectionTranslation = NULL;
 #else
@@ -403,8 +405,6 @@ CreateWellKnownSockets(void)
     ClearConnectionTranslation();
 #endif
 
-    FD_ZERO(&WellKnownConnections);
-
     /* display is initialized to "0" by main(). It is then set to the display
      * number if specified on the command line. */
 
@@ -441,13 +441,13 @@ CreateWellKnownSockets(void)
         int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
 
         ListenTransFds[i] = fd;
-        FD_SET(fd, &WellKnownConnections);
+        SetNotifyFd(fd, QueueNewConnections, X_NOTIFY_READ, NULL);
 
         if (!_XSERVTransIsLocal(ListenTransConns[i]))
             DefineSelf (fd);
     }
 
-    if (!XFD_ANYSET(&WellKnownConnections) && !NoListenAll)
+    if (ListenTransCount == 0 && !NoListenAll)
         FatalError
             ("Cannot establish any listening sockets - Make sure an X server isn't already running");
 
@@ -457,7 +457,6 @@ CreateWellKnownSockets(void)
 #endif
     OsSignal(SIGINT, GiveUp);
     OsSignal(SIGTERM, GiveUp);
-    XFD_COPYSET(&WellKnownConnections, &AllSockets);
     ResetHosts(display);
 
     InitParentProcess();
@@ -484,7 +483,7 @@ ResetWellKnownSockets(void)
                  * Remove it from out list.
                  */
 
-                FD_CLR(ListenTransFds[i], &WellKnownConnections);
+                RemoveNotifyFd(ListenTransFds[i]);
                 ListenTransFds[i] = ListenTransFds[ListenTransCount - 1];
                 ListenTransConns[i] = ListenTransConns[ListenTransCount - 1];
                 ListenTransCount -= 1;
@@ -497,12 +496,12 @@ ResetWellKnownSockets(void)
 
                 int newfd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
 
-                FD_CLR(ListenTransFds[i], &WellKnownConnections);
                 ListenTransFds[i] = newfd;
-                FD_SET(newfd, &WellKnownConnections);
             }
         }
     }
+    for (i = 0; i < ListenTransCount; i++)
+        SetNotifyFd(ListenTransFds[i], QueueNewConnections, X_NOTIFY_READ, NULL);
 
     ResetAuthorization();
     ResetHosts(display);
@@ -523,6 +522,7 @@ CloseWellKnownConnections(void)
         if (ListenTransConns[i] != NULL) {
             _XSERVTransClose(ListenTransConns[i]);
             ListenTransConns[i] = NULL;
+            RemoveNotifyFd(ListenTransFds[i]);
         }
     }
     ListenTransCount = 0;
@@ -810,22 +810,18 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time)
  *    and AllSockets.
  *****************/
 
- /*ARGSUSED*/ Bool
+static Bool
 EstablishNewConnections(ClientPtr clientUnused, void *closure)
 {
-    fd_set readyconnections;    /* set of listeners that are ready */
-    int curconn;                /* fd of listener that's ready */
-    register int newconn;       /* fd of new client */
+    int curconn = (int) (intptr_t) closure;
+    int newconn;       /* fd of new client */
     CARD32 connect_time;
-    register int i;
-    register ClientPtr client;
-    register OsCommPtr oc;
-    fd_set tmask;
+    int i;
+    ClientPtr client;
+    OsCommPtr oc;
+    XtransConnInfo trans_conn, new_trans_conn;
+    int status;
 
-    XFD_ANDSET(&tmask, (fd_set *) closure, &WellKnownConnections);
-    XFD_COPYSET(&tmask, &readyconnections);
-    if (!XFD_ANYSET(&readyconnections))
-        return TRUE;
     connect_time = GetTimeInMillis();
     /* kill off stragglers */
     for (i = 1; i < currentMaxClients; i++) {
@@ -837,58 +833,43 @@ EstablishNewConnections(ClientPtr clientUnused, void *closure)
                 CloseDownClient(client);
         }
     }
-#ifndef WIN32
-    for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) {
-        while (readyconnections.fds_bits[i])
-#else
-    for (i = 0; i < XFD_SETCOUNT(&readyconnections); i++)
-#endif
-    {
-        XtransConnInfo trans_conn, new_trans_conn;
-        int status;
 
-#ifndef WIN32
-        curconn = mffs(readyconnections.fds_bits[i]) - 1;
-        readyconnections.fds_bits[i] &= ~((fd_mask) 1 << curconn);
-        curconn += (i * (sizeof(fd_mask) * 8));
-#else
-        curconn = XFD_FD(&readyconnections, i);
-#endif
-
-        if ((trans_conn = lookup_trans_conn(curconn)) == NULL)
-            continue;
+    if ((trans_conn = lookup_trans_conn(curconn)) == NULL)
+        return TRUE;
 
-        if ((new_trans_conn = _XSERVTransAccept(trans_conn, &status)) == NULL)
-            continue;
+    if ((new_trans_conn = _XSERVTransAccept(trans_conn, &status)) == NULL)
+        return TRUE;
 
-        newconn = _XSERVTransGetConnectionNumber(new_trans_conn);
+    newconn = _XSERVTransGetConnectionNumber(new_trans_conn);
 
-        if (newconn < lastfdesc) {
-            int clientid;
+    if (newconn < lastfdesc) {
+        int clientid;
 
 #if !defined(WIN32)
-            clientid = ConnectionTranslation[newconn];
+        clientid = ConnectionTranslation[newconn];
 #else
-            clientid = GetConnectionTranslation(newconn);
+        clientid = GetConnectionTranslation(newconn);
 #endif
-            if (clientid && (client = clients[clientid]))
-                CloseDownClient(client);
-        }
+        if (clientid && (client = clients[clientid]))
+            CloseDownClient(client);
+    }
 
-        _XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1);
+    _XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1);
 
-        if (trans_conn->flags & TRANS_NOXAUTH)
-            new_trans_conn->flags = new_trans_conn->flags | TRANS_NOXAUTH;
+    if (trans_conn->flags & TRANS_NOXAUTH)
+        new_trans_conn->flags = new_trans_conn->flags | TRANS_NOXAUTH;
 
-        if (!AllocNewConnection(new_trans_conn, newconn, connect_time)) {
-            ErrorConnMax(new_trans_conn);
-            _XSERVTransClose(new_trans_conn);
-        }
+    if (!AllocNewConnection(new_trans_conn, newconn, connect_time)) {
+        ErrorConnMax(new_trans_conn);
+        _XSERVTransClose(new_trans_conn);
     }
-#ifndef WIN32
+    return TRUE;
 }
-#endif
-return TRUE;
+
+static void
+QueueNewConnections(int fd, int ready, void *data)
+{
+    QueueWorkProc(EstablishNewConnections, NULL, (void *) (intptr_t) fd);
 }
 
 #define NOROOM "Maximum number of clients reached"
@@ -1417,8 +1398,7 @@ ListenOnOpenFD(int fd, int noxauth)
     ListenTransConns[ListenTransCount] = ciptr;
     ListenTransFds[ListenTransCount] = fd;
 
-    FD_SET(fd, &WellKnownConnections);
-    FD_SET(fd, &AllSockets);
+    SetNotifyFd(fd, QueueNewConnections, X_NOTIFY_READ, NULL);
 
     /* Increment the count */
     ListenTransCount++;
commit 1df07dc36ca145c59f51176d9ab2651112506d75
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:16 2015 -0800

    hw/xfree86: Use NotifyFd for device and other input fd wakeups
    
    Remove code in xf86Wakeup for dealing with device and other input and
    switch to using the new NotifyFd interface.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 709afd6..2db6e5b 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -101,8 +101,6 @@ Bool VTSwitchEnabled = TRUE;    /* Allows run-time disabling for
                                  switches when using the DRI
                                  automatic full screen mode.*/
 
-extern fd_set EnabledDevices;
-
 #ifdef XF86PM
 extern void (*xf86OSPMClose) (void);
 #endif
@@ -247,45 +245,6 @@ xf86ProcessActionEvent(ActionEvent action, void *arg)
 void
 xf86Wakeup(void *blockData, int err, void *pReadmask)
 {
-    fd_set *LastSelectMask = (fd_set *) pReadmask;
-    fd_set devicesWithInput;
-    InputInfoPtr pInfo;
-
-    if (err >= 0) {
-
-        XFD_ANDSET(&devicesWithInput, LastSelectMask, &EnabledDevices);
-        if (XFD_ANYSET(&devicesWithInput)) {
-            pInfo = xf86InputDevs;
-            while (pInfo) {
-                if (pInfo->read_input && pInfo->fd >= 0 &&
-                    (FD_ISSET(pInfo->fd, &devicesWithInput) != 0)) {
-                    OsBlockSIGIO();
-
-                    /*
-                     * Remove the descriptior from the set because more than one
-                     * device may share the same file descriptor.
-                     */
-                    FD_CLR(pInfo->fd, &devicesWithInput);
-
-                    pInfo->read_input(pInfo);
-                    OsReleaseSIGIO();
-                }
-                pInfo = pInfo->next;
-            }
-        }
-    }
-
-    if (err >= 0) {             /* we don't want the handlers called if select() */
-        IHPtr ih, ih_tmp;       /* returned with an error condition, do we?      */
-
-        nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next) {
-            if (ih->enabled && ih->fd >= 0 && ih->ihproc &&
-                (FD_ISSET(ih->fd, ((fd_set *) pReadmask)) != 0)) {
-                ih->ihproc(ih->fd, ih->data);
-            }
-        }
-    }
-
     if (xf86VTSwitchPending())
         xf86VTSwitch();
 }
@@ -305,6 +264,15 @@ xf86SigioReadInput(int fd, void *closure)
     errno = errno_save;
 }
 
+static void
+xf86NotifyReadInput(int fd, int ready, void *closure)
+{
+    InputInfoPtr pInfo = closure;
+    OsBlockSIGIO();
+    pInfo->read_input(pInfo);
+    OsReleaseSIGIO();
+}
+
 /*
  * xf86AddEnabledDevice --
  *
@@ -314,6 +282,7 @@ xf86AddEnabledDevice(InputInfoPtr pInfo)
 {
     if (!xf86InstallSIGIOHandler(pInfo->fd, xf86SigioReadInput, pInfo)) {
         AddEnabledDevice(pInfo->fd);
+        SetNotifyFd(pInfo->fd, xf86NotifyReadInput, X_NOTIFY_READ, pInfo);
     }
 }
 
@@ -326,6 +295,7 @@ xf86RemoveEnabledDevice(InputInfoPtr pInfo)
 {
     if (!xf86RemoveSIGIOHandler(pInfo->fd)) {
         RemoveEnabledDevice(pInfo->fd);
+        RemoveNotifyFd(pInfo->fd);
     }
 }
 
@@ -636,6 +606,16 @@ xf86VTSwitch(void)
 
 /* Input handler registration */
 
+static void
+xf86InputHandlerNotify(int fd, int ready, void *data)
+{
+    IHPtr       ih = data;
+
+    if (ih->enabled && ih->fd >= 0 && ih->ihproc) {
+        ih->ihproc(ih->fd, ih->data);
+    }
+}
+
 static void *
 addInputHandler(int fd, InputHandlerProc proc, void *data)
 {
@@ -653,6 +633,11 @@ addInputHandler(int fd, InputHandlerProc proc, void *data)
     ih->data = data;
     ih->enabled = TRUE;
 
+    if (!SetNotifyFd(fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih)) {
+        free(ih);
+        return NULL;
+    }
+
     ih->next = InputHandlers;
     InputHandlers = ih;
 
commit e51ea53b26bd9ec05b9209825960af28d0b6bbe1
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:15 2015 -0800

    render: Use OsTimer for animated cursor timing
    
    This replaces the block/wakeup handlers with an OsTimer. This also
    avoids problems with performing rendering during the wakeup handler.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/render/animcur.c b/render/animcur.c
index 825ae1f..52e6b8b 100644
--- a/render/animcur.c
+++ b/render/animcur.c
@@ -59,15 +59,14 @@ typedef struct _AnimCur {
 
 typedef struct _AnimScrPriv {
     CloseScreenProcPtr CloseScreen;
-
-    ScreenBlockHandlerProcPtr BlockHandler;
-
     CursorLimitsProcPtr CursorLimits;
     DisplayCursorProcPtr DisplayCursor;
     SetCursorPositionProcPtr SetCursorPosition;
     RealizeCursorProcPtr RealizeCursor;
     UnrealizeCursorProcPtr UnrealizeCursor;
     RecolorCursorProcPtr RecolorCursor;
+    OsTimerPtr timer;
+    Bool timer_set;
 } AnimCurScreenRec, *AnimCurScreenPtr;
 
 static unsigned char empty[4];
@@ -129,28 +128,23 @@ AnimCurCursorLimits(DeviceIntPtr pDev,
 }
 
 /*
- * This has to be a screen block handler instead of a generic
- * block handler so that it is well ordered with respect to the DRI
- * block handler responsible for releasing the hardware to DRI clients
+ * The cursor animation timer has expired, go display any relevant cursor changes
+ * and compute a new timeout value
  */
 
-static void
-AnimCurScreenBlockHandler(ScreenPtr pScreen,
-                          void *pTimeout, void *pReadmask)
+static CARD32
+AnimCurTimerNotify(OsTimerPtr timer, CARD32 now, void *arg)
 {
+    ScreenPtr pScreen = arg;
     AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
     DeviceIntPtr dev;
     Bool activeDevice = FALSE;
-    CARD32 now = 0, soonest = ~0;       /* earliest time to wakeup again */
-
-    Unwrap(as, pScreen, BlockHandler);
+    CARD32 soonest = ~0;       /* earliest time to wakeup again */
 
     for (dev = inputInfo.devices; dev; dev = dev->next) {
         if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) {
-            if (!activeDevice) {
-                now = GetTimeInMillis();
+            if (!activeDevice)
                 activeDevice = TRUE;
-            }
 
             if ((INT32) (now - dev->spriteInfo->anim.time) >= 0) {
                 AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor);
@@ -180,13 +174,11 @@ AnimCurScreenBlockHandler(ScreenPtr pScreen,
     }
 
     if (activeDevice)
-        AdjustWaitForDelay(pTimeout, soonest - now);
-
-    (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
-    if (activeDevice)
-        Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
+        TimerSet(as->timer, TimerAbsolute, soonest, AnimCurTimerNotify, pScreen);
     else
-        as->BlockHandler = NULL;
+        as->timer_set = FALSE;
+
+    return 0;
 }
 
 static Bool
@@ -212,8 +204,11 @@ AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
                 pDev->spriteInfo->anim.pCursor = pCursor;
                 pDev->spriteInfo->anim.pScreen = pScreen;
 
-                if (!as->BlockHandler)
-                    Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
+                if (!as->timer_set) {
+                    TimerSet(as->timer, TimerAbsolute, pDev->spriteInfo->anim.time,
+                             AnimCurTimerNotify, pScreen);
+                    as->timer_set = TRUE;
+                }
             }
         }
         else
@@ -239,8 +234,11 @@ AnimCurSetCursorPosition(DeviceIntPtr pDev,
     if (pDev->spriteInfo->anim.pCursor) {
         pDev->spriteInfo->anim.pScreen = pScreen;
 
-        if (!as->BlockHandler)
-            Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
+        if (!as->timer_set) {
+            TimerSet(as->timer, TimerAbsolute, pDev->spriteInfo->anim.time,
+                     AnimCurTimerNotify, pScreen);
+            as->timer_set = TRUE;
+        }
     }
     ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
     Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
@@ -316,9 +314,14 @@ AnimCurInit(ScreenPtr pScreen)
     as = (AnimCurScreenPtr) malloc(sizeof(AnimCurScreenRec));
     if (!as)
         return FALSE;
-    Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen);
+    as->timer = TimerSet(NULL, TimerAbsolute, 0, AnimCurTimerNotify, pScreen);
+    if (!as->timer) {
+        free(as);
+        return FALSE;
+    }
+    as->timer_set = FALSE;
 
-    as->BlockHandler = NULL;
+    Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen);
 
     Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits);
     Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor);
commit 49c0f2413d32fdfe36e45861fcb32aaeab633094
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:14 2015 -0800

    os/xdmcp: Replace xdmcp block/wakeup handlers with timer and NotifyFd
    
    This removes the block and wakeup handlers and replaces them with a
    combination of a NotifyFd callback and timers.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/xdmcp.c b/os/xdmcp.c
index 5bdcbe9..dbf43ef 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -82,10 +82,10 @@ static struct sockaddr_in req_sockaddr;
 #endif
 static int req_socklen;
 static CARD32 SessionID;
-static CARD32 timeOutTime;
 static int timeOutRtx;
 static CARD16 DisplayNumber;
 static xdmcp_states XDM_INIT_STATE = XDM_OFF;
+static OsTimerPtr xdmcp_timer;
 
 #ifdef HASXDMAUTH
 static char *xdmAuthCookie;
@@ -197,13 +197,9 @@ static void send_packet(void);
 
 static void timeout(void);
 
-static void XdmcpBlockHandler(void              *data ,
-                              struct timeval    **wt,
-                              void              *LastSelectMask);
+static void XdmcpSocketNotify(int fd, int ready, void *data);
 
-static void XdmcpWakeupHandler(void             *data,
-                               int              i,
-                               void             *LastSelectMask);
+static CARD32 XdmcpTimerNotify(OsTimerPtr timer, CARD32 time, void *arg);
 
 /*
  * Register the Manufacturer display ID
@@ -579,6 +575,21 @@ XdmcpRegisterDisplayClass(const char *name, int length)
         DisplayClass.data[i] = (CARD8) name[i];
 }
 
+static void
+xdmcp_start(void)
+{
+    timeOutRtx = 0;
+    get_xdmcp_sock();
+    if (xdmcpSocket >= 0)
+        SetNotifyFd(xdmcpSocket, XdmcpSocketNotify, X_NOTIFY_READ, NULL);
+#if defined(IPv6) && defined(AF_INET6)
+    if (xdmcpSocket6 >= 0)
+        SetNotifyFd(xdmcpSocket6, XdmcpSocketNotify, X_NOTIFY_READ, NULL);
+#endif
+    xdmcp_timer = TimerSet(NULL, 0, 0, XdmcpTimerNotify, NULL);
+    send_packet();
+}
+
 /*
  * initialize XDMCP; create the socket, compute the display
  * number, set up the state machine
@@ -597,12 +608,8 @@ XdmcpInit(void)
         XdmcpRegisterDisplayClass(defaultDisplayClass,
                                   strlen(defaultDisplayClass));
         AccessUsingXdmcp();
-        RegisterBlockAndWakeupHandlers(XdmcpBlockHandler, XdmcpWakeupHandler,
-                                       (void *) 0);
-        timeOutRtx = 0;
         DisplayNumber = (CARD16) atoi(display);
-        get_xdmcp_sock();
-        send_packet();
+        xdmcp_start();
     }
 }
 
@@ -610,12 +617,8 @@ void
 XdmcpReset(void)
 {
     state = XDM_INIT_STATE;
-    if (state != XDM_OFF) {
-        RegisterBlockAndWakeupHandlers(XdmcpBlockHandler, XdmcpWakeupHandler,
-                                       (void *) 0);
-        timeOutRtx = 0;
-        send_packet();
-    }
+    if (state != XDM_OFF)
+        xdmcp_start();
 }
 
 /*
@@ -630,7 +633,7 @@ XdmcpOpenDisplay(int sock)
     if (state != XDM_AWAIT_MANAGE_RESPONSE)
         return;
     state = XDM_RUN_SESSION;
-    timeOutTime = GetTimeInMillis() + XDM_DEF_DORMANCY * 1000;
+    TimerSet(xdmcp_timer, 0, XDM_DEF_DORMANCY * 1000, XdmcpTimerNotify, NULL);
     sessionSocket = sock;
 }
 
@@ -648,69 +651,24 @@ XdmcpCloseDisplay(int sock)
     isItTimeToYield = TRUE;
 }
 
-/*
- * called before going to sleep, this routine
- * may modify the timeout value about to be sent
- * to select; in this way XDMCP can do appropriate things
- * dynamically while starting up
- */
-
- /*ARGSUSED*/ static void
-XdmcpBlockHandler(void *data, /* unused */
-                  struct timeval **wt, void *pReadmask)
+static void
+XdmcpSocketNotify(int fd, int ready, void *data)
 {
-    fd_set *last_select_mask = (fd_set *) pReadmask;
-    CARD32 millisToGo;
-
     if (state == XDM_OFF)
         return;
-    FD_SET(xdmcpSocket, last_select_mask);
-#if defined(IPv6) && defined(AF_INET6)
-    if (xdmcpSocket6 >= 0)
-        FD_SET(xdmcpSocket6, last_select_mask);
-#endif
-    if (timeOutTime == 0)
-        return;
-    millisToGo = timeOutTime - GetTimeInMillis();
-    if ((int) millisToGo < 0)
-        millisToGo = 0;
-    AdjustWaitForDelay(wt, millisToGo);
+    receive_packet(fd);
 }
 
-/*
- * called after select returns; this routine will
- * recognise when XDMCP packets await and
- * process them appropriately
- */
-
- /*ARGSUSED*/ static void
-XdmcpWakeupHandler(void *data,        /* unused */
-                   int i, void *pReadmask)
+static CARD32
+XdmcpTimerNotify(OsTimerPtr timer, CARD32 time, void *arg)
 {
-    fd_set *last_select_mask = (fd_set *) pReadmask;
-
-    if (state == XDM_OFF)
-        return;
-    if (i > 0) {
-        if (FD_ISSET(xdmcpSocket, last_select_mask)) {
-            receive_packet(xdmcpSocket);
-            FD_CLR(xdmcpSocket, last_select_mask);
-        }
-#if defined(IPv6) && defined(AF_INET6)
-        if (xdmcpSocket6 >= 0 && FD_ISSET(xdmcpSocket6, last_select_mask)) {
-            receive_packet(xdmcpSocket6);
-            FD_CLR(xdmcpSocket6, last_select_mask);
-        }
-#endif
-    }
-    else if (timeOutTime && (int) (GetTimeInMillis() - timeOutTime) >= 0) {
-        if (state == XDM_RUN_SESSION) {
-            state = XDM_KEEPALIVE;
-            send_packet();
-        }
-        else
-            timeout();
+    if (state == XDM_RUN_SESSION) {
+        state = XDM_KEEPALIVE;
+        send_packet();
     }
+    else
+        timeout();
+    return 0;
 }
 
 /*
@@ -832,7 +790,7 @@ send_packet(void)
     rtx = (XDM_MIN_RTX << timeOutRtx);
     if (rtx > XDM_MAX_RTX)
         rtx = XDM_MAX_RTX;
-    timeOutTime = GetTimeInMillis() + rtx * 1000;
+    TimerSet(xdmcp_timer, 0, rtx * 1000, XdmcpTimerNotify, NULL);
 }
 
 /*
@@ -847,7 +805,7 @@ XdmcpDeadSession(const char *reason)
     state = XDM_INIT_STATE;
     isItTimeToYield = TRUE;
     dispatchException |= DE_RESET;
-    timeOutTime = 0;
+    TimerCancel(xdmcp_timer);
     timeOutRtx = 0;
     send_packet();
 }
@@ -1391,7 +1349,7 @@ recv_alive_msg(unsigned length)
         XdmcpReadCARD32(&buffer, &AliveSessionID)) {
         if (SessionRunning && AliveSessionID == SessionID) {
             state = XDM_RUN_SESSION;
-            timeOutTime = GetTimeInMillis() + XDM_DEF_DORMANCY * 1000;
+            TimerSet(xdmcp_timer, 0, XDM_DEF_DORMANCY * 1000, XdmcpTimerNotify, NULL);
         }
         else {
             XdmcpDeadSession("Alive response indicates session dead");
commit 6a121f55381ecbb9cdaaef36ba6135890f3e006f
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:13 2015 -0800

    Xext/xselinux: Use NotifyFd interface
    
    Replace block/wakeup handlers with SetNotifyFd. Much nicer now.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/Xext/xselinux_hooks.c b/Xext/xselinux_hooks.c
index d9f2f68..2d85928 100644
--- a/Xext/xselinux_hooks.c
+++ b/Xext/xselinux_hooks.c
@@ -810,15 +810,9 @@ SELinuxResourceState(CallbackListPtr *pcbl, void *unused, void *calldata)
 static int netlink_fd;
 
 static void
-SELinuxBlockHandler(void *data, struct timeval **tv, void *read_mask)
+SELinuxNetlinkNotify(int fd, int ready, void *data)
 {
-}
-
-static void
-SELinuxWakeupHandler(void *data, int num_fds, void *read_mask)
-{
-    if (num_fds > 0 && FD_ISSET(netlink_fd, (fd_set *) read_mask))
-        avc_netlink_check_nb();
+    avc_netlink_check_nb();
 }
 
 void
@@ -844,9 +838,7 @@ SELinuxFlaskReset(void)
     /* Tear down SELinux stuff */
     audit_close(audit_fd);
     avc_netlink_release_fd();
-    RemoveBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler,
-                                 NULL);
-    RemoveGeneralSocket(netlink_fd);
+    RemoveNotifyFd(netlink_fd);
 
     avc_destroy();
 }
@@ -918,9 +910,7 @@ SELinuxFlaskInit(void)
         FatalError("SELinux: Failed to create atom\n");
 
     netlink_fd = avc_netlink_acquire_fd();
-    AddGeneralSocket(netlink_fd);
-    RegisterBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler,
-                                   NULL);
+    SetNotifyFd(netlink_fd, SELinuxNetlinkNotify, X_NOTIFY_READ, NULL);
 
     /* Register callbacks */
     ret &= AddCallback(&ClientStateCallback, SELinuxClientState, NULL);
commit f933a1b38ed1c65cc39fce1ee37aa18e3022c3f0
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Nov 23 17:36:53 2015 -0800

    hw/xwayland: Use NotifyFd handler to monitor wayland socket
    
    Replace the block/wakeup handler with a NotifyFd callback instead.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 55bf6d0..3d36205 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -115,6 +115,8 @@ xwl_close_screen(ScreenPtr screen)
                                   &xwl_screen->seat_list, link)
         xwl_seat_destroy(xwl_seat);
 
+    RemoveNotifyFd(xwl_screen->wayland_fd);
+
     wl_display_disconnect(xwl_screen->display);
 
     screen->CloseScreen = xwl_screen->CloseScreen;
@@ -453,17 +455,11 @@ static const struct wl_registry_listener registry_listener = {
 };
 
 static void
-wakeup_handler(void *data, int err, void *read_mask)
+socket_handler(int fd, int ready, void *data)
 {
     struct xwl_screen *xwl_screen = data;
     int ret;
 
-    if (err < 0)
-        return;
-
-    if (!FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask))
-        return;
-
     ret = wl_display_read_events(xwl_screen->display);
     if (ret == -1)
         FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
@@ -476,7 +472,12 @@ wakeup_handler(void *data, int err, void *read_mask)
 }
 
 static void
-block_handler(void *data, struct timeval **tv, void *read_mask)
+wakeup_handler(void *data, int err, void *pRead)
+{
+}
+
+static void
+block_handler(void *data, OSTimePtr pTimeout, void *pRead)
 {
     struct xwl_screen *xwl_screen = data;
     int ret;
@@ -651,7 +652,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
 #endif
 
     xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
-    AddGeneralSocket(xwl_screen->wayland_fd);
+    SetNotifyFd(xwl_screen->wayland_fd, socket_handler, X_NOTIFY_READ, xwl_screen);
     RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen);
 
     pScreen->SaveScreen = xwl_save_screen;
commit 8543d4d8bc0526d1c910913b76259e5dee108e74
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:11 2015 -0800

    modesetting: Use NotifyFd for drm event monitoring
    
    Replace the block/wakeup handlers with a NotifyFd callback.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index 77e0848..869472a 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -244,18 +244,16 @@ ms_crtc_msc_to_kernel_msc(xf86CrtcPtr crtc, uint64_t expect)
  * Check for pending DRM events and process them.
  */
 static void
-ms_drm_wakeup_handler(void *data, int err, void *mask)
+ms_drm_socket_handler(int fd, int ready, void *data)
 {
     ScreenPtr screen = data;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     modesettingPtr ms = modesettingPTR(scrn);
-    fd_set *read_mask = mask;
 
-    if (data == NULL || err < 0)
+    if (data == NULL)
         return;
 
-    if (FD_ISSET(ms->fd, read_mask))
-        drmHandleEvent(ms->fd, &ms->event_context);
+    drmHandleEvent(ms->fd, &ms->event_context);
 }
 
 /*
@@ -393,9 +391,7 @@ ms_vblank_screen_init(ScreenPtr screen)
      * registration within ScreenInit and not PreInit.
      */
     if (ms_ent->fd_wakeup_registered != serverGeneration) {
-        AddGeneralSocket(ms->fd);
-        RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
-                                       ms_drm_wakeup_handler, screen);
+        SetNotifyFd(ms->fd, ms_drm_socket_handler, X_NOTIFY_READ, screen);
         ms_ent->fd_wakeup_registered = serverGeneration;
         ms_ent->fd_wakeup_ref = 1;
     } else
@@ -415,8 +411,6 @@ ms_vblank_close_screen(ScreenPtr screen)
 
     if (ms_ent->fd_wakeup_registered == serverGeneration &&
         !--ms_ent->fd_wakeup_ref) {
-        RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
-                                     ms_drm_wakeup_handler, screen);
-        RemoveGeneralSocket(ms->fd);
+        RemoveNotifyFd(ms->fd);
     }
 }
commit 58354fcf472cefc35b9c19cf84bf079cadfa2e1d
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:10 2015 -0800

    kdrive/ephyr: Use NotifyFd for XCB connection input [v2]
    
    Eliminates polling every 20ms for device input.
    
    v2: rename ephyrPoll to ephyrXcbNotify and fix the API so it can be
        used directly for SetNotifyFd. Thanks to Daniel Martin
        <consume.noise at gmail.com>
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Cc: Daniel Martin <consume.noise at gmail.com>

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index cb1c16e..896bac5 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -1182,8 +1182,8 @@ ephyrProcessConfigureNotify(xcb_generic_event_t *xev)
 #endif /* RANDR */
 }
 
-void
-ephyrPoll(void)
+static void
+ephyrXcbNotify(int fd, int ready, void *data)
 {
     xcb_connection_t *conn = hostx_get_xcbconn();
 
@@ -1334,6 +1334,7 @@ static Status
 MouseEnable(KdPointerInfo * pi)
 {
     ((EphyrPointerPrivate *) pi->driverPrivate)->enabled = TRUE;
+    SetNotifyFd(hostx_get_fd(), ephyrXcbNotify, X_NOTIFY_READ, NULL);
     return Success;
 }
 
@@ -1341,6 +1342,7 @@ static void
 MouseDisable(KdPointerInfo * pi)
 {
     ((EphyrPointerPrivate *) pi->driverPrivate)->enabled = FALSE;
+    RemoveNotifyFd(hostx_get_fd());
     return;
 }
 
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index 18bfe11..f5015f6 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -168,9 +168,6 @@ Bool
 Bool
  ephyrCreateColormap(ColormapPtr pmap);
 
-void
- ephyrPoll(void);
-
 #ifdef RANDR
 Bool
  ephyrRandRGetInfo(ScreenPtr pScreen, Rotation * rotations);
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 3991c51..49516bb 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -1113,6 +1113,12 @@ hostx_get_screen(void)
 }
 
 int
+hostx_get_fd(void)
+{
+    return xcb_get_file_descriptor(HostX.conn);
+}
+
+int
 hostx_get_window(int a_screen_number)
 {
     EphyrScrPriv *scrpriv;
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 9299e8d..d416dae 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -198,4 +198,6 @@ int hostx_has_dri(void);
 int hostx_has_glx(void);
 #endif                          /* XF86DRI */
 
+int hostx_get_fd(void);
+
 #endif /*_XLIBS_STUFF_H_*/
diff --git a/hw/kdrive/ephyr/os.c b/hw/kdrive/ephyr/os.c
index 0dbcbb8..b481d0a 100644
--- a/hw/kdrive/ephyr/os.c
+++ b/hw/kdrive/ephyr/os.c
@@ -45,5 +45,4 @@ EphyrInit(void)
 
 KdOsFuncs EphyrOsFuncs = {
     .Init = EphyrInit,
-    .pollEvents = ephyrPoll,
 };
commit 483c2a1adf044ba1da844687b908c1c802060d2d
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:09 2015 -0800

    hw/kdrive: Use NotifyFd for kdrive input devices
    
    This switches the kdrive code to use FD notification for input
    devices, rather than the block and wakeup handlers.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 84b980f..1fdaa52 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -153,7 +153,16 @@ KdNonBlockFd(int fd)
 }
 
 static void
-KdAddFd(int fd)
+KdNotifyFd(int fd, int ready, void *data)
+{
+    int i = (int) (intptr_t) data;
+    OsBlockSIGIO();
+    (*kdInputFds[i].read)(fd, kdInputFds[i].closure);
+    OsReleaseSIGIO();
+}
+
+static void
+KdAddFd(int fd, int i)
 {
     struct sigaction act;
     sigset_t set;
@@ -162,6 +171,7 @@ KdAddFd(int fd)
     fcntl(fd, F_SETOWN, getpid());
     KdNonBlockFd(fd);
     AddEnabledDevice(fd);
+    SetNotifyFd(fd, KdNotifyFd, X_NOTIFY_READ, (void *) (intptr_t) i);
     memset(&act, '\0', sizeof act);
     act.sa_handler = KdSigio;
     sigemptyset(&act.sa_mask);
@@ -181,6 +191,7 @@ KdRemoveFd(int fd)
 
     kdnFds--;
     RemoveEnabledDevice(fd);
+    RemoveNotifyFd(fd);
     flags = fcntl(fd, F_GETFL);
     flags &= ~(FASYNC | NOBLOCK);
     fcntl(fd, F_SETFL, flags);
@@ -202,9 +213,9 @@ KdRegisterFd(int fd, void (*read) (int fd, void *closure), void *closure)
     kdInputFds[kdNumInputFds].enable = 0;
     kdInputFds[kdNumInputFds].disable = 0;
     kdInputFds[kdNumInputFds].closure = closure;
-    kdNumInputFds++;
     if (kdInputEnabled)
-        KdAddFd(fd);
+        KdAddFd(fd, kdNumInputFds);
+    kdNumInputFds++;
     return TRUE;
 }
 
@@ -1933,19 +1944,8 @@ KdBlockHandler(ScreenPtr pScreen, void *timeo, void *readmask)
 void
 KdWakeupHandler(ScreenPtr pScreen, unsigned long lresult, void *readmask)
 {
-    int result = (int) lresult;
-    fd_set *pReadmask = (fd_set *) readmask;
-    int i;
     KdPointerInfo *pi;
 
-    if (kdInputEnabled && result > 0) {
-        for (i = 0; i < kdNumInputFds; i++)
-            if (FD_ISSET(kdInputFds[i].fd, pReadmask)) {
-                OsBlockSIGIO();
-                (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
-                OsReleaseSIGIO();
-            }
-    }
     for (pi = kdPointers; pi; pi = pi->next) {
         if (pi->timeoutPending) {
             if ((long) (GetTimeInMillis() - pi->emulationTimeout) >= 0) {
commit 21c1680e83865a52d88cf8c80fb236d212931e5c
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:08 2015 -0800

    hw/kdrive: Use NotifyFd interface for kdrive/linux APM monitoring
    
    Replace the block/wakeup handlers with a NotifyFd callback
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/kdrive/linux/linux.c b/hw/kdrive/linux/linux.c
index 73a8169..a52bdef 100644
--- a/hw/kdrive/linux/linux.c
+++ b/hw/kdrive/linux/linux.c
@@ -169,19 +169,12 @@ LinuxSetSwitchMode(int mode)
     }
 }
 
-static void
-LinuxApmBlock(void *blockData, OSTimePtr pTimeout, void *pReadmask)
-{
-}
-
 static Bool LinuxApmRunning;
 
 static void
-LinuxApmWakeup(void *blockData, int result, void *pReadmask)
+LinuxApmNotify(int fd, int mask, void *blockData)
 {
-    fd_set *readmask = (fd_set *) pReadmask;
-
-    if (result > 0 && LinuxApmFd >= 0 && FD_ISSET(LinuxApmFd, readmask)) {
+    if (LinuxApmFd >= 0) {
         apm_event_t event;
         Bool running = LinuxApmRunning;
         int cmd = APM_IOC_SUSPEND;
@@ -242,8 +235,7 @@ LinuxEnable(void)
     if (LinuxApmFd >= 0) {
         LinuxApmRunning = TRUE;
         fcntl(LinuxApmFd, F_SETFL, fcntl(LinuxApmFd, F_GETFL) | NOBLOCK);
-        RegisterBlockAndWakeupHandlers(LinuxApmBlock, LinuxApmWakeup, 0);
-        AddEnabledDevice(LinuxApmFd);
+        SetNotifyFd(LinuxApmFd, LinuxApmNotify, X_NOTIFY_READ, NULL);
     }
 
     /*
@@ -273,8 +265,7 @@ LinuxDisable(void)
     }
     enabled = FALSE;
     if (LinuxApmFd >= 0) {
-        RemoveBlockAndWakeupHandlers(LinuxApmBlock, LinuxApmWakeup, 0);
-        RemoveEnabledDevice(LinuxApmFd);
+        RemoveNotifyFd(LinuxApmFd);
         close(LinuxApmFd);
         LinuxApmFd = -1;
     }
commit 8c8f3567fe4b4e372e22420810443c43e008da2c
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:07 2015 -0800

    config: Use NotifyFd interface for udev
    
    This uses the NotifyFd interface to monitor the udev file descriptor
    rather than adding another block/wakeup handler
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/config/udev.c b/config/udev.c
index 28c2658..08a954b 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -332,41 +332,30 @@ device_removed(struct udev_device *device)
 }
 
 static void
-wakeup_handler(void *data, int err, void *read_mask)
+socket_handler(int fd, int ready, void *data)
 {
-    int udev_fd = udev_monitor_get_fd(udev_monitor);
     struct udev_device *udev_device;
     const char *action;
 
-    if (err < 0)
+    udev_device = udev_monitor_receive_device(udev_monitor);
+    if (!udev_device)
         return;
-
-    if (FD_ISSET(udev_fd, (fd_set *) read_mask)) {
-        udev_device = udev_monitor_receive_device(udev_monitor);
-        if (!udev_device)
-            return;
-        action = udev_device_get_action(udev_device);
-        if (action) {
-            if (!strcmp(action, "add")) {
+    action = udev_device_get_action(udev_device);
+    if (action) {
+        if (!strcmp(action, "add")) {
+            device_removed(udev_device);
+            device_added(udev_device);
+        } else if (!strcmp(action, "change")) {
+            /* ignore change for the drm devices */
+            if (strcmp(udev_device_get_subsystem(udev_device), "drm")) {
                 device_removed(udev_device);
                 device_added(udev_device);
-            } else if (!strcmp(action, "change")) {
-                /* ignore change for the drm devices */
-                if (strcmp(udev_device_get_subsystem(udev_device), "drm")) {
-                    device_removed(udev_device);
-                    device_added(udev_device);
-                }
             }
-            else if (!strcmp(action, "remove"))
-                device_removed(udev_device);
         }
-        udev_device_unref(udev_device);
+        else if (!strcmp(action, "remove"))
+            device_removed(udev_device);
     }
-}
-
-static void
-block_handler(void *data, struct timeval **tv, void *read_mask)
-{
+    udev_device_unref(udev_device);
 }
 
 int
@@ -441,8 +430,7 @@ config_udev_init(void)
     }
     udev_enumerate_unref(enumerate);
 
-    RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
-    AddGeneralSocket(udev_monitor_get_fd(udev_monitor));
+    SetNotifyFd(udev_monitor_get_fd(udev_monitor), socket_handler, X_NOTIFY_READ, NULL);
 
     return 1;
 }
@@ -457,8 +445,7 @@ config_udev_fini(void)
 
     udev = udev_monitor_get_udev(udev_monitor);
 
-    RemoveGeneralSocket(udev_monitor_get_fd(udev_monitor));
-    RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
+    RemoveNotifyFd(udev_monitor_get_fd(udev_monitor));
     udev_monitor_unref(udev_monitor);
     udev_monitor = NULL;
     udev_unref(udev);
commit bf920b2390dc27947f87dd0b228518290a5ed85d
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:06 2015 -0800

    config: Use NotifyFd for dbus interface
    
    This uses the NotifyFd interface to monitor the dbus socket rather
    than a block/wakeup handler.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/config/dbus-core.c b/config/dbus-core.c
index 8351ea4..3c85ad7 100644
--- a/config/dbus-core.c
+++ b/config/dbus-core.c
@@ -48,11 +48,11 @@ static struct dbus_core_info bus_info;
 static CARD32 reconnect_timer(OsTimerPtr timer, CARD32 time, void *arg);
 
 static void
-wakeup_handler(void *data, int num_fds, void *read_mask)
+socket_handler(int fd, int ready, void *data)
 {
     struct dbus_core_info *info = data;
 
-    if (info->connection && num_fds > 0 && FD_ISSET(info->fd, (fd_set *) read_mask)) {
+    if (info->connection) {
         do {
             dbus_connection_read_write_dispatch(info->connection, 0);
         } while (info->connection &&
@@ -62,11 +62,6 @@ wakeup_handler(void *data, int num_fds, void *read_mask)
     }
 }
 
-static void
-block_handler(void *data, struct timeval **tv, void *read_mask)
-{
-}
-
 /**
  * Disconnect (if we haven't already been forcefully disconnected), clean up
  * after ourselves, and call all registered disconnect hooks.
@@ -87,9 +82,8 @@ teardown(void)
     if (bus_info.connection)
         dbus_connection_unref(bus_info.connection);
 
-    RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, &bus_info);
     if (bus_info.fd != -1)
-        RemoveGeneralSocket(bus_info.fd);
+        RemoveNotifyFd(bus_info.fd);
     bus_info.fd = -1;
     bus_info.connection = NULL;
 
@@ -162,9 +156,7 @@ connect_to_bus(void)
     }
 
     dbus_error_free(&error);
-    AddGeneralSocket(bus_info.fd);
-
-    RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, &bus_info);
+    SetNotifyFd(bus_info.fd, socket_handler, X_NOTIFY_READ, &bus_info);
 
     for (hook = bus_info.hooks; hook; hook = hook->next) {
         if (hook->connect)
commit 91ea0965dd4dfeba0a914c47ad4a64768e983b1b
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:04 2015 -0800

    dix: Move InitFonts up above screen initialization
    
    Font initialization was split into two stages, the first was to set up
    font privates with a call to ResetFontPrivateIndex, then much later
    the call to InitFonts to set up all of the FPEs. Doing the full font
    initialization before initializing the video drivers means that we can
    move the call to ResetFontPrivateIndex inside InitFonts.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/dixfonts.c b/dix/dixfonts.c
index 300bf04..19db141 100644
--- a/dix/dixfonts.c
+++ b/dix/dixfonts.c
@@ -1809,6 +1809,8 @@ InitFonts(void)
 {
     patternCache = MakeFontPatternCache();
 
+    ResetFontPrivateIndex();
+
     register_fpe_functions();
 }
 
diff --git a/dix/main.c b/dix/main.c
index 5495676..661ab03 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -199,7 +199,7 @@ dix_main(int argc, char *argv[], char *envp[])
         InitEvents();
         InitGlyphCaching();
         dixResetRegistry();
-        ResetFontPrivateIndex();
+        InitFonts();
         InitCallbackManager();
         InitOutput(&screenInfo, argc, argv);
 
@@ -232,7 +232,6 @@ dix_main(int argc, char *argv[], char *envp[])
                 FatalError("failed to create root window");
         }
 
-        InitFonts();
         if (SetDefaultFontPath(defaultFontPath) != Success) {
             ErrorF("[dix] failed to set default font path '%s'",
                    defaultFontPath);
commit 4020aacd1fc5b9c63369f011aeb9120af9c55218
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:03 2015 -0800

    os: Implement support for NotifyFd X_NOTIFY_WRITE
    
    This adds the ability to be notified when a file descriptor is
    available for writing.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/WaitFor.c b/os/WaitFor.c
index 12b21bb..b579e1b 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -156,6 +156,7 @@ WaitForSomething(int *pClientsReady)
     fd_set devicesReadable;
     CARD32 now = 0;
     Bool someReady = FALSE;
+    Bool someNotifyWriteReady = FALSE;
 
     FD_ZERO(&clientsReadable);
     FD_ZERO(&clientsWritable);
@@ -213,9 +214,10 @@ WaitForSomething(int *pClientsReady)
         /* keep this check close to select() call to minimize race */
         if (dispatchException)
             i = -1;
-        else if (AnyClientsWriteBlocked) {
-            XFD_COPYSET(&ClientsWriteBlocked, &clientsWritable);
-            i = Select(MaxClients, &LastSelectMask, &clientsWritable, NULL, wt);
+        else if (AnyWritesPending) {
+            XFD_COPYSET(&ClientsWriteBlocked, &LastSelectWriteMask);
+            XFD_ORSET(&LastSelectWriteMask, &NotifyWriteFds, &LastSelectWriteMask);
+            i = Select(MaxClients, &LastSelectMask, &LastSelectWriteMask, NULL, wt);
         }
         else {
             i = Select(MaxClients, &LastSelectMask, NULL, NULL, wt);
@@ -291,12 +293,20 @@ WaitForSomething(int *pClientsReady)
             }
             if (someReady)
                 XFD_ORSET(&LastSelectMask, &ClientsWithInput, &LastSelectMask);
-            if (AnyClientsWriteBlocked && XFD_ANYSET(&clientsWritable)) {
-                NewOutputPending = TRUE;
-                XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending);
-                XFD_UNSET(&ClientsWriteBlocked, &clientsWritable);
-                if (!XFD_ANYSET(&ClientsWriteBlocked))
-                    AnyClientsWriteBlocked = FALSE;
+            if (AnyWritesPending) {
+                XFD_ANDSET(&clientsWritable, &LastSelectWriteMask, &ClientsWriteBlocked);
+                if (XFD_ANYSET(&clientsWritable)) {
+                    NewOutputPending = TRUE;
+                    XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending);
+                    XFD_UNSET(&ClientsWriteBlocked, &clientsWritable);
+                    if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0)
+                        AnyWritesPending = FALSE;
+                }
+                if (NumNotifyWriteFd != 0) {
+                    XFD_ANDSET(&tmp_set, &LastSelectWriteMask, &NotifyWriteFds);
+                    if (XFD_ANYSET(&tmp_set))
+                        someNotifyWriteReady = TRUE;
+                }
             }
 
             XFD_ANDSET(&devicesReadable, &LastSelectMask, &EnabledDevices);
@@ -307,7 +317,7 @@ WaitForSomething(int *pClientsReady)
                               (void *) &LastSelectMask);
 
             XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds);
-            if (XFD_ANYSET(&tmp_set))
+            if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady)
                 HandleNotifyFds();
 
             if (XFD_ANYSET(&devicesReadable) || XFD_ANYSET(&clientsReadable))
diff --git a/os/connection.c b/os/connection.c
index 0df4391..4da01a6 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -124,15 +124,18 @@ static int lastfdesc;           /* maximum file descriptor */
 fd_set WellKnownConnections;    /* Listener mask */
 fd_set EnabledDevices;          /* mask for input devices that are on */
 fd_set NotifyReadFds;           /* mask for other file descriptors */
+fd_set NotifyWriteFds;          /* mask for other write file descriptors */
 fd_set AllSockets;              /* select on this */
 fd_set AllClients;              /* available clients */
 fd_set LastSelectMask;          /* mask returned from last select call */
+fd_set LastSelectWriteMask;     /* mask returned from last select call */
 fd_set ClientsWithInput;        /* clients with FULL requests in buffer */
 fd_set ClientsWriteBlocked;     /* clients who cannot receive output */
 fd_set OutputPending;           /* clients with reply/event data ready to go */
 int MaxClients = 0;
+int NumNotifyWriteFd;           /* Number of NotifyFd members with write set */
 Bool NewOutputPending;          /* not yet attempted to write some new output */
-Bool AnyClientsWriteBlocked;    /* true if some client blocked on write */
+Bool AnyWritesPending;          /* true if some client blocked on write or NotifyFd with write */
 Bool NoListenAll;               /* Don't establish any listening sockets */
 
 static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
@@ -969,8 +972,8 @@ CloseDownFileDescriptor(OsCommPtr oc)
         FD_CLR(connection, &SavedClientsWithInput);
     }
     FD_CLR(connection, &ClientsWriteBlocked);
-    if (!XFD_ANYSET(&ClientsWriteBlocked))
-        AnyClientsWriteBlocked = FALSE;
+    if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0)
+        AnyWritesPending = FALSE;
     FD_CLR(connection, &OutputPending);
 }
 
@@ -1112,6 +1115,7 @@ InitNotifyFds(void)
             RemoveNotifyFd(s->fd);
 
     xorg_list_init(&notify_fds);
+    NumNotifyWriteFd = 0;
     been_here = 1;
 }
 
@@ -1153,6 +1157,20 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data)
             FD_CLR(fd, &NotifyReadFds);
         }
     }
+
+    if (changes & X_NOTIFY_WRITE) {
+        if (mask & X_NOTIFY_WRITE) {
+            FD_SET(fd, &NotifyWriteFds);
+            if (!NumNotifyWriteFd++)
+                AnyWritesPending = TRUE;
+        } else {
+            FD_CLR(fd, &NotifyWriteFds);
+            if (!--NumNotifyWriteFd)
+                if (!XFD_ANYSET(&ClientsWriteBlocked))
+                    AnyWritesPending = FALSE;
+        }
+    }
+
     if (mask == 0) {
         xorg_list_del(&n->list);
         free(n);
@@ -1174,12 +1192,16 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data)
 void
 HandleNotifyFds(void)
 {
-    struct notify_fd *s, *next;
-
-    xorg_list_for_each_entry_safe(s, next, &notify_fds, list) {
-        if (FD_ISSET(s->fd, &LastSelectMask)) {
-            s->notify(s->fd, X_NOTIFY_READ, s->data);
-        }
+    struct notify_fd *n, *next;
+
+    xorg_list_for_each_entry_safe(n, next, &notify_fds, list) {
+        int ready = 0;
+        if ((n->mask & X_NOTIFY_READ) && FD_ISSET(n->fd, &LastSelectMask))
+            ready |= X_NOTIFY_READ;
+        if ((n->mask & X_NOTIFY_WRITE) & FD_ISSET(n->fd, &LastSelectWriteMask))
+            ready |= X_NOTIFY_WRITE;
+        if (ready != 0)
+            n->notify(n->fd, ready, n->data);
     }
 }
 
diff --git a/os/io.c b/os/io.c
index 971fdc9..19a449a 100644
--- a/os/io.c
+++ b/os/io.c
@@ -946,7 +946,7 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
                and not ready to accept more.  Make a note of it and buffer
                the rest. */
             FD_SET(connection, &ClientsWriteBlocked);
-            AnyClientsWriteBlocked = TRUE;
+            AnyWritesPending = TRUE;
 
             if (written < oco->count) {
                 if (written > 0) {
@@ -1009,10 +1009,10 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
     /* everything was flushed out */
     oco->count = 0;
     /* check to see if this client was write blocked */
-    if (AnyClientsWriteBlocked) {
+    if (AnyWritesPending) {
         FD_CLR(oc->fd, &ClientsWriteBlocked);
-        if (!XFD_ANYSET(&ClientsWriteBlocked))
-            AnyClientsWriteBlocked = FALSE;
+        if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0)
+            AnyWritesPending = FALSE;
     }
     if (oco->size > BUFWATERMARK) {
         free(oco->buf);
diff --git a/os/osdep.h b/os/osdep.h
index 2bfc783..2fbfc48 100644
--- a/os/osdep.h
+++ b/os/osdep.h
@@ -168,9 +168,11 @@ extern void HandleNotifyFds(void);
 extern fd_set AllSockets;
 extern fd_set AllClients;
 extern fd_set LastSelectMask;
+extern fd_set LastSelectWriteMask;
 extern fd_set WellKnownConnections;
 extern fd_set EnabledDevices;
 extern fd_set NotifyReadFds;
+extern fd_set NotifyWriteFds;
 extern fd_set ClientsWithInput;
 extern fd_set ClientsWriteBlocked;
 extern fd_set OutputPending;
@@ -185,7 +187,8 @@ extern void ClearConnectionTranslation(void);
 #endif
 
 extern Bool NewOutputPending;
-extern Bool AnyClientsWriteBlocked;
+extern Bool AnyWritesPending;
+extern Bool NumNotifyWriteFd;
 
 extern WorkQueuePtr workQueue;
 
commit 0c41b7af4ab0c8d22b88f201293f59524d1e7317
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:02 2015 -0800

    os: Add NotifyFd interfaces
    
    This provides a callback-based interface to monitor file
    descriptors beyond the usual client and device interfaces.
    
    Modules within the server using file descriptors for reading and/or
    writing can call
    
        Bool SetNotifyFd(int fd, NotifyFdProcPtr notify_fd, int mask, void *data);
    
    mask can be any combination of X_NOTIFY_READ and X_NOTIFY_WRITE.
    
    When 'fd' becomes readable or writable, the notify_fd function will be
    called with the 'fd', the ready conditions and 'data' values as arguments,
    
    When the module no longer needs to monitor the fd, it will call
    
        void RemoveNotifyFd(int fd);
    
    RemoveNotifyFd may be called from the notify function.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/os.h b/include/os.h
index 9937f2e..aed2e2f 100644
--- a/include/os.h
+++ b/include/os.h
@@ -154,6 +154,19 @@ extern _X_EXPORT void AddEnabledDevice(int /*fd */ );
 
 extern _X_EXPORT void RemoveEnabledDevice(int /*fd */ );
 
+typedef void (*NotifyFdProcPtr)(int fd, int ready, void *data);
+
+#define X_NOTIFY_NONE   0
+#define X_NOTIFY_READ   1
+#define X_NOTIFY_WRITE  2
+
+extern _X_EXPORT Bool SetNotifyFd(int fd, NotifyFdProcPtr notify_fd, int mask, void *data);
+
+static inline void RemoveNotifyFd(int fd)
+{
+    (void) SetNotifyFd(fd, NULL, X_NOTIFY_NONE, NULL);
+}
+
 extern _X_EXPORT int OnlyListenToOneClient(ClientPtr /*client */ );
 
 extern _X_EXPORT void ListenToAllClients(void);
diff --git a/os/WaitFor.c b/os/WaitFor.c
index 7325430..12b21bb 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -306,6 +306,10 @@ WaitForSomething(int *pClientsReady)
                 QueueWorkProc(EstablishNewConnections, NULL,
                               (void *) &LastSelectMask);
 
+            XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds);
+            if (XFD_ANYSET(&tmp_set))
+                HandleNotifyFds();
+
             if (XFD_ANYSET(&devicesReadable) || XFD_ANYSET(&clientsReadable))
                 break;
             /* check here for DDXes that queue events during Block/Wakeup */
diff --git a/os/connection.c b/os/connection.c
index 3d33c41..0df4391 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -123,6 +123,7 @@ static int lastfdesc;           /* maximum file descriptor */
 
 fd_set WellKnownConnections;    /* Listener mask */
 fd_set EnabledDevices;          /* mask for input devices that are on */
+fd_set NotifyReadFds;           /* mask for other file descriptors */
 fd_set AllSockets;              /* select on this */
 fd_set AllClients;              /* available clients */
 fd_set LastSelectMask;          /* mask returned from last select call */
@@ -1090,6 +1091,98 @@ RemoveEnabledDevice(int fd)
     RemoveGeneralSocket(fd);
 }
 
+struct notify_fd {
+    struct xorg_list list;
+    int fd;
+    int mask;
+    NotifyFdProcPtr notify;
+    void *data;
+};
+
+static struct xorg_list notify_fds;
+
+void
+InitNotifyFds(void)
+{
+    struct notify_fd *s, *next;
+    static int been_here;
+
+    if (been_here)
+        xorg_list_for_each_entry_safe(s, next, &notify_fds, list)
+            RemoveNotifyFd(s->fd);
+
+    xorg_list_init(&notify_fds);
+    been_here = 1;
+}
+
+/*****************
+ * SetNotifyFd
+ *    Registers a callback to be invoked when the specified
+ *    file descriptor becomes readable.
+ *****************/
+
+Bool
+SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data)
+{
+    struct notify_fd *n;
+    int changes;
+
+    xorg_list_for_each_entry(n, &notify_fds, list)
+        if (n->fd == fd)
+            break;
+
+    if (&n->list == &notify_fds) {
+        if (mask == 0)
+            return TRUE;
+
+        n = calloc(1, sizeof (struct notify_fd));
+        if (!n)
+            return FALSE;
+        n->fd = fd;
+        xorg_list_add(&n->list, &notify_fds);
+    }
+
+    changes = n->mask ^ mask;
+
+    if (changes & X_NOTIFY_READ) {
+        if (mask & X_NOTIFY_READ) {
+            FD_SET(fd, &NotifyReadFds);
+            AddGeneralSocket(fd);
+        } else {
+            RemoveGeneralSocket(fd);
+            FD_CLR(fd, &NotifyReadFds);
+        }
+    }
+    if (mask == 0) {
+        xorg_list_del(&n->list);
+        free(n);
+    } else {
+        n->mask = mask;
+        n->data = data;
+        n->notify = notify;
+    }
+
+    return TRUE;
+}
+
+/*****************
+ * HandlNotifyFds
+ *    A WorkProc to be called when any of the registered
+ *    file descriptors are readable.
+ *****************/
+
+void
+HandleNotifyFds(void)
+{
+    struct notify_fd *s, *next;
+
+    xorg_list_for_each_entry_safe(s, next, &notify_fds, list) {
+        if (FD_ISSET(s->fd, &LastSelectMask)) {
+            s->notify(s->fd, X_NOTIFY_READ, s->data);
+        }
+    }
+}
+
 /*****************
  * OnlyListenToOneClient:
  *    Only accept requests from  one client.  Continue to handle new
diff --git a/os/osdep.h b/os/osdep.h
index 86263a5..2bfc783 100644
--- a/os/osdep.h
+++ b/os/osdep.h
@@ -159,6 +159,10 @@ extern int FlushClient(ClientPtr /*who */ ,
 extern void FreeOsBuffers(OsCommPtr     /*oc */
     );
 
+extern void InitNotifyFds(void);
+
+extern void HandleNotifyFds(void);
+
 #include "dix.h"
 
 extern fd_set AllSockets;
@@ -166,6 +170,7 @@ extern fd_set AllClients;
 extern fd_set LastSelectMask;
 extern fd_set WellKnownConnections;
 extern fd_set EnabledDevices;
+extern fd_set NotifyReadFds;
 extern fd_set ClientsWithInput;
 extern fd_set ClientsWriteBlocked;
 extern fd_set OutputPending;
diff --git a/os/osinit.c b/os/osinit.c
index 6ec2f11..54b39a0 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -314,6 +314,7 @@ OsInit(void)
         LockServer();
         been_here = TRUE;
     }
+    InitNotifyFds();
     TimerInit();
     OsVendorInit();
     OsResetSignals();
commit e10ba9e4b52269b2ac75c4802dce4ca47d169657
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:01 2015 -0800

    Remove non-smart scheduler. Don't require setitimer.
    
    This allows the server to call GetTimeInMillis() after each request is
    processed to avoid needing setitimer. -dumbSched now turns off the
    setitimer.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 14a5bb8..2e38efa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -218,7 +218,7 @@ 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 seteuid shmctl64 strncasecmp vasprintf vsnprintf walkcontext setitimer])
 AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup])
 
 AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]])
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 2c20124..53032dc 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -222,11 +222,11 @@ UpdateCurrentTimeIf(void)
 #define SMART_SCHEDULE_DEFAULT_INTERVAL	5
 #define SMART_SCHEDULE_MAX_SLICE	15
 
-#if defined(WIN32) && !defined(__CYGWIN__)
-Bool SmartScheduleDisable = TRUE;
-#else
-Bool SmartScheduleDisable = FALSE;
+#ifdef HAVE_SETITIMER
+#define SMART_SCHEDULE_DEFAULT_SIGNAL_ENABLE HAVE_SETITIMER
+Bool SmartScheduleSignalEnable = SMART_SCHEDULE_DEFAULT_SIGNAL_ENABLE;
 #endif
+
 long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
 long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
 long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
@@ -358,7 +358,7 @@ Dispatch(void)
 
         nready = WaitForSomething(clientReady);
 
-        if (nready && !SmartScheduleDisable) {
+        if (nready) {
             clientReady[0] = SmartScheduleClient(clientReady, nready);
             nready = 1;
         }
@@ -386,8 +386,8 @@ Dispatch(void)
                     ProcessInputEvents();
 
                 FlushIfCriticalOutputPending();
-                if (!SmartScheduleDisable &&
-                    (SmartScheduleTime - start_tick) >= SmartScheduleSlice) {
+                if ((SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+                {
                     /* Penalize clients which consume ticks */
                     if (client->smart_priority > SMART_MIN_PRIORITY)
                         client->smart_priority--;
@@ -431,6 +431,9 @@ Dispatch(void)
                             (*client->requestVector[client->majorOp]) (client);
                     XaceHookAuditEnd(client, result);
                 }
+                if (!SmartScheduleSignalEnable)
+                    SmartScheduleTime = GetTimeInMillis();
+
 #ifdef XSERVER_DTRACE
                 if (XSERVER_REQUEST_DONE_ENABLED())
                     XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp),
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 112ab95..940d2b7 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 setitimer support */
+#undef HAVE_SETITIMER
+
 #endif /* _DIX_CONFIG_H_ */
diff --git a/include/dixstruct.h b/include/dixstruct.h
index 7575066..8e70ae1 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -130,7 +130,11 @@ extern long SmartScheduleTime;
 extern long SmartScheduleInterval;
 extern long SmartScheduleSlice;
 extern long SmartScheduleMaxSlice;
-extern Bool SmartScheduleDisable;
+#if HAVE_SETITIMER
+extern Bool SmartScheduleSignalEnable;
+#else
+#define SmartScheduleSignalEnable FALSE
+#endif
 extern void SmartScheduleStartTimer(void);
 extern void SmartScheduleStopTimer(void);
 
diff --git a/os/WaitFor.c b/os/WaitFor.c
index 993c14e..7325430 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -175,16 +175,10 @@ WaitForSomething(int *pClientsReady)
         if (workQueue)
             ProcessWorkQueue();
         if (XFD_ANYSET(&ClientsWithInput)) {
-            if (!SmartScheduleDisable) {
-                someReady = TRUE;
-                waittime.tv_sec = 0;
-                waittime.tv_usec = 0;
-                wt = &waittime;
-            }
-            else {
-                XFD_COPYSET(&ClientsWithInput, &clientsReadable);
-                break;
-            }
+            someReady = TRUE;
+            waittime.tv_sec = 0;
+            waittime.tv_usec = 0;
+            wt = &waittime;
         }
         if (someReady) {
             XFD_COPYSET(&AllSockets, &LastSelectMask);
diff --git a/os/io.c b/os/io.c
index 55644ea..971fdc9 100644
--- a/os/io.c
+++ b/os/io.c
@@ -462,23 +462,14 @@ ReadRequestFromClient(ClientPtr client)
             )
             FD_SET(fd, &ClientsWithInput);
         else {
-            if (!SmartScheduleDisable)
-                FD_CLR(fd, &ClientsWithInput);
-            else
-                YieldControlNoInput(fd);
+            FD_CLR(fd, &ClientsWithInput);
         }
     }
     else {
         if (!gotnow)
             AvailableInput = oc;
-        if (!SmartScheduleDisable)
-            FD_CLR(fd, &ClientsWithInput);
-        else
-            YieldControlNoInput(fd);
+        FD_CLR(fd, &ClientsWithInput);
     }
-    if (SmartScheduleDisable)
-        if (++timesThisConnection >= MAX_TIMES_PER)
-            YieldControl();
     if (move_header) {
         request = (xReq *) oci->bufptr;
         oci->bufptr += (sizeof(xBigReq) - sizeof(xReq));
diff --git a/os/utils.c b/os/utils.c
index b45719e..ef7a2cc 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -71,7 +71,6 @@ __stdcall unsigned long GetTickCount(void);
 #if !defined(WIN32) || !defined(__MINGW32__)
 #include <sys/time.h>
 #include <sys/resource.h>
-# define SMART_SCHEDULE_POSSIBLE
 #endif
 #include "misc.h"
 #include <X11/X.h>
@@ -1005,10 +1004,11 @@ ProcessCommandLine(int argc, char *argv[])
             i = skip - 1;
         }
 #endif
-#ifdef SMART_SCHEDULE_POSSIBLE
+#if HAVE_SETITIMER
         else if (strcmp(argv[i], "-dumbSched") == 0) {
-            SmartScheduleDisable = TRUE;
+            SmartScheduleSignalEnable = FALSE;
         }
+#endif
         else if (strcmp(argv[i], "-schedInterval") == 0) {
             if (++i < argc) {
                 SmartScheduleInterval = atoi(argv[i]);
@@ -1024,7 +1024,6 @@ ProcessCommandLine(int argc, char *argv[])
             else
                 UseMsg();
         }
-#endif
         else if (strcmp(argv[i], "-render") == 0) {
             if (++i < argc) {
                 int policy = PictureParseCmapPolicy(argv[i]);
@@ -1208,10 +1207,10 @@ XNFstrdup(const char *s)
 void
 SmartScheduleStopTimer(void)
 {
-#ifdef SMART_SCHEDULE_POSSIBLE
+#if HAVE_SETITIMER
     struct itimerval timer;
 
-    if (SmartScheduleDisable)
+    if (!SmartScheduleSignalEnable)
         return;
     timer.it_interval.tv_sec = 0;
     timer.it_interval.tv_usec = 0;
@@ -1224,10 +1223,10 @@ SmartScheduleStopTimer(void)
 void
 SmartScheduleStartTimer(void)
 {
-#ifdef SMART_SCHEDULE_POSSIBLE
+#if HAVE_SETITIMER
     struct itimerval timer;
 
-    if (SmartScheduleDisable)
+    if (!SmartScheduleSignalEnable)
         return;
     timer.it_interval.tv_sec = 0;
     timer.it_interval.tv_usec = SmartScheduleInterval * 1000;
@@ -1237,6 +1236,7 @@ SmartScheduleStartTimer(void)
 #endif
 }
 
+#if HAVE_SETITIMER
 static void
 SmartScheduleTimer(int sig)
 {
@@ -1247,10 +1247,9 @@ static int
 SmartScheduleEnable(void)
 {
     int ret = 0;
-#ifdef SMART_SCHEDULE_POSSIBLE
     struct sigaction act;
 
-    if (SmartScheduleDisable)
+    if (!SmartScheduleSignalEnable)
         return 0;
 
     memset((char *) &act, 0, sizeof(struct sigaction));
@@ -1261,7 +1260,6 @@ SmartScheduleEnable(void)
     sigemptyset(&act.sa_mask);
     sigaddset(&act.sa_mask, SIGALRM);
     ret = sigaction(SIGALRM, &act, 0);
-#endif
     return ret;
 }
 
@@ -1269,10 +1267,9 @@ static int
 SmartSchedulePause(void)
 {
     int ret = 0;
-#ifdef SMART_SCHEDULE_POSSIBLE
     struct sigaction act;
 
-    if (SmartScheduleDisable)
+    if (!SmartScheduleSignalEnable)
         return 0;
 
     memset((char *) &act, 0, sizeof(struct sigaction));
@@ -1280,20 +1277,19 @@ SmartSchedulePause(void)
     act.sa_handler = SIG_IGN;
     sigemptyset(&act.sa_mask);
     ret = sigaction(SIGALRM, &act, 0);
-#endif
     return ret;
 }
+#endif
 
 void
 SmartScheduleInit(void)
 {
-    if (SmartScheduleDisable)
-        return;
-
+#if HAVE_SETITIMER
     if (SmartScheduleEnable() < 0) {
         perror("sigaction for smart scheduler");
-        SmartScheduleDisable = TRUE;
+        SmartScheduleSignalEnable = FALSE;
     }
+#endif
 }
 
 #ifdef SIG_BLOCK
@@ -1490,6 +1486,7 @@ Popen(const char *command, const char *type)
     }
 
     /* Ignore the smart scheduler while this is going on */
+#if HAVE_SETITIMER
     if (SmartSchedulePause() < 0) {
         close(pdes[0]);
         close(pdes[1]);
@@ -1497,14 +1494,17 @@ Popen(const char *command, const char *type)
         perror("signal");
         return NULL;
     }
+#endif
 
     switch (pid = fork()) {
     case -1:                   /* error */
         close(pdes[0]);
         close(pdes[1]);
         free(cur);
+#if HAVE_SETITIMER
         if (SmartScheduleEnable() < 0)
             perror("signal");
+#endif
         return NULL;
     case 0:                    /* child */
         if (setgid(getgid()) == -1)
@@ -1678,10 +1678,12 @@ Pclose(void *iop)
     /* allow EINTR again */
     OsReleaseSignals();
 
+#if HAVE_SETITIMER
     if (SmartScheduleEnable() < 0) {
         perror("signal");
         return -1;
     }
+#endif
 
     return pid == -1 ? -1 : pstat;
 }
commit c7f4aef8f45e500c900d59f68c653477148907ea
Author: agoins <agoins at nvidia.com>
Date:   Wed Nov 25 18:39:31 2015 -0800

    randr: Cleanup rrSetupPixmapSharing()
    
    protopix is completely redundant with mscreenpix. Get rid of it.
    
    We don't need rrScrPriv, so remove it.
    
    [ajax: also squash an unused variable in RRCrtcDetachScanoutPixmap,
    though it'll come back when the rest of this series lands]
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alex Goins <agoins at nvidia.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 6e459ed..8d9c5bb 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -379,11 +379,8 @@ void
 RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
 {
     ScreenPtr master = crtc->pScreen->current_master;
-    PixmapPtr mscreenpix;
     rrScrPriv(crtc->pScreen);
 
-    mscreenpix = master->GetScreenPixmap(master);
-
     pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL);
     if (crtc->scanout_pixmap) {
         rrDestroySharedPixmap(crtc, crtc->scanout_pixmap);
@@ -429,8 +426,6 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
     ScreenPtr master = crtc->pScreen->current_master;
     int depth;
     PixmapPtr mscreenpix;
-    PixmapPtr protopix = master->GetScreenPixmap(master);
-    rrScrPriv(crtc->pScreen);
     PixmapPtr spix;
 
     /* create a pixmap on the master screen,
@@ -442,7 +437,7 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
     */
 
     mscreenpix = master->GetScreenPixmap(master);
-    depth = protopix->drawable.depth;
+    depth = mscreenpix->drawable.depth;
 
     if (crtc->scanout_pixmap)
         RRCrtcDetachScanoutPixmap(crtc);
commit 8d3f0e964e399dcfa8eb5e85d405217fdc5dbcd4
Author: agoins <agoins at nvidia.com>
Date:   Wed Nov 25 18:39:27 2015 -0800

    xf86: Bump ABI version to 21
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alex Goins <agoins at nvidia.com>

diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index 9e5dc6d..7a8b7ab 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -80,7 +80,7 @@ typedef enum {
  * mask is 0xFFFF0000.
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
-#define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(20, 0)
+#define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(21, 0)
 #define ABI_XINPUT_VERSION	SET_ABI_VERSION(22, 1)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(9, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
commit 7006b4e7ff759c899d5391b7d12db889cbc0b535
Author: agoins <agoins at nvidia.com>
Date:   Wed Nov 25 18:39:26 2015 -0800

    randr: Factor out shared pixmap creation
    
    The old version of rrCreateSharedPixmap(), in addition to actually creating
    a shared pixmap with scanout, also set up pixmap tracking on the source
    driver.
    
    I will be needing to create multiple shared pixmaps for PRIME double
    buffering, so factor the part that does shared pixmap creation into its own
    function, the new rrCreateSharedPixmap(). Rename the old
    rrCreateSharedPixmap() to rrSetupPixmapSharing(), a function that
    replicates the old functionality of rrCreateSharedPixmap() using the new
    rrCreateSharedPixmap().
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alex Goins <agoins at nvidia.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index cbd03d0..6e459ed 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -392,17 +392,46 @@ RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
     RRCrtcChanged(crtc, TRUE);
 }
 
-static Bool
-rrCreateSharedPixmap(RRCrtcPtr crtc, int width, int height,
+static PixmapPtr
+rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master,
+                     int width, int height, int depth,
                      int x, int y, Rotation rotation)
 {
+    Bool ret;
     PixmapPtr mpix, spix;
+    rrScrPriv(crtc->pScreen);
+
+    mpix = master->CreatePixmap(master, width, height, depth,
+                                CREATE_PIXMAP_USAGE_SHARED);
+    if (!mpix)
+        return NULL;
+
+    spix = PixmapShareToSlave(mpix, crtc->pScreen);
+    if (spix == NULL) {
+        master->DestroyPixmap(mpix);
+        return NULL;
+    }
+
+    ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix);
+    if (ret == FALSE) {
+        rrDestroySharedPixmap(crtc, spix);
+        ErrorF("randr: failed to set shadow slave pixmap\n");
+        return NULL;
+    }
+
+    return spix;
+}
+
+static Bool
+rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
+                     int x, int y, Rotation rotation)
+{
     ScreenPtr master = crtc->pScreen->current_master;
-    Bool ret;
     int depth;
     PixmapPtr mscreenpix;
     PixmapPtr protopix = master->GetScreenPixmap(master);
     rrScrPriv(crtc->pScreen);
+    PixmapPtr spix;
 
     /* create a pixmap on the master screen,
        then get a shared handle for it
@@ -422,20 +451,10 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, int width, int height,
         return TRUE;
     }
 
-    mpix = master->CreatePixmap(master, width, height, depth,
-                                CREATE_PIXMAP_USAGE_SHARED);
-    if (!mpix)
-        return FALSE;
-
-    spix = PixmapShareToSlave(mpix, crtc->pScreen);
+    spix = rrCreateSharedPixmap(crtc, master,
+                                width, height, depth,
+                                x, y, rotation);
     if (spix == NULL) {
-        master->DestroyPixmap(mpix);
-        return FALSE;
-    }
-
-    ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix);
-    if (ret == FALSE) {
-        ErrorF("randr: failed to set shadow slave pixmap\n");
         return FALSE;
     }
 
@@ -599,7 +618,7 @@ RRCrtcSet(RRCrtcPtr crtc,
                 return FALSE;
 
             if (pScreen->current_master) {
-                ret = rrCreateSharedPixmap(crtc, width, height, x, y, rotation);
+                ret = rrSetupPixmapSharing(crtc, width, height, x, y, rotation);
             }
         }
 #if RANDR_12_INTERFACE
commit cf5d6414e0c21140f763d618bde1e91ad2b1cb49
Author: agoins <agoins at nvidia.com>
Date:   Wed Nov 25 18:39:25 2015 -0800

    randr: Factor out shared pixmap destruction
    
    Shared pixmap destruction is done by unrefing the master pixmap twice: once
    for the original reference, and once for the reference implicitly added by
    PixmapShareToSlave. Then, unrefing the slave pixmap once.
    
    When I add PRIME double buffering and synchronization, I will need to do
    this in multiple places. To avoid duplication of code and comments
    explaining it everywhere, factor it out into its own function and use that
    in place of where it was before.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alex Goins <agoins at nvidia.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 9bc456b..cbd03d0 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -361,6 +361,20 @@ RRComputeContiguity(ScreenPtr pScreen)
     pScrPriv->discontiguous = discontiguous;
 }
 
+static void
+rrDestroySharedPixmap(RRCrtcPtr crtc, PixmapPtr pPixmap) {
+    if (crtc->pScreen->current_master && pPixmap->master_pixmap) {
+        /*
+         * Unref the pixmap twice: once for the original reference, and once
+         * for the reference implicitly added by PixmapShareToSlave.
+         */
+        crtc->pScreen->current_master->DestroyPixmap(pPixmap->master_pixmap);
+        crtc->pScreen->current_master->DestroyPixmap(pPixmap->master_pixmap);
+    }
+
+    crtc->pScreen->DestroyPixmap(pPixmap);
+}
+
 void
 RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
 {
@@ -372,14 +386,7 @@ RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
 
     pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL);
     if (crtc->scanout_pixmap) {
-        master->StopPixmapTracking(mscreenpix, crtc->scanout_pixmap);
-        /*
-         * Unref the pixmap twice: once for the original reference, and once
-         * for the reference implicitly added by PixmapShareToSlave.
-         */
-        master->DestroyPixmap(crtc->scanout_pixmap->master_pixmap);
-        master->DestroyPixmap(crtc->scanout_pixmap->master_pixmap);
-        crtc->pScreen->DestroyPixmap(crtc->scanout_pixmap);
+        rrDestroySharedPixmap(crtc, crtc->scanout_pixmap);
     }
     crtc->scanout_pixmap = NULL;
     RRCrtcChanged(crtc, TRUE);
commit ab9837cc6a11f46b9df780f131b69de3822c3dd9
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Dec 1 17:16:03 2015 +0100

    xwayland: Update screen size on output removal
    
    When unplugging an output, it's still listed in xrandr and the size
    of the root window still includes the removed output.
    
    The RR output should be destroyed when its Wayland counterpart is
    destroyed and the screen dimensions must be updated in both the done
    and the destroy handlers.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92914
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Marek Chalupa <mchqwerty at gmail.com>

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 8b2f8cb..e9ec190 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -159,33 +159,11 @@ approximate_mmpd(struct xwl_screen *xwl_screen)
 }
 
 static void
-output_handle_done(void *data, struct wl_output *wl_output)
+update_screen_size(struct xwl_output *xwl_output, int width, int height)
 {
-    struct xwl_output *it, *xwl_output = data;
     struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
-    int width = 0, height = 0, has_this_output = 0;
     double mmpd;
 
-    xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
-        /* output done event is sent even when some property
-         * of output is changed. That means that we may already
-         * have this output. If it is true, we must not add it
-         * into the output_list otherwise we'll corrupt it */
-        if (it == xwl_output)
-            has_this_output = 1;
-
-        output_get_new_size(it, &height, &width);
-    }
-
-    if (!has_this_output) {
-        xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
-
-        /* we did not check this output for new screen size, do it now */
-        output_get_new_size(xwl_output, &height, &width);
-
-	--xwl_screen->expecting_event;
-    }
-
     if (!xwl_screen->rootless)
         SetRootClip(xwl_screen->screen, FALSE);
 
@@ -216,6 +194,36 @@ output_handle_done(void *data, struct wl_output *wl_output)
 }
 
 static void
+output_handle_done(void *data, struct wl_output *wl_output)
+{
+    struct xwl_output *it, *xwl_output = data;
+    struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
+    int width = 0, height = 0, has_this_output = 0;
+
+    xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
+        /* output done event is sent even when some property
+         * of output is changed. That means that we may already
+         * have this output. If it is true, we must not add it
+         * into the output_list otherwise we'll corrupt it */
+        if (it == xwl_output)
+            has_this_output = 1;
+
+        output_get_new_size(it, &height, &width);
+    }
+
+    if (!has_this_output) {
+        xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
+
+        /* we did not check this output for new screen size, do it now */
+        output_get_new_size(xwl_output, &height, &width);
+
+	--xwl_screen->expecting_event;
+    }
+
+    update_screen_size(xwl_output, width, height);
+}
+
+static void
 output_handle_scale(void *data, struct wl_output *wl_output, int32_t factor)
 {
 }
@@ -284,8 +292,18 @@ err:
 void
 xwl_output_destroy(struct xwl_output *xwl_output)
 {
+    struct xwl_output *it;
+    struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
+    int width = 0, height = 0;
+
     wl_output_destroy(xwl_output->output);
     xorg_list_del(&xwl_output->link);
+    RROutputDestroy(xwl_output->randr_output);
+
+    xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
+        output_get_new_size(it, &height, &width);
+    update_screen_size(xwl_output, width, height);
+
     free(xwl_output);
 }
 
commit 07941a50a547f2ca094e242588298695f48903ed
Author: Jonas Ã…dahl <jadahl at gmail.com>
Date:   Wed Oct 7 12:01:53 2015 +0800

    xwayland: Always update the wl_pointer cursor on pointer focus
    
    In Wayland, a client (in this case XWayland) should set the cursor
    surface when it receives pointer focus. Not doing this will leave the
    curser at whatever it was previously.
    
    When running on XWayland, the X server will not be the entity that
    controls what actual pointer cursor is displayed, and it wont be notified
    about the pointer cursor changes done by the Wayland compositor. This
    causes X11 clients running via XWayland to end up with incorrect pointer
    cursors because the X server believes that, if the cursor was previously
    set to the cursor C, if we receive Wayland pointer focus over window W
    which also has the pointer cursor C, we do not need to update it. This
    will cause us to end up with the wrong cursor if cursor C was not the
    same one that was already set by the Wayland compositor.
    
    This patch works around this by, when receiving pointer focus, getting
    the private mipointer struct changing the "current sprite" pointer to
    an invalid cursor in order to trigger the update path next time a cursor
    is displayed by dix.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Jonas Ã…dahl <jadahl at gmail.com>

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 473f306..61ca70b 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -32,6 +32,14 @@
 #include <xkbsrv.h>
 #include <xserver-properties.h>
 #include <inpututils.h>
+#include <mipointer.h>
+#include <mipointrst.h>
+
+/* Copied from mipointer.c */
+#define MIPOINTER(dev) \
+    (IsFloating(dev) ? \
+        (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \
+        (miPointerPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miPointerPrivKey))
 
 static void
 xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl)
@@ -210,6 +218,8 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
 {
     struct xwl_seat *xwl_seat = data;
     DeviceIntPtr dev = xwl_seat->pointer;
+    DeviceIntPtr master;
+    miPointerPtr mipointer;
     int i;
     int sx = wl_fixed_to_int(sx_w);
     int sy = wl_fixed_to_int(sy_w);
@@ -230,8 +240,18 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
 
     xwl_seat->focus_window = wl_surface_get_user_data(surface);
 
+    master = GetMaster(dev, POINTER_OR_FLOAT);
     (*pScreen->SetCursorPosition) (dev, pScreen, sx, sy, TRUE);
-    CheckMotion(NULL, GetMaster(dev, POINTER_OR_FLOAT));
+
+    /* X is very likely to have the wrong idea of what the actual cursor
+     * sprite is, so in order to force updating the cursor lets set the
+     * current sprite to some invalid cursor behind its back so that it
+     * always will think it changed to the not invalid cursor.
+     */
+    mipointer = MIPOINTER(master);
+    mipointer->pSpriteCursor = (CursorPtr) 1;
+
+    CheckMotion(NULL, master);
 
     /* Ideally, X clients shouldn't see these button releases.  When
      * the pointer leaves a window with buttons down, it means that
commit 51a4399b94f9adfac5f7718d4cbf73f793dcca56
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Mon Nov 23 08:51:48 2015 +0100

    xwayland: Do not set root clip when rootless
    
    Otherwise the server may try to draw onto the root window when closing
    down, but when running rootless the root window has no storage thus
    causing a memory corruption.
    
    Thanks to Adam Jackson <ajax at redhat.com> for helping tracking this down!
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93045
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Tested-by: Marek Chalupa <mchqwerty at gmail.com>

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index ebaf05a..c357217 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -233,9 +233,11 @@ xwl_glamor_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_glamor_create_pixmap(screen, screen->width, screen->height,
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 260c9dc..8b2f8cb 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -186,7 +186,7 @@ output_handle_done(void *data, struct wl_output *wl_output)
 	--xwl_screen->expecting_event;
     }
 
-    if (xwl_screen->screen->root)
+    if (!xwl_screen->rootless)
         SetRootClip(xwl_screen->screen, FALSE);
 
     xwl_screen->width = width;
@@ -206,11 +206,13 @@ output_handle_done(void *data, struct wl_output *wl_output)
     if (xwl_screen->screen->root) {
         xwl_screen->screen->root->drawable.width = width;
         xwl_screen->screen->root->drawable.height = height;
-        SetRootClip(xwl_screen->screen, TRUE);
         RRScreenSizeNotify(xwl_screen->screen);
     }
 
     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 1022c0d..7072be4 100644
--- a/hw/xwayland/xwayland-shm.c
+++ b/hw/xwayland/xwayland-shm.c
@@ -279,9 +279,11 @@ 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,
commit 5b2ca3413203210d112a08a4e20d14382abae437
Author: Marek Chalupa <mchqwerty at gmail.com>
Date:   Fri Nov 27 14:27:46 2015 +0100

    xwayland: check if creating xwl_output succeeded
    
    check return values of RR.*Create calls
    
    v2. do not bail out if we don't have any output
    
    Signed-off-by: Marek Chalupa <mchqwerty at gmail.com>
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index e4623d4..260c9dc 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -240,6 +240,11 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
 
     xwl_output->output = wl_registry_bind(xwl_screen->registry, id,
                                           &wl_output_interface, 2);
+    if (!xwl_output->output) {
+        ErrorF("Failed binding wl_output\n");
+        goto err;
+    }
+
     xwl_output->server_output_id = id;
     wl_output_add_listener(xwl_output->output, &output_listener, xwl_output);
 
@@ -247,13 +252,31 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
 
     xwl_output->xwl_screen = xwl_screen;
     xwl_output->randr_crtc = RRCrtcCreate(xwl_screen->screen, xwl_output);
+    if (!xwl_output->randr_crtc) {
+        ErrorF("Failed creating RandR CRTC\n");
+        goto err;
+    }
+
     xwl_output->randr_output = RROutputCreate(xwl_screen->screen, name,
                                               strlen(name), xwl_output);
+    if (!xwl_output->randr_output) {
+        ErrorF("Failed creating RandR Output\n");
+        goto err;
+    }
+
     RRCrtcGammaSetSize(xwl_output->randr_crtc, 256);
     RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1);
     RROutputSetConnection(xwl_output->randr_output, RR_Connected);
 
     return xwl_output;
+
+err:
+    if (xwl_output->randr_crtc)
+        RRCrtcDestroy(xwl_output->randr_crtc);
+    if (xwl_output->output)
+        wl_output_destroy(xwl_output->output);
+    free(xwl_output);
+    return NULL;
 }
 
 void
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 1ce5868..55bf6d0 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -421,8 +421,8 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
             wl_registry_bind(registry, id, &wl_shell_interface, 1);
     }
     else if (strcmp(interface, "wl_output") == 0 && version >= 2) {
-        xwl_output_create(xwl_screen, id);
-        xwl_screen->expecting_event++;
+        if (xwl_output_create(xwl_screen, id))
+            xwl_screen->expecting_event++;
     }
 #ifdef GLAMOR_HAS_GBM
     else if (xwl_screen->glamor &&
commit 646ebea456b4c5251ae997eab8d9b971f97de836
Author: Marek Chalupa <mchqwerty at gmail.com>
Date:   Fri Nov 27 14:59:27 2015 +0100

    xwayland: fix memory leaks on error paths in xwl_realize_window
    
    don't leak memory when realizing window fails
    
    v2. take care of all memory allocation and return values,
        not just one leak
    
    Signed-off-by: Marek Chalupa <mchqwerty at gmail.com>
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index e31becf..1ce5868 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -233,23 +233,36 @@ xwl_realize_window(WindowPtr window)
     }
 
     xwl_window = calloc(sizeof *xwl_window, 1);
+    if (xwl_window == NULL)
+        return FALSE;
+
     xwl_window->xwl_screen = xwl_screen;
     xwl_window->window = window;
     xwl_window->surface = wl_compositor_create_surface(xwl_screen->compositor);
     if (xwl_window->surface == NULL) {
         ErrorF("wl_display_create_surface failed\n");
-        return FALSE;
+        goto err;
     }
 
     if (!xwl_screen->rootless) {
         xwl_window->shell_surface =
             wl_shell_get_shell_surface(xwl_screen->shell, xwl_window->surface);
+        if (xwl_window->shell_surface == NULL) {
+            ErrorF("Failed creating shell surface\n");
+            goto err_surf;
+        }
+
         wl_shell_surface_add_listener(xwl_window->shell_surface,
                                       &shell_surface_listener, xwl_window);
 
         wl_shell_surface_set_toplevel(xwl_window->shell_surface);
 
         region = wl_compositor_create_region(xwl_screen->compositor);
+        if (region == NULL) {
+            ErrorF("Failed creating region\n");
+            goto err_surf;
+        }
+
         wl_region_add(region, 0, 0,
                       window->drawable.width, window->drawable.height);
         wl_surface_set_opaque_region(xwl_window->surface, region);
@@ -262,17 +275,29 @@ xwl_realize_window(WindowPtr window)
 
     wl_surface_set_user_data(xwl_window->surface, xwl_window);
 
-    dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window);
-
     xwl_window->damage =
         DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty,
                      FALSE, screen, xwl_window);
+    if (xwl_window->damage == NULL) {
+        ErrorF("Failed creating damage\n");
+        goto err_surf;
+    }
+
     DamageRegister(&window->drawable, xwl_window->damage);
     DamageSetReportAfterOp(xwl_window->damage, TRUE);
 
+    dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window);
     xorg_list_init(&xwl_window->link_damage);
 
     return ret;
+
+err_surf:
+    if (xwl_window->shell_surface)
+        wl_shell_surface_destroy(xwl_window->shell_surface);
+    wl_surface_destroy(xwl_window->surface);
+err:
+    free(xwl_window);
+    return FALSE;
 }
 
 static Bool
commit e6b106715f24112d1dc7a84c6e37df4b5debb2d0
Author: Richard PALO <richard at NetBSD.org>
Date:   Tue Nov 17 07:02:07 2015 +0100

    Replace 'sun' with '__sun'
    
    Globally replace #ifdef and #if defined usage of 'sun' with '__sun'
    such that strict ISO compiler modes such as -ansi or -std=c99 can be used.
    
    Signed-off-by: Richard PALO <richard at NetBSD.org>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index d5741f1..84b980f 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -34,7 +34,7 @@
 #endif
 #include <signal.h>
 #include <stdio.h>
-#ifdef sun
+#ifdef __sun
 #include <sys/file.h>           /* needed for FNONBLOCK & FASYNC */
 #endif
 
diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 6b8d0eb..e6ab900 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -45,7 +45,7 @@
 #include "xf86sbusBus.h"
 #endif
 
-#ifdef sun
+#ifdef __sun
 #include <sys/visual_io.h>
 #include <ctype.h>
 #endif
@@ -202,7 +202,7 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
 #ifdef XSERVER_PLATFORM_BUS
     i = xf86PlatformMatchDriver(matches, nmatches);
 #endif
-#ifdef sun
+#ifdef __sun
     /* Check for driver type based on /dev/fb type and if valid, use
        it instead of PCI bus probe results */
     if (xf86Info.consoleFd >= 0 && (i < (nmatches - 1))) {
@@ -271,7 +271,7 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
     matches[i++] = xnfstrdup("modesetting");
 #endif
 
-#if !defined(sun)
+#if !defined(__sun)
     /* Fallback to platform default frame buffer driver */
     if (i < (nmatches - 1)) {
 #if !defined(__linux__) && defined(__sparc__)
@@ -280,13 +280,13 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
         matches[i++] = xnfstrdup("fbdev");
 #endif
     }
-#endif                          /* !sun */
+#endif                          /* !__sun */
 
     /* Fallback to platform default hardware */
     if (i < (nmatches - 1)) {
 #if defined(__i386__) || defined(__amd64__) || defined(__hurd__)
         matches[i++] = xnfstrdup("vesa");
-#elif defined(__sparc__) && !defined(sun)
+#elif defined(__sparc__) && !defined(__sun)
         matches[i++] = xnfstrdup("sunffb");
 #endif
     }
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index 93a35b8..86bf15d 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -98,7 +98,7 @@ xf86InfoRec xf86Info = {
     .vtno = -1,
     .lastEventTime = -1,
     .vtRequestsPending = FALSE,
-#ifdef sun
+#ifdef __sun
     .vtPendingNum = -1,
 #endif
     .dontVTSwitch = FALSE,
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index cffa14d..2eefeaf 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -55,7 +55,7 @@ typedef struct {
     /* event handler part */
     int lastEventTime;
     Bool vtRequestsPending;
-#ifdef sun
+#ifdef __sun
     int vtPendingNum;
 #endif
     Bool dontVTSwitch;
diff --git a/hw/xfree86/common/xf86cmap.c b/hw/xfree86/common/xf86cmap.c
index 704e353..ba0b277 100644
--- a/hw/xfree86/common/xf86cmap.c
+++ b/hw/xfree86/common/xf86cmap.c
@@ -29,7 +29,7 @@
 #include <xorg-config.h>
 #endif
 
-#if defined(_XOPEN_SOURCE) || defined(sun) && defined(__SVR4)
+#if defined(_XOPEN_SOURCE) || defined(__sun) && defined(__SVR4)
 #include <math.h>
 #else
 #define _XOPEN_SOURCE           /* to get prototype for pow on some systems */
diff --git a/hw/xfree86/loader/os.c b/hw/xfree86/loader/os.c
index e3a9ac4..8d03721 100644
--- a/hw/xfree86/loader/os.c
+++ b/hw/xfree86/loader/os.c
@@ -50,7 +50,7 @@
 #define OSNAME "openbsd"
 #elif defined(__GNU__)
 #define OSNAME "hurd"
-#elif defined(SVR4) && defined(sun)
+#elif defined(SVR4) && defined(__sun)
 #define OSNAME "solaris"
 #elif defined(SVR5)
 #define OSNAME "svr5"
diff --git a/hw/xfree86/os-support/bus/Sbus.c b/hw/xfree86/os-support/bus/Sbus.c
index 86b4d68..a526577 100644
--- a/hw/xfree86/os-support/bus/Sbus.c
+++ b/hw/xfree86/os-support/bus/Sbus.c
@@ -31,7 +31,7 @@
 #include <stdlib.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
-#ifdef sun
+#ifdef __sun
 #include <sys/utsname.h>
 #endif
 #include "xf86.h"
@@ -173,7 +173,7 @@ promIsP1275(void)
             break;
         }
     fclose(f);
-#elif defined(sun)
+#elif defined(__sun)
     struct utsname buffer;
 
     if ((uname(&buffer) >= 0) && !strcmp(buffer.machine, "sun4u"))
diff --git a/hw/xfree86/os-support/xf86_OSlib.h b/hw/xfree86/os-support/xf86_OSlib.h
index c7b295a..5d78c66 100644
--- a/hw/xfree86/os-support/xf86_OSlib.h
+++ b/hw/xfree86/os-support/xf86_OSlib.h
@@ -84,7 +84,7 @@
 /* SYSV386 (SVR3, SVR4), including Solaris                                */
 /**************************************************************************/
 #if (defined(SYSV) || defined(SVR4)) && \
-    (defined(sun) || defined(__i386__))
+    (defined(__sun) || defined(__i386__))
 #include <sys/ioctl.h>
 #include <signal.h>
 #include <termio.h>
@@ -94,21 +94,21 @@
 #include <errno.h>
 
 #if defined(_NEED_SYSI86)
-#if !(defined (sun) && defined (SVR4))
+#if !(defined (__sun) && defined (SVR4))
 #include <sys/immu.h>
 #include <sys/region.h>
 #include <sys/proc.h>
 #endif
 #include <sys/tss.h>
 #include <sys/sysi86.h>
-#if defined(SVR4) && !defined(sun)
+#if defined(SVR4) && !defined(__sun)
 #include <sys/seg.h>
-#endif                          /* SVR4 && !sun */
+#endif                          /* SVR4 && !__sun */
 /* V86SC_IOPL was moved to <sys/sysi86.h> on Solaris 7 and later */
 #if !defined(V86SC_IOPL)        /* Solaris 7 or later? */
 #include <sys/v86.h>            /* Nope */
 #endif
-#if defined(sun) && (defined (__i386__) || defined(__i386) || defined(__x86))  && defined (SVR4)
+#if defined(__sun) && (defined (__i386__) || defined(__i386) || defined(__x86))  && defined (SVR4)
 #include <sys/psw.h>
 #endif
 #endif                          /* _NEED_SYSI86 */
@@ -122,14 +122,14 @@
 #include <sys/mmap.h>           /* MMAP driver header */
 #endif
 
-#if !defined(sun) || defined(HAVE_SYS_VT_H)
+#if !defined(__sun) || defined(HAVE_SYS_VT_H)
 #define HAS_USL_VTS
 #endif
-#if !defined(sun)
+#if !defined(__sun)
 #include <sys/emap.h>
 #endif
 #if   defined(HAS_USL_VTS)
-#if !defined(sun)
+#if !defined(__sun)
 #include <sys/at_ansi.h>
 #endif
 #include <sys/kd.h>
@@ -139,7 +139,7 @@ extern _X_HIDDEN void xf86VTAcquire(int);
 extern _X_HIDDEN void xf86VTRelease(int);
 #endif
 
-#if defined(sun)
+#if defined(__sun)
 #include <sys/fbio.h>
 extern _X_HIDDEN char xf86SolarisFbDev[PATH_MAX];
 
@@ -156,7 +156,7 @@ extern _X_HIDDEN char xf86SolarisFbDev[PATH_MAX];
 #define LED_NUM LED_NUM_LOCK
 #define LED_SCR LED_SCROLL_LOCK
 #define LED_COMP LED_COMPOSE
-#endif                          /* sun */
+#endif                          /* __sun */
 
 #if !defined(VT_ACKACQ)
 #define VT_ACKACQ 2
@@ -164,7 +164,7 @@ extern _X_HIDDEN char xf86SolarisFbDev[PATH_MAX];
 
 #if defined(SVR4)
 #include <sys/mman.h>
-#if !(defined(sun) && defined (SVR4))
+#if !(defined(__sun) && defined (SVR4))
 #define DEV_MEM "/dev/pmem"
 #endif
 #define CLEARDTR_SUPPORT
diff --git a/os/access.c b/os/access.c
index 2499a9f..10a48c3 100644
--- a/os/access.c
+++ b/os/access.c
@@ -112,7 +112,7 @@ SOFTWARE.
 
 #ifdef HAVE_GETPEERUCRED
 #include <ucred.h>
-#ifdef sun
+#ifdef __sun
 #include <zone.h>
 #endif
 #endif
@@ -162,7 +162,7 @@ SOFTWARE.
  * Test for Solaris commented out  --  TSI @ UQV  2003.06.13
  */
 #ifdef SIOCGLIFCONF
-/* #if defined(sun) */
+/* #if defined(__sun) */
 #define USE_SIOCGLIFCONF
 /* #endif */
 #endif
@@ -383,7 +383,7 @@ AccessUsingXdmcp(void)
     LocalHostEnabled = FALSE;
 }
 
-#if  defined(SVR4) && !defined(sun)  && defined(SIOCGIFCONF) && !defined(USE_SIOCGLIFCONF)
+#if  defined(SVR4) && !defined(__sun)  && defined(SIOCGIFCONF) && !defined(USE_SIOCGLIFCONF)
 
 /* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
 
@@ -1145,7 +1145,7 @@ GetLocalClientCreds(ClientPtr client, LocalClientCredRec ** lccp)
     if (client == NULL)
         return -1;
     ci = ((OsCommPtr) client->osPrivate)->trans_conn;
-#if !(defined(sun) && defined(HAVE_GETPEERUCRED))
+#if !(defined(__sun) && defined(HAVE_GETPEERUCRED))
     /* Most implementations can only determine peer credentials for Unix
      * domain sockets - Solaris getpeerucred can work with a bit more, so
      * we just let it tell us if the connection type is supported or not
diff --git a/os/backtrace.c b/os/backtrace.c
index fd129ef..9e3e38e 100644
--- a/os/backtrace.c
+++ b/os/backtrace.c
@@ -155,7 +155,7 @@ xorg_backtrace(void)
 
 #else                           /* not glibc or glibc < 2.1 */
 
-#if defined(sun) && defined(__SVR4)
+#if defined(__sun) && defined(__SVR4)
 #define HAVE_PSTACK
 #endif
 
diff --git a/os/io.c b/os/io.c
index 96a243d..55644ea 100644
--- a/os/io.c
+++ b/os/io.c
@@ -368,7 +368,7 @@ ReadRequestFromClient(ClientPtr client)
                                  oci->size - oci->bufcnt);
         if (result <= 0) {
             if ((result < 0) && ETEST(errno)) {
-#if defined(SVR4) && defined(__i386__) && !defined(sun)
+#if defined(SVR4) && defined(__i386__) && !defined(__sun)
                 if (0)
 #endif
                 {
diff --git a/os/rpcauth.c b/os/rpcauth.c
index 413cc61..5680489 100644
--- a/os/rpcauth.c
+++ b/os/rpcauth.c
@@ -46,7 +46,7 @@ from The Open Group.
 
 #include <rpc/rpc.h>
 
-#ifdef sun
+#ifdef __sun
 /* <rpc/auth.h> only includes this if _KERNEL is #defined... */
 extern bool_t xdr_opaque_auth(XDR *, struct opaque_auth *);
 #endif
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index 30e10bd..9c772f5 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -60,7 +60,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #define	LED_NUM		5
 #define	PHYS_LEDS	0x1f
 #else
-#ifdef sun
+#ifdef __sun
 #define LED_NUM		1
 #define	LED_SCROLL	2
 #define	LED_COMPOSE	3
commit 44d0fd435a4eaf45e252b4f00409152a6d599dfc
Author: Egbert Eich <eich at suse.de>
Date:   Tue Nov 24 17:37:36 2015 +0100

    kdrive/UnregisterFd: Fix off by one
    
    The number of FDs has been decremented already, therefore the
    number contained the index of the top one that is to me moved down.
    
    This problem was introduced by:
      commit 1110b71e360195aab040d835b54540ab558638c5
      Author: Chris Clayton <chris2553 at googlemail.com>
    
        kdrive: fix build error on gcc 4.8 for out-of-bounds array access
    
    The reason for the warning was likely a confused compiler.
    Hoping to reduce the confusion by moving the decrement behind the end
    if the copy loop.
    
    Signed-off-by: Egbert Eich <eich at suse.de>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 4bb9315..d5741f1 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -220,9 +220,9 @@ KdUnregisterFd(void *closure, int fd, Bool do_close)
                 KdRemoveFd(kdInputFds[i].fd);
             if (do_close)
                 close(kdInputFds[i].fd);
-            kdNumInputFds--;
             for (j = i; j < (kdNumInputFds - 1); j++)
                 kdInputFds[j] = kdInputFds[j + 1];
+            kdNumInputFds--;
             break;
         }
     }
commit eb36924ead40564325aa56d54a973dc8fb4eae83
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Nov 24 08:31:21 2015 -0500

    dix: Remove redundant ChangeWindowProperty
    
    Use dixChangeWindowProperty(serverClient, ...) instead.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/property.c b/dix/property.c
index 99608af..92c2558 100644
--- a/dix/property.c
+++ b/dix/property.c
@@ -355,14 +355,6 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
 }
 
 int
-ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
-                     int mode, unsigned long len, void *value, Bool sendevent)
-{
-    return dixChangeWindowProperty(serverClient, pWin, property, type, format,
-                                   mode, len, value, sendevent);
-}
-
-int
 DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName)
 {
     PropertyPtr pProp, prevProp;
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 6570f0b..709afd6 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -448,9 +448,10 @@ xf86UpdateHasVTProperty(Bool hasVT)
     if (property_name == BAD_RESOURCE)
         FatalError("Failed to retrieve \"HAS_VT\" atom\n");
     for (i = 0; i < xf86NumScreens; i++) {
-        ChangeWindowProperty(xf86ScrnToScreen(xf86Screens[i])->root,
-                             property_name, XA_INTEGER, 32,
-                             PropModeReplace, 1, &value, TRUE);
+        dixChangeWindowProperty(serverClient,
+                                xf86ScrnToScreen(xf86Screens[i])->root,
+                                property_name, XA_INTEGER, 32,
+                                PropModeReplace, 1, &value, TRUE);
     }
 }
 
diff --git a/include/property.h b/include/property.h
index e350513..be875e9 100644
--- a/include/property.h
+++ b/include/property.h
@@ -67,15 +67,6 @@ extern _X_EXPORT int dixChangeWindowProperty(ClientPtr pClient,
                                              void *value,
                                              Bool sendevent);
 
-extern _X_EXPORT int ChangeWindowProperty(WindowPtr pWin,
-                                          Atom property,
-                                          Atom type,
-                                          int format,
-                                          int mode,
-                                          unsigned long len,
-                                          void *value,
-                                          Bool sendevent);
-
 extern _X_EXPORT int DeleteProperty(ClientPtr /*client */ ,
                                     WindowPtr /*pWin */ ,
                                     Atom /*propName */ );
commit 4affa75a90d2455c81087b930126ad7adfd019f0
Author: Adam Jackson <ajax at redhat.com>
Date:   Thu Nov 19 12:21:08 2015 -0500

    xnest: Fix needless build dependency on xcb-util-keysyms
    
    This was added in:
    
        commit 43014795087a0a8774dd9687f5967329b15f06a2
        Author: Olivier Fourdan <ofourdan at redhat.com>
        Date:   Mon Jan 5 16:44:22 2015 +0100
    
            Synchronize capslock in Xnest and Xephyr
    
    Which is fine if you're building both, but if you don't happen to have
    xcb-util-keysyms' headers installed Xnest will configure as enabled but
    fail to build.
    
    Fortunately <X11/X.h> has a corresponding #define, so use that instead.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c
index 7ee7a7c..85deaba 100644
--- a/hw/xnest/Keyboard.c
+++ b/hw/xnest/Keyboard.c
@@ -22,7 +22,6 @@ is" without express or implied warranty.
 
 #include <X11/X.h>
 #include <X11/Xproto.h>
-#include <xcb/xcb_keysyms.h>
 #include <X11/keysym.h>
 #include "screenint.h"
 #include "inputstr.h"
@@ -252,7 +251,7 @@ xnestUpdateModifierState(unsigned int state)
 
             for (key = 0; key < MAP_LENGTH; key++)
                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
-                    if (mask == XCB_MOD_MASK_LOCK) {
+                    if (mask == LockMask) {
                         xnestQueueKeyEvent(KeyPress, key);
                         xnestQueueKeyEvent(KeyRelease, key);
                     }
@@ -270,7 +269,7 @@ xnestUpdateModifierState(unsigned int state)
             for (key = 0; key < MAP_LENGTH; key++)
                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
                     xnestQueueKeyEvent(KeyPress, key);
-                    if (mask == XCB_MOD_MASK_LOCK)
+                    if (mask == LockMask)
                         xnestQueueKeyEvent(KeyRelease, key);
                     break;
                 }
commit fee0827a9a695600765f3d04376fc9babe497401
Author: Daniel Stone <daniels at collabora.com>
Date:   Fri Nov 20 15:37:31 2015 +0000

    XWayland: Use FocusIn events for keyboard enter
    
    wl_keyboard::enter is the equivalent of FocusIn + KeymapNotify: it
    notifies us that the surface/window has now received the focus, and
    provides us a set of keys which are currently down.
    
    We should use these keys to update the current state, but not to send
    any events to clients.
    
    Signed-off-by: Daniel Stone <daniels at collabora.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 0515eb9..473f306 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -432,7 +432,7 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
 
     wl_array_copy(&xwl_seat->keys, keys);
     wl_array_for_each(k, &xwl_seat->keys)
-        QueueKeyboardEvents(xwl_seat->keyboard, KeyPress, *k + 8);
+        QueueKeyboardEvents(xwl_seat->keyboard, KeymapNotify, *k + 8);
 }
 
 static void
@@ -444,6 +444,10 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
 
     xwl_seat->xwl_screen->serial = serial;
 
+    /* Unlike keymap_handle_enter above, this time we _do_ want to trigger
+     * full release, as we don't know how long we'll be out of focus for.
+     * Notify clients that the keys have been released, disable autorepeat,
+     * etc. */
     wl_array_for_each(k, &xwl_seat->keys)
         QueueKeyboardEvents(xwl_seat->keyboard, KeyRelease, *k + 8);
 
commit 816015648ffe660ddaa0f7d4d192e555b723c372
Author: Daniel Stone <daniels at collabora.com>
Date:   Fri Nov 20 15:37:30 2015 +0000

    Input: Add focus-in event source
    
    Add a new event source type for keypress events synthesised from focus
    notifications (e.g. KeymapNotify from the parent server, when running
    nested). This is used to keep the keys-down array in sync with the host
    server's, without sending actual keypress events to clients.
    
    Signed-off-by: Daniel Stone <daniels at collabora.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index e728310..74e49ed 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1760,6 +1760,10 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
 
     switch (event->type) {
     case ET_KeyPress:
+        /* Don't deliver focus events (e.g. from KeymapNotify when running
+         * nested) to clients. */
+        if (event->source_type == EVENT_SOURCE_FOCUS)
+            return;
         if (!grab && CheckDeviceGrabs(device, event, 0))
             return;
         break;
diff --git a/dix/getevents.c b/dix/getevents.c
index f04b415..4d06818 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1101,6 +1101,11 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
     }
 #endif
 
+    if (type == KeymapNotify) {
+        source_type = EVENT_SOURCE_FOCUS;
+        type = KeyPress;
+    }
+
     /* refuse events from disabled devices */
     if (!pDev->enabled)
         return 0;
diff --git a/include/eventstr.h b/include/eventstr.h
index 4fd846f..7446961 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -83,6 +83,7 @@ enum EventType {
  */
 enum DeviceEventSource {
   EVENT_SOURCE_NORMAL = 0, /**< Default: from a user action (e.g. key press) */
+  EVENT_SOURCE_FOCUS, /**< Keys or buttons previously down on focus-in */
 };
 
 /**
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index ddd09ab..aeb702c 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1206,6 +1206,32 @@ XkbActionGetFilter(DeviceIntPtr dev, DeviceEvent *event, KeyCode key,
     XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
     XkbFilterPtr filter;
 
+    /* For focus events, we only want to run actions which update our state to
+     * (hopefully vaguely kinda) match that of the host server, rather than
+     * actually execute anything. For example, if we enter our VT with
+     * Ctrl+Alt+Backspace held down, we don't want to terminate our server
+     * immediately, but we _do_ want Ctrl+Alt to be latched down, so if
+     * Backspace is released and then pressed again, the server will terminate.
+     *
+     * This is pretty flaky, and we should in fact inherit the complete state
+     * from the host server. There are some state combinations that we cannot
+     * express by running the state machine over every key, e.g. if AltGr+Shift
+     * generates a different state to Shift+AltGr. */
+    if (event->source_type == EVENT_SOURCE_FOCUS) {
+        switch (act->type) {
+        case XkbSA_SetMods:
+        case XkbSA_SetGroup:
+        case XkbSA_LatchMods:
+        case XkbSA_LatchGroup:
+        case XkbSA_LockMods:
+        case XkbSA_LockGroup:
+            break;
+        default:
+            *sendEvent = 1;
+            return;
+        }
+    }
+
     switch (act->type) {
     case XkbSA_SetMods:
     case XkbSA_SetGroup:
commit c3788394e9190130a8eed44c5c93eeb93c2a9893
Author: Daniel Stone <daniels at collabora.com>
Date:   Fri Nov 20 15:37:29 2015 +0000

    Input: Add DeviceEventSource enum
    
    Add a flag to DeviceEvents, giving the source of the event. Currently
    this only supports a 'normal' flag, but will be used later to add a
    'focus-in' flag, noting events synthesised from key/button arrays on
    focus-in notifications.
    
    Signed-off-by: Daniel Stone <daniels at collabora.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index 7ebddc4..f04b415 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1092,6 +1092,7 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
     CARD32 ms = 0;
     DeviceEvent *event;
     RawDeviceEvent *raw;
+    enum DeviceEventSource source_type = EVENT_SOURCE_NORMAL;
 
 #if XSERVER_DTRACE
     if (XSERVER_INPUT_EVENT_ENABLED()) {
@@ -1126,14 +1127,15 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
 
     ms = GetTimeInMillis();
 
-    raw = &events->raw_event;
-    events++;
-    num_events++;
-
-    init_raw(pDev, raw, ms, type, key_code);
+    if (source_type == EVENT_SOURCE_NORMAL) {
+        raw = &events->raw_event;
+        init_raw(pDev, raw, ms, type, key_code);
+        events++;
+        num_events++;
+    }
 
     event = &events->device_event;
-    init_device_event(event, pDev, ms);
+    init_device_event(event, pDev, ms, source_type);
     event->detail.key = key_code;
 
     if (type == KeyPress) {
@@ -1468,7 +1470,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
     }
 
     event = &events->device_event;
-    init_device_event(event, pDev, ms);
+    init_device_event(event, pDev, ms, EVENT_SOURCE_NORMAL);
 
     if (type == MotionNotify) {
         event->type = ET_Motion;
@@ -1804,7 +1806,7 @@ GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
         UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
     event = &events->device_event;
-    init_device_event(event, pDev, GetTimeInMillis());
+    init_device_event(event, pDev, GetTimeInMillis(), EVENT_SOURCE_NORMAL);
     event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
 
     clipValuators(pDev, &mask);
@@ -1939,7 +1941,7 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
     event = &events->device_event;
     num_events++;
 
-    init_device_event(event, dev, ms);
+    init_device_event(event, dev, ms, EVENT_SOURCE_NORMAL);
 
     switch (type) {
     case XI_TouchBegin:
@@ -2054,7 +2056,7 @@ GetDixTouchEnd(InternalEvent *ievent, DeviceIntPtr dev, TouchPointInfoPtr ti,
 
     BUG_WARN(!dev->enabled);
 
-    init_device_event(event, dev, ms);
+    init_device_event(event, dev, ms, EVENT_SOURCE_NORMAL);
 
     event->sourceid = ti->sourceid;
     event->type = ET_TouchEnd;
@@ -2098,7 +2100,7 @@ PostSyntheticMotion(DeviceIntPtr pDev,
 #endif
 
     memset(&ev, 0, sizeof(DeviceEvent));
-    init_device_event(&ev, pDev, time);
+    init_device_event(&ev, pDev, time, EVENT_SOURCE_NORMAL);
     ev.root_x = x;
     ev.root_y = y;
     ev.type = ET_Motion;
diff --git a/dix/inpututils.c b/dix/inpututils.c
index 1363988..5b7da3a 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -727,7 +727,8 @@ verify_internal_event(const InternalEvent *ev)
  * device.
  */
 void
-init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms)
+init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms,
+                  enum DeviceEventSource source_type)
 {
     memset(event, 0, sizeof(DeviceEvent));
     event->header = ET_Internal;
@@ -735,6 +736,7 @@ init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms)
     event->time = ms;
     event->deviceid = dev->id;
     event->sourceid = dev->id;
+    event->source_type = source_type;
 }
 
 int
diff --git a/include/eventstr.h b/include/eventstr.h
index cce903d..4fd846f 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -25,6 +25,7 @@
 #ifndef EVENTSTR_H
 #define EVENTSTR_H
 
+#include "inputstr.h"
 #include <events.h>
 /**
  * @file events.h
@@ -78,6 +79,13 @@ enum EventType {
 };
 
 /**
+ * How a DeviceEvent was provoked
+ */
+enum DeviceEventSource {
+  EVENT_SOURCE_NORMAL = 0, /**< Default: from a user action (e.g. key press) */
+};
+
+/**
  * Used for ALL input device events internal in the server until
  * copied into the matching protocol event.
  *
@@ -124,6 +132,7 @@ struct _DeviceEvent {
     int key_repeat;   /**< Internally-generated key repeat event */
     uint32_t flags;   /**< Flags to be copied into the generated event */
     uint32_t resource; /**< Touch event resource, only for TOUCH_REPLAYING */
+    enum DeviceEventSource source_type; /**< How this event was provoked */
 };
 
 /**
diff --git a/include/inpututils.h b/include/inpututils.h
index 4e90815..48c95c4 100644
--- a/include/inpututils.h
+++ b/include/inpututils.h
@@ -30,6 +30,7 @@
 #define INPUTUTILS_H
 
 #include "input.h"
+#include "eventstr.h"
 #include <X11/extensions/XI2proto.h>
 
 extern Mask event_filters[MAXDEVICES][MAXEVENTS];
@@ -43,7 +44,8 @@ struct _ValuatorMask {
 };
 
 extern void verify_internal_event(const InternalEvent *ev);
-extern void init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms);
+extern void init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms,
+                              enum DeviceEventSource event_source);
 extern int event_get_corestate(DeviceIntPtr mouse, DeviceIntPtr kbd);
 extern void event_set_state(DeviceIntPtr mouse, DeviceIntPtr kbd,
                             DeviceEvent *event);
diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index 7fd6a48..02e820b 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -126,7 +126,7 @@ AccessXKeyboardEvent(DeviceIntPtr keybd, int type, BYTE keyCode, Bool isRepeat)
 {
     DeviceEvent event;
 
-    init_device_event(&event, keybd, GetTimeInMillis());
+    init_device_event(&event, keybd, GetTimeInMillis(), EVENT_SOURCE_NORMAL);
     event.type = type;
     event.detail.key = keyCode;
     event.key_repeat = isRepeat;
commit 2e61901e46d28ce2f436219ad1a495aa0dcd0fba
Author: Daniel Stone <daniels at collabora.com>
Date:   Fri Nov 20 15:37:28 2015 +0000

    XKB: Split filter execution into a separate function
    
    Move the giant state machine which maps from a key action to actually
    running the filters into a separate function, to be used when adding
    KeyFocusIn.
    
    Signed-off-by: Daniel Stone <daniels at collabora.com>
    Tested-by: Giulio Camuffo <giuliocamuffo at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 1a9878d..ddd09ab 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1199,6 +1199,80 @@ XkbPushLockedStateToSlaves(DeviceIntPtr master, int evtype, int key)
     }
 }
 
+static void
+XkbActionGetFilter(DeviceIntPtr dev, DeviceEvent *event, KeyCode key,
+                   XkbAction *act, int *sendEvent)
+{
+    XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+    XkbFilterPtr filter;
+
+    switch (act->type) {
+    case XkbSA_SetMods:
+    case XkbSA_SetGroup:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterSetState(xkbi, filter, key, act);
+        break;
+    case XkbSA_LatchMods:
+    case XkbSA_LatchGroup:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterLatchState(xkbi, filter, key, act);
+        break;
+    case XkbSA_LockMods:
+    case XkbSA_LockGroup:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterLockState(xkbi, filter, key, act);
+        break;
+    case XkbSA_ISOLock:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterISOLock(xkbi, filter, key, act);
+        break;
+    case XkbSA_MovePtr:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterPointerMove(xkbi, filter, key, act);
+        break;
+    case XkbSA_PtrBtn:
+    case XkbSA_LockPtrBtn:
+    case XkbSA_SetPtrDflt:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterPointerBtn(xkbi, filter, key, act);
+        break;
+    case XkbSA_Terminate:
+        *sendEvent = XkbDDXTerminateServer(dev, key, act);
+        break;
+    case XkbSA_SwitchScreen:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterSwitchScreen(xkbi, filter, key, act);
+        break;
+    case XkbSA_SetControls:
+    case XkbSA_LockControls:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterControls(xkbi, filter, key, act);
+        break;
+    case XkbSA_ActionMessage:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterActionMessage(xkbi, filter, key, act);
+        break;
+    case XkbSA_RedirectKey:
+        filter = _XkbNextFreeFilter(xkbi);
+        /* redirect actions must create a new DeviceEvent.  The
+         * source device id for this event cannot be obtained from
+         * xkbi, so we pass it here explicitly. The field deviceid
+         * equals to xkbi->device->id. */
+        filter->priv = event->sourceid;
+        *sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, act);
+        break;
+    case XkbSA_DeviceBtn:
+    case XkbSA_LockDeviceBtn:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterDeviceBtn(xkbi, filter, key, act);
+        break;
+    case XkbSA_XFree86Private:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterXF86Private(xkbi, filter, key, act);
+        break;
+    }
+}
+
 void
 XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
 {
@@ -1208,7 +1282,6 @@ XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
     int sendEvent;
     Bool genStateNotify;
     XkbAction act;
-    XkbFilterPtr filter;
     Bool keyEvent;
     Bool pressEvent;
     ProcessInputProc backupproc;
@@ -1236,74 +1309,9 @@ XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
             act = XkbGetButtonAction(kbd, dev, key);
             key |= BTN_ACT_FLAG;
         }
+
         sendEvent = _XkbApplyFilters(xkbi, key, &act);
-        if (sendEvent) {
-            switch (act.type) {
-            case XkbSA_SetMods:
-            case XkbSA_SetGroup:
-                filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterSetState(xkbi, filter, key, &act);
-                break;
-            case XkbSA_LatchMods:
-            case XkbSA_LatchGroup:
-                filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
-                break;
-            case XkbSA_LockMods:
-            case XkbSA_LockGroup:
-                filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
-                break;
-            case XkbSA_ISOLock:
-                filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterISOLock(xkbi, filter, key, &act);
-                break;
-            case XkbSA_MovePtr:
-                filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterPointerMove(xkbi, filter, key, &act);
-                break;
-            case XkbSA_PtrBtn:
-            case XkbSA_LockPtrBtn:
-            case XkbSA_SetPtrDflt:
-                filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterPointerBtn(xkbi, filter, key, &act);
-                break;
-            case XkbSA_Terminate:
-                sendEvent = XkbDDXTerminateServer(dev, key, &act);
-                break;
-            case XkbSA_SwitchScreen:
-                filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterSwitchScreen(xkbi, filter, key, &act);
-                break;
-            case XkbSA_SetControls:
-            case XkbSA_LockControls:
-                filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterControls(xkbi, filter, key, &act);
-                break;
-            case XkbSA_ActionMessage:
-                filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterActionMessage(xkbi, filter, key, &act);
-                break;
-            case XkbSA_RedirectKey:
-                filter = _XkbNextFreeFilter(xkbi);
-                /* redirect actions must create a new DeviceEvent.  The
-                 * source device id for this event cannot be obtained from
-                 * xkbi, so we pass it here explicitly. The field deviceid
-                 * equals to xkbi->device->id. */
-                filter->priv = event->sourceid;
-                sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, &act);
-                break;
-            case XkbSA_DeviceBtn:
-            case XkbSA_LockDeviceBtn:
-                filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterDeviceBtn(xkbi, filter, key, &act);
-                break;
-            case XkbSA_XFree86Private:
-                filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterXF86Private(xkbi, filter, key, &act);
-                break;
-            }
-        }
+        XkbActionGetFilter(dev, event, key, &act, &sendEvent);
     }
     else {
         if (!keyEvent)
commit 71ba82690158f46d50a455e69a83ee0d685bb274
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Nov 23 07:59:24 2015 +1000

    xfree86: fix minor memory leak
    
    xf86*StrOption returns a strdup
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index a5b0568..c56a2b9 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -843,7 +843,7 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
     DeviceIntPtr dev = NULL;
     Bool paused;
     int rval;
-    const char *path;
+    char *path = NULL;
 
     /* Memory leak for every attached device if we don't
      * test if the module is already loaded first */
@@ -873,6 +873,7 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
                 new_input_devices[new_input_devices_count] = pInfo;
                 new_input_devices_count++;
                 systemd_logind_release_fd(pInfo->major, pInfo->minor, fd);
+                free(path);
                 return BadMatch;
             }
             pInfo->fd = fd;
@@ -881,6 +882,8 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
         }
     }
 
+    free(path);
+
     xf86Msg(X_INFO, "Using input driver '%s' for '%s'\n", drv->driverName,
             pInfo->name);
 
commit 51984dddfcc7133ed3c1f20d03514aa98c9a7831
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.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index 12dff8e..a4e0655 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -140,11 +140,6 @@ extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front,
 
 /* The DDX is not supposed to call these three functions */
 extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen);
-extern _X_EXPORT unsigned int glamor_egl_create_argb8888_based_texture(ScreenPtr
-                                                                       screen,
-                                                                       int w,
-                                                                       int h,
-                                                                       Bool linear);
 extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr,
                                                       unsigned int, Bool,
                                                       CARD16 *, CARD32 *);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index e68af18..ea0443d 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -187,49 +187,6 @@ glamor_egl_get_gbm_device(ScreenPtr screen)
 #endif
 }
 
-unsigned int
-glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear)
-{
-    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-    struct glamor_egl_screen_private *glamor_egl;
-    EGLImageKHR image;
-    GLuint texture;
-
-#ifdef GLAMOR_HAS_GBM
-    struct gbm_bo *bo;
-    EGLNativePixmapType native_pixmap;
-
-    glamor_egl = glamor_egl_get_screen_private(scrn);
-    bo = gbm_bo_create(glamor_egl->gbm, w, h, GBM_FORMAT_ARGB8888,
-#ifdef GLAMOR_HAS_GBM_LINEAR
-                       (linear ? GBM_BO_USE_LINEAR : 0) |
-#endif
-                       GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
-    if (!bo)
-        return 0;
-
-    /* If the following assignment raises an error or a warning
-     * then that means EGLNativePixmapType is not struct gbm_bo *
-     * on your platform: This code won't work and you should not
-     * compile with dri3 support enabled */
-    native_pixmap = bo;
-
-    image = eglCreateImageKHR(glamor_egl->display,
-                              EGL_NO_CONTEXT,
-                              EGL_NATIVE_PIXMAP_KHR,
-                              native_pixmap, NULL);
-    gbm_bo_destroy(bo);
-    if (image == EGL_NO_IMAGE_KHR)
-        return 0;
-    glamor_create_texture_from_image(screen, image, &texture);
-    eglDestroyImageKHR(glamor_egl->display, image);
-
-    return texture;
-#else
-    return 0;                   /* this path should never happen */
-#endif
-}
-
 Bool
 glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 {
@@ -380,79 +337,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
+}
 
 struct gbm_bo *
 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
@@ -468,7 +438,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;
 
@@ -504,8 +474,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);
 
@@ -528,10 +498,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 35944c8..40f7fcc 100644
--- a/glamor/glamor_egl_stubs.c
+++ b/glamor/glamor_egl_stubs.c
@@ -43,9 +43,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 dedefdc..ebaf05a 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -409,12 +409,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 7cd495a88807698b4ebaf9c1fb3db6edf31dd7e6
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Oct 15 13:25:12 2015 -0700

    glamor: Make glamor_get_name_from_bo static.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index fde7688..e68af18 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -369,9 +369,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
 }
 
 #ifdef GLAMOR_HAS_GBM
-void glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name);
-
-void
+static void
 glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name)
 {
     union gbm_bo_handle handle;
commit 6be33fd044949330e0b2b4185882c9664d2f90b4
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>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index f3650b7..fde7688 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -506,18 +506,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);
 
@@ -527,23 +517,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;
 
@@ -871,8 +850,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 1b8f16d8e659fb483453e1123a9fa876adb758ff
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jun 18 11:21:10 2015 -0700

    glamor: Use real types for glamor_egl's public gbm functions.
    
    I think void * was just used to avoid needing to #include gbm.h, but
    we can just forward-declare the structs and be fine.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index 4459fa4..12dff8e 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -40,6 +40,8 @@
 #endif
 
 struct glamor_context;
+struct gbm_bo;
+struct gbm_device;
 
 /*
  * glamor_pixmap_type : glamor pixmap's type.
@@ -147,7 +149,7 @@ extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr,
                                                       unsigned int, Bool,
                                                       CARD16 *, CARD32 *);
 
-extern _X_EXPORT void *glamor_egl_get_gbm_device(ScreenPtr screen);
+extern _X_EXPORT struct gbm_device *glamor_egl_get_gbm_device(ScreenPtr screen);
 
 /* @glamor_supports_pixmap_import_export: Returns whether
  * glamor_fd_from_pixmap(), glamor_name_from_pixmap(), and
@@ -207,8 +209,8 @@ extern _X_EXPORT int glamor_name_from_pixmap(PixmapPtr pixmap,
  *
  * Returns the gbm_bo on success, NULL on error.
  * */
-extern _X_EXPORT void *glamor_gbm_bo_from_pixmap(ScreenPtr screen,
-                                                 PixmapPtr pixmap);
+extern _X_EXPORT struct gbm_bo *glamor_gbm_bo_from_pixmap(ScreenPtr screen,
+                                                          PixmapPtr pixmap);
 
 /* @glamor_pixmap_from_fd: Creates a pixmap to wrap a dma-buf fd.
  *
@@ -315,7 +317,8 @@ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap,
  * This function is similar to glamor_egl_create_textured_pixmap.
  */
 extern _X_EXPORT Bool
- glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo);
+ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
+                                               struct gbm_bo *bo);
 
 #endif
 
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 6580141..f3650b7 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -175,7 +175,7 @@ glamor_create_texture_from_image(ScreenPtr screen,
     return TRUE;
 }
 
-void *
+struct gbm_device *
 glamor_egl_get_gbm_device(ScreenPtr screen)
 {
 #ifdef GLAMOR_HAS_GBM
@@ -335,7 +335,8 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 }
 
 Bool
-glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
+glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
+                                              struct gbm_bo *bo)
 {
     ScreenPtr screen = pixmap->drawable.pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
@@ -428,7 +429,7 @@ _get_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, unsigned int tex)
 }
 #endif
 
-void *
+struct gbm_bo *
 glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap)
 {
 #ifdef GLAMOR_HAS_GBM
commit f80758f32a7b922baf8fbf3ac6d8c9aae5fea1c4
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jun 18 11:15:40 2015 -0700

    glamor: Use the GBM function for getting an FD from a GBM BO.
    
    We were rolling ioctl calls ourselves, when there's a nice interface
    for it.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 761874f..6580141 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -368,22 +368,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
 }
 
 #ifdef GLAMOR_HAS_GBM
-int glamor_get_fd_from_bo(int gbm_fd, struct gbm_bo *bo, int *fd);
 void glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name);
-int
-glamor_get_fd_from_bo(int gbm_fd, struct gbm_bo *bo, int *fd)
-{
-    union gbm_bo_handle handle;
-    struct drm_prime_handle args;
-
-    handle = gbm_bo_get_handle(bo);
-    args.handle = handle.u32;
-    args.flags = DRM_CLOEXEC;
-    if (ioctl(gbm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args))
-        return FALSE;
-    *fd = args.fd;
-    return TRUE;
-}
 
 void
 glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name)
@@ -495,8 +480,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
             glamor_get_name_from_bo(glamor_egl->fd, bo, &fd);
     }
     else {
-        if (glamor_get_fd_from_bo(glamor_egl->fd, bo, &fd)) {
-        }
+        fd = gbm_bo_get_fd(bo);
     }
     *stride = pixmap->devKind;
     *size = pixmap->devKind * gbm_bo_get_height(bo);
commit ff2850424c99652506d0d6bc43506b4c16bf2ad5
Author: Eric Anholt <eric at anholt.net>
Date:   Sun Oct 18 19:26:14 2015 -0700

    glamor: Hook up EGL DestroyPixmap through the normal wrap chain.
    
    One less layering violation (EGL should call glamor, if anything, not
    the other way around).
    
    v2: Move glamor.c's DestroyPixmap wrapping up above the
        glamor_egl_screen_init() call, since glamor.c's DestroyPixmap
        needs to be the bottom of the stack (it calls fb directly and
        doesn't wrap).  Caught by Michel.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 4cd98c4..116d10c 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -206,9 +206,6 @@ Bool
 glamor_destroy_pixmap(PixmapPtr pixmap)
 {
     if (pixmap->refcnt == 1) {
-#if GLAMOR_HAS_GBM
-        glamor_egl_destroy_pixmap_image(pixmap);
-#endif
         glamor_pixmap_destroy_fbo(pixmap);
     }
 
@@ -461,6 +458,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_priv->saved_procs.close_screen = screen->CloseScreen;
     screen->CloseScreen = glamor_close_screen;
 
+    glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
+    screen->DestroyPixmap = glamor_destroy_pixmap;
+
     /* If we are using egl screen, call egl screen init to
      * register correct close screen function. */
     if (flags & GLAMOR_USE_EGL_SCREEN) {
@@ -615,9 +615,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
     screen->CreatePixmap = glamor_create_pixmap;
 
-    glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
-    screen->DestroyPixmap = glamor_destroy_pixmap;
-
     glamor_priv->saved_procs.get_spans = screen->GetSpans;
     screen->GetSpans = glamor_get_spans;
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 6d135df..4459fa4 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -147,8 +147,6 @@ extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr,
                                                       unsigned int, Bool,
                                                       CARD16 *, CARD32 *);
 
-extern void glamor_egl_destroy_pixmap_image(PixmapPtr pixmap);
-
 extern _X_EXPORT void *glamor_egl_get_gbm_device(ScreenPtr screen);
 
 /* @glamor_supports_pixmap_import_export: Returns whether
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 24d5586..761874f 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -78,6 +78,7 @@ struct glamor_egl_screen_private {
     int dri3_capable;
 
     CloseScreenProcPtr saved_close_screen;
+    DestroyPixmapProcPtr saved_destroy_pixmap;
     xf86FreeScreenProc *saved_free_screen;
 };
 
@@ -598,20 +599,29 @@ glamor_pixmap_from_fd(ScreenPtr screen,
 #endif
 }
 
-void
-glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
+static Bool
+glamor_egl_destroy_pixmap(PixmapPtr pixmap)
 {
-    struct glamor_pixmap_private *pixmap_priv =
-        glamor_get_pixmap_private(pixmap);
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
+    Bool ret;
 
-    if (pixmap_priv->image) {
-        ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
-        struct glamor_egl_screen_private *glamor_egl =
-            glamor_egl_get_screen_private(scrn);
+    if (pixmap->refcnt == 1) {
+        struct glamor_pixmap_private *pixmap_priv =
+            glamor_get_pixmap_private(pixmap);
 
-        eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
-        pixmap_priv->image = NULL;
+        if (pixmap_priv->image)
+            eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
     }
+
+    screen->DestroyPixmap = glamor_egl->saved_destroy_pixmap;
+    ret = screen->DestroyPixmap(pixmap);
+    glamor_egl->saved_destroy_pixmap = screen->DestroyPixmap;
+    screen->DestroyPixmap = glamor_egl_destroy_pixmap;
+
+    return ret;
 }
 
 _X_EXPORT void
@@ -723,6 +733,9 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
     glamor_egl->saved_close_screen = screen->CloseScreen;
     screen->CloseScreen = glamor_egl_close_screen;
 
+    glamor_egl->saved_destroy_pixmap = screen->DestroyPixmap;
+    screen->DestroyPixmap = glamor_egl_destroy_pixmap;
+
     glamor_ctx->ctx = glamor_egl->context;
     glamor_ctx->display = glamor_egl->display;
 
diff --git a/glamor/glamor_egl_stubs.c b/glamor/glamor_egl_stubs.c
index c11e6d5..35944c8 100644
--- a/glamor/glamor_egl_stubs.c
+++ b/glamor/glamor_egl_stubs.c
@@ -35,11 +35,6 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
 {
 }
 
-void
-glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
-{
-}
-
 int
 glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
                                  PixmapPtr pixmap,
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index ece7dbe..dedefdc 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -400,11 +400,6 @@ xwl_screen_init_glamor(struct xwl_screen *xwl_screen,
     return TRUE;
 }
 
-void
-glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
-{
-}
-
 int
 glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
                                  PixmapPtr pixmap,
commit e91fd30049ba9ebfb6ee8aded74eebe006af3f57
Author: Eric Anholt <eric at anholt.net>
Date:   Sun Oct 18 21:34:45 2015 -0700

    glamor: Unexport glamor_destroy_textured_pixmap().
    
    This is just a bit of the DestroyPixmap chain.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index e69f83d..4cd98c4 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -202,8 +202,8 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     return pixmap;
 }
 
-void
-glamor_destroy_textured_pixmap(PixmapPtr pixmap)
+Bool
+glamor_destroy_pixmap(PixmapPtr pixmap)
 {
     if (pixmap->refcnt == 1) {
 #if GLAMOR_HAS_GBM
@@ -211,12 +211,7 @@ glamor_destroy_textured_pixmap(PixmapPtr pixmap)
 #endif
         glamor_pixmap_destroy_fbo(pixmap);
     }
-}
 
-Bool
-glamor_destroy_pixmap(PixmapPtr pixmap)
-{
-    glamor_destroy_textured_pixmap(pixmap);
     return fbDestroyPixmap(pixmap);
 }
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 54fec1d..6d135df 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -110,7 +110,6 @@ extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap,
 
 extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap,
                                              glamor_pixmap_type_t type);
-extern _X_EXPORT void glamor_destroy_textured_pixmap(PixmapPtr pixmap);
 extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
 
 extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
commit 3dd202933fd94615aeeaec7e4cfd05a68954a3f3
Author: Eric Anholt <eric at anholt.net>
Date:   Sun Oct 18 21:28:19 2015 -0700

    glamor: Remove glamor_egl_destroy_textured_pixmap().
    
    The DestroyPixmap chain and CloseScreen chain all do pixmap teardown
    already, and calling it manually would be redundant.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index 4be8800..54fec1d 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -324,7 +324,6 @@ extern _X_EXPORT Bool
 
 extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen,
                                              struct glamor_context *glamor_ctx);
-extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
 
 extern _X_EXPORT int glamor_create_gc(GCPtr gc);
 
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index cc16b0a..24d5586 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -633,12 +633,6 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
     glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
 }
 
-void
-glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
-{
-    glamor_destroy_textured_pixmap(pixmap);
-}
-
 static Bool
 glamor_egl_close_screen(ScreenPtr screen)
 {
commit 9d2b76652f0bca5680b9e3ae2aacd508d5525684
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jun 19 15:56:13 2015 -0700

    modesetting: No need to free the EGLImage just before freeing the pixmap.
    
    DestroyPixmap handles that just fine.  This also lets us drop our use
    of the manual image destruction function (Note that the radeon driver
    still uses it in a similar fashion, though).
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 4421578..0d34ca1 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -780,7 +780,6 @@ drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
     drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
     if (rotate_pixmap) {
-        drmmode_set_pixmap_bo(drmmode, rotate_pixmap, NULL);
         rotate_pixmap->drawable.pScreen->DestroyPixmap(rotate_pixmap);
     }
 
@@ -1588,11 +1587,6 @@ drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo)
     if (!drmmode->glamor)
         return TRUE;
 
-    if (bo == NULL) {
-        glamor_egl_destroy_textured_pixmap(pixmap);
-        return TRUE;
-    }
-
 #ifdef GLAMOR_HAS_GBM
     if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) {
         xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
commit 98a1993536add730b7ec29a9e37f62b1cd70ad31
Author: Eric Anholt <eric at anholt.net>
Date:   Sun Oct 18 19:16:20 2015 -0700

    glamor: No need to glFlush before destroying a pixmap.
    
    I assume this was a workaround for an old, broken, closed driver.  The
    driver doesn't get to throw away rendering just because the rendering
    context's shared-across-processes render target is getting freed from
    the local address space.  If the rendering isn't to a shared render
    target, then we *do* want to throw away the rendering to it.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 2e6c7bd..cc16b0a 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -609,10 +609,6 @@ glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
         struct glamor_egl_screen_private *glamor_egl =
             glamor_egl_get_screen_private(scrn);
 
-        /* Before destroy an image which was attached to
-         * a texture. we must call glFlush to make sure the
-         * operation on that texture has been done.*/
-        glamor_block_handler(pixmap->drawable.pScreen);
         eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
         pixmap_priv->image = NULL;
     }
commit 9a5972801f7789833062e5711e77483b643eef92
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 5 16:35:56 2015 -0800

    glamor: Fix segfault in fallback picture uploading.
    
    If the source/mask pixmap is a pixmap that doesn't have an FBO
    attached, and it doesn't match the Render operation's size, then we'll
    composite it to a CPU temporary (not sure why).  We would take the
    PictFormatShort from the source Picture, make a pixmap of that depth,
    and try to look up the PictFormat description from the depth and the
    PictFormatShort.  However, the screen's PictFormats are only attached
    to the screen's visuals' depths.  So, with an x2r10g10b10 short format
    (depth 30), we wouldn't find the screen's PictFormat for it
    (associated with depth 32).
    
    Instead of trying to look up from the screen, just use the pFormat
    that came from our source picture.  The only time we need to look up a
    PictFormat when we're doing non-shader gradients, which we put in
    a8r8g8b8.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index c3a8f17..d8574ec 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1279,12 +1279,17 @@ glamor_convert_gradient_picture(ScreenPtr screen,
     PixmapPtr pixmap;
     PicturePtr dst = NULL;
     int error;
+    PictFormatPtr pFormat;
     PictFormatShort format;
 
-    if (!source->pDrawable)
+    if (source->pDrawable) {
+        pFormat = source->pFormat;
+        format = pFormat->format;
+    } else {
         format = PICT_a8r8g8b8;
-    else
-        format = source->format;
+        pFormat = PictureMatchFormat(screen, 32, format);
+    }
+
 #ifdef GLAMOR_GRADIENT_SHADER
     if (!source->pDrawable) {
         if (source->pSourcePict->type == SourcePictTypeLinear) {
@@ -1320,10 +1325,7 @@ glamor_convert_gradient_picture(ScreenPtr screen,
         return NULL;
 
     dst = CreatePicture(0,
-                        &pixmap->drawable,
-                        PictureMatchFormat(screen,
-                                           PIXMAN_FORMAT_DEPTH(format),
-                                           format), 0, 0, serverClient, &error);
+                        &pixmap->drawable, pFormat, 0, 0, serverClient, &error);
     glamor_destroy_pixmap(pixmap);
     if (!dst)
         return NULL;
commit e7aa4d3c7420d45cca2b7e1e69e22cebc64d5b74
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 5 16:03:14 2015 -0800

    glamor: Fix assert failures when fallback picture upload alloc fails.
    
    If the glTexImage (or glTexSubImage) out-of-memories, error out
    cleanly so that we can fall back to software.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 9b09454..d6f37cf 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -534,7 +534,7 @@ glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h,
  * Upload pixmap to a specified texture.
  * This texture may not be the one attached to it.
  **/
-static void
+static Bool
 __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
                                   GLenum format,
                                   GLenum type,
@@ -567,13 +567,24 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
         glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
     }
+    glamor_priv->suppress_gl_out_of_memory_logging = true;
     if (non_sub)
         glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
     else
         glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, type, bits);
+    glamor_priv->suppress_gl_out_of_memory_logging = false;
+    if (glGetError() == GL_OUT_OF_MEMORY) {
+        if (non_sub) {
+            glDeleteTextures(1, tex);
+            *tex = 0;
+        }
+        return FALSE;
+    }
 
     if (bits == NULL)
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+    return TRUE;
 }
 
 static Bool
@@ -645,10 +656,15 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
         assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
         assert(x + fbo_x_off + w <= pixmap_priv->fbo->width);
         assert(y + fbo_y_off + h <= pixmap_priv->fbo->height);
-        __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
-                                          format, type,
-                                          x + fbo_x_off, y + fbo_y_off, w, h,
-                                          bits, pbo);
+        if (!__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
+                                               format, type,
+                                               x + fbo_x_off, y + fbo_y_off,
+                                               w, h,
+                                               bits, pbo)) {
+            if (need_free_bits)
+                free(bits);
+            return FALSE;
+        }
     } else {
         ptexcoords = texcoords_inv;
 
@@ -660,6 +676,15 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
                                      vertices);
         /* Slow path, we need to flip y or wire alpha to 1. */
         glamor_make_current(glamor_priv);
+
+        if (!__glamor_upload_pixmap_to_texture(pixmap, &tex,
+                                               format, type, 0, 0, w, h, bits,
+                                               pbo)) {
+            if (need_free_bits)
+                free(bits);
+            return FALSE;
+        }
+
         glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
                               GL_FALSE, 2 * sizeof(float), vertices);
         glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -669,8 +694,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
 
         glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
         glamor_set_alu(screen, GXcopy);
-        __glamor_upload_pixmap_to_texture(pixmap, &tex,
-                                          format, type, 0, 0, w, h, bits, pbo);
         glActiveTexture(GL_TEXTURE0);
         glBindTexture(GL_TEXTURE_2D, tex);
 
commit ff8ef975df9cd99ec6f0b8b8047445091bf35ef0
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 5 15:13:55 2015 -0800

    glamor: Fix rendering when core font texture allocation fails.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_font.c b/glamor/glamor_font.c
index 6b3a16a..6753d50 100644
--- a/glamor/glamor_font.c
+++ b/glamor/glamor_font.c
@@ -127,8 +127,13 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
     }
 
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+    glamor_priv->suppress_gl_out_of_memory_logging = true;
     glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, overall_width, overall_height,
                  0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, bits);
+    glamor_priv->suppress_gl_out_of_memory_logging = false;
+    if (glGetError() == GL_OUT_OF_MEMORY)
+        return NULL;
 
     free(bits);
 
commit a6b05d10da2fe476f46e6dc4ad8a603964735905
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 5 15:05:11 2015 -0800

    glamor: Fix crashes when the glyph atlas allocation fails.
    
    We already have a fallback path, so we just need to jump to it when we
    hit the failure.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c
index 389c8f4..8692904 100644
--- a/glamor/glamor_composite_glyphs.c
+++ b/glamor/glamor_composite_glyphs.c
@@ -127,6 +127,10 @@ glamor_glyph_atlas_init(ScreenPtr screen, struct glamor_glyph_atlas *atlas)
     atlas->atlas = glamor_create_pixmap(screen, glamor_priv->glyph_atlas_dim,
                                         glamor_priv->glyph_atlas_dim, format->depth,
                                         GLAMOR_CREATE_FBO_NO_FBO);
+    if (!glamor_pixmap_has_fbo(atlas->atlas)) {
+        glamor_destroy_pixmap(atlas->atlas);
+        atlas->atlas = NULL;
+    }
     atlas->x = 0;
     atlas->y = 0;
     atlas->row_height = 0;
@@ -420,8 +424,11 @@ glamor_composite_glyphs(CARD8 op,
                                 glyph_atlas->atlas = NULL;
                             }
                         }
-                        if (!glyph_atlas->atlas)
+                        if (!glyph_atlas->atlas) {
                             glamor_glyph_atlas_init(screen, glyph_atlas);
+                            if (!glyph_atlas->atlas)
+                                goto bail_one;
+                        }
                         glamor_glyph_add(glyph_atlas, glyph_draw);
                     }
 
commit de959ec939b262cb1cb4c0b6146826e3092843f9
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 5 14:47:42 2015 -0800

    glamor: Handle GL_OUT_OF_MEMORY when allocating texture images.
    
    The spec allows general undefined behavior when GL_OOM is thrown.  But
    if the driver happens to throw the error at this point, it probably
    means the pixmap was just too big, so we should delete that texture
    and have this pixmap fall back to software.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index d4a0236..e69f83d 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -379,6 +379,13 @@ glamor_debug_output_callback(GLenum source,
                              const void *userParam)
 {
     ScreenPtr screen = (void *)userParam;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    if (glamor_priv->suppress_gl_out_of_memory_logging &&
+        source == GL_DEBUG_SOURCE_API && type == GL_DEBUG_TYPE_ERROR) {
+        return;
+    }
+
     LogMessageVerb(X_ERROR, 0, "glamor%d: GL error: %*s\n",
                screen->myNum, length, message);
 }
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 262033f..545f89f 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -347,9 +347,25 @@ _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);
+
+        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) {
+            LogMessageVerb(X_WARNING, 0, "glamor: Failed to allocate %dx%d "
+                           "FBO due to GL_OUT_OF_MEMORY.\n", w, h);
+            LogMessageVerb(X_WARNING, 0,
+                           "glamor: Expect reduced performance.\n");
+            glamor_priv->logged_any_fbo_allocation_failure = true;
+        }
+        glDeleteTextures(1, &tex);
+        return 0;
+    }
+
     return tex;
 }
 
@@ -368,6 +384,8 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
         return fbo;
  new_fbo:
     tex = _glamor_create_tex(glamor_priv, w, h, format, flag == CREATE_PIXMAP_USAGE_SHARED);
+    if (!tex)
+        return NULL;
     fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
 
     return fbo;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index f89d56d..a190e67 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -293,6 +293,9 @@ typedef struct glamor_screen_private {
     ScreenPtr screen;
     int dri3_enabled;
 
+    Bool suppress_gl_out_of_memory_logging;
+    Bool logged_any_fbo_allocation_failure;
+
     /* xv */
     GLint xv_prog;
 
commit 74be466d40080545117628c376cb59b696db33bc
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Nov 9 15:47:05 2015 -0800

    glamor: Avoid GL errors from mapping with size == 0.
    
    GL 4.5 / GLES 3.0 require throwing GL errors at map time, and Mesa
    before that might throw errors accidentally if a malloc(0) call was
    made to return the mapping.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Rob Clark <robdclark at gmail.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index f3950f1..f89d56d 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -251,6 +251,7 @@ typedef struct glamor_screen_private {
     /** Next offset within the VBO that glamor_get_vbo_space() will use. */
     int vbo_offset;
     int vbo_size;
+    Bool vbo_mapped;
     /**
      * Pointer to glamor_get_vbo_space()'s current VBO mapping.
      *
diff --git a/glamor/glamor_vbo.c b/glamor/glamor_vbo.c
index d74a005..ba60ce6 100644
--- a/glamor/glamor_vbo.c
+++ b/glamor/glamor_vbo.c
@@ -96,6 +96,15 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset)
         data = glamor_priv->vb + glamor_priv->vbo_offset;
         glamor_priv->vbo_offset += size;
     } else if (glamor_priv->has_map_buffer_range) {
+        /* Avoid GL errors on GL 4.5 / ES 3.0 with mapping size == 0,
+         * which callers may sometimes pass us (for example, if
+         * clipping leads to zero rectangles left).  Prior to that
+         * version, Mesa would sometimes throw errors on unmapping a
+         * zero-size mapping.
+         */
+        if (size == 0)
+            return NULL;
+
         if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) {
             glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size);
             glamor_priv->vbo_offset = 0;
@@ -109,9 +118,9 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset)
                                 GL_MAP_WRITE_BIT |
                                 GL_MAP_UNSYNCHRONIZED_BIT |
                                 GL_MAP_INVALIDATE_RANGE_BIT);
-        assert(data != NULL);
         *vbo_offset = (char *)(uintptr_t)glamor_priv->vbo_offset;
         glamor_priv->vbo_offset += size;
+        glamor_priv->vbo_mapped = TRUE;
     } else {
         /* Return a pointer to the statically allocated non-VBO
          * memory. We'll upload it through glBufferData() later.
@@ -145,7 +154,10 @@ glamor_put_vbo_space(ScreenPtr screen)
          * reach the end of the buffer.
          */
     } else if (glamor_priv->has_map_buffer_range) {
-        glUnmapBuffer(GL_ARRAY_BUFFER);
+        if (glamor_priv->vbo_mapped) {
+            glUnmapBuffer(GL_ARRAY_BUFFER);
+            glamor_priv->vbo_mapped = FALSE;
+        }
     } else {
         glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
                      glamor_priv->vb, GL_DYNAMIC_DRAW);
commit a6cddb8c04ddc3c48aae3f3611ad9f336fecb09d
Author: Michael Stapelberg <stapelberg at google.com>
Date:   Tue Nov 3 03:51:48 2015 -0800

    Also dump passive grabs on XF86LogGrabInfo
    
    Signed-off-by: Michael Stapelberg <stapelberg at google.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/window.c b/dix/window.c
index 69b5a7c..25d29ec 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -127,6 +127,7 @@ Equipment Corporation.
 #include "compint.h"
 #endif
 #include "selection.h"
+#include "inpututils.h"
 
 #include "privates.h"
 #include "xace.h"
@@ -272,6 +273,131 @@ log_window_info(WindowPtr pWin, int depth)
     ErrorF("\n");
 }
 
+static const char*
+grab_grabtype_to_text(GrabPtr pGrab)
+{
+    switch (pGrab->grabtype) {
+        case XI2:
+            return "xi2";
+        case CORE:
+            return "core";
+        default:
+            return "xi1";
+    }
+}
+
+static const char*
+grab_type_to_text(GrabPtr pGrab)
+{
+    switch (pGrab->type) {
+        case ButtonPress:
+            return "ButtonPress";
+        case KeyPress:
+            return "KeyPress";
+        case XI_Enter:
+            return "XI_Enter";
+        case XI_FocusIn:
+            return "XI_FocusIn";
+        default:
+            return "unknown?!";
+    }
+}
+
+static void
+log_grab_info(void *value, XID id, void *cdata)
+{
+    int i, j;
+    GrabPtr pGrab = (GrabPtr)value;
+
+    ErrorF("  grab 0x%lx (%s), type '%s' on window 0x%lx\n",
+           (unsigned long) pGrab->resource,
+           grab_grabtype_to_text(pGrab),
+           grab_type_to_text(pGrab),
+           (unsigned long) pGrab->window->drawable.id);
+    ErrorF("    detail %d (mask %lu), modifiersDetail %d (mask %lu)\n",
+           pGrab->detail.exact,
+           pGrab->detail.pMask ? (unsigned long) *(pGrab->detail.pMask) : 0,
+           pGrab->modifiersDetail.exact,
+           pGrab->modifiersDetail.pMask ?
+           (unsigned long) *(pGrab->modifiersDetail.pMask) :
+           (unsigned long) 0);
+    ErrorF("    device '%s' (%d), modifierDevice '%s' (%d)\n",
+           pGrab->device->name, pGrab->device->id,
+           pGrab->modifierDevice->name, pGrab->modifierDevice->id);
+    if (pGrab->grabtype == CORE) {
+        ErrorF("    core event mask 0x%lx\n",
+               (unsigned long) pGrab->eventMask);
+    }
+    else if (pGrab->grabtype == XI) {
+        ErrorF("    xi1 event mask 0x%lx\n",
+               (unsigned long) pGrab->eventMask);
+    }
+    else if (pGrab->grabtype == XI2) {
+        for (i = 0; i < xi2mask_num_masks(pGrab->xi2mask); i++) {
+            const unsigned char *mask;
+            int print;
+
+            print = 0;
+            for (j = 0; j < XI2MASKSIZE; j++) {
+                mask = xi2mask_get_one_mask(pGrab->xi2mask, i);
+                if (mask[j]) {
+                    print = 1;
+                    break;
+                }
+            }
+            if (!print)
+                continue;
+            ErrorF("      xi2 event mask 0x");
+            for (j = 0; j < xi2mask_mask_size(pGrab->xi2mask); j++)
+                ErrorF("%x ", mask[j]);
+            ErrorF("\n");
+        }
+    }
+    ErrorF("    owner-events %s, kb %d ptr %d, confine 0x%lx, cursor 0x%lx\n",
+           pGrab->ownerEvents ? "true" : "false",
+           pGrab->keyboardMode, pGrab->pointerMode,
+           pGrab->confineTo ? (unsigned long) pGrab->confineTo->drawable.id : 0,
+           pGrab->cursor ? (unsigned long) pGrab->cursor->id : 0);
+}
+
+void
+PrintPassiveGrabs(void)
+{
+    int i;
+    LocalClientCredRec *lcc;
+    pid_t clientpid;
+    const char *cmdname;
+    const char *cmdargs;
+
+    ErrorF("Printing all currently registered grabs\n");
+
+    for (i = 1; i < currentMaxClients; i++) {
+        if (!clients[i] || clients[i]->clientState != ClientStateRunning)
+            continue;
+
+        clientpid = GetClientPid(clients[i]);
+        cmdname = GetClientCmdName(clients[i]);
+        cmdargs = GetClientCmdArgs(clients[i]);
+        if ((clientpid > 0) && (cmdname != NULL)) {
+            ErrorF("  Printing all registered grabs of client pid %ld %s %s\n",
+                   (long) clientpid, cmdname, cmdargs ? cmdargs : "");
+        } else {
+            if (GetLocalClientCreds(clients[i], &lcc) == -1) {
+                ErrorF("  GetLocalClientCreds() failed\n");
+                continue;
+            }
+            ErrorF("  Printing all registered grabs of client pid %ld uid %ld gid %ld\n",
+                   (lcc->fieldsSet & LCC_PID_SET) ? (long) lcc->pid : 0,
+                   (lcc->fieldsSet & LCC_UID_SET) ? (long) lcc->euid : 0,
+                   (lcc->fieldsSet & LCC_GID_SET) ? (long) lcc->egid : 0);
+            FreeLocalClientCreds(lcc);
+        }
+
+        FindClientResourcesByType(clients[i], RT_PASSIVEGRAB, log_grab_info, NULL);
+    }
+    ErrorF("End list of registered passive grabs\n");
+}
+
 void
 PrintWindowTree(void)
 {
diff --git a/hw/xfree86/dixmods/xkbPrivate.c b/hw/xfree86/dixmods/xkbPrivate.c
index 574590f..4b9ef33 100644
--- a/hw/xfree86/dixmods/xkbPrivate.c
+++ b/hw/xfree86/dixmods/xkbPrivate.c
@@ -38,6 +38,8 @@ XkbDDXPrivate(DeviceIntPtr dev, KeyCode key, XkbAction *act)
                 if (tmp->deviceGrab.grab)
                     PrintDeviceGrabInfo(tmp);
             xf86Msg(X_INFO, "End list of active device grabs\n");
+
+            PrintPassiveGrabs();
         }
         else if (strcasecmp(msgbuf, "ungrab") == 0)
             UngrabAllDevices(FALSE);
diff --git a/include/window.h b/include/window.h
index 6daec85..f13ed51 100644
--- a/include/window.h
+++ b/include/window.h
@@ -223,6 +223,7 @@ extern _X_EXPORT RegionPtr CreateClipShape(WindowPtr /* pWin */ );
 
 extern _X_EXPORT void SetRootClip(ScreenPtr pScreen, Bool enable);
 extern _X_EXPORT void PrintWindowTree(void);
+extern _X_EXPORT void PrintPassiveGrabs(void);
 
 extern _X_EXPORT VisualPtr WindowGetVisual(WindowPtr /*pWin*/);
 #endif                          /* WINDOW_H */
commit f2ceb683c2da1ec08c8e07d7ec146f14864f2386
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 9 16:22:12 2015 -0500

    Post-release version bump for 1.19
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/configure.ac b/configure.ac
index 96c0242..14a5bb8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,9 +26,9 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.60)
-AC_INIT([xorg-server], 1.18.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+AC_INIT([xorg-server], 1.18.99.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
 RELEASE_DATE="2015-11-09"
-RELEASE_NAME="Moussaka"
+RELEASE_NAME="Ouzo"
 AC_CONFIG_SRCDIR([Makefile.am])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
commit 43fb888bd01cf9d3d277e77a52a3d0c93ccff8bd
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 9 16:00:26 2015 -0500

    xserver 1.18.0
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/configure.ac b/configure.ac
index 9828cab..96c0242 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,9 +26,9 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.60)
-AC_INIT([xorg-server], 1.17.99.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2015-10-26"
-RELEASE_NAME="Amontillado"
+AC_INIT([xorg-server], 1.18.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2015-11-09"
+RELEASE_NAME="Moussaka"
 AC_CONFIG_SRCDIR([Makefile.am])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
commit 2203735887ab548b3ee004400d1b89149aae412c
Author: Axel Davy <axel.davy at ens.fr>
Date:   Wed Nov 4 18:42:42 2015 +0100

    present: Fix Async swap logic
    
    According to the spec, PresentOptionAsync should only
    trigger a different behaviour when the target msc has been reached.
    
    In this case if the driver is able to do async swaps, we use
    them to avoid a screen copy.
    
    When the target msc hasn't been reached yet, we want to use sync swaps.
    
    v2: Fix indentation and simplify checks for Async flips
    
    Signed-off-by: Axel Davy <axel.davy at ens.fr>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/present/present.c b/present/present.c
index 5900c22..beb01dc 100644
--- a/present/present.c
+++ b/present/present.c
@@ -836,19 +836,20 @@ present_pixmap(WindowPtr window,
     vblank->notifies = notifies;
     vblank->num_notifies = num_notifies;
 
-    if (!(options & PresentOptionAsync))
-        vblank->sync_flip = TRUE;
-
-    if (!(options & PresentOptionCopy) &&
-        !((options & PresentOptionAsync) &&
-          (!screen_priv->info ||
-           !(screen_priv->info->capabilities & PresentCapabilityAsync))) &&
-        pixmap != NULL &&
-        present_check_flip (target_crtc, window, pixmap, vblank->sync_flip, valid, x_off, y_off))
-    {
-        vblank->flip = TRUE;
-        if (vblank->sync_flip)
+    if (pixmap != NULL &&
+        !(options & PresentOptionCopy) &&
+        screen_priv->info) {
+        if (target_msc > crtc_msc &&
+            present_check_flip (target_crtc, window, pixmap, TRUE, valid, x_off, y_off))
+        {
+            vblank->flip = TRUE;
+            vblank->sync_flip = TRUE;
             target_msc--;
+        } else if ((screen_priv->info->capabilities & PresentCapabilityAsync) &&
+            present_check_flip (target_crtc, window, pixmap, FALSE, valid, x_off, y_off))
+        {
+            vblank->flip = TRUE;
+        }
     }
 
     if (wait_fence) {
commit 3f35909acba117dc8934920d788c7ce612bce444
Author: Jammy Zhou <Jammy.Zhou at amd.com>
Date:   Wed Oct 28 18:39:10 2015 +0800

    present: Execute right away if target_msc equals current_msc
    
    It is according to the protocol:
    
    "If 'options' contains PresentOptionAsync, and the 'target-msc'
    is less than or equal to the current msc for 'window', then
    the operation will be performed as soon as possible, not
    necessarily waiting for the next vertical blank interval."
    
    Signed-off-by: Jammy Zhou <Jammy.Zhou at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Axel Davy <axel.davy at ens.fr>

diff --git a/present/present.c b/present/present.c
index beb4ff0..5900c22 100644
--- a/present/present.c
+++ b/present/present.c
@@ -871,7 +871,7 @@ present_pixmap(WindowPtr window,
 
     xorg_list_add(&vblank->event_queue, &present_exec_queue);
     vblank->queued = TRUE;
-    if ((pixmap && target_msc >= crtc_msc) || (!pixmap && target_msc > crtc_msc)) {
+    if (target_msc > crtc_msc) {
         ret = present_queue_vblank(screen, target_crtc, vblank->event_id, target_msc);
         if (ret == Success)
             return Success;
commit 7d1e4783853f9830344d101ceab087feb19995be
Author: Daniel Martin <consume.noise at gmail.com>
Date:   Thu Oct 29 14:58:11 2015 +0100

    modesetting: Remove XF86_CRTC_VERSION checks
    
    The ifdef checks for XF86_CRTC_VERSION >= 3/5 are remnants from the
    out-of-tree driver. Within the tree, we can rely on:
        xf86Crtc.h:#define XF86_CRTC_VERSION 6
    
    Signed-off-by: Daniel Martin <consume.noise at gmail.com>
    Reviewed-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 2684bae..4421578 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -462,11 +462,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
         crtc->y = saved_y;
         crtc->rotation = saved_rotation;
         crtc->mode = saved_mode;
-    }
-#if defined(XF86_CRTC_VERSION) && XF86_CRTC_VERSION >= 3
-    else
+    } else
         crtc->active = TRUE;
-#endif
 
     free(output_ids);
 
@@ -1789,9 +1786,7 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
     drmmode_clones_init(pScrn, drmmode, mode_res);
 
     drmModeFreeResources(mode_res);
-#if XF86_CRTC_VERSION >= 5
     xf86ProviderSetup(pScrn, NULL, "modesetting");
-#endif
 
     xf86InitialConfiguration(pScrn, TRUE);
 
commit 45c83a266d18eb515313aa3f1a4d7ff6af53be5d
Author: Daniel Martin <consume.noise at gmail.com>
Date:   Thu Oct 29 14:58:10 2015 +0100

    modesetting: Free output_ids in drmmode_set_mode_major()
    
    We calloc() output_ids. Let's free() it, too.
    
    Signed-off-by: Daniel Martin <consume.noise at gmail.com>
    Reviewed-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index f86c1f8..2684bae 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -340,7 +340,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
     int saved_x, saved_y;
     Rotation saved_rotation;
     DisplayModeRec saved_mode;
-    uint32_t *output_ids;
+    uint32_t *output_ids = NULL;
     int output_count = 0;
     Bool ret = TRUE;
     int i;
@@ -468,6 +468,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
         crtc->active = TRUE;
 #endif
 
+    free(output_ids);
+
     return ret;
 }
 
commit 2674d424020bd71d4f99b8d8de8b0b21aa490d54
Author: Daniel Martin <consume.noise at gmail.com>
Date:   Thu Oct 29 14:58:09 2015 +0100

    modesetting: Handle failures in setting a CRTC to a DRM mode properly
    
    This fixes a bug where running the card out of PPLL's when hotplugging
    another monitor would result in all of the displays going blank and
    failing to work properly until X was restarted or the user switched to
    another VT.
    
    [Michel Dänzer: Pass errno instead of -ret to strerror()]
    [Daniel Martin: Add \n to log message]
    
    Picked from xf86-video-ati
        7186a87 Handle failures in setting a CRTC to a DRM mode properly
    
    Signed-off-by: Daniel Martin <consume.noise at gmail.com>
    Reviewed-by: Emil Velikov <emil.l.velikov at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 736bfc4..f86c1f8 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -421,12 +421,13 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
             fb_id = drmmode_crtc->rotate_fb_id;
             x = y = 0;
         }
-        ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-                             fb_id, x, y, output_ids, output_count, &kmode);
-        if (ret)
+        if (drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+                           fb_id, x, y, output_ids, output_count, &kmode)) {
             xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
-                       "failed to set mode: %s", strerror(-ret));
-        else
+                       "failed to set mode: %s\n", strerror(errno));
+            ret = FALSE;
+            goto done;
+        } else
             ret = TRUE;
 
         if (crtc->scrn->pScreen)
commit 250666586e2b6f3ed1371340452dc2be2d094d40
Author: Adam Jackson <ajax at redhat.com>
Date:   Thu Oct 29 10:08:17 2015 -0400

    vidmode: Drop the unused event code
    
    As the code says, this is "far from complete".  So far, in fact, that
    it's been basically untouched for twenty years (XFree86 3.1!).  As far
    as I can tell it was never enabled in any XFree86 build, and certainly
    has never been enabled since Xorg 7.0.
    
    Also, K&R.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Emil Velikov <emil.l.velikov at gmail.com>

diff --git a/hw/xfree86/common/xf86vmode.c b/hw/xfree86/common/xf86vmode.c
index 818e7dc..d133687 100644
--- a/hw/xfree86/common/xf86vmode.c
+++ b/hw/xfree86/common/xf86vmode.c
@@ -71,46 +71,6 @@ typedef struct {
 static unsigned char XF86VidModeReqCode = 0;
 #endif
 
-/* The XF86VIDMODE_EVENTS code is far from complete */
-
-#ifdef XF86VIDMODE_EVENTS
-static int XF86VidModeEventBase = 0;
-
-static void SXF86VidModeNotifyEvent(xXF86VidModeNotifyEvent * /* from */ , xXF86VidModeNotifyEvent *    /* to */
-    );
-
-static RESTYPE EventType;       /* resource type for event masks */
-
-typedef struct _XF86VidModeEvent *XF86VidModeEventPtr;
-
-typedef struct _XF86VidModeEvent {
-    XF86VidModeEventPtr next;
-    ClientPtr client;
-    ScreenPtr screen;
-    XID resource;
-    CARD32 mask;
-} XF86VidModeEventRec;
-
-static int XF86VidModeFreeEvents();
-
-typedef struct _XF86VidModeScreenPrivate {
-    XF86VidModeEventPtr events;
-    Bool hasWindow;
-} XF86VidModeScreenPrivateRec, *XF86VidModeScreenPrivatePtr;
-
-static DevPrivateKeyRec ScreenPrivateKeyRec;
-
-#define ScreenPrivateKey (&ScreenPrivateKeyRec)
-
-#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \
-    dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey))
-#define SetScreenPrivate(s,v) \
-    dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v)
-#define SetupScreen(s)  ScreenSaverScreenPrivatePtr pPriv = GetScreenPrivate(s)
-
-#define New(t)  (malloc(sizeof (t)))
-#endif
-
 #ifdef DEBUG
 #define DEBUG_P(x) ErrorF(x"\n");
 #else
@@ -128,159 +88,6 @@ ClientMajorVersion(ClientPtr client)
         return pPriv->major;
 }
 
-#ifdef XF86VIDMODE_EVENTS
-static void
-CheckScreenPrivate(pScreen)
-ScreenPtr
- pScreen;
-{
-    SetupScreen(pScreen);
-
-    if (!pPriv)
-        return;
-    if (!pPriv->events && !pPriv->hasWindow) {
-        free(pPriv);
-        SetScreenPrivate(pScreen, NULL);
-    }
-}
-
-static XF86VidModeScreenPrivatePtr
-MakeScreenPrivate(pScreen)
-ScreenPtr
- pScreen;
-{
-    SetupScreen(pScreen);
-
-    if (pPriv)
-        return pPriv;
-    pPriv = New(XF86VidModeScreenPrivateRec);
-    if (!pPriv)
-        return 0;
-    pPriv->events = 0;
-    pPriv->hasWindow = FALSE;
-    SetScreenPrivate(pScreen, pPriv);
-    return pPriv;
-}
-
-static unsigned long
-getEventMask(ScreenPtr pScreen, ClientPtr client)
-{
-    SetupScreen(pScreen);
-    XF86VidModeEventPtr pEv;
-
-    if (!pPriv)
-        return 0;
-    for (pEv = pPriv->events; pEv; pEv = pEv->next)
-        if (pEv->client == client)
-            return pEv->mask;
-    return 0;
-}
-
-static Bool
-setEventMask(ScreenPtr pScreen, ClientPtr client, unsigned long mask)
-{
-    SetupScreen(pScreen);
-    XF86VidModeEventPtr pEv, *pPrev;
-
-    if (getEventMask(pScreen, client) == mask)
-        return TRUE;
-    if (!pPriv) {
-        pPriv = MakeScreenPrivate(pScreen);
-        if (!pPriv)
-            return FALSE;
-    }
-    for (pPrev = &pPriv->events; pEv = *pPrev; pPrev = &pEv->next)
-        if (pEv->client == client)
-            break;
-    if (mask == 0) {
-        *pPrev = pEv->next;
-        free(pEv);
-        CheckScreenPrivate(pScreen);
-    }
-    else {
-        if (!pEv) {
-            pEv = New(ScreenSaverEventRec);
-            if (!pEv) {
-                CheckScreenPrivate(pScreen);
-                return FALSE;
-            }
-            *pPrev = pEv;
-            pEv->next = NULL;
-            pEv->client = client;
-            pEv->screen = pScreen;
-            pEv->resource = FakeClientID(client->index);
-        }
-        pEv->mask = mask;
-    }
-    return TRUE;
-}
-
-static int
-XF86VidModeFreeEvents(void *value, XID id)
-{
-    XF86VidModeEventPtr pOld = (XF86VidModeEventPtr) value;
-    ScreenPtr pScreen = pOld->screen;
-
-    SetupScreen(pScreen);
-    XF86VidModeEventPtr pEv, *pPrev;
-
-    if (!pPriv)
-        return TRUE;
-    for (pPrev = &pPriv->events; pEv = *pPrev; pPrev = &pEv->next)
-        if (pEv == pOld)
-            break;
-    if (!pEv)
-        return TRUE;
-    *pPrev = pEv->next;
-    free(pEv);
-    CheckScreenPrivate(pScreen);
-    return TRUE;
-}
-
-static void
-SendXF86VidModeNotify(ScreenPtr pScreen, int state, Bool forced)
-{
-    XF86VidModeScreenPrivatePtr pPriv;
-    unsigned long mask;
-    xXF86VidModeNotifyEvent ev;
-    int kind;
-
-    UpdateCurrentTimeIf();
-    mask = XF86VidModeNotifyMask;
-    pScreen = screenInfo.screens[pScreen->myNum];
-    pPriv = GetScreenPrivate(pScreen);
-    if (!pPriv)
-        return;
-    kind = XF86VidModeModeChange;
-    for (pEv = pPriv->events; pEv; pEv = pEv->next) {
-        if (pEv->mask & mask) {
-            XF86VidModeEventPtr pEv = {
-                .type = XF86VidModeNotify + XF86VidModeEventBase,
-                .state = state,
-                .timestamp = currentTime.milliseconds,
-                .root = pScreen->root->drawable.id,
-                .kind = kind,
-                .forced = forced
-            };
-            WriteEventsToClient(pEv->client, 1, (xEvent *) &ev);
-        }
-    }
-}
-
-static void
-SXF86VidModeNotifyEvent(xXF86VidModeNotifyEvent * from,
-                        xXF86VidModeNotifyEvent * to)
-{
-    to->type = from->type;
-    to->state = from->state;
-    cpswaps(from->sequenceNumber, to->sequenceNumber);
-    cpswapl(from->timestamp, to->timestamp);
-    cpswapl(from->root, to->root);
-    to->kind = from->kind;
-    to->forced = from->forced;
-}
-#endif
-
 static int
 ProcXF86VidModeQueryVersion(ClientPtr client)
 {
@@ -2124,14 +1931,6 @@ XFree86VidModeExtensionInit(void)
 
     if (!dixRegisterPrivateKey(&VidModeClientPrivateKeyRec, PRIVATE_CLIENT, 0))
         return;
-#ifdef XF86VIDMODE_EVENTS
-    if (!dixRegisterPrivateKey(&ScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
-        return;
-#endif
-
-#ifdef XF86VIDMODE_EVENTS
-    EventType = CreateNewResourceType(XF86VidModeFreeEvents, "VidModeEvent");
-#endif
 
     for (i = 0; i < screenInfo.numScreens; i++) {
         pScreen = screenInfo.screens[i];
@@ -2142,24 +1941,15 @@ XFree86VidModeExtensionInit(void)
     if (!enabled)
         return;
 
-    if (
-#ifdef XF86VIDMODE_EVENTS
-           EventType &&
-#endif
-           (extEntry = AddExtension(XF86VIDMODENAME,
-                                    XF86VidModeNumberEvents,
-                                    XF86VidModeNumberErrors,
-                                    ProcXF86VidModeDispatch,
-                                    SProcXF86VidModeDispatch,
-                                    NULL, StandardMinorOpcode))) {
+    if ((extEntry = AddExtension(XF86VIDMODENAME,
+                                 XF86VidModeNumberEvents,
+                                 XF86VidModeNumberErrors,
+                                 ProcXF86VidModeDispatch,
+                                 SProcXF86VidModeDispatch,
+                                 NULL, StandardMinorOpcode))) {
 #if 0
         XF86VidModeReqCode = (unsigned char) extEntry->base;
 #endif
         VidModeErrorBase = extEntry->errorBase;
-#ifdef XF86VIDMODE_EVENTS
-        XF86VidModeEventBase = extEntry->eventBase;
-        EventSwapVector[XF86VidModeEventBase] =
-            (EventSwapPtr) SXF86VidModeNotifyEvent;
-#endif
     }
 }
commit 478efe285a440c33b053bdf0bfbfdd482f429f01
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Oct 27 19:44:28 2015 -0700

    Xserver.man: document more transports for -nolisten & -listen options
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/man/Xserver.man b/man/Xserver.man
index d927913..506e5bb 100644
--- a/man/Xserver.man
+++ b/man/Xserver.man
@@ -1,5 +1,5 @@
-.\" $Xorg: Xserver.man,v 1.4 2001/02/09 02:04:07 xorgcvs Exp $
-.\" $XdotOrg: xserver/xorg/doc/Xserver.man.pre,v 1.4 2005/12/23 20:11:12 alanc Exp $
+'\" t
+.\"
 .\" Copyright 1984 - 1991, 1993, 1994, 1998  The Open Group
 .\"
 .\" Permission to use, copy, modify, distribute, and sell this software and its
@@ -205,6 +205,15 @@ with
 .BR "\-nolisten tcp" .
 This option may be issued multiple times to disable listening to different
 transport types.
+Supported transport types are platform dependent, but commonly include:
+.TS
+l l.
+tcp     TCP over IPv4 or IPv6
+inet    TCP over IPv4 only
+inet6   TCP over IPv6 only
+unix    UNIX Domain Sockets
+local   Platform preferred local connection method
+.TE
 .TP 8
 .B \-listen \fItrans-type\fP
 enables a transport type.  For example, TCP/IP connections can be enabled
commit 8fc295bde9a736f3c8c047031a6698d140d5266f
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Oct 27 19:44:27 2015 -0700

    Xorg.man: update to reflect -nolisten tcp becoming default
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xfree86/man/Xorg.man b/hw/xfree86/man/Xorg.man
index b23db3d..def9bfc 100644
--- a/hw/xfree86/man/Xorg.man
+++ b/hw/xfree86/man/Xorg.man
@@ -53,8 +53,9 @@ listens on port
 .RI 6000+ n ,
 where
 .I n
-is the display number.  This connection type can be disabled with the
-.B \-nolisten
+is the display number.  This connection type is usually disabled by default,
+but may be enabled with the
+.B \-listen
 option (see the Xserver(1) man page for details).
 .SH OPTIONS
 .B Xorg
commit 75157b7dbf4ed4db0492328a44e4e67dda83f769
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Oct 27 19:44:26 2015 -0700

    Xorg.man: move XLOCAL details to X(7) man page instead
    
    These settings affect clients, not server, so belong there, next to
    the information about how to set $DISPLAY.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xfree86/man/Xorg.man b/hw/xfree86/man/Xorg.man
index 646a90c..b23db3d 100644
--- a/hw/xfree86/man/Xorg.man
+++ b/hw/xfree86/man/Xorg.man
@@ -44,7 +44,8 @@ byte-streams:
 .I "Local"
 On most platforms, the "Local" connection type is a UNIX-domain socket.
 On some System V platforms, the "local" connection types also include
-STREAMS pipes, named pipes, and some other mechanisms.
+STREAMS pipes, named pipes, and some other mechanisms.  See the
+"LOCAL CONNECTIONS" section of X(__miscmansuffix__) for details.
 .TP 4
 .I TCP/IP
 .B Xorg
@@ -55,58 +56,6 @@ where
 is the display number.  This connection type can be disabled with the
 .B \-nolisten
 option (see the Xserver(1) man page for details).
-.SH "ENVIRONMENT VARIABLES"
-For operating systems that support local connections other than Unix
-Domain sockets (SVR3 and SVR4), there is a compiled-in list specifying
-the order in which local connections should be attempted.  This list
-can be overridden by the
-.I XLOCAL
-environment variable described below.  If the display name indicates a
-best-choice connection should be made (e.g.
-.BR :0.0 ),
-each connection mechanism is tried until a connection succeeds or no
-more mechanisms are available.  Note: for these OSs, the Unix Domain
-socket connection is treated differently from the other local connection
-types.  To use it the connection must be made to
-.BR unix:0.0 .
-.PP
-The
-.I XLOCAL
-environment variable should contain a list of one more
-more of the following:
-.PP
-.RS 8
-.nf
-NAMED
-PTS
-SCO
-ISC
-.fi
-.RE
-.PP
-which represent SVR4 Named Streams pipe, Old-style USL Streams pipe,
-SCO XSight Streams pipe, and ISC Streams pipe, respectively.  You can
-select a single mechanism (e.g.
-.IR XLOCAL=NAMED ),
-or an ordered list (e.g. \fIXLOCAL="NAMED:PTS:SCO"\fP).
-his variable overrides the compiled-in defaults.  For SVR4 it is
-recommended that
-.I NAMED
-be the first preference connection.  The default setting is
-.IR PTS:NAMED:ISC:SCO .
-.PP
-To globally override the compiled-in defaults, you should define (and
-export if using
-.B sh
-or
-.BR ksh )
-.I XLOCAL
-globally.  If you use startx(1) or xinit(1), the definition should be
-at the top of your
-.I .xinitrc
-file.  If you use xdm(1), the definitions should be early on in the
-.I __projectroot__/lib/X11/xdm/Xsession
-script.
 .SH OPTIONS
 .B Xorg
 supports several mechanisms for supplying/obtaining configuration and
commit 50c167164700e8ead9b7ccf9f9eafc7541baac75
Author: Martin Peres <martin.peres at linux.intel.com>
Date:   Mon Jul 20 10:37:30 2015 +0300

    os: make sure the clientsWritable fd_set is initialized before use
    
    In WaitForSomething(), the fd_set clientsWritable may be used
    unitialized when the boolean AnyClientsWriteBlocked is set in the
    WakeupHandler(). This leads to a crash in FlushAllOutput() after
    x11proto's commit 2c94cdb453bc641246cc8b9a876da9799bee1ce7.
    
    The problem did not manifest before because both the XFD_SIZE and the
    maximum number of clients were set to 256. As the connectionTranslation
    table was initalized for the 256 clients to 0, the test on the index not
    being 0 was aborting before dereferencing the client #0.
    
    As of commit 2c94cdb453bc641246cc8b9a876da9799bee1ce7 in x11proto, the
    XFD_SIZE got bumped to 512. This lead the OutputPending fd_set to have
    any fd above 256 to be uninitialized which in turns lead to reading an
    index after the end of the ConnectionTranslation table. This index would
    then be used to find the client corresponding to the fd marked as
    pending writes and would also result to an out-of-bound access which
    would usually be the fatal one.
    
    Fix this by zeroing the clientsWritable fd_set at the beginning of
    WaitForSomething(). In this case, the bottom part of the loop, which
    would indirectly call FlushAllOutput, will not do any work but the next
    call to select will result in the execution of the right codepath. This
    is exactly what we want because we need to know the writable clients
    before handling them. In the end, it also makes sure that the fds above
    MaxClient are initialized, preventing the crash in FlushAllOutput().
    
    Thanks to everyone involved in tracking this one down!
    
    Reported-by: Karol Herbst <freedesktop at karolherbst.de>
    Reported-by: Tobias Klausmann <tobias.klausmann at mni.thm.de>
    Signed-off-by: Martin Peres <martin.peres at linux.intel.com>
    Tested-by: Tobias Klausmann <tobias.klausmann at mni.thm.de>
    Tested-by: Martin Peres <martin.peres at linux.intel.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91316
    Cc: Ilia Mirkin  <imirkin at alum.mit.edu>
    Cc: Olivier Fourdan <ofourdan at redhat.com
    Cc: Adam Jackson <ajax at redhat.com>
    Cc: Alan Coopersmith <alan.coopersmith at oracle.com
    Cc: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/os/WaitFor.c b/os/WaitFor.c
index 431f1a6..993c14e 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -158,6 +158,7 @@ WaitForSomething(int *pClientsReady)
     Bool someReady = FALSE;
 
     FD_ZERO(&clientsReadable);
+    FD_ZERO(&clientsWritable);
 
     if (nready)
         SmartScheduleStopTimer();
commit bb78c464f09f515db557182a458b12b63c3b52d7
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Oct 27 13:28:37 2015 -0400

    build: Remove stale miext/cw include paths
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Emil Velikov <emil.l.velikov at gmail.com>

diff --git a/exa/Makefile.am b/exa/Makefile.am
index 6a09966..00b28b1 100644
--- a/exa/Makefile.am
+++ b/exa/Makefile.am
@@ -4,9 +4,7 @@ if XORG
 sdk_HEADERS = exa.h
 endif
 
-AM_CPPFLAGS = \
-	$(XORG_INCS) \
-	-I$(srcdir)/../miext/cw
+AM_CPPFLAGS = $(XORG_INCS)
 
 AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
 
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index c45d8c9..64c4f74 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -49,7 +49,7 @@ bin_PROGRAMS = Xorg
 nodist_Xorg_SOURCES = sdksyms.c
 
 AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
-AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/parser -I$(top_srcdir)/miext/cw \
+AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/parser \
 	-I$(srcdir)/ddc -I$(srcdir)/i2c -I$(srcdir)/modes -I$(srcdir)/ramdac \
 	-I$(srcdir)/dri -I$(srcdir)/dri2 -I$(top_srcdir)/dri3
 
diff --git a/hw/xfree86/exa/Makefile.am b/hw/xfree86/exa/Makefile.am
index 1e42cda..ccbb305 100644
--- a/hw/xfree86/exa/Makefile.am
+++ b/hw/xfree86/exa/Makefile.am
@@ -6,8 +6,7 @@ libexa_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG)
 
 AM_CPPFLAGS = \
 	$(XORG_INCS) \
-	-I$(srcdir)/../../../exa \
-	-I$(srcdir)/../../../miext/cw
+	-I$(srcdir)/../../../exa
 
 AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
 
diff --git a/hw/xfree86/loader/Makefile.am b/hw/xfree86/loader/Makefile.am
index a658ca5..9218cab 100644
--- a/hw/xfree86/loader/Makefile.am
+++ b/hw/xfree86/loader/Makefile.am
@@ -1,6 +1,6 @@
 noinst_LTLIBRARIES = libloader.la
 
-AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/../parser -I$(top_srcdir)/miext/cw \
+AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/../parser \
 	   -I$(srcdir)/../ddc -I$(srcdir)/../i2c -I$(srcdir)/../modes \
 	   -I$(srcdir)/../ramdac -I$(srcdir)/../dri -I$(srcdir)/../dri2
 
diff --git a/test/Makefile.am b/test/Makefile.am
index 4d935a2..d151b02 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -16,7 +16,7 @@ TESTS=$(noinst_PROGRAMS)
 TESTS_ENVIRONMENT = $(XORG_MALLOC_DEBUG_ENV)
 
 AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
-AM_CPPFLAGS = $(XORG_INCS) -I$(top_srcdir)/miext/cw
+AM_CPPFLAGS = $(XORG_INCS)
 if XORG
 AM_CPPFLAGS += -I$(top_srcdir)/hw/xfree86/parser \
 	-I$(top_srcdir)/hw/xfree86/ddc \
commit 524844c8c18e226aad30feb371b19ef491d83449
Author: Julien Cristau <jcristau at debian.org>
Date:   Tue Oct 27 13:23:13 2015 +0100

    Xext: fix build with --disable-xace
    
    Regression from 990cf5b2828f73dc7a07f1e38f608af39acfd81d
    
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    Cc: Andrew Eikum <aeikum at codeweavers.com>
    Cc: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>

diff --git a/Xext/xace.h b/Xext/xace.h
index 3303f76..6a8d0c4 100644
--- a/Xext/xace.h
+++ b/Xext/xace.h
@@ -112,6 +112,7 @@ extern _X_EXPORT void XaceCensorImage(ClientPtr client,
 
 #ifdef __GNUC__
 #define XaceHook(args...) Success
+#define XaceHookIsSet(args...) 0
 #define XaceHookDispatch(args...) Success
 #define XaceHookPropertyAccess(args...) Success
 #define XaceHookSelectionAccess(args...) Success
@@ -119,6 +120,7 @@ extern _X_EXPORT void XaceCensorImage(ClientPtr client,
 #define XaceCensorImage(args...) { ; }
 #else
 #define XaceHook(...) Success
+#define XaceHookIsSet(...) 0
 #define XaceHookDispatch(...) Success
 #define XaceHookPropertyAccess(...) Success
 #define XaceHookSelectionAccess(...) Success
commit ac2f27f1a9fa8cd88c5dbe7ec0f96238eecf2c3e
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Oct 27 11:51:49 2015 +0900

    DRI2: Sync radeonsi_pci_ids.h from Mesa
    
    Fixes DRI2 client driver name mapping for newer AMD GPUs with the
    modesetting driver, allowing the DRI2 extension to initialize.
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h b/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h
index 571e863..bcf15a1 100644
--- a/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h
+++ b/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h
@@ -63,6 +63,7 @@ CHIPSET(0x6608, OLAND_6608, OLAND)
 CHIPSET(0x6610, OLAND_6610, OLAND)
 CHIPSET(0x6611, OLAND_6611, OLAND)
 CHIPSET(0x6613, OLAND_6613, OLAND)
+CHIPSET(0x6617, OLAND_6617, OLAND)
 CHIPSET(0x6620, OLAND_6620, OLAND)
 CHIPSET(0x6621, OLAND_6621, OLAND)
 CHIPSET(0x6623, OLAND_6623, OLAND)
@@ -85,6 +86,7 @@ CHIPSET(0x6651, BONAIRE_6651, BONAIRE)
 CHIPSET(0x6658, BONAIRE_6658, BONAIRE)
 CHIPSET(0x665C, BONAIRE_665C, BONAIRE)
 CHIPSET(0x665D, BONAIRE_665D, BONAIRE)
+CHIPSET(0x665F, BONAIRE_665F, BONAIRE)
 
 CHIPSET(0x9830, KABINI_9830, KABINI)
 CHIPSET(0x9831, KABINI_9831, KABINI)
@@ -155,3 +157,29 @@ CHIPSET(0x67B8, HAWAII_67B8, HAWAII)
 CHIPSET(0x67B9, HAWAII_67B9, HAWAII)
 CHIPSET(0x67BA, HAWAII_67BA, HAWAII)
 CHIPSET(0x67BE, HAWAII_67BE, HAWAII)
+
+CHIPSET(0x6900, ICELAND_, ICELAND)
+CHIPSET(0x6901, ICELAND_, ICELAND)
+CHIPSET(0x6902, ICELAND_, ICELAND)
+CHIPSET(0x6903, ICELAND_, ICELAND)
+CHIPSET(0x6907, ICELAND_, ICELAND)
+
+CHIPSET(0x6920, TONGA_, TONGA)
+CHIPSET(0x6921, TONGA_, TONGA)
+CHIPSET(0x6928, TONGA_, TONGA)
+CHIPSET(0x6929, TONGA_, TONGA)
+CHIPSET(0x692B, TONGA_, TONGA)
+CHIPSET(0x692F, TONGA_, TONGA)
+CHIPSET(0x6930, TONGA_, TONGA)
+CHIPSET(0x6938, TONGA_, TONGA)
+CHIPSET(0x6939, TONGA_, TONGA)
+
+CHIPSET(0x9870, CARRIZO_, CARRIZO)
+CHIPSET(0x9874, CARRIZO_, CARRIZO)
+CHIPSET(0x9875, CARRIZO_, CARRIZO)
+CHIPSET(0x9876, CARRIZO_, CARRIZO)
+CHIPSET(0x9877, CARRIZO_, CARRIZO)
+
+CHIPSET(0x7300, FIJI_, FIJI)
+
+CHIPSET(0x98E4, STONEY_, STONEY)


More information about the Xquartz-changes mailing list