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

Jeremy Huddleston jeremyhu at freedesktop.org
Sun Feb 15 00:39:41 PST 2015


 Xext/xcmisc.c                                    |    1 
 Xext/xvdisp.c                                    |   20 
 Xext/xvmain.c                                    |    2 
 Xi/chgdctl.c                                     |    8 
 Xi/chgfctl.c                                     |    2 
 Xi/exevents.c                                    |    5 
 Xi/sendexev.c                                    |    3 
 Xi/xiallowev.c                                   |    2 
 Xi/xichangecursor.c                              |    2 
 Xi/xichangehierarchy.c                           |   35 +
 Xi/xigetclientpointer.c                          |    1 
 Xi/xigrabdev.c                                   |    9 
 Xi/xipassivegrab.c                               |   12 
 Xi/xiproperty.c                                  |   14 
 Xi/xiquerydevice.c                               |    1 
 Xi/xiquerypointer.c                              |    2 
 Xi/xiselectev.c                                  |    8 
 Xi/xisetclientpointer.c                          |    3 
 Xi/xisetdevfocus.c                               |    4 
 Xi/xiwarppointer.c                               |    2 
 config/udev.c                                    |   37 +
 configure.ac                                     |    9 
 dbe/dbe.c                                        |   17 
 devbook.am                                       |   10 
 dix/Xserver.d                                    |    5 
 dix/devices.c                                    |    2 
 dix/dispatch.c                                   |    8 
 dix/events.c                                     |    8 
 dix/getevents.c                                  |   13 
 dix/region.c                                     |   20 
 dix/resource.c                                   |    5 
 doc/Makefile.am                                  |    2 
 doc/filter-xmlto.sh                              |   21 
 dri3/dri3_request.c                              |    6 
 glamor/glamor.c                                  |   58 +-
 glamor/glamor.h                                  |    4 
 glamor/glamor_egl.c                              |   89 ++--
 glamor/glamor_egl_stubs.c                        |    2 
 glamor/glamor_fbo.c                              |    7 
 glamor/glamor_priv.h                             |    5 
 glamor/glamor_xv.c                               |   26 -
 glx/clientinfo.c                                 |   20 
 glx/glxcmds.c                                    |  167 ++++---
 glx/glxcmdsswap.c                                |    4 
 glx/glxext.c                                     |    8 
 glx/glxext.h                                     |    1 
 glx/glxserver.h                                  |   43 +-
 glx/indirect_program.c                           |    2 
 glx/indirect_reqsize.c                           |  142 +++---
 glx/indirect_reqsize.h                           |  181 +++++---
 glx/indirect_texture_compression.c               |    4 
 glx/indirect_util.c                              |    9 
 glx/rensize.c                                    |  114 +++--
 glx/single2.c                                    |   23 -
 glx/single2swap.c                                |   19 
 glx/singlepix.c                                  |   60 +-
 glx/singlepixswap.c                              |   50 +-
 glx/swap_interval.c                              |    2 
 glx/unpack.h                                     |    3 
 hw/dmx/config/dmxparse.h                         |    3 
 hw/dmx/config/dmxprint.c                         |   20 
 hw/dmx/dmx.c                                     |    1 
 hw/dmx/dmxcb.c                                   |    3 
 hw/dmx/dmxfont.h                                 |    2 
 hw/dmx/dmxgc.c                                   |    4 
 hw/dmx/dmxgc.h                                   |    4 
 hw/dmx/dmxinit.c                                 |   42 -
 hw/dmx/dmxpict.c                                 |    1 
 hw/dmx/dmxprop.c                                 |    6 
 hw/dmx/dmxscrinit.c                              |    1 
 hw/dmx/dmxwindow.c                               |    4 
 hw/dmx/glxProxy/compsize.h                       |    7 
 hw/dmx/glxProxy/g_disptab.h                      |   21 
 hw/dmx/glxProxy/glxcmds.c                        |    7 
 hw/dmx/glxProxy/glxcmds.h                        |    6 
 hw/dmx/glxProxy/glxcmdsswap.c                    |    2 
 hw/dmx/glxProxy/glxext.h                         |    1 
 hw/dmx/glxProxy/glxscreens.c                     |    6 
 hw/dmx/glxProxy/glxscreens.h                     |    2 
 hw/dmx/glxProxy/glxserver.h                      |    8 
 hw/dmx/glxProxy/glxsingle.c                      |    6 
 hw/dmx/glxProxy/glxsingle.h                      |    4 
 hw/dmx/glxProxy/glxswap.c                        |    4 
 hw/dmx/glxProxy/glxvendor.c                      |    6 
 hw/dmx/input/dmxinputinit.c                      |   10 
 hw/kdrive/ephyr/ephyr.c                          |   10 
 hw/kdrive/ephyr/ephyr.h                          |    1 
 hw/kdrive/ephyr/hostx.c                          |   11 
 hw/kdrive/ephyr/hostx.h                          |    2 
 hw/xfree86/Makefile.am                           |    2 
 hw/xfree86/Xorg.sh.in                            |    4 
 hw/xfree86/common/xf86AutoConfig.c               |    1 
 hw/xfree86/common/xf86Module.h                   |    4 
 hw/xfree86/dri2/dri2.c                           |    9 
 hw/xfree86/dri2/dri2ext.c                        |    3 
 hw/xfree86/drivers/modesetting/Makefile.am       |    3 
 hw/xfree86/drivers/modesetting/dri2.c            |    2 
 hw/xfree86/drivers/modesetting/driver.c          |  106 ++---
 hw/xfree86/drivers/modesetting/driver.h          |   15 
 hw/xfree86/drivers/modesetting/drmmode_display.c |  487 ++++++++++++++---------
 hw/xfree86/drivers/modesetting/drmmode_display.h |   37 +
 hw/xfree86/drivers/modesetting/dumb_bo.c         |  134 ++++++
 hw/xfree86/drivers/modesetting/dumb_bo.h         |   45 ++
 hw/xfree86/drivers/modesetting/present.c         |  228 ++++++++++
 hw/xfree86/drivers/modesetting/vblank.c          |   37 +
 hw/xfree86/man/Xorg.wrap.man                     |    2 
 hw/xfree86/os-support/solaris/sun_init.c         |   33 -
 hw/xfree86/os-support/xf86_OSlib.h               |    5 
 hw/xfree86/xorg-wrapper.c                        |   10 
 hw/xnest/Keyboard.c                              |    9 
 hw/xwayland/Makefile.am                          |    1 
 hw/xwayland/xwayland-glamor.c                    |    6 
 hw/xwayland/xwayland-input.c                     |    7 
 hw/xwayland/xwayland.c                           |    2 
 hw/xwin/InitOutput.c                             |    4 
 hw/xwin/XWin.rc                                  |    1 
 hw/xwin/man/XWin.man                             |    6 
 hw/xwin/winclipboard/internal.h                  |   14 
 hw/xwin/winclipboard/thread.c                    |   56 +-
 hw/xwin/winclipboard/winclipboard.h              |    2 
 hw/xwin/winclipboard/wndproc.c                   |  227 ++++++----
 hw/xwin/winclipboard/xevents.c                   |  175 ++++----
 hw/xwin/winclipboard/xwinclip.c                  |    7 
 hw/xwin/winclipboard/xwinclip.man                |    3 
 hw/xwin/winclipboardwrappers.c                   |    6 
 hw/xwin/winprocarg.c                             |   27 -
 hw/xwin/winresource.h                            |    1 
 hw/xwin/wintrayicon.c                            |   19 
 hw/xwin/winwndproc.c                             |    6 
 include/Makefile.am                              |    1 
 include/dix.h                                    |    7 
 include/probes.h                                 |   41 +
 include/regionstr.h                              |   10 
 man/Xserver.man                                  |   10 
 mi/miarc.c                                       |   15 
 mi/mipointer.c                                   |    9 
 os/WaitFor.c                                     |   41 +
 os/access.c                                      |    6 
 os/connection.c                                  |   12 
 os/io.c                                          |    7 
 os/log.c                                         |    7 
 os/osinit.c                                      |    6 
 os/rpcauth.c                                     |    4 
 os/xsha1.c                                       |   25 +
 present/present.c                                |   32 -
 present/present_request.c                        |    6 
 randr/rroutput.c                                 |    7 
 randr/rrscreen.c                                 |   22 -
 randr/rrsdispatch.c                              |    4 
 randr/rrxinerama.c                               |   12 
 render/picture.c                                 |   45 +-
 render/render.c                                  |   20 
 test/Makefile.am                                 |    2 
 test/misc.c                                      |   37 +
 test/xi1/Makefile.am                             |   34 +
 test/xi1/protocol-xchangedevicecontrol.c         |  122 +++++
 test/xi2/protocol-xigetclientpointer.c           |    5 
 test/xi2/protocol-xipassivegrabdevice.c          |    8 
 test/xi2/protocol-xiquerypointer.c               |    4 
 test/xi2/protocol-xiwarppointer.c                |    3 
 xfixes/select.c                                  |    1 
 xkb/xkb.c                                        |  100 ++--
 162 files changed, 2727 insertions(+), 1231 deletions(-)

New commits:
commit 3a06faf3fcdb7451125a46181f9152e8e59e9770
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Feb 10 22:16:49 2015 -0800

    Mark development version for 1.18
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 2b46552..280c369 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,7 +26,7 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.60)
-AC_INIT([xorg-server], 1.17.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+AC_INIT([xorg-server], 1.17.99.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
 RELEASE_DATE="2015-02-02"
 RELEASE_NAME="Côte de veau"
 AC_CONFIG_SRCDIR([Makefile.am])
commit 4a758f59a8a65c313244e06852745c8e180ff247
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 22:38:26 2014 -0800

    dmx: include header for DMXExtensionInit() in dmx.c
    
    Gets rid of gcc 4.8 warning:
    
    dmx.c:1193:1: warning: no previous prototype for ‘DMXExtensionInit’ [-Wmissing-prototypes]
     DMXExtensionInit(void)
     ^
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/dmx.c b/hw/dmx/dmx.c
index 99e970c..2988df3 100644
--- a/hw/dmx/dmx.c
+++ b/hw/dmx/dmx.c
@@ -55,6 +55,7 @@
 #include "extinit.h"
 #include "opaque.h"
 
+#include "dmx.h"
 #include "dmxextension.h"
 #include <X11/extensions/dmxproto.h>
 #include <X11/extensions/dmx.h>
commit a0e44ddfb0c641e7896a55abf26621ae3d17e337
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 22:33:54 2014 -0800

    dmx: constify GCOps & GCFuncs pointers
    
    Gets rid of 16 instances of gcc 4.8 warnings:
    
    In file included from dmxgc.c:41:0:
    dmx.h:327:23: warning: assignment discards ‘const’ qualifier from
     pointer target type [enabled by default]
         (_saved)->_entry  = (_actual)->_entry;    \
                           ^
    dmxgc.h:80:5: note: in expansion of macro ‘DMX_WRAP’
         DMX_WRAP(funcs, &dmxGCFuncs, _pGCPriv, (_pGC));   \
         ^
    dmxgc.c:192:5: note: in expansion of macro ‘DMX_GC_FUNC_EPILOGUE’
         DMX_GC_FUNC_EPILOGUE(pGC);
         ^
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/dmxgc.c b/hw/dmx/dmxgc.c
index 2343167..ec15d27 100644
--- a/hw/dmx/dmxgc.c
+++ b/hw/dmx/dmxgc.c
@@ -49,7 +49,7 @@
 #include "pixmapstr.h"
 #include "migc.h"
 
-static GCFuncs dmxGCFuncs = {
+static const GCFuncs dmxGCFuncs = {
     dmxValidateGC,
     dmxChangeGC,
     dmxCopyGC,
@@ -59,7 +59,7 @@ static GCFuncs dmxGCFuncs = {
     dmxCopyClip,
 };
 
-static GCOps dmxGCOps = {
+static const GCOps dmxGCOps = {
     dmxFillSpans,
     dmxSetSpans,
     dmxPutImage,
diff --git a/hw/dmx/dmxgc.h b/hw/dmx/dmxgc.h
index c8ecb53..c5c6b77 100644
--- a/hw/dmx/dmxgc.h
+++ b/hw/dmx/dmxgc.h
@@ -41,8 +41,8 @@
 
 /** GC private area. */
 typedef struct _dmxGCPriv {
-    GCOps *ops;
-    GCFuncs *funcs;
+    const GCOps *ops;
+    const GCFuncs *funcs;
     XlibGC gc;
     Bool msc;
 } dmxGCPrivRec, *dmxGCPrivPtr;
commit 9682c47e228962e4008855c4da7467748742685e
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 22:20:24 2014 -0800

    dmx: Mark glxIsExtensionSupported as a const char *
    
    Gets rid of 9 instances of gcc 4.8 warning:
    
    glxcmds.c: In function ‘CreateContext’:
    glxcmds.c:378:13: warning: passing argument 1 of ‘glxIsExtensionSupported’
     discards ‘const’ qualifier from pointer target type [enabled by default]
                 else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
                 ^
    In file included from glxserver.h:49:0,
                     from glxcmds.c:41:
    glxscreens.h:53:12: note: expected ‘char *’ but argument is of type
     ‘const char *’
     extern int glxIsExtensionSupported(char *ext);
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/glxProxy/glxscreens.c b/hw/dmx/glxProxy/glxscreens.c
index b62776c..15bb1e8 100644
--- a/hw/dmx/glxProxy/glxscreens.c
+++ b/hw/dmx/glxProxy/glxscreens.c
@@ -335,7 +335,7 @@ __glXGetServerString(unsigned int name)
 }
 
 int
-glxIsExtensionSupported(char *ext)
+glxIsExtensionSupported(const char *ext)
 {
     return (strstr(ExtensionsString, ext) != NULL);
 }
diff --git a/hw/dmx/glxProxy/glxscreens.h b/hw/dmx/glxProxy/glxscreens.h
index 9a538d1..bb7477b 100644
--- a/hw/dmx/glxProxy/glxscreens.h
+++ b/hw/dmx/glxProxy/glxscreens.h
@@ -50,6 +50,6 @@ extern void __glXScreenReset(void);
 
 extern char *__glXGetServerString(unsigned int name);
 
-extern int glxIsExtensionSupported(char *ext);
+extern int glxIsExtensionSupported(const char *ext);
 
 #endif                          /* !__GLX_screens_h__ */
commit 45ec646d77086eeb5f94766b055a93b5c75bdef0
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 22:16:49 2014 -0800

    dmx: remove redundant redeclarations of variables from other headers
    
    Gets rid of these gcc 4.8 warnings:
    
    dmxcb.c:50:12: warning: redundant redeclaration of ‘PanoramiXPixWidth’
     [-Wredundant-decls]
     extern int PanoramiXPixWidth;
                ^
    In file included from dmxcb.c:49:0:
    ../../Xext/panoramiXsrv.h:12:22: note: previous declaration of
     ‘PanoramiXPixWidth’ was here
     extern _X_EXPORT int PanoramiXPixWidth;
                          ^
    dmxcb.c:51:12: warning: redundant redeclaration of ‘PanoramiXPixHeight’
     [-Wredundant-decls]
     extern int PanoramiXPixHeight;
                ^
    In file included from dmxcb.c:49:0:
    ../../Xext/panoramiXsrv.h:13:22: note: previous declaration of
     ‘PanoramiXPixHeight’ was here
     extern _X_EXPORT int PanoramiXPixHeight;
                          ^
    dmxcb.c:52:12: warning: redundant redeclaration of ‘PanoramiXNumScreens’
     [-Wredundant-decls]
     extern int PanoramiXNumScreens;
                ^
    In file included from dmxcb.c:49:0:
    ../../Xext/panoramiXsrv.h:11:22: note: previous declaration of
     ‘PanoramiXNumScreens’ was here
     extern _X_EXPORT int PanoramiXNumScreens;
                          ^
    
    dmxpict.c:60:12: warning: redundant redeclaration of ‘RenderErrBase’
     [-Wredundant-decls]
     extern int RenderErrBase;
                ^
    In file included from ../../render/glyphstr.h:29:0,
                     from ../../render/picturestr.h:28,
                     from dmx.h:65,
                     from dmxpict.c:42:
    ../../render/picture.h:176:22: note: previous declaration of ‘RenderErrBase’
     was here
     extern _X_EXPORT int RenderErrBase;
                          ^
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/dmxcb.c b/hw/dmx/dmxcb.c
index 86015f3..cca5702 100644
--- a/hw/dmx/dmxcb.c
+++ b/hw/dmx/dmxcb.c
@@ -47,9 +47,6 @@ extern int connBlockScreenStart;
 
 #ifdef PANORAMIX
 #include "panoramiXsrv.h"
-extern int PanoramiXPixWidth;
-extern int PanoramiXPixHeight;
-extern int PanoramiXNumScreens;
 #endif
 
 int dmxGlobalWidth, dmxGlobalHeight;
diff --git a/hw/dmx/dmxpict.c b/hw/dmx/dmxpict.c
index 64d0ae1..aaca178 100644
--- a/hw/dmx/dmxpict.c
+++ b/hw/dmx/dmxpict.c
@@ -57,7 +57,6 @@
 #include "mipict.h"
 #include "fbpict.h"
 
-extern int RenderErrBase;
 extern int (*ProcRenderVector[RenderNumberRequests]) (ClientPtr);
 
 static int (*dmxSaveRenderVector[RenderNumberRequests]) (ClientPtr);
commit 1033b85196e0f25877b4b9081993aff16bf32138
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 22:13:28 2014 -0800

    dmx: remove redundant declaration of dmxFontPrivateIndex from dmxfont.h
    
    Gets rid of 8 instances of gcc 4.8 warning:
    
    In file included from glxcmds.c:38:0:
    ../../../hw/dmx/dmxfont.h:57:12: warning: redundant redeclaration of
     ‘dmxFontPrivateIndex’ [-Wredundant-decls]
     extern int dmxFontPrivateIndex;
                ^
    In file included from glxcmds.c:35:0:
    ../../../hw/dmx/dmx.h:388:12: note: previous declaration of
     ‘dmxFontPrivateIndex’ was here
     extern int dmxFontPrivateIndex;        /**< Private index for Fonts     */
                ^
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/dmxfont.h b/hw/dmx/dmxfont.h
index 8575ca9..66c6633 100644
--- a/hw/dmx/dmxfont.h
+++ b/hw/dmx/dmxfont.h
@@ -54,6 +54,4 @@ extern Bool dmxUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
 extern Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont);
 extern Bool dmxBEFreeFont(ScreenPtr pScreen, FontPtr pFont);
 
-extern int dmxFontPrivateIndex;
-
 #endif                          /* DMXFONT_H */
commit ac64a653fb4935a799baca7545ba6ca401e20fa1
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 22:09:14 2014 -0800

    dmx: glxproxy prototype cleanup
    
    Gets rid of 107 -Wmissing-prototypes & -Wredundant-decls warnings
    from gcc 4.8
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/glxProxy/compsize.h b/hw/dmx/glxProxy/compsize.h
index 3609662..5e759b0 100644
--- a/hw/dmx/glxProxy/compsize.h
+++ b/hw/dmx/glxProxy/compsize.h
@@ -48,4 +48,11 @@ extern GLint __glTexGeniv_size(GLenum e);
 extern GLint __glTexParameterfv_size(GLenum e);
 extern GLint __glTexParameteriv_size(GLenum e);
 
+extern GLint __glCallLists_size(GLsizei n, GLenum type);
+extern GLint __glDrawPixels_size(GLenum format, GLenum type, GLsizei w, GLsizei h);
+extern GLint __glBitmap_size(GLsizei w, GLsizei h);
+extern GLint __glTexImage1D_size(GLenum format, GLenum type, GLsizei w);
+extern GLint __glTexImage2D_size(GLenum format, GLenum type, GLsizei w, GLsizei h);
+extern GLint __glTexImage3D_size(GLenum format, GLenum type, GLsizei w, GLsizei h, GLsizei d);
+
 #endif                          /* !__compsize_h__ */
diff --git a/hw/dmx/glxProxy/g_disptab.h b/hw/dmx/glxProxy/g_disptab.h
index 5303387..783f87a 100644
--- a/hw/dmx/glxProxy/g_disptab.h
+++ b/hw/dmx/glxProxy/g_disptab.h
@@ -655,7 +655,6 @@ extern void __glXDispSwap_CopyConvolutionFilter2D(GLbyte *);
 extern void __glXDispSwap_SeparableFilter2D(GLbyte *);
 extern void __glXDispSwap_TexImage3D(GLbyte *);
 extern void __glXDispSwap_TexSubImage3D(GLbyte *);
-extern void __glXDispSwap_DrawArrays(GLbyte *);
 extern void __glXDispSwap_PrioritizeTextures(GLbyte *);
 extern void __glXDispSwap_CopyTexImage1D(GLbyte *);
 extern void __glXDispSwap_CopyTexImage2D(GLbyte *);
@@ -663,6 +662,26 @@ extern void __glXDispSwap_CopyTexSubImage1D(GLbyte *);
 extern void __glXDispSwap_CopyTexSubImage2D(GLbyte *);
 extern void __glXDispSwap_CopyTexSubImage3D(GLbyte *);
 
+extern void __glXDispSwap_BindTexture(GLbyte *);
+extern void __glXDispSwap_BlendColor(GLbyte *);
+extern void __glXDispSwap_BlendEquation(GLbyte *);
+extern void __glXDispSwap_ColorTable(GLbyte *);
+extern void __glXDispSwap_ColorTableParameterfv(GLbyte *);
+extern void __glXDispSwap_ColorTableParameteriv(GLbyte *);
+extern void __glXDispSwap_CopyColorTable(GLbyte *);
+extern void __glXDispSwap_ConvolutionParameterf(GLbyte *);
+extern void __glXDispSwap_ConvolutionParameteri(GLbyte *);
+extern void __glXDispSwap_Histogram(GLbyte *);
+extern void __glXDispSwap_Minmax(GLbyte *);
+extern void __glXDispSwap_ResetHistogram(GLbyte *);
+extern void __glXDispSwap_ResetMinmax(GLbyte *);
+
+extern int __glXSwapCreateContextWithConfigSGIX(__GLXclientState *, GLbyte *);
+extern int __glXSwapBindSwapBarrierSGIX(__GLXclientState *, GLbyte *);
+extern int __glXSwapJoinSwapGroupSGIX(__GLXclientState *, GLbyte *);
+extern int __glXSwapQueryMaxSwapBarriersSGIX(__GLXclientState *, GLbyte *);
+extern int __glXSwapMakeCurrentReadSGI(__GLXclientState *, GLbyte *);
+
 #define __GLX_MIN_GLXCMD_OPCODE 1
 #define __GLX_MAX_GLXCMD_OPCODE 20
 #define __GLX_MIN_RENDER_OPCODE 1
diff --git a/hw/dmx/glxProxy/glxcmds.c b/hw/dmx/glxProxy/glxcmds.c
index 88c2eb1..4c500c9 100644
--- a/hw/dmx/glxProxy/glxcmds.c
+++ b/hw/dmx/glxProxy/glxcmds.c
@@ -61,7 +61,6 @@
 extern __GLXFBConfig **__glXFBConfigs;
 extern int __glXNumFBConfigs;
 
-extern int glxIsExtensionSupported(char *ext);
 extern int __glXGetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc);
 
 #define BE_TO_CLIENT_ERROR(x) \
diff --git a/hw/dmx/glxProxy/glxcmds.h b/hw/dmx/glxProxy/glxcmds.h
index b074592..689e334 100644
--- a/hw/dmx/glxProxy/glxcmds.h
+++ b/hw/dmx/glxProxy/glxcmds.h
@@ -33,5 +33,11 @@ extern int __glXCreateContextWithConfigSGIX(__GLXclientState * cl, GLbyte * pc);
 extern int __glXJoinSwapGroupSGIX(__GLXclientState * cl, GLbyte * pc);
 extern int __glXMakeCurrentReadSGI(__GLXclientState * cl, GLbyte * pc);
 extern int __glXQueryMaxSwapBarriersSGIX(__GLXclientState * cl, GLbyte * pc);
+extern int __glXDoSwapBuffers(__GLXclientState * cl, XID drawId,
+                              GLXContextTag tag);
+
+extern Display *GetBackEndDisplay(__GLXclientState * cl, int s);
+extern int GetCurrentBackEndTag(__GLXclientState * cl, GLXContextTag tag,
+                                int s);
 
 #endif                          /* !__GLX_cmds_h__ */
diff --git a/hw/dmx/glxProxy/glxcmdsswap.c b/hw/dmx/glxProxy/glxcmdsswap.c
index ab3e7ed..600a6e1 100644
--- a/hw/dmx/glxProxy/glxcmdsswap.c
+++ b/hw/dmx/glxProxy/glxcmdsswap.c
@@ -39,8 +39,6 @@
 #include "glxext.h"
 #include "glxvendor.h"
 
-extern int glxIsExtensionSupported(char *ext);
-
 int __glXSwapGetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc);
 
 /************************************************************************/
diff --git a/hw/dmx/glxProxy/glxext.h b/hw/dmx/glxProxy/glxext.h
index 47cec15..b96ebc1 100644
--- a/hw/dmx/glxProxy/glxext.h
+++ b/hw/dmx/glxProxy/glxext.h
@@ -53,6 +53,7 @@ extern void __glXFlushContextCache(void);
 
 extern void __glXFreeGLXWindow(__glXWindow * pGlxWindow);
 extern void __glXFreeGLXPixmap(__GLXpixmap * pGlxPixmap);
+extern void __glXFreeGLXPbuffer(__glXPbuffer * pGlxPbuffer);
 
 extern void __glXNoSuchRenderOpcode(GLbyte *);
 extern int __glXNoSuchSingleOpcode(__GLXclientState *, GLbyte *);
diff --git a/hw/dmx/glxProxy/glxscreens.h b/hw/dmx/glxProxy/glxscreens.h
index a9fe2a9..9a538d1 100644
--- a/hw/dmx/glxProxy/glxscreens.h
+++ b/hw/dmx/glxProxy/glxscreens.h
@@ -50,4 +50,6 @@ extern void __glXScreenReset(void);
 
 extern char *__glXGetServerString(unsigned int name);
 
+extern int glxIsExtensionSupported(char *ext);
+
 #endif                          /* !__GLX_screens_h__ */
diff --git a/hw/dmx/glxProxy/glxserver.h b/hw/dmx/glxProxy/glxserver.h
index 754ad30..7aa5ad2 100644
--- a/hw/dmx/glxProxy/glxserver.h
+++ b/hw/dmx/glxProxy/glxserver.h
@@ -149,9 +149,7 @@ extern __GLXclientState *__glXClients[];
 typedef void (*__GLXdispatchRenderProcPtr) (GLbyte *);
 typedef int (*__GLXdispatchSingleProcPtr) (__GLXclientState *, GLbyte *);
 typedef int (*__GLXdispatchVendorPrivProcPtr) (__GLXclientState *, GLbyte *);
-extern __GLXdispatchSingleProcPtr __glXSingleTable[];
 extern __GLXdispatchVendorPrivProcPtr __glXVendorPrivTable_EXT[];
-extern __GLXdispatchSingleProcPtr __glXSwapSingleTable[];
 extern __GLXdispatchVendorPrivProcPtr __glXSwapVendorPrivTable_EXT[];
 extern __GLXdispatchRenderProcPtr __glXSwapRenderTable[];
 
@@ -193,9 +191,6 @@ extern RESTYPE __glXPbufferRes;
 
 extern char *__glXcombine_strings(const char *, const char *);
 
-extern void __glXDisp_DrawArrays(GLbyte *);
-extern void __glXDispSwap_DrawArrays(GLbyte *);
-
 /*
 ** Routines for sending swapped replies.
 */
@@ -287,9 +282,6 @@ extern int __glXConvolutionParameterfvSize(GLenum pname);
 extern int __glXColorTableParameterfvSize(GLenum pname);
 extern int __glXColorTableParameterivSize(GLenum pname);
 
-extern void __glXFreeGLXWindow(__glXWindow * pGlxWindow);
-extern void __glXFreeGLXPbuffer(__glXPbuffer * pGlxPbuffer);
-
 extern int __glXVersionMajor;
 extern int __glXVersionMinor;
 
diff --git a/hw/dmx/glxProxy/glxsingle.c b/hw/dmx/glxProxy/glxsingle.c
index 0344973..79d426b 100644
--- a/hw/dmx/glxProxy/glxsingle.c
+++ b/hw/dmx/glxProxy/glxsingle.c
@@ -45,6 +45,8 @@
 /* #include "g_disptab_EXT.h" */
 #include "unpack.h"
 #include "glxutil.h"
+#include "glxcmds.h"
+#include "glxsingle.h"
 
 #include "GL/glxproto.h"
 
@@ -81,10 +83,6 @@
 
 #define X_GLXSingle 0           /* needed by GetReqExtra */
 
-extern Display *GetBackEndDisplay(__GLXclientState * cl, int s);
-extern int GetCurrentBackEndTag(__GLXclientState * cl, GLXContextTag tag,
-                                int s);
-
 static int swap_vec_element_size = 0;
 
 static void
diff --git a/hw/dmx/glxProxy/glxsingle.h b/hw/dmx/glxProxy/glxsingle.h
index 32a9d49..6126177 100644
--- a/hw/dmx/glxProxy/glxsingle.h
+++ b/hw/dmx/glxProxy/glxsingle.h
@@ -47,8 +47,4 @@ extern int __glXForwardAllWithReplySwapsv(__GLXclientState * cl, GLbyte * pc);
 extern int __glXForwardAllWithReplySwapiv(__GLXclientState * cl, GLbyte * pc);
 extern int __glXForwardAllWithReplySwapdv(__GLXclientState * cl, GLbyte * pc);
 
-extern int __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc);
-extern int __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc);
-extern int __glXDispSwap_GetColorTable(__GLXclientState * cl, GLbyte * pc);
-
 #endif
diff --git a/hw/dmx/glxProxy/glxswap.c b/hw/dmx/glxProxy/glxswap.c
index 5f56501..bc18e55 100644
--- a/hw/dmx/glxProxy/glxswap.c
+++ b/hw/dmx/glxProxy/glxswap.c
@@ -39,9 +39,7 @@
 #include "dmxwindow.h"
 #include "glxserver.h"
 #include "glxswap.h"
-
-extern int __glXDoSwapBuffers(__GLXclientState * cl, XID drawId,
-                              GLXContextTag tag);
+#include "glxcmds.h"
 
 typedef struct _SwapGroup *SwapGroupPtr;
 
diff --git a/hw/dmx/glxProxy/glxvendor.c b/hw/dmx/glxProxy/glxvendor.c
index fc8aff0..52d70eb 100644
--- a/hw/dmx/glxProxy/glxvendor.c
+++ b/hw/dmx/glxProxy/glxvendor.c
@@ -44,6 +44,8 @@
 /* #include "g_disptab_EXT.h" */
 #include "unpack.h"
 #include "glxutil.h"
+#include "glxcmds.h"
+#include "glxvendor.h"
 
 #include "GL/glxproto.h"
 
@@ -78,10 +80,6 @@
 	dpy->request++
 #endif
 
-extern Display *GetBackEndDisplay(__GLXclientState * cl, int s);
-extern int GetCurrentBackEndTag(__GLXclientState * cl, GLXContextTag tag,
-                                int s);
-
 static int swap_vec_element_size = 0;
 
 static void
commit bd563fd48f909094d6660854e97811ad7e676ddf
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 21:11:17 2014 -0800

    dmx: more unshadowing of variables
    
    Gets rid of gcc 4.8 warnings:
    
    dmxinputinit.c: In function ‘dmxInputScanForExtensions’:
    dmxinputinit.c:877:14: warning: declaration of ‘display’ shadows a global declaration [-Wshadow]
         Display *display;
                  ^
    In file included from ../../../include/windowstr.h:60:0,
                     from dmxinputinit.c:72:
    ../../../include/opaque.h:52:30: warning: shadowed declaration is here [-Wshadow]
     extern _X_EXPORT const char *display;
                                  ^
    
    glxcmds.c: In function ‘__glXCreatePbuffer’:
    glxcmds.c:3397:21: warning: declaration of ‘pc’ shadows a parameter [-Wshadow]
                 CARD32 *pc = (CARD32 *) (be_req + 1);
                         ^
    glxcmds.c:3314:52: warning: shadowed declaration is here [-Wshadow]
     __glXCreatePbuffer(__GLXclientState * cl, GLbyte * pc)
                                                        ^
    
    glxscreens.c: In function ‘CalcServerVersionAndExtensions’:
    glxscreens.c:139:35: warning: declaration of ‘req’ shadows a previous local [-Wshadow]
             xGLXQueryServerStringReq *req;
                                       ^
    glxscreens.c:68:26: warning: shadowed declaration is here [-Wshadow]
         xGLXQueryVersionReq *req;
                              ^
    glxscreens.c:140:36: warning: declaration of ‘reply’ shadows a previous local [-Wshadow]
             xGLXQueryServerStringReply reply;
                                        ^
    glxscreens.c:69:27: warning: shadowed declaration is here [-Wshadow]
         xGLXQueryVersionReply reply;
                               ^
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/glxProxy/glxcmds.c b/hw/dmx/glxProxy/glxcmds.c
index fb4d5ac..88c2eb1 100644
--- a/hw/dmx/glxProxy/glxcmds.c
+++ b/hw/dmx/glxProxy/glxcmds.c
@@ -3394,11 +3394,11 @@ __glXCreatePbuffer(__GLXclientState * cl, GLbyte * pc)
 
         /* Send attributes */
         if (attr != NULL) {
-            CARD32 *pc = (CARD32 *) (be_req + 1);
+            CARD32 *pca = (CARD32 *) (be_req + 1);
 
             while (numAttribs-- > 0) {
-                *pc++ = *attr++;        /* token */
-                *pc++ = *attr++;        /* value */
+                *pca++ = *attr++;        /* token */
+                *pca++ = *attr++;        /* value */
             }
         }
 
diff --git a/hw/dmx/glxProxy/glxscreens.c b/hw/dmx/glxProxy/glxscreens.c
index 138afed..b62776c 100644
--- a/hw/dmx/glxProxy/glxscreens.c
+++ b/hw/dmx/glxProxy/glxscreens.c
@@ -65,8 +65,6 @@ static void
 CalcServerVersionAndExtensions(void)
 {
     int s;
-    xGLXQueryVersionReq *req;
-    xGLXQueryVersionReply reply;
     char **be_extensions;
     char *ext;
     char *denied_extensions;
@@ -80,6 +78,8 @@ CalcServerVersionAndExtensions(void)
     for (s = 0; s < __glXNumActiveScreens; s++) {
         DMXScreenInfo *dmxScreen = &dmxScreens[s];
         Display *dpy = dmxScreen->beDisplay;
+        xGLXQueryVersionReq *req;
+        xGLXQueryVersionReply reply;
 
         /* Send the glXQueryVersion request */
         LockDisplay(dpy);
diff --git a/hw/dmx/input/dmxinputinit.c b/hw/dmx/input/dmxinputinit.c
index abb6a85..56a39df 100644
--- a/hw/dmx/input/dmxinputinit.c
+++ b/hw/dmx/input/dmxinputinit.c
@@ -874,17 +874,17 @@ dmxInputScanForExtensions(DMXInputInfo * dmxInput, int doXI)
 {
     XExtensionVersion *ext;
     XDeviceInfo *devices;
-    Display *display;
+    Display *dsp;
     int num;
     int i, j;
     XextErrorHandler handler;
 
-    if (!(display = XOpenDisplay(dmxInput->name)))
+    if (!(dsp = XOpenDisplay(dmxInput->name)))
         return;
 
     /* Print out information about the XInput Extension. */
     handler = XSetExtensionErrorHandler(dmxInputExtensionErrorHandler);
-    ext = XGetExtensionVersion(display, INAME);
+    ext = XGetExtensionVersion(dsp, INAME);
     XSetExtensionErrorHandler(handler);
 
     if (!ext || ext == (XExtensionVersion *) NoSuchExtension) {
@@ -894,7 +894,7 @@ dmxInputScanForExtensions(DMXInputInfo * dmxInput, int doXI)
         dmxLogInput(dmxInput, "Locating devices on %s (%s version %d.%d)\n",
                     dmxInput->name, INAME,
                     ext->major_version, ext->minor_version);
-        devices = XListInputDevices(display, &num);
+        devices = XListInputDevices(dsp, &num);
 
         XFree(ext);
         ext = NULL;
@@ -956,7 +956,7 @@ dmxInputScanForExtensions(DMXInputInfo * dmxInput, int doXI)
         }
         XFreeDeviceList(devices);
     }
-    XCloseDisplay(display);
+    XCloseDisplay(dsp);
 }
 
 /** Re-initialize all the devices described in \a dmxInput.  Called from
commit 57e08fae82f733304200a473f55b86e689404c13
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 21:07:12 2014 -0800

    dmx: attempt to untangle nested loops using same index variable
    
    This doesn't just make gcc sad, it makes my brain sad.
    
    Change from:
        for (i = 0; i < dmxNumScreens; i++) {
            int i;
            for (i = 0; i < nconfigs; i++) {
                for (j = 0; j < dmxScreen->beNumVisuals; j++) {
    
    to the easier to follow:
        for (i = 0; i < dmxNumScreens; i++) {
            for (j = 0; j < nconfigs; j++) {
                for (k = 0; k < dmxScreen->beNumVisuals; k++) {
    
    Gets rid of gcc 4.8 warning:
    
    dmxinit.c: In function ‘InitOutput’:
    dmxinit.c:765:17: warning: declaration of ‘i’ shadows a previous local [-Wshadow]
                 int i;
                     ^
    dmxinit.c:608:9: warning: shadowed declaration is here [-Wshadow]
         int i;
             ^
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c
index 37961b8..025dc86 100644
--- a/hw/dmx/dmxinit.c
+++ b/hw/dmx/dmxinit.c
@@ -762,7 +762,6 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
             dmxGlxVisualPrivate **configprivs = NULL;
             int nconfigs = 0;
             int (*oldErrorHandler) (Display *, XErrorEvent *);
-            int i;
 
             /* Catch errors if when using an older GLX w/o FBconfigs */
             oldErrorHandler = XSetErrorHandler(dmxNOPErrorHandler);
@@ -797,28 +796,29 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
             configprivs = malloc(nconfigs * sizeof(dmxGlxVisualPrivate *));
 
             if (configs != NULL && configprivs != NULL) {
+                int j;
 
                 /* Initialize our private info for each visual
                  * (currently only x_visual_depth and x_visual_class)
                  */
-                for (i = 0; i < nconfigs; i++) {
+                for (j = 0; j < nconfigs; j++) {
 
-                    configprivs[i] = (dmxGlxVisualPrivate *)
+                    configprivs[j] = (dmxGlxVisualPrivate *)
                         malloc(sizeof(dmxGlxVisualPrivate));
-                    configprivs[i]->x_visual_depth = 0;
-                    configprivs[i]->x_visual_class = 0;
+                    configprivs[j]->x_visual_depth = 0;
+                    configprivs[j]->x_visual_class = 0;
 
                     /* Find the visual depth */
-                    if (configs[i].vid > 0) {
-                        int j;
-
-                        for (j = 0; j < dmxScreen->beNumVisuals; j++) {
-                            if (dmxScreen->beVisuals[j].visualid ==
-                                configs[i].vid) {
-                                configprivs[i]->x_visual_depth =
-                                    dmxScreen->beVisuals[j].depth;
-                                configprivs[i]->x_visual_class =
-                                    dmxScreen->beVisuals[j].class;
+                    if (configs[j].vid > 0) {
+                        int k;
+
+                        for (k = 0; k < dmxScreen->beNumVisuals; k++) {
+                            if (dmxScreen->beVisuals[k].visualid ==
+                                configs[j].vid) {
+                                configprivs[j]->x_visual_depth =
+                                    dmxScreen->beVisuals[k].depth;
+                                configprivs[j]->x_visual_class =
+                                    dmxScreen->beVisuals[k].class;
                                 break;
                             }
                         }
commit 0fbebad72428abbc9fc3fa9f406f7a7e1b9d95b2
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 20:53:33 2014 -0800

    dmx: remove unused variables
    
    Gets rid of gcc 4.8 warnings:
    
    dmxscrinit.c: In function ‘dmxBEScreenInit’:
    dmxscrinit.c:83:15: warning: unused variable ‘gcvals’ [-Wunused-variable]
         XGCValues gcvals;
                   ^
    
    dmxwindow.c: In function ‘dmxResizeWindow’:
    dmxwindow.c:860:19: warning: variable ‘pSibPriv’ set but not used [-Wunused-but-set-variable]
         dmxWinPrivPtr pSibPriv;
                       ^
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/dmxscrinit.c b/hw/dmx/dmxscrinit.c
index 963d3a9..097418d 100644
--- a/hw/dmx/dmxscrinit.c
+++ b/hw/dmx/dmxscrinit.c
@@ -80,7 +80,6 @@ dmxBEScreenInit(ScreenPtr pScreen)
 {
     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
     XSetWindowAttributes attribs;
-    XGCValues gcvals;
     unsigned long mask;
     int i, j;
 
diff --git a/hw/dmx/dmxwindow.c b/hw/dmx/dmxwindow.c
index c753735..c157e10 100644
--- a/hw/dmx/dmxwindow.c
+++ b/hw/dmx/dmxwindow.c
@@ -857,13 +857,9 @@ dmxResizeWindow(WindowPtr pWindow, int x, int y,
     ScreenPtr pScreen = pWindow->drawable.pScreen;
     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
     dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-    dmxWinPrivPtr pSibPriv;
     unsigned int m;
     XWindowChanges c;
 
-    if (pSib)
-        pSibPriv = DMX_GET_WINDOW_PRIV(pSib);
-
     DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
 #if 1
     if (pScreen->ResizeWindow)
commit f358f0d50cadaf10f7d97e21da00419a4a37c4e1
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 19:09:36 2014 -0800

    dmx: fix printf format argument warnings
    
    Gets rid of these gcc 4.8 warnings:
    
    dmxinit.c: In function ‘dmxErrorHandler’:
    dmxinit.c:167:16: warning: format ‘%x’ expects argument of type ‘unsigned int’,
     but argument 3 has type ‘XID64’ [-Wformat=]
                    ev->resourceid);
                    ^
    dmxinit.c:171:16: warning: format ‘%x’ expects argument of type ‘unsigned int’,
     but argument 3 has type ‘XID64’ [-Wformat=]
                    ev->resourceid);
                    ^
    dmxinit.c:175:16: warning: format ‘%x’ expects argument of type ‘unsigned int’,
     but argument 3 has type ‘XID64’ [-Wformat=]
                    ev->resourceid);
                    ^
    dmxinit.c:181:12: warning: format ‘%d’ expects argument of type ‘int’,
     but argument 3 has type ‘long unsigned int’ [-Wformat=]
                ev->serial);
                ^
    dmxinit.c:183:12: warning: format ‘%d’ expects argument of type ‘int’,
     but argument 3 has type ‘long unsigned int’ [-Wformat=]
                dpy->request);
                ^
    dmxinit.c: In function ‘InitOutput’:
    dmxinit.c:637:9: warning: format ‘%d’ expects argument of type ‘int’,
     but argument 3 has type ‘long unsigned int’ [-Wformat=]
             dmxLog(dmxInfo, "Generation:         %d\n", dmxGeneration);
             ^
    
    dmxprop.c: In function ‘dmxPropertyCheckOtherWindows’:
    dmxprop.c:223:24: warning: format ‘%lu’ expects argument of type ‘long
     unsigned int’, but argument 4 has type ‘Window’ [-Wformat=]
                            dmxScreen->name, win, tp.value);
                            ^
    dmxprop.c: In function ‘dmxPropertyWindow’:
    dmxprop.c:364:16: warning: format ‘%lu’ expects argument of type ‘long
     unsigned int’, but argument 5 has type ‘Window’ [-Wformat=]
                    other->index, other->name, other->scrnWin);
                    ^
    dmxprop.c:364:16: warning: format ‘%lu’ expects argument of type ‘long
     unsigned int’, but argument 8 has type ‘Window’ [-Wformat=]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c
index fd2ade0..37961b8 100644
--- a/hw/dmx/dmxinit.c
+++ b/hw/dmx/dmxinit.c
@@ -164,23 +164,23 @@ dmxErrorHandler(Display * dpy, XErrorEvent * ev)
     switch (ev->error_code) {
     case BadValue:
         dmxLog(dmxWarning, "                 Value:        0x%x\n",
-               ev->resourceid);
+               (unsigned int) ev->resourceid);
         break;
     case BadAtom:
         dmxLog(dmxWarning, "                 AtomID:       0x%x\n",
-               ev->resourceid);
+               (unsigned int) ev->resourceid);
         break;
     default:
         dmxLog(dmxWarning, "                 ResourceID:   0x%x\n",
-               ev->resourceid);
+               (unsigned int) ev->resourceid);
         break;
     }
 
     /* Provide serial number information */
     dmxLog(dmxWarning, "                 Failed serial number:  %d\n",
-           ev->serial);
+           (unsigned int) ev->serial);
     dmxLog(dmxWarning, "                 Current serial number: %d\n",
-           dpy->request);
+           (unsigned int) dpy->request);
     return 0;
 }
 
@@ -634,7 +634,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
         if (major > 0 && minor > 0)
             year += 2000;
 
-        dmxLog(dmxInfo, "Generation:         %d\n", dmxGeneration);
+        dmxLog(dmxInfo, "Generation:         %lu\n", dmxGeneration);
         dmxLog(dmxInfo, "DMX version:        %d.%d.%02d%02d%02d (%s)\n",
                major, minor, year, month, day, VENDOR_STRING);
 
diff --git a/hw/dmx/dmxprop.c b/hw/dmx/dmxprop.c
index 4be2dbd..5e306d2 100644
--- a/hw/dmx/dmxprop.c
+++ b/hw/dmx/dmxprop.c
@@ -220,7 +220,7 @@ dmxPropertyCheckOtherWindows(DMXScreenInfo * dmxScreen, Atom atom)
 
             if (XGetTextProperty(dpy, win, &tp, atom) && tp.nitems) {
                 dmxLog(dmxDebug, "On %s/%lu: %s\n",
-                       dmxScreen->name, win, tp.value);
+                       dmxScreen->name, (unsigned long) win, tp.value);
                 if (!strncmp((char *) tp.value, (char *) id,
                              strlen((char *) id))) {
                     int idx;
@@ -360,8 +360,8 @@ dmxPropertyWindow(DMXScreenInfo * dmxScreen)
         dmxScreen->next = (other->next ? other->next : other);
         other->next = (tmp ? tmp : dmxScreen);
         dmxLog(dmxDebug, "%d/%s/%lu and %d/%s/%lu are on the same backend\n",
-               dmxScreen->index, dmxScreen->name, dmxScreen->scrnWin,
-               other->index, other->name, other->scrnWin);
+               dmxScreen->index, dmxScreen->name, (unsigned long) dmxScreen->scrnWin,
+               other->index, other->name, (unsigned long) other->scrnWin);
     }
 
     snprintf(buf, sizeof(buf), ".%d,%lu", dmxScreen->index,
commit 11af200b004b4810c9267e3e16449c3175c64d4a
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 18:58:01 2014 -0800

    dmx: move format strings inline so gcc can check
    
    Gets rid of gcc 4.8 warnings:
    
    dmxprint.c: In function ‘dmxConfigPrintPair’:
    dmxprint.c:284:25: warning: format not a string literal,
      argument types not checked [-Wformat-nonliteral]
                             p->ysign < 0 ? '-' : '+', p->y);
                             ^
    dmxprint.c:289:9: warning: format not a string literal,
      argument types not checked [-Wformat-nonliteral]
             dmxConfigOutput(addSpace, 0, p->comment, format, p->x, p->y);
             ^
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/config/dmxprint.c b/hw/dmx/config/dmxprint.c
index 536d92b..c80e830 100644
--- a/hw/dmx/config/dmxprint.c
+++ b/hw/dmx/config/dmxprint.c
@@ -261,32 +261,20 @@ dmxConfigPrintString(DMXConfigStringPtr p, int quote)
 static int
 dmxConfigPrintPair(DMXConfigPairPtr p, int addSpace)
 {
-    const char *format = NULL;
-
     if (!p)
         return 0;
-    switch (p->token) {
-    case T_ORIGIN:
-        format = "@%dx%d";
-        break;
-    case T_DIMENSION:
-        format = "%dx%d";
-        break;
-    case T_OFFSET:
-        format = "%c%d%c%d";
-        break;
-    }
     if (p->token == T_OFFSET) {
         if (!p->comment && !p->x && !p->y && p->xsign >= 0 && p->ysign >= 0)
             return 0;
-        dmxConfigOutput(addSpace, 0, p->comment, format,
+        dmxConfigOutput(addSpace, 0, p->comment, "%c%d%c%d",
                         p->xsign < 0 ? '-' : '+', p->x,
                         p->ysign < 0 ? '-' : '+', p->y);
     }
     else {
         if (!p->comment && !p->x && !p->y)
             return 0;
-        dmxConfigOutput(addSpace, 0, p->comment, format, p->x, p->y);
+        dmxConfigOutput(addSpace, 0, p->comment, "%s%dx%d",
+                        (p->token == T_ORIGIN) ? "@" : "", p->x, p->y);
     }
     return 1;
 }
commit 5e01eac10e915568324aff81b51d3af558757042
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Dec 12 18:52:05 2014 -0800

    dmx: Add _X_ATTRIBUTE_PRINTF to dmxConfigLog() & dmxConfigOutput()
    
    Gets rid of gcc 4.8 warnings:
    
    dmxparse.c: In function ‘dmxConfigLog’:
    dmxparse.c:61:5: warning: function might be possible candidate for
     ‘gnu_printf’ format attribute [-Wsuggest-attribute=format]
         vprintf(format, args);      /* RATS: All calls to dmxConfigLog from
         ^
    
    dmxprint.c: In function ‘dmxConfigOutput’:
    dmxprint.c:149:9: warning: function might be possible candidate for
     ‘gnu_printf’ format attribute [-Wsuggest-attribute=format]
             pos += vfprintf(str, format, args);     /* assumes no newlines! */
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rémi Cardona <remi at gentoo.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/config/dmxparse.h b/hw/dmx/config/dmxparse.h
index 7d31b63..cc2f0eb 100644
--- a/hw/dmx/config/dmxparse.h
+++ b/hw/dmx/config/dmxparse.h
@@ -38,6 +38,7 @@
 #define _DMXPARSE_H_
 
 #include <stdio.h>              /* For FILE */
+#include <X11/Xfuncproto.h>     /* For _X_ATTRIBUTE_PRINTF */
 
 /** Stores tokens not stored in other structures (e.g., keywords and ;) */
 typedef struct _DMXConfigToken {
@@ -203,7 +204,7 @@ extern int yylex(void);
 extern int yydebug;
 extern void yyerror(const char *message);
 
-extern void dmxConfigLog(const char *format, ...);
+extern void dmxConfigLog(const char *format, ...) _X_ATTRIBUTE_PRINTF(1,0);
 extern void *dmxConfigAlloc(unsigned long bytes);
 extern void *dmxConfigRealloc(void *orig,
                               unsigned long orig_bytes, unsigned long bytes);
diff --git a/hw/dmx/config/dmxprint.c b/hw/dmx/config/dmxprint.c
index 9dec52b..536d92b 100644
--- a/hw/dmx/config/dmxprint.c
+++ b/hw/dmx/config/dmxprint.c
@@ -130,7 +130,7 @@ dmxConfigPopState(void)
     dmxConfigNewline();
 }
 
-static void
+static void _X_ATTRIBUTE_PRINTF(4, 5)
 dmxConfigOutput(int addSpace, int doNewline, const char *comment,
                 const char *format, ...)
 {
commit 9e002dfcd71439fd81563db1f70e8c1964d52fab
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Dec 9 18:27:11 2014 -0800

    Get rid of const warnings in XSERVER_INPUT_EVENT dtrace probe calls
    
    Use typedefs to work around dtrace dropping const qualifiers from probe
    arguments when generating Xserver-dtrace.h.   Add new probes.h header to
    avoid having to replicate these typedefs in every file with dtrace probes.
    
    Gets rid of these warnings from gcc 4.8:
     getevents.c:1096:9:
      warning: passing argument 6 of '__dtrace_Xserver___input__event' discards
      'const' qualifier from pointer target type [enabled by default]
     getevents.c:1096:9:
      warning: passing argument 7 of '__dtrace_Xserver___input__event' disards
      'const' qualifier from pointer target type [enabled by default]
     getevents.c:1651:9:
      warning: passing argument 6 of '__dtrace_Xserver___input__event' disards
      'const' qualifier from pointer target type [enabled by default]
     getevents.c:1651:9:
      warning: passing argument 7 of '__dtrace_Xserver___input__event' disards
      'const' qualifier from pointer target type [enabled by default]
     getevents.c:1791:9:
      warning: passing argument 6 of '__dtrace_Xserver___input__event' disards
      'const' qualifier from pointer target type [enabled by default]
     getevents.c:1791:9:
      warning: passing argument 7 of '__dtrace_Xserver___input__event' disards
      'const' qualifier from pointer target type [enabled by default]
     getevents.c:1921:9:
      warning: passing argument 6 of '__dtrace_Xserver___input__event' disards
      'const' qualifier from pointer target type [enabled by default]
     getevents.c:1921:9:
      warning: passing argument 7 of '__dtrace_Xserver___input__event' disards
      'const' qualifier from pointer target type [enabled by default]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/Xserver.d b/dix/Xserver.d
index 248d48e..f4f229d 100644
--- a/dix/Xserver.d
+++ b/dix/Xserver.d
@@ -31,6 +31,9 @@
 #include <sys/types.h>
 #endif
 
+typedef const uint8_t *const_uint8_p;
+typedef const double *const_double_p;
+
 provider Xserver {
 	/* reqType, data, length, client id, request buffer */
 	probe request__start(string, uint8_t, uint16_t, int, void *);
@@ -49,7 +52,7 @@ provider Xserver {
 	/* client id, event type, event* */
 	probe send__event(int, uint8_t, void *);
 	/* deviceid, type, button/keycode/touchid, flags, nvalues, mask, values */
-	probe input__event(int, int, uint32_t, uint32_t, int8_t, uint8_t*, double*);
+	probe input__event(int, int, uint32_t, uint32_t, int8_t, const_uint8_p, const_double_p);
 };
 
 #pragma D attributes Unstable/Unstable/Common provider Xserver provider
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 9044ac7..17fa75e 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -131,10 +131,7 @@ int ProcInitialConnection();
 
 #ifdef XSERVER_DTRACE
 #include "registry.h"
-#include <sys/types.h>
-typedef const char *string;
-
-#include "Xserver-dtrace.h"
+#include "probes.h"
 #endif
 
 #define mskcnt ((MAXCLIENTS + 31) / 32)
diff --git a/dix/events.c b/dix/events.c
index b8c67fd..c232eba 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -125,13 +125,7 @@ Equipment Corporation.
 #include <X11/extensions/XKBproto.h>
 #include "xkbsrv.h"
 #include "xace.h"
-
-#ifdef XSERVER_DTRACE
-#include <sys/types.h>
-typedef const char *string;
-
-#include "Xserver-dtrace.h"
-#endif
+#include "probes.h"
 
 #include <X11/extensions/XIproto.h>
 #include <X11/extensions/XI2proto.h>
diff --git a/dix/getevents.c b/dix/getevents.c
index 6fb12c5..bc7ffa6 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -68,12 +68,7 @@
 #include "exevents.h"
 #include "extnsionst.h"
 #include "listdev.h"            /* for sizing up DeviceClassesChangedEvent */
-
-#if XSERVER_DTRACE
-#include <sys/types.h>
-typedef const char *string;
-#include <Xserver-dtrace.h>
-#endif
+#include "probes.h"
 
 /* Number of motion history events to store. */
 #define MOTION_HISTORY_SIZE 256
diff --git a/dix/resource.c b/dix/resource.c
index 26debdb..964f0b3 100644
--- a/dix/resource.c
+++ b/dix/resource.c
@@ -144,10 +144,7 @@ Equipment Corporation.
 #include "gcstruct.h"
 
 #ifdef XSERVER_DTRACE
-#include <sys/types.h>
-typedef const char *string;
-
-#include "Xserver-dtrace.h"
+#include "probes.h"
 
 #define TypeNameString(t) LookupResourceName(t)
 #endif
diff --git a/include/Makefile.am b/include/Makefile.am
index 6578038..168b00f 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -71,6 +71,7 @@ EXTRA_DIST = 	\
 	busfault.h dbus-core.h \
 	dix-config-apple-verbatim.h \
 	dixfontstubs.h eventconvert.h eventstr.h inpututils.h \
+	probes.h \
 	protocol-versions.h \
 	systemd-logind.h \
 	xsha1.h
diff --git a/include/probes.h b/include/probes.h
new file mode 100644
index 0000000..e9cdd3e
--- /dev/null
+++ b/include/probes.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef XORG_PROBES_H
+#define XORG_PROBES_H
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+/* definitions needed to include Dtrace probes in a source file */
+
+#if XSERVER_DTRACE
+#include <sys/types.h>
+typedef const char *string;
+typedef const uint8_t *const_uint8_p;
+typedef const double *const_double_p;
+#include "../dix/Xserver-dtrace.h"
+#endif
+
+#endif /* XORG_PROBES_H */
diff --git a/os/connection.c b/os/connection.c
index da3397d..ddfe50a 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -113,17 +113,11 @@ SOFTWARE.
 #ifdef HAVE_GETPEERUCRED
 #include <ucred.h>
 #include <zone.h>
-#endif
-
-#ifdef XSERVER_DTRACE
-#include <sys/types.h>
-typedef const char *string;
-
-#ifndef HAVE_GETPEERUCRED
+#else
 #define zoneid_t int
 #endif
-#include "../dix/Xserver-dtrace.h"
-#endif
+
+#include "probes.h"
 
 static int lastfdesc;           /* maximum file descriptor */
 
commit 20079c36cf7d377938ca5478447d8b9045cb7d43
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Jan 16 08:44:45 2015 +0100

    xkb: Check strings length against request size
    
    Ensure that the given strings length in an XkbSetGeometry request remain
    within the limits of the size of the request.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.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/xkb.c b/xkb/xkb.c
index b9a3ac4..f3988f9 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -4957,25 +4957,29 @@ ProcXkbGetGeometry(ClientPtr client)
 
 /***====================================================================***/
 
-static char *
-_GetCountedString(char **wire_inout, Bool swap)
+static Status
+_GetCountedString(char **wire_inout, ClientPtr client, char **str)
 {
-    char *wire, *str;
+    char *wire, *next;
     CARD16 len;
 
     wire = *wire_inout;
     len = *(CARD16 *) wire;
-    if (swap) {
+    if (client->swapped) {
         swaps(&len);
     }
-    str = malloc(len + 1);
-    if (str) {
-        memcpy(str, &wire[2], len);
-        str[len] = '\0';
-    }
-    wire += XkbPaddedSize(len + 2);
-    *wire_inout = wire;
-    return str;
+    next = wire + XkbPaddedSize(len + 2);
+    /* Check we're still within the size of the request */
+    if (client->req_len <
+        bytes_to_int32(next - (char *) client->requestBuffer))
+        return BadValue;
+    *str = malloc(len + 1);
+    if (!*str)
+        return BadAlloc;
+    memcpy(*str, &wire[2], len);
+    *(*str + len) = '\0';
+    *wire_inout = next;
+    return Success;
 }
 
 static Status
@@ -4987,6 +4991,7 @@ _CheckSetDoodad(char **wire_inout,
     xkbAnyDoodadWireDesc any;
     xkbTextDoodadWireDesc text;
     XkbDoodadPtr doodad;
+    Status status;
 
     dWire = (xkbDoodadWireDesc *) (*wire_inout);
     any = dWire->any;
@@ -5036,8 +5041,14 @@ _CheckSetDoodad(char **wire_inout,
         doodad->text.width = text.width;
         doodad->text.height = text.height;
         doodad->text.color_ndx = dWire->text.colorNdx;
-        doodad->text.text = _GetCountedString(&wire, client->swapped);
-        doodad->text.font = _GetCountedString(&wire, client->swapped);
+        status = _GetCountedString(&wire, client, &doodad->text.text);
+        if (status != Success)
+            return status;
+        status = _GetCountedString(&wire, client, &doodad->text.font);
+        if (status != Success) {
+            free (doodad->text.text);
+            return status;
+        }
         break;
     case XkbIndicatorDoodad:
         if (dWire->indicator.onColorNdx >= geom->num_colors) {
@@ -5072,7 +5083,9 @@ _CheckSetDoodad(char **wire_inout,
         }
         doodad->logo.color_ndx = dWire->logo.colorNdx;
         doodad->logo.shape_ndx = dWire->logo.shapeNdx;
-        doodad->logo.logo_name = _GetCountedString(&wire, client->swapped);
+        status = _GetCountedString(&wire, client, &doodad->logo.logo_name);
+        if (status != Success)
+            return status;
         break;
     default:
         client->errorValue = _XkbErrCode2(0x4F, dWire->any.type);
@@ -5304,18 +5317,20 @@ _CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client)
     char *wire;
 
     wire = (char *) &req[1];
-    geom->label_font = _GetCountedString(&wire, client->swapped);
+    status = _GetCountedString(&wire, client, &geom->label_font);
+    if (status != Success)
+        return status;
 
     for (i = 0; i < req->nProperties; i++) {
         char *name, *val;
 
-        name = _GetCountedString(&wire, client->swapped);
-        if (!name)
-            return BadAlloc;
-        val = _GetCountedString(&wire, client->swapped);
-        if (!val) {
+        status = _GetCountedString(&wire, client, &name);
+        if (status != Success)
+            return status;
+        status = _GetCountedString(&wire, client, &val);
+        if (status != Success) {
             free(name);
-            return BadAlloc;
+            return status;
         }
         if (XkbAddGeomProperty(geom, name, val) == NULL) {
             free(name);
@@ -5349,9 +5364,9 @@ _CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client)
     for (i = 0; i < req->nColors; i++) {
         char *name;
 
-        name = _GetCountedString(&wire, client->swapped);
-        if (!name)
-            return BadAlloc;
+        status = _GetCountedString(&wire, client, &name);
+        if (status != Success)
+            return status;
         if (!XkbAddGeomColor(geom, name, geom->num_colors)) {
             free(name);
             return BadAlloc;
commit 81c90dc8f0aae3b65730409b1b615b5fa7280ebd
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Jan 16 20:08:59 2015 +0100

    xkb: Don't swap XkbSetGeometry data in the input buffer
    
    The XkbSetGeometry request embeds data which needs to be swapped when the
    server and the client have different endianess.
    
    _XkbSetGeometry() invokes functions that swap these data directly in the
    input buffer.
    
    However, ProcXkbSetGeometry() may call _XkbSetGeometry() more than once
    (if there is more than one keyboard), thus causing on swapped clients the
    same data to be swapped twice in memory, further causing a server crash
    because the strings lengths on the second time are way off bounds.
    
    To allow _XkbSetGeometry() to run reliably more than once with swapped
    clients, do not swap the data in the buffer, use variables instead.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkb.c b/xkb/xkb.c
index 15c7f34..b9a3ac4 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -4961,14 +4961,13 @@ static char *
 _GetCountedString(char **wire_inout, Bool swap)
 {
     char *wire, *str;
-    CARD16 len, *plen;
+    CARD16 len;
 
     wire = *wire_inout;
-    plen = (CARD16 *) wire;
+    len = *(CARD16 *) wire;
     if (swap) {
-        swaps(plen);
+        swaps(&len);
     }
-    len = *plen;
     str = malloc(len + 1);
     if (str) {
         memcpy(str, &wire[2], len);
@@ -4985,25 +4984,28 @@ _CheckSetDoodad(char **wire_inout,
 {
     char *wire;
     xkbDoodadWireDesc *dWire;
+    xkbAnyDoodadWireDesc any;
+    xkbTextDoodadWireDesc text;
     XkbDoodadPtr doodad;
 
     dWire = (xkbDoodadWireDesc *) (*wire_inout);
+    any = dWire->any;
     wire = (char *) &dWire[1];
     if (client->swapped) {
-        swapl(&dWire->any.name);
-        swaps(&dWire->any.top);
-        swaps(&dWire->any.left);
-        swaps(&dWire->any.angle);
+        swapl(&any.name);
+        swaps(&any.top);
+        swaps(&any.left);
+        swaps(&any.angle);
     }
     CHK_ATOM_ONLY(dWire->any.name);
-    doodad = XkbAddGeomDoodad(geom, section, dWire->any.name);
+    doodad = XkbAddGeomDoodad(geom, section, any.name);
     if (!doodad)
         return BadAlloc;
     doodad->any.type = dWire->any.type;
     doodad->any.priority = dWire->any.priority;
-    doodad->any.top = dWire->any.top;
-    doodad->any.left = dWire->any.left;
-    doodad->any.angle = dWire->any.angle;
+    doodad->any.top = any.top;
+    doodad->any.left = any.left;
+    doodad->any.angle = any.angle;
     switch (doodad->any.type) {
     case XkbOutlineDoodad:
     case XkbSolidDoodad:
@@ -5026,12 +5028,13 @@ _CheckSetDoodad(char **wire_inout,
                                               dWire->text.colorNdx);
             return BadMatch;
         }
+        text = dWire->text;
         if (client->swapped) {
-            swaps(&dWire->text.width);
-            swaps(&dWire->text.height);
+            swaps(&text.width);
+            swaps(&text.height);
         }
-        doodad->text.width = dWire->text.width;
-        doodad->text.height = dWire->text.height;
+        doodad->text.width = text.width;
+        doodad->text.height = text.height;
         doodad->text.color_ndx = dWire->text.colorNdx;
         doodad->text.text = _GetCountedString(&wire, client->swapped);
         doodad->text.font = _GetCountedString(&wire, client->swapped);
commit 28f6427aec1f5a1982e1c01eff45af0d401bf659
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Feb 2 07:41:06 2015 +0100

    Update to version 1.17.0
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 1434727..2b46552 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.16.99.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2015-01-23"
-RELEASE_NAME="TimTam"
+AC_INIT([xorg-server], 1.17.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2015-02-02"
+RELEASE_NAME="Côte de veau"
 AC_CONFIG_SRCDIR([Makefile.am])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
commit 697b696e5e24d0679f133183a3bb0852025377c2
Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Jan 30 09:59:49 2015 +1000

    config/udev: Respect seat assignments when assigned devices
    
    Jonathan Dieter posted a few patches to do this inside the Xorg
    server but it makes no sense to do it there, just have the code
    we use to probe the device list at startup check seat assignments
    using the same code we check at hotplug time.
    
    Bugilla: https://bugzilla.redhat.com/show_bug.cgi?id=1183654
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Hans de Goede <hdegoede at redhat.com>
    Tested-by: Jonathan Dieter <jdieter at lesbg.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/config/udev.c b/config/udev.c
index 1d2140a..28c2658 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -69,6 +69,24 @@ static const char *itoa(int i)
     return itoa_buf;
 }
 
+static Bool
+check_seat(struct udev_device *udev_device)
+{
+    const char *dev_seat;
+
+    dev_seat = udev_device_get_property_value(udev_device, "ID_SEAT");
+    if (!dev_seat)
+        dev_seat = "seat0";
+
+    if (SeatId && strcmp(dev_seat, SeatId))
+        return FALSE;
+
+    if (!SeatId && strcmp(dev_seat, "seat0"))
+        return FALSE;
+
+    return TRUE;
+}
+
 static void
 device_added(struct udev_device *udev_device)
 {
@@ -83,7 +101,6 @@ device_added(struct udev_device *udev_device)
     struct udev_list_entry *set, *entry;
     struct udev_device *parent;
     int rc;
-    const char *dev_seat;
     dev_t devnum;
 
     path = udev_device_get_devnode(udev_device);
@@ -93,14 +110,7 @@ device_added(struct udev_device *udev_device)
     if (!path || !syspath)
         return;
 
-    dev_seat = udev_device_get_property_value(udev_device, "ID_SEAT");
-    if (!dev_seat)
-        dev_seat = "seat0";
-
-    if (SeatId && strcmp(dev_seat, SeatId))
-        return;
-
-    if (!SeatId && strcmp(dev_seat, "seat0"))
+    if (!check_seat(udev_device))
         return;
 
     devnum = udev_device_get_devnum(udev_device);
@@ -505,6 +515,8 @@ config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback)
             goto no_probe;
         else if (strncmp(sysname, "card", 4) != 0)
             goto no_probe;
+        else if (!check_seat(udev_device))
+            goto no_probe;
 
         config_udev_odev_setup_attribs(path, syspath, major(devnum),
                                        minor(devnum), probe_callback);
commit df1b401f57ad4b4925bad66684445b476562f26f
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jan 7 09:19:27 2015 +1000

    randr: attempt to fix primary on slave output (v2)
    
    If the user wants to set one of the slave devices as
    the primary output, we shouldn't fail to do so,
    we were returning BadMatch which was tripping up
    gnome-settings-daemon and bad things ensues.
    
    Fix all the places we use primaryOutput to work
    out primaryCrtc and take it into a/c when slave
    gpus are in use.
    
    v2: review from Aaron, fix indent, unhide has_primary from
    macro. I left the int vs Bool alone to be consistent with
    code below, a future patch could fix both.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/randr/rroutput.c b/randr/rroutput.c
index 5d46fac..548e07d 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -541,7 +541,11 @@ ProcRRSetOutputPrimary(ClientPtr client)
     if (stuff->output) {
         VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
 
-        if (output->pScreen != pWin->drawable.pScreen) {
+        if (!output->pScreen->isGPU && output->pScreen != pWin->drawable.pScreen) {
+            client->errorValue = stuff->window;
+            return BadMatch;
+        }
+        if (output->pScreen->isGPU && output->pScreen->current_master != pWin->drawable.pScreen) {
             client->errorValue = stuff->window;
             return BadMatch;
         }
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index 36179ae..e7ea49d 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -322,8 +322,13 @@ static inline void swap_modeinfos(xRRModeInfo *modeinfos, int i)
     swapl(&modeinfos[i].modeFlags);
 }
 
-#define update_arrays(gpuscreen, pScrPriv) do {            \
+#define update_arrays(gpuscreen, pScrPriv, primary_crtc, has_primary) do {            \
     for (j = 0; j < pScrPriv->numCrtcs; j++) {             \
+        if (has_primary && \
+            primary_crtc == pScrPriv->crtcs[j]) { \
+            has_primary = 0;   \
+            continue; \
+        }\
         crtcs[crtc_count] = pScrPriv->crtcs[j]->id;        \
         if (client->swapped)                               \
             swapl(&crtcs[crtc_count]);                     \
@@ -366,9 +371,11 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
     unsigned long extraLen;
     CARD8 *extra;
     RRCrtc *crtcs;
+    RRCrtcPtr primary_crtc = NULL;
     RROutput *outputs;
     xRRModeInfo *modeinfos;
     CARD8 *names;
+    int has_primary = 0;
 
     /* we need to iterate all the GPU masters and all their output slaves */
     total_crtcs = 0;
@@ -426,18 +433,25 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
     modeinfos = (xRRModeInfo *)(outputs + total_outputs);
     names = (CARD8 *)(modeinfos + total_modes);
 
-    /* TODO primary */
     crtc_count = 0;
     output_count = 0;
     mode_count = 0;
 
     pScrPriv = rrGetScrPriv(pScreen);
-    update_arrays(pScreen, pScrPriv);
+    if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
+        has_primary = 1;
+        primary_crtc = pScrPriv->primaryOutput->crtc;
+        crtcs[0] = pScrPriv->primaryOutput->crtc->id;
+        if (client->swapped)
+            swapl(&crtcs[0]);
+        crtc_count = 1;
+    }
+    update_arrays(pScreen, pScrPriv, primary_crtc, has_primary);
 
     xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
         pScrPriv = rrGetScrPriv(iter);
 
-        update_arrays(iter, pScrPriv);
+        update_arrays(iter, pScrPriv, primary_crtc, has_primary);
     }
 
     assert(bytes_to_int32((char *) names - (char *) extra) == rep.length);
diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c
index 26894a6..b336bd7 100644
--- a/randr/rrxinerama.c
+++ b/randr/rrxinerama.c
@@ -344,15 +344,17 @@ ProcRRXineramaQueryScreens(ClientPtr client)
         ScreenPtr slave;
         rrScrPriv(pScreen);
         int has_primary = 0;
+        RRCrtcPtr primary_crtc = NULL;
 
         if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
             has_primary = 1;
+            primary_crtc = pScrPriv->primaryOutput->crtc;
             RRXineramaWriteCrtc(client, pScrPriv->primaryOutput->crtc);
         }
 
         for (i = 0; i < pScrPriv->numCrtcs; i++) {
             if (has_primary &&
-                pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i]) {
+                primary_crtc == pScrPriv->crtcs[i]) {
                 has_primary = 0;
                 continue;
             }
@@ -362,8 +364,14 @@ ProcRRXineramaQueryScreens(ClientPtr client)
         xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
             rrScrPrivPtr pSlavePriv;
             pSlavePriv = rrGetScrPriv(slave);
-            for (i = 0; i < pSlavePriv->numCrtcs; i++)
+            for (i = 0; i < pSlavePriv->numCrtcs; i++) {
+                if (has_primary &&
+                    primary_crtc == pSlavePriv->crtcs[i]) {
+                    has_primary = 0;
+                    continue;
+                }
                 RRXineramaWriteCrtc(client, pSlavePriv->crtcs[i]);
+            }
         }
     }
 
commit 62fcd364ac8c71a2db1db84b17b17cade6832492
Author: Adel Gadllah <adel.gadllah at gmail.com>
Date:   Sat Jan 3 21:12:25 2015 +0100

    dri2: Set vdpau driver name if ddx does not provide any driver name
    
    Currently when the ddx does not set any driver name we set DRI2 driver but
    not the VDPAU driver name. The result is that VDPAU drivers will not get found
    by libvdpau when the modesetting driver is being used.
    
    Just assume that the VDPAU driver matches the DRI2 driver name, this is true
    for nouveau, r300, r600 and radeonsi i.e all VDPAU drivers currently supported
    by mesa.
    
    Signed-off-by: Adel Gadllah <adel.gadllah at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 0b43369..0c038b3 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -1576,15 +1576,15 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
 
     if (info->version == 3 || info->numDrivers == 0) {
         /* Driver too old: use the old-style driverName field */
-        ds->numDrivers = 1;
-        ds->driverNames = malloc(sizeof(*ds->driverNames));
+        ds->numDrivers = info->driverName ? 1 : 2;
+        ds->driverNames = malloc(ds->numDrivers * sizeof(*ds->driverNames));
         if (!ds->driverNames)
             goto err_out;
 
         if (info->driverName) {
             ds->driverNames[0] = info->driverName;
         } else {
-            ds->driverNames[0] = dri2_probe_driver_name(pScreen, info);
+            ds->driverNames[0] = ds->driverNames[1] = dri2_probe_driver_name(pScreen, info);
             if (!ds->driverNames[0])
                 return FALSE;
         }
commit fe4c774c572e3f55a7417f0ca336ae1479a966ad
Author: Nikhil Mahale <nmahale at nvidia.com>
Date:   Sat Jan 24 17:06:59 2015 -0800

    os: Fix timer race conditions
    
    Fixing following kind of race-conditions -
    
        WaitForSomething()
        |
        ---->  // timers -> timer-1 -> timer-2 -> null
               while (timers && (int) (timers->expires - now) <= 0)
                   // prototype - DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev)
                   DoTimer(timers, now, &timers)
                   |
                   |
                   ----> OsBlockSignals();  .... OS Signal comes just before blocking it,
                                            .... timer-1 handler gets called.
                                                 // timer-1 gets served and scheduled again;
                                                 // timers -> timer-2 -> timer-1 -> null
                                            ....
                         *prev = timer->next;
                          timer->next = NULL;   // timers -> null
                          // timers list gets corrupted here and timer-2 gets removed from list.
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=86288
    Signed-off-by: Nikhil Mahale <nmahale at nvidia.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    
    v2: Apply warning fixes from Keith Packard <keithp at keithp.com>
    
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/WaitFor.c b/os/WaitFor.c
index 86d96c8..431f1a6 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -121,9 +121,9 @@ struct _OsTimerRec {
     void *arg;
 };
 
-static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev);
+static void DoTimer(OsTimerPtr timer, CARD32 now, volatile OsTimerPtr *prev);
 static void CheckAllTimers(void);
-static OsTimerPtr timers = NULL;
+static volatile OsTimerPtr timers = NULL;
 
 /*****************
  * WaitForSomething:
@@ -263,11 +263,14 @@ WaitForSomething(int *pClientsReady)
                 if ((int) (timers->expires - now) <= 0)
                     expired = 1;
 
-                while (timers && (int) (timers->expires - now) <= 0)
-                    DoTimer(timers, now, &timers);
+                if (expired) {
+                    OsBlockSignals();
+                    while (timers && (int) (timers->expires - now) <= 0)
+                        DoTimer(timers, now, &timers);
+                    OsReleaseSignals();
 
-                if (expired)
                     return 0;
+                }
             }
         }
         else {
@@ -281,11 +284,14 @@ WaitForSomething(int *pClientsReady)
                     if ((int) (timers->expires - now) <= 0)
                         expired = 1;
 
-                    while (timers && (int) (timers->expires - now) <= 0)
-                        DoTimer(timers, now, &timers);
+                    if (expired) {
+                        OsBlockSignals();
+                        while (timers && (int) (timers->expires - now) <= 0)
+                            DoTimer(timers, now, &timers);
+                        OsReleaseSignals();
 
-                    if (expired)
                         return 0;
+                    }
                 }
             }
             if (someReady)
@@ -401,24 +407,25 @@ CheckAllTimers(void)
 }
 
 static void
-DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev)
+DoTimer(OsTimerPtr timer, CARD32 now, volatile OsTimerPtr *prev)
 {
     CARD32 newTime;
 
     OsBlockSignals();
     *prev = timer->next;
     timer->next = NULL;
+    OsReleaseSignals();
+
     newTime = (*timer->callback) (timer, now, timer->arg);
     if (newTime)
         TimerSet(timer, 0, newTime, timer->callback, timer->arg);
-    OsReleaseSignals();
 }
 
 OsTimerPtr
 TimerSet(OsTimerPtr timer, int flags, CARD32 millis,
          OsTimerCallback func, void *arg)
 {
-    register OsTimerPtr *prev;
+    volatile OsTimerPtr *prev;
     CARD32 now = GetTimeInMillis();
 
     if (!timer) {
@@ -470,7 +477,7 @@ Bool
 TimerForce(OsTimerPtr timer)
 {
     int rc = FALSE;
-    OsTimerPtr *prev;
+    volatile OsTimerPtr *prev;
 
     OsBlockSignals();
     for (prev = &timers; *prev; prev = &(*prev)->next) {
@@ -487,7 +494,7 @@ TimerForce(OsTimerPtr timer)
 void
 TimerCancel(OsTimerPtr timer)
 {
-    OsTimerPtr *prev;
+    volatile OsTimerPtr *prev;
 
     if (!timer)
         return;
@@ -515,8 +522,12 @@ TimerCheck(void)
 {
     CARD32 now = GetTimeInMillis();
 
-    while (timers && (int) (timers->expires - now) <= 0)
-        DoTimer(timers, now, &timers);
+    if (timers && (int) (timers->expires - now) <= 0) {
+        OsBlockSignals();
+        while (timers && (int) (timers->expires - now) <= 0)
+            DoTimer(timers, now, &timers);
+        OsReleaseSignals();
+    }
 }
 
 void
commit 58f28b0427f0a0c0c445f314bd42721ca8e1e844
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Jan 23 10:59:39 2015 -0800

    Update to version 1.16.99.902
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index b593fc7..1434727 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.16.99.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2014-10-28"
-RELEASE_NAME="Chanterelle"
+AC_INIT([xorg-server], 1.16.99.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2015-01-23"
+RELEASE_NAME="TimTam"
 AC_CONFIG_SRCDIR([Makefile.am])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
commit fef2f6357b40b238ae01c4c80b0d29b17b839686
Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Tue Jan 13 15:08:38 2015 -0800

    modesetting: Return the crtc for a drawable even if it's rotated
    
    All of our checks for what crtc we are on take rotation into account so we
    select the correct crtc.  The only problem is that we weren't returning it
    we were rotated.  This caused X to think DRI3 apps were not on any crtc and
    limit them to 1 FPS.
    
    Signed-off-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.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 711f6ed..a342662 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -147,20 +147,13 @@ ms_dri2_crtc_covering_drawable(DrawablePtr pDraw)
     ScreenPtr pScreen = pDraw->pScreen;
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     BoxRec box, crtcbox;
-    xf86CrtcPtr crtc;
 
     box.x1 = pDraw->x;
     box.y1 = pDraw->y;
     box.x2 = box.x1 + pDraw->width;
     box.y2 = box.y1 + pDraw->height;
 
-    crtc = ms_covering_crtc(pScrn, &box, NULL, &crtcbox);
-
-    /* Make sure the CRTC is valid and this is the real front buffer */
-    if (crtc != NULL && !crtc->rotatedData)
-        return crtc;
-
-    return NULL;
+    return ms_covering_crtc(pScrn, &box, NULL, &crtcbox);
 }
 
 static Bool
commit 3dcd591fa9b71a3dce58d612ca5970209d8386eb
Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Tue Jan 13 15:08:37 2015 -0800

    modesetting: Add support for using RandR shadow buffers
    
    This replaces the stubs for shadow buffer creation/allocation with actual
    functions and adds a shadow_destroy function.  With this, we actually get
    shadow buffers and RandR now works properly.  Most of this is copied from
    the xf86-video-intel driver and modified for modesetting.
    
    v2 Jason Ekstrand <jason.ekstrand at intel.com>:
     - Fix build with --disable-glamor
     - Set the pixel data pointer in the pixmap header for dumb shadow bo's
     - Call drmmode_create_bo with the right bpp
    
    v2 Jason Ekstrand <jason.ekstrand at intel.com>:
     - Make shadow buffers per-crtc and leave shadow_enable alone
    
    Signed-off-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index ee7087b..1ea799b 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -540,13 +540,122 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
 static void *
 drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
 {
-    return NULL;
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+    drmmode_ptr drmmode = drmmode_crtc->drmmode;
+    int ret;
+
+    if (!drmmode_create_bo(drmmode, &drmmode_crtc->rotate_bo,
+                           width, height, crtc->scrn->bitsPerPixel)) {
+        xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
+               "Couldn't allocate shadow memory for rotated CRTC\n");
+        return NULL;
+    }
+
+    ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth,
+                       crtc->scrn->bitsPerPixel,
+                       drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo),
+                       drmmode_bo_get_handle(&drmmode_crtc->rotate_bo),
+                       &drmmode_crtc->rotate_fb_id);
+
+    if (ret) {
+        ErrorF("failed to add rotate fb\n");
+        drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo);
+        return NULL;
+    }
+
+#ifdef GLAMOR_HAS_GBM
+    if (drmmode->gbm)
+        return drmmode_crtc->rotate_bo.gbm;
+#endif
+    return drmmode_crtc->rotate_bo.dumb;
 }
 
 static PixmapPtr
+drmmode_create_pixmap_header(ScreenPtr pScreen, int width, int height,
+                             int depth, int bitsPerPixel, int devKind,
+                             void *pPixData)
+{
+    PixmapPtr pixmap;
+
+    /* width and height of 0 means don't allocate any pixmap data */
+    pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0);
+
+    if (pixmap) {
+        if ((*pScreen->ModifyPixmapHeader)(pixmap, width, height, depth,
+                                           bitsPerPixel, devKind, pPixData))
+            return pixmap;
+        (*pScreen->DestroyPixmap)(pixmap);
+    }
+    return NullPixmap;
+}
+
+static Bool
+drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo);
+
+static PixmapPtr
 drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
 {
-    return NULL;
+    ScrnInfoPtr scrn = crtc->scrn;
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+    drmmode_ptr drmmode = drmmode_crtc->drmmode;
+    uint32_t rotate_pitch;
+    PixmapPtr rotate_pixmap;
+    void *pPixData = NULL;
+
+    if (!data) {
+        data = drmmode_shadow_allocate(crtc, width, height);
+        if (!data) {
+            xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                       "Couldn't allocate shadow pixmap for rotated CRTC\n");
+            return NULL;
+        }
+    }
+
+    if (!drmmode_bo_has_bo(&drmmode_crtc->rotate_bo)) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                   "Couldn't allocate shadow pixmap for rotated CRTC\n");
+        return NULL;
+    }
+
+    pPixData = drmmode_bo_map(drmmode, &drmmode_crtc->rotate_bo);
+    rotate_pitch = drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo),
+
+    rotate_pixmap = drmmode_create_pixmap_header(scrn->pScreen,
+                                                 width, height,
+                                                 scrn->depth,
+                                                 scrn->bitsPerPixel,
+                                                 rotate_pitch,
+                                                 pPixData);
+
+    if (rotate_pixmap == NULL) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                   "Couldn't allocate shadow pixmap for rotated CRTC\n");
+        return NULL;
+    }
+
+    drmmode_set_pixmap_bo(drmmode, rotate_pixmap, &drmmode_crtc->rotate_bo);
+
+    return rotate_pixmap;
+}
+
+static void
+drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+    drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+    if (rotate_pixmap) {
+        drmmode_set_pixmap_bo(drmmode, rotate_pixmap, NULL);
+        rotate_pixmap->drawable.pScreen->DestroyPixmap(rotate_pixmap);
+    }
+
+    if (data) {
+        drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id);
+        drmmode_crtc->rotate_fb_id = 0;
+
+        drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo);
+        memset(&drmmode_crtc->rotate_bo, 0, sizeof drmmode_crtc->rotate_bo);
+    }
 }
 
 static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
@@ -563,6 +672,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
     .set_scanout_pixmap = drmmode_set_scanout_pixmap,
     .shadow_allocate = drmmode_shadow_allocate,
     .shadow_create = drmmode_shadow_create,
+    .shadow_destroy = drmmode_shadow_destroy,
 };
 
 static uint32_t
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 66d0ca2..3a8959a 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -89,10 +89,12 @@ typedef struct {
     int dpms_mode;
     struct dumb_bo *cursor_bo;
     Bool cursor_up;
-    unsigned rotate_fb_id;
     uint16_t lut_r[256], lut_g[256], lut_b[256];
     DamagePtr slave_damage;
 
+    drmmode_bo rotate_bo;
+    unsigned rotate_fb_id;
+
     /**
      * @{ MSC (vblank count) handling for the PRESENT extension.
      *
commit 7c656bfcae1d68aeffd5e202b3c1569885f5d13d
Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Tue Jan 13 15:08:36 2015 -0800

    modesetting: Add drmmode_bo_has_bo and drmmode_bo_map helper function
    
    Signed-off-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index ea59ffe..ee7087b 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -82,6 +82,17 @@ drmmode_bo_get_pitch(drmmode_bo *bo)
     return bo->dumb->pitch;
 }
 
+static Bool
+drmmode_bo_has_bo(drmmode_bo *bo)
+{
+#ifdef GLAMOR_HAS_GBM
+    if (bo->gbm)
+        return TRUE;
+#endif
+
+    return bo->dumb != NULL;
+}
+
 uint32_t
 drmmode_bo_get_handle(drmmode_bo *bo)
 {
@@ -93,6 +104,26 @@ drmmode_bo_get_handle(drmmode_bo *bo)
     return bo->dumb->handle;
 }
 
+static void *
+drmmode_bo_map(drmmode_ptr drmmode, drmmode_bo *bo)
+{
+    int ret;
+
+#ifdef GLAMOR_HAS_GBM
+    if (bo->gbm)
+        return NULL;
+#endif
+
+    if (bo->dumb->ptr)
+        return bo->dumb->ptr;
+
+    ret = dumb_bo_map(drmmode->fd, bo->dumb);
+    if (ret)
+        return NULL;
+
+    return bo->dumb->ptr;
+}
+
 static Bool
 drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
                   unsigned width, unsigned height, unsigned bpp)
@@ -1570,17 +1601,7 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 void *
 drmmode_map_front_bo(drmmode_ptr drmmode)
 {
-    int ret;
-
-    if (drmmode->front_bo.dumb->ptr)
-        return drmmode->front_bo.dumb->ptr;
-
-    ret = dumb_bo_map(drmmode->fd, drmmode->front_bo.dumb);
-    if (ret)
-        return NULL;
-
-    return drmmode->front_bo.dumb->ptr;
-
+    return drmmode_bo_map(drmmode, &drmmode->front_bo);
 }
 
 void *
commit b4703a5a6e529b78810db8d8782317f0b4e2f265
Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Tue Jan 13 15:08:35 2015 -0800

    modesetting: Refactor drmmode_glamor_new_screen_pixmap
    
    The original drmmode_glamor_new_screen_pixmap function was specific to the
    primary screen pixmap.  This commit pulls the guts out into a new, more
    general, drmmode_set_pixmap_bo function for setting a buffer on a pixmap.
    The new function also properly tears down the glamor bits if the buffer
    being set is NULL.  The drmmode_glamor_new_screen_pixmap function is now
    just a 3-line wrapper around drmmode_set_pixmap_bo.
    
    v2 Jason Ekstrand <jason.ekstrand at intel.com>:
     - Re-arranged code in drmmode_set_pixmap_bo and
       drmmode_glamor_handle_new_screen_pixmap so that glamor_set_screen_pixmap
       only gets called for the screen pixmap
     - Guard the call to glamor_set_screen_pixmapa with a drmmode->glamor check
    
    Signed-off-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 824500b..ea59ffe 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1123,34 +1123,32 @@ drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
     }
 }
 
-Bool
-drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
+static Bool
+drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo)
 {
 #ifdef GLAMOR
     ScrnInfoPtr scrn = drmmode->scrn;
-    ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn);
-    PixmapPtr screen_pixmap;
-    void *gbm_bo;
 
     if (!drmmode->glamor)
         return TRUE;
 
-#ifdef GLAMOR_HAS_GBM
-    gbm_bo = drmmode->front_bo.gbm;
-    screen_pixmap = screen->GetScreenPixmap(screen);
+    if (bo == NULL) {
+        glamor_egl_destroy_textured_pixmap(pixmap);
+        return TRUE;
+    }
 
-    if (!glamor_egl_create_textured_pixmap_from_gbm_bo(screen_pixmap, gbm_bo)) {
+#ifdef GLAMOR_HAS_GBM
+    if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) {
         xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
         return FALSE;
     }
-    glamor_set_screen_pixmap(screen_pixmap, NULL);
 #else
-    if (!glamor_egl_create_textured_screen(screen,
+    if (!glamor_egl_create_textured_pixmap(pixmap,
                                            drmmode_bo_get_handle(&drmmode->front_bo),
                                            scrn->displayWidth *
                                            scrn->bitsPerPixel / 8)) {
         xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-                   "glamor_egl_create_textured_screen() failed\n");
+                   "glamor_egl_create_textured_pixmap() failed\n");
         return FALSE;
     }
 #endif
@@ -1159,6 +1157,23 @@ drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
     return TRUE;
 }
 
+Bool
+drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
+{
+    ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn);
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+    if (!drmmode_set_pixmap_bo(drmmode, screen_pixmap, &drmmode->front_bo))
+        return FALSE;
+
+#ifdef GLAMOR
+    if (drmmode->glamor)
+        glamor_set_screen_pixmap(screen_pixmap, NULL);
+#endif
+
+    return TRUE;
+}
+
 static Bool
 drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
 {
commit bb23fbf5bb278113c9c481875423b4d128180972
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Jan 5 16:48:11 2015 -0500

    dix: make RegionInit legal C++
    
    The CVE fix in:
    
        commit 97015a07b9e15d8ec5608b95d95ec0eb51202acb
        Author: Alan Coopersmith <alan.coopersmith at oracle.com>
        Date:   Wed Jan 22 22:37:15 2014 -0800
    
            dix: integer overflow in RegionSizeof() [CVE-2014-8092 3/4]
    
    offended the C++ demons:
    
    ../../include/regionstr.h:147:45: error: invalid conversion from 'void*' to
    'pixman_region16_data_t* {aka pixman_region16_data*}' [-fpermissive]
    
    Normally this isn't a problem, because around here we have the sense and
    common decency to not use C++, but this does make tigervnc fail to build,
    which is a little rude of us.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/regionstr.h b/include/regionstr.h
index 079375d..1032358 100644
--- a/include/regionstr.h
+++ b/include/regionstr.h
@@ -144,7 +144,7 @@ RegionInit(RegionPtr _pReg, BoxPtr _rect, int _size)
         size_t rgnSize;
         (_pReg)->extents = RegionEmptyBox;
         if (((_size) > 1) && ((rgnSize = RegionSizeof(_size)) > 0) &&
-            (((_pReg)->data = malloc(rgnSize)) != NULL)) {
+            (((_pReg)->data = (RegDataPtr) malloc(rgnSize)) != NULL)) {
             (_pReg)->data->size = (_size);
             (_pReg)->data->numRects = 0;
         }
commit 082931014811e587a9734cbf4d88fd948979b641
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jan 17 10:09:54 2015 +0000

    dri2: SourceOffloads may be for DRI3 only
    
    As a DDX may declare offload support without supporting DRI2
    (because it is using an alternative acceleration mechanism like DRI3),
    when iterating the list of offload_source Screens to find a matching
    DRI2 provider we need to check before assuming it is DRI2 capable.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88514
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index c8fcd62..0b43369 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -156,6 +156,9 @@ GetScreenPrime(ScreenPtr master, int prime_id)
         DRI2ScreenPtr ds;
 
         ds = DRI2GetScreen(slave);
+        if (ds == NULL)
+            continue;
+
         if (ds->prime_id == prime_id)
             return slave;
     }
commit f27d743c1899f307ec8063febbb3198c8945d372
Author: Carlos Olmedo Escobar <carlos.olmedo.e at gmail.com>
Date:   Wed Jan 21 01:44:54 2015 +0100

    Avoid possible null pointer dereference.
    
    Signed-off-by: Carlos Olmedo Escobar <carlos.olmedo.e at gmail.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 37d6d82..7e8d667 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -513,9 +513,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     int ret, bpc, green_bpc, i;
 
     xwl_screen = calloc(sizeof *xwl_screen, 1);
-    xwl_screen->wm_fd = -1;
     if (xwl_screen == NULL)
         return FALSE;
+    xwl_screen->wm_fd = -1;
 
     if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0))
         return FALSE;
commit 437d2ec5f250f8ab4b44cbae56f938719802e1cc
Author: Carlos Sánchez de La Lama <csanchezdll at gmail.com>
Date:   Wed Jan 21 10:22:05 2015 +0100

    randr: swap num-preferred field on RRGetOutputInfo reply
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=88614
    Signed-off-by: Carlos Sánchez de La Lama <csanchezdll at gmail.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/randr/rroutput.c b/randr/rroutput.c
index f824f50..5d46fac 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -487,6 +487,7 @@ ProcRRGetOutputInfo(ClientPtr client)
         swapl(&rep.mmHeight);
         swaps(&rep.nCrtcs);
         swaps(&rep.nModes);
+        swaps(&rep.nPreferred);
         swaps(&rep.nClones);
         swaps(&rep.nameLength);
     }
commit 3d12941b408de7a3bdc579e34e119f8aa81ea926
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Jan 22 22:28:34 2015 -0800

    drivers/modesetting: Save current BlockHandler on return in msBlockHandler
    
    If the BlockHandler chain is modified while it is active, we need to
    re-fetch the current value and store it in our private for use the
    next time through.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 1cb0c7c..d52517d 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -538,6 +538,7 @@ msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask)
 
     pScreen->BlockHandler = ms->BlockHandler;
     pScreen->BlockHandler(pScreen, pTimeout, pReadmask);
+    ms->BlockHandler = pScreen->BlockHandler;
     pScreen->BlockHandler = msBlockHandler;
     if (pScreen->isGPU)
         dispatch_slave_dirty(pScreen);
commit b3e496c6d21058147de9a11b78860e73c74db3cb
Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Jan 23 16:28:28 2015 +1000

    glamor: use screen blockhandler rather than dix one (v3)
    
    This adds glamor into the block handler call chain
    in the correct place.
    
    This should fix interactions between glamor and drivers
    requiring damage from glamor.
    
    v2: okay don't consolidate, just leave things wierd for now
    remove blcokhandler in screen close.
    
    v3: block handler wrapping the right way.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 78e8278..017266a 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -249,20 +249,20 @@ glamor_block_handler(ScreenPtr screen)
 }
 
 static void
-_glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask)
+_glamor_block_handler(ScreenPtr screen, void *timeout, void *readmask)
 {
-    glamor_screen_private *glamor_priv = data;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    screen->BlockHandler = glamor_priv->saved_procs.block_handler;
+    screen->BlockHandler(screen, timeout, readmask);
+    glamor_priv->saved_procs.block_handler = screen->BlockHandler;
+    screen->BlockHandler = _glamor_block_handler;
 
     glamor_make_current(glamor_priv);
     glFlush();
 }
 
 static void
-_glamor_wakeup_handler(void *data, int result, void *last_select_mask)
-{
-}
-
-static void
 glamor_set_debug_level(int *debug_level)
 {
     char *debug_level_string;
@@ -443,11 +443,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         goto fail;
 
     if (flags & GLAMOR_USE_SCREEN) {
-        if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
-                                            _glamor_wakeup_handler,
-                                            glamor_priv)) {
-            goto fail;
-        }
+
+        glamor_priv->saved_procs.block_handler = screen->BlockHandler;
+        screen->BlockHandler = _glamor_block_handler;
 
         glamor_priv->saved_procs.create_gc = screen->CreateGC;
         screen->CreateGC = glamor_create_gc;
@@ -597,6 +595,7 @@ glamor_close_screen(ScreenPtr screen)
             glamor_priv->saved_procs.change_window_attributes;
         screen->CopyWindow = glamor_priv->saved_procs.copy_window;
         screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
+        screen->BlockHandler = glamor_priv->saved_procs.block_handler;
     }
 #ifdef RENDER
     if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) {
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index f699497..ed6e2d1 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -215,6 +215,7 @@ struct glamor_saved_procs {
 #if XSYNC
     SyncScreenFuncsRec sync_screen_funcs;
 #endif
+    ScreenBlockHandlerProcPtr block_handler;
 };
 
 #define CACHE_FORMAT_COUNT 3
commit 5af2f5b7d2f955586d0cb40eb30812f1893db22e
Author: Markus Wick <markus at selfnet.de>
Date:   Thu Jan 15 22:03:18 2015 +0100

    xwayland: Set glamor filter to nearest
    
    glEGLImageTargetTexture2DOES only set the first level.
    Mesa handles this new texture as incomplete and renders a black screen.
    We also want to prevent linear filtering.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=81800
    
    Signed-off-by: Markus Wick <markus at selfnet.de>
    Reviewed-and-Tested-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 09b454f..dd85518 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -137,6 +137,9 @@ xwl_glamor_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, int depth)
 
     glGenTextures(1, &xwl_pixmap->texture);
     glBindTexture(GL_TEXTURE_2D, xwl_pixmap->texture);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image);
     glBindTexture(GL_TEXTURE_2D, 0);
 
commit 5f2e8ac51ccbf7c02f25c8cb7617df0238418cd1
Merge: 4e12d7b 4301479
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Jan 10 14:51:57 2015 +1300

    Merge remote-tracking branch 'whot/for-keith'

commit 4e12d7b6f4489fa06475465993a3e1e1d896390b
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sun Jan 4 23:27:32 2015 -0800

    modesetting: Update the cursor without hiding it
    
    In the new KMS APIs, the legacy drmModeSetCursor ioctl actually waits
    for a vblank after changing the cursor image before returning, meaning
    that the X server, in attempting to hide the cursor before updating
    its image, actually makes that hide *visible* for a full vblank.
    
    It's unknown why the X server does this by default, but turn it off.
    
    If we're with a legacy driver that doesn't support the modern
    drmModeSetCursor by waiting for a vblank before returning, we're going
    to get a tiny bit of tearing on the cursor plane. But between tearing
    with a new cursor image and tearing with a blank cursor image, I'd
    rather the former.
    
    The only proper solution to this is an atomic ioctl that page flips
    all planes, including the cursor plane, at vblank time and at the same
    time.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 1ebf807..1cb0c7c 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1077,6 +1077,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
     if (!ms->drmmode.sw_cursor)
         xf86_cursors_init(pScreen, ms->cursor_width, ms->cursor_height,
                           HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
+                          HARDWARE_CURSOR_UPDATE_UNHIDDEN |
                           HARDWARE_CURSOR_ARGB);
 
     /* Must force it before EnterVT, so we are in control of VT and
commit 43014795087a0a8774dd9687f5967329b15f06a2
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Mon Jan 5 16:44:22 2015 +0100

    Synchronize capslock in Xnest and Xephyr
    
    In Xnest or Xephyr, pressing CapsLock when focus is on another
    window does not update the state in the nested X server.
    
    This is because when synchronizing the lock modifier, sending a
    keypress or a key release only is not sufficient to toggle the state,
    unlike regular modifiers, one has to emulate a full press/release
    to lock or unlock the modifier.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.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/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 907bbeb..164ebdc 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -806,7 +806,11 @@ ephyrUpdateModifierState(unsigned int state)
 
             for (key = 0; key < MAP_LENGTH; key++)
                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
-                    if (key_is_down(pDev, key, KEY_PROCESSED))
+                    if (mask == XCB_MOD_MASK_LOCK) {
+                        KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE);
+                        KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE);
+                    }
+                    else if (key_is_down(pDev, key, KEY_PROCESSED))
                         KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE);
 
                     if (--count == 0)
@@ -820,6 +824,8 @@ ephyrUpdateModifierState(unsigned int state)
             for (key = 0; key < MAP_LENGTH; key++)
                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
                     KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE);
+                    if (mask == XCB_MOD_MASK_LOCK)
+                        KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE);
                     break;
                 }
     }
diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c
index 2cf1624..ee3f68e 100644
--- a/hw/xnest/Keyboard.c
+++ b/hw/xnest/Keyboard.c
@@ -18,6 +18,7 @@ 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"
@@ -247,7 +248,11 @@ xnestUpdateModifierState(unsigned int state)
 
             for (key = 0; key < MAP_LENGTH; key++)
                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
-                    if (key_is_down(pDev, key, KEY_PROCESSED))
+                    if (mask == XCB_MOD_MASK_LOCK) {
+                        xnestQueueKeyEvent(KeyPress, key);
+                        xnestQueueKeyEvent(KeyRelease, key);
+                    }
+                    else if (key_is_down(pDev, key, KEY_PROCESSED))
                         xnestQueueKeyEvent(KeyRelease, key);
 
                     if (--count == 0)
@@ -261,6 +266,8 @@ 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)
+                        xnestQueueKeyEvent(KeyRelease, key);
                     break;
                 }
     }
commit 24b943132f90bc72ce8b5dc954fe9ee8484edfc2
Author: Olivier Fourdan <fourdan at xfce.org>
Date:   Fri Jan 2 18:50:17 2015 +0100

    Fix subwindow in Xi emulated events
    
    Bug: 70790
    
    Signed-off-by: Olivier Fourdan <fourdan at xfce.org>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index b0bc47e..0857bce 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1403,7 +1403,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
 
             if (grab->ownerEvents) {
                 WindowPtr focus = NullWindow;
-                WindowPtr sprite_win = dev->spriteInfo->sprite->win;
+                WindowPtr sprite_win = DeepestSpriteWin(dev->spriteInfo->sprite);
 
                 deliveries = DeliverDeviceEvents(sprite_win, ptrev, grab, focus, dev);
             }
@@ -1429,8 +1429,9 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
     }
     else {
         GrabPtr devgrab = dev->deviceGrab.grab;
+        WindowPtr sprite_win = DeepestSpriteWin(dev->spriteInfo->sprite);
 
-        DeliverDeviceEvents(win, ptrev, grab, win, dev);
+        DeliverDeviceEvents(sprite_win, ptrev, grab, win, dev);
         /* FIXME: bad hack
          * Implicit passive grab activated in response to this event. Store
          * the event.
commit b058dec281568d6a9c5b5e230c20eed096cbdc6d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jan 5 11:19:46 2015 +1000

    mi: fix accidental x/y coordinate swap
    
    Reported-by: Adam Greenblatt <adam.greenblatt at gmail.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/mi/mipointer.c b/mi/mipointer.c
index 2bdd6ca..ada1ab5 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -598,8 +598,8 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx,
         int constrained_x, constrained_y;
         int current_x, current_y; /* current position in per-screen coord */
 
-        current_x = MIPOINTER(pDev)->x - pScreen->y;
-        current_y = MIPOINTER(pDev)->y - pScreen->x;
+        current_x = MIPOINTER(pDev)->x - pScreen->x;
+        current_y = MIPOINTER(pDev)->y - pScreen->y;
 
         input_constrain_cursor(pDev, pScreen,
                                current_x, current_y, x, y,
commit 23a11fd85e12e94d29ee6d33715ac49684867b16
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Jan 4 19:13:35 2015 -0800

    doc: Create a script to filter xmlto output
    
    This reduces the build log spam while still preserving the xmlto
    status to catch build failures correctly.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/devbook.am b/devbook.am
index 400b2ca..edddc86 100644
--- a/devbook.am
+++ b/devbook.am
@@ -20,6 +20,8 @@ noinst_DATA =
 # DocBook/XML file with chapters, appendix and images it includes
 dist_noinst_DATA = $(docbook) $(chapters)
 
+FILTER_XMLTO=$(SHELL) $(top_srcdir)/doc/filter-xmlto.sh $(XMLTO)
+
 if HAVE_STYLESHEETS
 
 XMLTO_HTML_FLAGS = 					\
@@ -29,12 +31,12 @@ XMLTO_HTML_FLAGS = 					\
 
 noinst_DATA += $(docbook:.xml=.html)
 %.html: %.xml  $(chapters)
-	$(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) xhtml-nochunks $<
+	$(AM_V_GEN)$(FILTER_XMLTO) $(XMLTO_HTML_FLAGS) xhtml-nochunks $<
 
 if HAVE_XMLTO_TEXT
 noinst_DATA += $(docbook:.xml=.txt)
 %.txt: %.xml $(chapters)
-	$(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) txt $<
+	$(AM_V_GEN)$(FILTER_XMLTO) $(XMLTO_HTML_FLAGS) txt $<
 endif HAVE_XMLTO_TEXT
 
 if HAVE_FOP
@@ -46,9 +48,9 @@ XMLTO_FO_FLAGS = 					\
 
 noinst_DATA += $(docbook:.xml=.pdf) $(docbook:.xml=.ps)
 %.pdf: %.xml $(chapters)
-	$(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop pdf $<
+	$(AM_V_GEN)$(FILTER_XMLTO) $(XMLTO_FO_FLAGS) --with-fop pdf $<
 %.ps: %.xml $(chapters)
-	$(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop ps $<
+	$(AM_V_GEN)$(FILTER_XMLTO) $(XMLTO_FO_FLAGS) --with-fop ps $<
 endif HAVE_FOP
 endif HAVE_STYLESHEETS
 
diff --git a/doc/Makefile.am b/doc/Makefile.am
index e6974fe..b305f4d 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -12,4 +12,4 @@ include $(top_srcdir)/devbook.am
 endif HAVE_XMLTO
 endif ENABLE_DEVEL_DOCS
 
-EXTRA_DIST = smartsched
+EXTRA_DIST = smartsched filter-xmlto.sh
diff --git a/doc/filter-xmlto.sh b/doc/filter-xmlto.sh
new file mode 100755
index 0000000..3596ed1
--- /dev/null
+++ b/doc/filter-xmlto.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# Run the xmlto command, filtering its output to
+# reduce the amount of useless warnings in the build log.
+#
+# Exit with the status of the xmlto process, not the status of the
+# output filtering commands
+#
+# This is a bit twisty, but avoids any temp files by using pipes for
+# everything. It routes the command output through file
+# descriptor 4 while sending the (numeric) exit status through
+# standard output.
+#
+(((("$@" 2>&1; echo $? >&3) |
+       grep -v overflows |
+       grep -v 'Making' |
+       grep -v 'hyphenation' |
+       grep -v 'Font.*not found' |
+       grep -v '/tmp/xml' |
+       grep -v Rendered >&4) 3>&1) |
+     (read status; exit $status)) 4>&1
commit 1c01633877caa4239f901f02fbe113926318d030
Merge: 3573855 e774663
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Jan 4 17:02:25 2015 -0800

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

commit 3573855514557a518de40a93b3c578f28c7d9c2b
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Dec 3 13:49:37 2014 +0100

    Remove explicit dependency on $(WAYLAND_LIBS)
    
    Xwayland Makefile explicitely set its dependencies on
    WAYLAND_LIBS. If the ibrairies are installed in a non-standard
    path, WAYLAND_LIBS contains '-L/path/to/the/lib' which will fail
    at build time with:
    
    "No rule to make target '-L/path/to/the/lib', needed by 'Xwayland'.
     Stop"
    
    Remove that explicit dependency to avoid the problem (LDADD ought
    to be enough to get the right libraries linked).
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am
index 4e0e1bb..9945540 100644
--- a/hw/xwayland/Makefile.am
+++ b/hw/xwayland/Makefile.am
@@ -26,7 +26,6 @@ Xwayland_LDADD =				\
 	$(XWAYLAND_LIBS)			\
 	$(XWAYLAND_SYS_LIBS)			\
 	$(XSERVER_SYS_LIBS)
-Xwayland_DEPENDENCIES = $(XWAYLAND_LIBS)
 Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
 
 
commit de89c6b8c6e81bad131c7f432e355cb42d233e87
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Dec 16 13:59:45 2014 +1000

    xfree86: rename Xorg.bin to Xorg
    
    If the suid wrapper is enabled, /usr/bin/Xorg is just a shell script that
    execs either /usr/libexec/Xorg.bin directly or the Xorg.wrap binary which then
    execve's /usr/libexec/Xorg.bin.
    
    Either way, we end up with Xorg.bin, which is problematic for two reasons:
    * ps shows the command as Xorg.bin
    * _COMM and _EXE in systemd's journal will both show Xorg.bin as well
    
    There's not much we can do about the path, but having the actual command stay
    as Xorg means better compatibility to existing scripts. And, the reason for
    this path: the command
       journalctl _COMM=Xorg
    works universally, regardless of whether the wrapper is used or not.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Acked-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/configure.ac b/configure.ac
index 96524c5..b593fc7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -923,7 +923,7 @@ if test "x$SUID_WRAPPER" = xyes; then
         PKG_CHECK_MODULES([LIBDRM], $LIBDRM)
         dnl This is a define so that if some platforms want to put the wrapper
         dnl somewhere else this can be easily changed
-        AC_DEFINE_DIR(SUID_WRAPPER_DIR, libexecdir, [Where to install Xorg.bin and Xorg.wrap])
+        AC_DEFINE_DIR(SUID_WRAPPER_DIR, libexecdir, [Where to install the Xorg binary and Xorg.wrap])
         SETUID="no"
 fi
 AM_CONDITIONAL(SUID_WRAPPER, [test "x$SUID_WRAPPER" = xyes])
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index d46bf0a..27f2cc6 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -106,7 +106,7 @@ if INSTALL_SETUID
 endif
 if SUID_WRAPPER
 	$(MKDIR_P) $(DESTDIR)$(SUID_WRAPPER_DIR)
-	mv $(DESTDIR)$(bindir)/Xorg $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.bin
+	mv $(DESTDIR)$(bindir)/Xorg $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg
 	${INSTALL} -m 755 Xorg.sh $(DESTDIR)$(bindir)/Xorg
 	-chown root $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap && chmod u+s $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap
 endif
diff --git a/hw/xfree86/Xorg.sh.in b/hw/xfree86/Xorg.sh.in
index cef4859..4814135 100644
--- a/hw/xfree86/Xorg.sh.in
+++ b/hw/xfree86/Xorg.sh.in
@@ -1,11 +1,11 @@
 #!/bin/sh
 #
-# Execute Xorg.wrap if it exists otherwise execute Xorg.bin directly.
+# Execute Xorg.wrap if it exists otherwise execute Xorg directly.
 # This allows distros to put the suid wrapper in a separate package.
 
 basedir=@SUID_WRAPPER_DIR@
 if [ -x "$basedir"/Xorg.wrap ]; then
 	exec "$basedir"/Xorg.wrap "$@"
 else
-	exec "$basedir"/Xorg.bin "$@"
+	exec "$basedir"/Xorg "$@"
 fi
diff --git a/hw/xfree86/man/Xorg.wrap.man b/hw/xfree86/man/Xorg.wrap.man
index 58937c7..11090f1 100644
--- a/hw/xfree86/man/Xorg.wrap.man
+++ b/hw/xfree86/man/Xorg.wrap.man
@@ -33,7 +33,7 @@ Xorg.wrap \- Xorg X server binary wrapper
 The Xorg X server may need root rights to function properly. To start the
 Xorg X server with these rights your system is using a suid root wrapper
 installed as __suid_wrapper_dir__/Xorg.wrap which will execute the real
-X server which is installed as __suid_wrapper_dir__/Xorg.bin .
+X server which is installed as __suid_wrapper_dir__/Xorg.
 .PP
 By default Xorg.wrap will autodetect if root rights are necessary, and
 if not it will drop its elevated rights before starting the real X server.
diff --git a/hw/xfree86/xorg-wrapper.c b/hw/xfree86/xorg-wrapper.c
index 4ea4733..22e97ad 100644
--- a/hw/xfree86/xorg-wrapper.c
+++ b/hw/xfree86/xorg-wrapper.c
@@ -255,18 +255,18 @@ int main(int argc, char *argv[])
         }
     }
 
-    snprintf(buf, sizeof(buf), "%s/Xorg.bin", SUID_WRAPPER_DIR);
+    snprintf(buf, sizeof(buf), "%s/Xorg", SUID_WRAPPER_DIR);
 
     /* Check if the server is executable by our real uid */
     if (access(buf, X_OK) != 0) {
-        fprintf(stderr, "%s: Missing execute permissions for %s/Xorg.bin: %s\n",
-            progname, SUID_WRAPPER_DIR, strerror(errno));
+        fprintf(stderr, "%s: Missing execute permissions for %s: %s\n",
+            progname, buf, strerror(errno));
         exit(1);
     }
 
     argv[0] = buf;
     (void) execv(argv[0], argv);
-    fprintf(stderr, "%s: Failed to execute %s/Xorg.bin: %s\n",
-        progname, SUID_WRAPPER_DIR, strerror(errno));
+    fprintf(stderr, "%s: Failed to execute %s: %s\n",
+        progname, buf, strerror(errno));
     exit(1);
 }
commit ee21be1324de1d6ef14e529fed7b75992e971beb
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 11 10:32:45 2014 +1000

    dix: offset touch root coordinates by ScreenRec origins (#86655)
    
    For two ScreenRecs abs pointer positioning was working fine, but touch events
    stuck to the lower/right edge on any screen but the one with a 0/0 origin.
    Cause is a missing offset by the screen coordinates, causing the root
    coordinates in the event to desktop-wide, not screen-wide.
    
    Offset properly, just like we do for pointer events.
    
    X.Org Bug 86655 <http://bugs.freedesktop.org/show_bug.cgi?id=86655>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index dd96265..6fb12c5 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -2044,7 +2044,7 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
 
     event->root = scr->root->drawable.id;
 
-    event_set_root_coordinates(event, screenx, screeny);
+    event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y);
     event->touchid = client_id;
     event->flags = flags;
 
@@ -2082,8 +2082,8 @@ GetDixTouchEnd(InternalEvent *ievent, DeviceIntPtr dev, TouchPointInfoPtr ti,
     /* Get screen event coordinates from the sprite.  Is this really the best
      * we can do? */
     event_set_root_coordinates(event,
-                               dev->last.valuators[0],
-                               dev->last.valuators[1]);
+                               dev->last.valuators[0] - scr->x,
+                               dev->last.valuators[1] - scr->y);
     event->touchid = ti->client_id;
     event->flags = flags;
 
commit dc777c346d5d452a53b13b917c45f6a1bad2f20b
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Jan 3 08:46:45 2015 -0800

    dix: Allow zero-height PutImage requests
    
    The length checking code validates PutImage height and byte width by
    making sure that byte-width >= INT32_MAX / height. If height is zero,
    this generates a divide by zero exception. Allow zero height requests
    explicitly, bypassing the INT32_MAX check.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/dix/dispatch.c b/dix/dispatch.c
index 55b978d..9044ac7 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -2000,7 +2000,7 @@ ProcPutImage(ClientPtr client)
     tmpImage = (char *) &stuff[1];
     lengthProto = length;
 
-    if (lengthProto >= (INT32_MAX / stuff->height))
+    if (stuff->height != 0 && lengthProto >= (INT32_MAX / stuff->height))
         return BadLength;
 
     if ((bytes_to_int32(lengthProto * stuff->height) +
commit 924996c41c419dda0f02a96aafdf52f7670ff4ea
Author: Michele Baldessari <michele at redhat.com>
Date:   Wed Dec 3 11:53:10 2014 -0500

    ephyr: Implement per-screen colormaps
    
    Xephyr's pseudocolor emulation added in:
    
        commit 81a3b6fe27567b4f91033ece69996aa6bf8d01a3
        Author: Matthew Allum <breakfast at 10.am>
        Date:   Mon Nov 8 22:39:47 2004 +0000
    
            Add support to Xephyr for lower depths than hosts
    
    only tracks one global colormap for the whole (Xephyr) display.  Move
    this to per-screen state so each screen's colormap can be correct.
    
    [ajax: rebased to 1.17, cleaned up commit message]
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Michele Baldessari <michele at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 93a48a9..907bbeb 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -1292,7 +1292,7 @@ ephyrPutColors(ScreenPtr pScreen, int n, xColorItem * pdefs)
         if (p > max)
             max = p;
 
-        hostx_set_cmap_entry(p,
+        hostx_set_cmap_entry(pScreen, p,
                              pdefs->red >> 8,
                              pdefs->green >> 8, pdefs->blue >> 8);
         pdefs++;
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index 2395a7f..18bfe11 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -83,6 +83,7 @@ typedef struct _ephyrScrPriv {
 
     KdScreenInfo *screen;
     int mynum;                  /* Screen number */
+    unsigned long cmap[256];
 
     /**
      * Per-screen Xlib-using state for glamor (private to
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 8d6d5e8..f64861b 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -82,8 +82,6 @@ struct EphyrHostXVars {
     KdScreenInfo **screens;
 
     long damage_debug_msec;
-
-    unsigned long cmap[256];
 };
 
 /* memset ( missing> ) instead of below  */
@@ -751,9 +749,12 @@ hostx_calculate_color_shift(unsigned long mask)
 }
 
 void
-hostx_set_cmap_entry(unsigned char idx,
+hostx_set_cmap_entry(ScreenPtr pScreen, unsigned char idx,
                      unsigned char r, unsigned char g, unsigned char b)
 {
+    KdScreenPriv(pScreen);
+    KdScreenInfo *screen = pScreenPriv->screen;
+    EphyrScrPriv *scrpriv = screen->driver;
 /* need to calculate the shifts for RGB because server could be BGR. */
 /* XXX Not sure if this is correct for 8 on 16, but this works for 8 on 24.*/
     static int rshift, bshift, gshift = 0;
@@ -765,7 +766,7 @@ hostx_set_cmap_entry(unsigned char idx,
         gshift = hostx_calculate_color_shift(HostX.visual->green_mask);
         bshift = hostx_calculate_color_shift(HostX.visual->blue_mask);
     }
-    HostX.cmap[idx] = ((r << rshift) & HostX.visual->red_mask) |
+    scrpriv->cmap[idx] = ((r << rshift) & HostX.visual->red_mask) |
         ((g << gshift) & HostX.visual->green_mask) |
         ((b << bshift) & HostX.visual->blue_mask);
 }
@@ -1017,7 +1018,7 @@ hostx_paint_rect(KdScreenInfo *screen,
                     unsigned char pixel =
                         *(unsigned char *) (scrpriv->fb_data + idx);
                     xcb_image_put_pixel(scrpriv->ximg, x, y,
-                                        HostX.cmap[pixel]);
+                                        scrpriv->cmap[pixel]);
                     break;
                 }
                 default:
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 87acd5a..93aaa50 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -141,7 +141,7 @@ hostx_get_visual_masks(KdScreenInfo *screen,
                        CARD32 *rmsk, CARD32 *gmsk, CARD32 *bmsk);
 void
 
-hostx_set_cmap_entry(unsigned char idx,
+hostx_set_cmap_entry(ScreenPtr pScreen, unsigned char idx,
                      unsigned char r, unsigned char g, unsigned char b);
 
 void *hostx_screen_init(KdScreenInfo *screen,
commit 7b076fdfc0e7a98430b6cb1c43079c137d7d3a6c
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Dec 11 19:09:48 2014 -0800

    os/xsha1.c: Add license and copyright attribution.
    
    I'm interested in copying this code to the mesa project, but before
    doing that it seems prudent to have the license and copyright
    attributions in place before copying that. To get this list of names I
    went through:
    
    	git log -- os/xsha1.c
    and:
    	git log -- render/glyph.c
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/xsha1.c b/os/xsha1.c
index 24c0aa2..c54e68c 100644
--- a/os/xsha1.c
+++ b/os/xsha1.c
@@ -1,3 +1,28 @@
+/* Copyright © 2007 Carl Worth
+ * Copyright © 2009 Jeremy Huddleston, Julien Cristau, and Matthieu Herrb
+ * Copyright © 2009-2010 Mikhail Gusarov
+ * Copyright © 2012 Yaakov Selkowitz and Keith Packard
+ *
+ * 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.
+ */
+
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
 #endif
commit 66726064204b869a24e5a8dc6e24daa5acb92bab
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Dec 30 11:51:43 2014 -0800

    modesetting: Fix build with --disable-glamor.
    
    present.c: In function 'ms_present_flush':
    present.c:204:9: error: implicit declaration of function
    'glamor_block_handler'
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87858
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Rob Clark <robdclark at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index 63d7b76..359e113 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -196,12 +196,14 @@ ms_present_abort_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
 static void
 ms_present_flush(WindowPtr window)
 {
+#ifdef GLAMOR
     ScreenPtr screen = window->drawable.pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     modesettingPtr ms = modesettingPTR(scrn);
 
     if (ms->drmmode.glamor)
         glamor_block_handler(screen);
+#endif
 }
 
 static present_screen_info_rec ms_present_screen_info = {
commit d723928870eea9fc2554abe137d6e57f7ad29e98
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Dec 27 09:11:33 2014 -0800

    glamor: Fix nlines in glamor_xv_put_image when src_y is odd
    
    The number of lines of video to update in the texture needs to be
    computed from the height of the updated source, not the full height of
    the source.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 1c877da..83e24ad 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -435,7 +435,7 @@ glamor_xv_put_image(glamor_port_private *port_priv,
     }
 
     top = (src_y) & ~1;
-    nlines = (src_y + height) - top;
+    nlines = (src_y + src_h) - top;
 
     switch (id) {
     case FOURCC_YV12:
commit 09230a2d435aa7f893ad5022220e3eb39ffb6db5
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Thu Dec 11 13:37:14 2014 -0800

    modesetting: Add vblank synchronization support when using Present.
    
    modesetting hooked up vblank support for DRI2, but was missing support
    for vblanks in Present.
    
    This is mostly copy and pasted from Keith's code in the intel driver.
    
    v2: Use ms_crtc_msc_to_kernel_msc in ms_present_queue_vblank to hook
        up the vblank_offset workaround for bogus MSC values (which the
        DRI2 code already did).
    
        Also simplify the ms_present_get_crtc function.  vblank.c already
        implements the functionality; we just need to convert types.
    
    v3: Fix ms_flush_drm_events return code.  I'd copied code where 0 meant
        success into a function that returned a boolean, so the return code
        was always backwards.
    
        Also add DebugPresent calls in ms_present_vblank_{handler,abort}.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/Makefile.am b/hw/xfree86/drivers/modesetting/Makefile.am
index 921ca00..82c4f2f 100644
--- a/hw/xfree86/drivers/modesetting/Makefile.am
+++ b/hw/xfree86/drivers/modesetting/Makefile.am
@@ -50,6 +50,7 @@ modesetting_drv_la_SOURCES = \
 	 drmmode_display.h \
 	 dumb_bo.c \
 	 dumb_bo.h \
+	 present.c \
 	 vblank.c \
 	 $(NULL)
 
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 26054f2..1ebf807 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1128,6 +1128,11 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                        "Failed to initialize the DRI2 extension.\n");
         }
+
+        if (!ms_present_screen_init(pScreen)) {
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Failed to initialize the Present extension.\n");
+        }
     }
 #endif
 
diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index 4267fa1..3decc3e 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -114,6 +114,10 @@ uint32_t ms_drm_queue_alloc(xf86CrtcPtr crtc,
                             ms_drm_handler_proc handler,
                             ms_drm_abort_proc abort);
 
+void ms_drm_abort(ScrnInfoPtr scrn,
+                  Bool (*match)(void *data, void *match_data),
+                  void *match_data);
+
 xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
 xf86CrtcPtr ms_covering_crtc(ScrnInfoPtr scrn, BoxPtr box,
                              xf86CrtcPtr desired, BoxPtr crtc_box_ret);
@@ -129,3 +133,5 @@ void ms_dri2_close_screen(ScreenPtr screen);
 
 Bool ms_vblank_screen_init(ScreenPtr screen);
 void ms_vblank_close_screen(ScreenPtr screen);
+
+Bool ms_present_screen_init(ScreenPtr screen);
diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
new file mode 100644
index 0000000..63d7b76
--- /dev/null
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include "dix-config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <xf86.h>
+#include <xf86Crtc.h>
+#include <xf86drm.h>
+#include <xf86str.h>
+#include <present.h>
+
+#include "driver.h"
+
+#if 0
+#define DebugPresent(x) ErrorF x
+#else
+#define DebugPresent(x)
+#endif
+
+struct ms_present_vblank_event {
+    uint64_t        event_id;
+};
+
+static RRCrtcPtr
+ms_present_get_crtc(WindowPtr window)
+{
+    xf86CrtcPtr xf86_crtc = ms_dri2_crtc_covering_drawable(&window->drawable);
+    return xf86_crtc ? xf86_crtc->randr_crtc : NULL;
+}
+
+static int
+ms_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc)
+{
+    xf86CrtcPtr xf86_crtc = crtc->devPrivate;
+
+    return ms_get_crtc_ust_msc(xf86_crtc, ust, msc);
+}
+
+/*
+ * Flush the DRM event queue when full; makes space for new events.
+ */
+static Bool
+ms_flush_drm_events(ScreenPtr screen)
+{
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    modesettingPtr ms = modesettingPTR(scrn);
+
+    struct pollfd p = { .fd = ms->fd, .events = POLLIN };
+    int r;
+
+    do {
+            r = poll(&p, 1, 0);
+    } while (r == -1 && (errno == EINTR || errno == EAGAIN));
+
+    if (r <= 0)
+        return TRUE;
+
+    return drmHandleEvent(ms->fd, &ms->event_context) >= 0;
+}
+
+/*
+ * Called when the queued vblank event has occurred
+ */
+static void
+ms_present_vblank_handler(uint64_t msc, uint64_t usec, void *data)
+{
+    struct ms_present_vblank_event *event = data;
+
+    DebugPresent(("\t\tmh %lld msc %llu\n",
+                 (long long) event->event_id, (long long) msc));
+
+    present_event_notify(event->event_id, usec, msc);
+    free(event);
+}
+
+/*
+ * Called when the queued vblank is aborted
+ */
+static void
+ms_present_vblank_abort(void *data)
+{
+    struct ms_present_vblank_event *event = data;
+
+    DebugPresent(("\t\tma %lld\n", (long long) event->event_id));
+
+    free(event);
+}
+
+/*
+ * Queue an event to report back to the Present extension when the specified
+ * MSC has past
+ */
+static int
+ms_present_queue_vblank(RRCrtcPtr crtc,
+                        uint64_t event_id,
+                        uint64_t msc)
+{
+    xf86CrtcPtr xf86_crtc = crtc->devPrivate;
+    ScreenPtr screen = crtc->pScreen;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    modesettingPtr ms = modesettingPTR(scrn);
+    drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
+    struct ms_present_vblank_event *event;
+    drmVBlank vbl;
+    int ret;
+    uint32_t seq;
+
+    event = calloc(sizeof(struct ms_present_vblank_event), 1);
+    if (!event)
+        return BadAlloc;
+    event->event_id = event_id;
+    seq = ms_drm_queue_alloc(xf86_crtc, event,
+                             ms_present_vblank_handler,
+                             ms_present_vblank_abort);
+    if (!seq) {
+        free(event);
+        return BadAlloc;
+    }
+
+    vbl.request.type =
+        DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | drmmode_crtc->vblank_pipe;
+    vbl.request.sequence = ms_crtc_msc_to_kernel_msc(xf86_crtc, msc);
+    vbl.request.signal = seq;
+    for (;;) {
+        ret = drmWaitVBlank(ms->fd, &vbl);
+        if (!ret)
+            break;
+        if (errno != EBUSY || !ms_flush_drm_events(screen))
+            return BadAlloc;
+    }
+    DebugPresent(("\t\tmq %lld seq %u msc %llu (hw msc %u)\n",
+                 (long long) event_id, seq, (long long) msc,
+                 vbl.request.sequence));
+    return Success;
+}
+
+static Bool
+ms_present_event_match(void *data, void *match_data)
+{
+    struct ms_present_vblank_event *event = data;
+    uint64_t *match = match_data;
+
+    return *match == event->event_id;
+}
+
+/*
+ * Remove a pending vblank event from the DRM queue so that it is not reported
+ * to the extension
+ */
+static void
+ms_present_abort_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
+{
+    ScreenPtr screen = crtc->pScreen;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+
+    ms_drm_abort(scrn, ms_present_event_match, &event_id);
+}
+
+/*
+ * Flush our batch buffer when requested by the Present extension.
+ */
+static void
+ms_present_flush(WindowPtr window)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    modesettingPtr ms = modesettingPTR(scrn);
+
+    if (ms->drmmode.glamor)
+        glamor_block_handler(screen);
+}
+
+static present_screen_info_rec ms_present_screen_info = {
+    .version = PRESENT_SCREEN_INFO_VERSION,
+
+    .get_crtc = ms_present_get_crtc,
+    .get_ust_msc = ms_present_get_ust_msc,
+    .queue_vblank = ms_present_queue_vblank,
+    .abort_vblank = ms_present_abort_vblank,
+    .flush = ms_present_flush,
+
+    .capabilities = PresentCapabilityNone,
+    .check_flip = 0,
+    .flip = 0,
+    .unflip = 0,
+};
+
+Bool
+ms_present_screen_init(ScreenPtr screen)
+{
+    return present_screen_init(screen, &ms_present_screen_info);
+}
diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index ee5e371..711f6ed 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -331,6 +331,24 @@ ms_drm_abort_scrn(ScrnInfoPtr scrn)
 }
 
 /*
+ * Externally usable abort function that uses a callback to match a single
+ * queued entry to abort
+ */
+void
+ms_drm_abort(ScrnInfoPtr scrn, Bool (*match)(void *data, void *match_data),
+             void *match_data)
+{
+    struct ms_drm_queue *q;
+
+    xorg_list_for_each_entry(q, &ms_drm_queue, list) {
+        if (match(q->data, match_data)) {
+            ms_drm_abort_one(q);
+            break;
+        }
+    }
+}
+
+/*
  * General DRM kernel handler. Looks for the matching sequence number in the
  * drm event queue and calls the handler for it.
  */
commit 3b5be33fc55b3090d996014fa56603edb9c1d411
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Thu Dec 11 13:48:04 2014 -0800

    modesetting: Include glamor.h from driver.h.
    
    We basically want it throughout the driver.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c
index 6c88060..63cb065 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -43,8 +43,6 @@
 #include "dri2.h"
 
 #ifdef GLAMOR
-#define GLAMOR_FOR_XORG 1
-#include "glamor.h"
 
 enum ms_dri2_frame_event_type {
     MS_DRI2_QUEUE_SWAP,
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index be025bd..26054f2 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -61,11 +61,6 @@
 
 #include "driver.h"
 
-#ifdef GLAMOR
-#define GLAMOR_FOR_XORG 1
-#include "glamor.h"
-#endif
-
 static void AdjustFrame(ScrnInfoPtr pScrn, int x, int y);
 static Bool CloseScreen(ScreenPtr pScreen);
 static Bool EnterVT(ScrnInfoPtr pScrn);
diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index bbf1ae0..4267fa1 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -33,6 +33,14 @@
 #include <xf86Crtc.h>
 #include <damage.h>
 
+#ifdef GLAMOR
+#define GLAMOR_FOR_XORG 1
+#include "glamor.h"
+#ifdef GLAMOR_HAS_GBM
+#include <gbm.h>
+#endif
+#endif
+
 #include "drmmode_display.h"
 #define DRV_ERROR(msg)	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
 
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index fd5cf2b..824500b 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -50,14 +50,6 @@
 
 #include "driver.h"
 
-#ifdef GLAMOR
-#define GLAMOR_FOR_XORG 1
-#include "glamor.h"
-#ifdef GLAMOR_HAS_GBM
-#include <gbm.h>
-#endif
-#endif
-
 static int
 drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
 {
commit 7d1fc04d27857c999bd732d54a0b36f5079449b8
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Thu Dec 18 17:58:18 2014 -0800

    modesetting: Check DPMS mode in ms_covering_crtc().
    
    crtc->enabled is insufficient; we should also make sure DPMS is on.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.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 5031ef8..ee5e371 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -88,6 +88,14 @@ static int ms_box_area(BoxPtr box)
     return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1);
 }
 
+static Bool
+ms_crtc_on(xf86CrtcPtr crtc)
+{
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+    return crtc->enabled && drmmode_crtc->dpms_mode == DPMSModeOn;
+}
+
 /*
  * Return the crtc covering 'box'. If two crtcs cover a portion of
  * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
@@ -114,7 +122,7 @@ ms_covering_crtc(ScrnInfoPtr scrn,
         crtc = xf86_config->crtc[c];
 
         /* If the CRTC is off, treat it as not covering */
-        if (!crtc->enabled)
+        if (!ms_crtc_on(crtc))
             continue;
 
         ms_crtc_box(crtc, &crtc_box);
commit 8affaade2c127ea08989c86e7d71cc9da3db1824
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Thu Dec 18 17:55:29 2014 -0800

    modesetting: Track the CRTC's DPMS mode.
    
    We don't want to try to vblank synchronize to monitors which are off.
    
    In order to handle that properly, we need to know the CRTC's DPMS mode.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 8d9bf8b..fd5cf2b 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -193,18 +193,8 @@ drmmode_ConvertToKMode(ScrnInfoPtr scrn,
 static void
 drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
 {
-#if 0
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
-
-//      drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-//      drmmode_ptr drmmode = drmmode_crtc->drmmode;
-
-    /* bonghits in the randr 1.2 - uses dpms to disable crtc - bad buzz */
-    if (mode == DPMSModeOff) {
-//              drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-//                             0, 0, 0, NULL, 0, NULL);
-    }
-#endif
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+    drmmode_crtc->dpms_mode = mode;
 }
 
 #if 0
@@ -347,6 +337,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 
         if (crtc->scrn->pScreen)
             xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
+
+        crtc->funcs->dpms(crtc, DPMSModeOn);
+
         /* go through all the outputs and force DPMS them back on? */
         for (i = 0; i < xf86_config->num_output; i++) {
             xf86OutputPtr output = xf86_config->output[i];
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 0983cf1..66d0ca2 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -86,6 +86,7 @@ typedef struct {
     drmmode_ptr drmmode;
     drmModeCrtcPtr mode_crtc;
     uint32_t vblank_pipe;
+    int dpms_mode;
     struct dumb_bo *cursor_bo;
     Bool cursor_up;
     unsigned rotate_fb_id;
commit b51f804b1ca826699296aff9de27d19257d78dae
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Thu Dec 18 17:22:00 2014 -0800

    present: If present_queue_vblank() fails, do present_execute().
    
    Previously, if present_queue_vblank() failed, we simply dropped the
    present request on the floor, and returned an error.  This was rather
    mean to clients - after presenting, they wait for a PresentComplete
    event to come back.  But since the present never happens, they end up
    waiting forever, and lock up in poll().
    
    This patch falls back to present_execute if present_queue_vblank fails.
    We still print a debugging message to warn when queueing fails, which
    allows us to continue debugging problems, but makes Present robust
    enough to not lock up people's compositing manager when vblank bugs
    happen.
    
    v2: Don't do present_queue_vblank() /and/ present_execute() (a bug that
        snuck in during last minute tidying).
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/present/present.c b/present/present.c
index e27fe30..2a705a9 100644
--- a/present/present.c
+++ b/present/present.c
@@ -871,19 +871,18 @@ present_pixmap(WindowPtr window,
     vblank->queued = TRUE;
     if ((pixmap && target_msc >= crtc_msc) || (!pixmap && target_msc > crtc_msc)) {
         ret = present_queue_vblank(screen, target_crtc, vblank->event_id, target_msc);
-        if (ret != Success) {
-            xorg_list_del(&vblank->event_queue);
-            vblank->queued = FALSE;
-            goto failure;
-        }
-    } else
-        present_execute(vblank, ust, crtc_msc);
+        if (ret == Success)
+            return Success;
+
+        DebugPresent(("present_queue_vblank failed\n"));
+    }
+
+    present_execute(vblank, ust, crtc_msc);
 
     return Success;
 
 no_mem:
     ret = BadAlloc;
-failure:
     vblank->notifies = NULL;
     present_vblank_destroy(vblank);
     return ret;
commit f9e22cefcb9684bf495ada3ec4b0231ab2dc6cff
Author: Dima Ryazanov <dima at gmail.com>
Date:   Mon Dec 22 11:35:29 2014 -0800

    Fix "Back", "Forward", and other special mouse buttons in XWayland.
    
    Currently, the indexes are off by 4 because of the scroll buttons.
    
    Signed-off-by: Dima Ryazanov <dima at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index b8c543c..5e20418 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -233,6 +233,9 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
     xwl_seat->xwl_screen->serial = serial;
 
     switch (button) {
+    case BTN_LEFT:
+        index = 1;
+        break;
     case BTN_MIDDLE:
         index = 2;
         break;
@@ -240,7 +243,9 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
         index = 3;
         break;
     default:
-        index = button - BTN_LEFT + 1;
+        /* Skip indexes 4-7: they are used for vertical and horizontal scroll.
+           The rest of the buttons go in order: BTN_SIDE becomes 8, etc. */
+        index = 8 + button - BTN_SIDE;
         break;
     }
 
commit 70a6f65f9e2b26ef7539dcacfcfea927bc1f13fd
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Dec 25 11:42:03 2014 +0900

    glamor: Make sure Xvideo source image data is properly aligned
    
    _glamor_upload_bits_to_pixmap_texture currently ignores the stride
    parameter, but __glamor_upload_pixmap_to_texture uses 4-byte alignment
    via glPixelStorei(GL_UNPACK_ALIGNMENT, 4).
    
    Also fix up the stride argument passed in though, in case it starts
    being used properly in the future.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87455
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 26bdef6..1c877da 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -208,15 +208,14 @@ glamor_xv_query_image_attributes(int id,
     switch (id) {
     case FOURCC_YV12:
     case FOURCC_I420:
-        *h = *h;
-        *w = *w;
-        size = *w;
+        *h = ALIGN(*h, 2);
+        size = ALIGN(*w, 4);
         if (pitches)
             pitches[0] = size;
         size *= *h;
         if (offsets)
             offsets[1] = size;
-        tmp = *w >> 1;
+        tmp = ALIGN(*w >> 1, 4);
         if (pitches)
             pitches[1] = pitches[2] = tmp;
         tmp *= (*h >> 1);
@@ -413,9 +412,6 @@ glamor_xv_put_image(glamor_port_private *port_priv,
 
     s2offset = s3offset = srcPitch2 = 0;
 
-    srcPitch = width;
-    srcPitch2 = width >> 1;
-
     if (!port_priv->src_pix[0] ||
         (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) {
         int i;
@@ -444,6 +440,8 @@ glamor_xv_put_image(glamor_port_private *port_priv,
     switch (id) {
     case FOURCC_YV12:
     case FOURCC_I420:
+        srcPitch = ALIGN(width, 4);
+        srcPitch2 = ALIGN(width >> 1, 4);
         s2offset = srcPitch * height;
         s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1));
         s2offset += ((top >> 1) * srcPitch2);
@@ -454,18 +452,18 @@ glamor_xv_put_image(glamor_port_private *port_priv,
             s3offset = tmp;
         }
         glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0],
-                                            0, 0, srcPitch, nlines,
-                                            port_priv->src_pix[0]->devKind,
+                                            0, 0, width, nlines,
+                                            srcPitch,
                                             buf + (top * srcPitch), 0);
 
         glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1],
-                                            0, 0, srcPitch2, (nlines + 1) >> 1,
-                                            port_priv->src_pix[1]->devKind,
+                                            0, 0, width >> 1, (nlines + 1) >> 1,
+                                            srcPitch2,
                                             buf + s2offset, 0);
 
         glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2],
-                                            0, 0, srcPitch2, (nlines + 1) >> 1,
-                                            port_priv->src_pix[2]->devKind,
+                                            0, 0, width >> 1, (nlines + 1) >> 1,
+                                            srcPitch2,
                                             buf + s3offset, 0);
         break;
     default:
commit 11b85ab2fc944c0645df43180a6c7e2d6a06483a
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Dec 24 11:46:46 2014 +0900

    glamor: Make glamor_purge_fbo static
    
    Only called from glamor_fbo.c now.
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index d2aabb2..8d73e47 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -126,7 +126,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 #endif
 }
 
-void
+static void
 glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 {
     glamor_make_current(fbo->glamor_priv);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index ffd327e..f699497 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -653,7 +653,6 @@ glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private *glamor_priv, int w,
                                      int h, GLenum format, int flag);
 void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
 void glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv);
-void glamor_purge_fbo(glamor_pixmap_fbo *fbo);
 
 void glamor_init_pixmap_fbo(ScreenPtr screen);
 void glamor_fini_pixmap_fbo(ScreenPtr screen);
commit 8323d2e90150bb86a12d00a16269c69a24efc896
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Dec 24 11:46:18 2014 +0900

    glamor: Call glamor_pixmap_destroy_fbo from glamor_set_pixmap_private
    
    Calling glamor_purge_fbo directly was incorrect for large pixmaps.
    
    Fixes use-after free with large pixmaps:
    
    ==2029== Invalid write of size 8                                                                                                                                      ~
    ==2029==    at 0x85F93AD: __xorg_list_del (list.h:184)
    ==2029==    by 0x85F93AD: xorg_list_del (list.h:204)
    ==2029==    by 0x85F93AD: glamor_fbo_expire (glamor_fbo.c:280)
    ==2029==    by 0x85F95CA: glamor_pixmap_fbo_cache_put (glamor_fbo.c:159)
    ==2029==    by 0x85D7AB5: glamor_destroy_textured_pixmap (glamor.c:228)
    ==2029==    by 0xC1BDDC4: radeon_glamor_destroy_pixmap (radeon_glamor.c:272)
    ==2029==    by 0x519D00: damageDestroyPixmap (damage.c:1473)
    ==2029==    by 0x4DD307: XvDestroyPixmap (xvmain.c:370)
    ==2029==    by 0x4DB975: ShmDestroyPixmap (shm.c:258)
    ==2029==    by 0x5098F6: FreePicture (picture.c:1425)
    ==2029==    by 0x85E678E: glamor_composite_clipped_region (glamor_render.c:1558)
    ==2029==    by 0x85F763A: glamor_composite_largepixmap_region (glamor_largepixmap.c:1347)
    ==2029==    by 0x85E7964: _glamor_composite (glamor_render.c:1679)
    ==2029==    by 0x85E7A38: glamor_composite (glamor_render.c:1758)
    ==2029==  Address 0x1141d3c0 is 0 bytes inside a block of size 64 free'd
    ==2029==    at 0x4C29E90: free (vg_replace_malloc.c:473)
    ==2029==    by 0x85D7167: glamor_set_pixmap_private (glamor.c:570)
    ==2029==    by 0xC1BDDC4: radeon_glamor_destroy_pixmap (radeon_glamor.c:272)
    ==2029==    by 0x519D00: damageDestroyPixmap (damage.c:1473)
    ==2029==    by 0x4DD307: XvDestroyPixmap (xvmain.c:370)
    ==2029==    by 0x4DB975: ShmDestroyPixmap (shm.c:258)
    ==2029==    by 0x45B246: doFreeResource (resource.c:875)
    ==2029==    by 0x45BD5E: FreeResource (resource.c:905)
    ==2029==    by 0x43444B: ProcFreePixmap (dispatch.c:1422)
    ==2029==    by 0x43856E: Dispatch (dispatch.c:432)
    ==2029==    by 0x43C96F: dix_main (main.c:298)
    ==2029==    by 0x6CFAB44: (below main) (libc-start.c:287)
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index e6e8647..78e8278 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -225,7 +225,6 @@ glamor_destroy_textured_pixmap(PixmapPtr pixmap)
 #if GLAMOR_HAS_GBM
             glamor_egl_destroy_pixmap_image(pixmap);
 #endif
-            glamor_pixmap_destroy_fbo(pixmap_priv);
             glamor_set_pixmap_private(pixmap, NULL);
         }
     }
@@ -554,7 +553,6 @@ _X_EXPORT void
 glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
 {
     glamor_pixmap_private *old_priv;
-    glamor_pixmap_fbo *fbo;
 
     old_priv = dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
 
@@ -565,10 +563,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
         if (old_priv == NULL)
             return;
 
-        if (old_priv->base.fbo) {
-            fbo = glamor_pixmap_detach_fbo(old_priv);
-            glamor_purge_fbo(fbo);
-        }
+        glamor_pixmap_destroy_fbo(old_priv);
         free(old_priv);
     }
 
commit 0d37c7e4b5d63308a60ca59c9de981b380af8689
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Dec 19 18:40:19 2014 -0800

    modesetting: Detect whether damage tracking is needed
    
    Call drmModeDirtyFB and check the return value to detect whether the
    driver support for damage tracking is present, only initialize it in
    that case.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Jason Ekstrand <jason.ekstrand at intel.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 5929c03..be025bd 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -875,6 +875,7 @@ CreateScreenResources(ScreenPtr pScreen)
     PixmapPtr rootPixmap;
     Bool ret;
     void *pixels = NULL;
+    int err;
 
     pScreen->CreateScreenResources = ms->createScreenResources;
     ret = pScreen->CreateScreenResources(pScreen);
@@ -911,18 +912,22 @@ CreateScreenResources(ScreenPtr pScreen)
             return FALSE;
     }
 
-    ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
-                              pScreen, rootPixmap);
+    err = drmModeDirtyFB(ms->fd, ms->drmmode.fb_id, NULL, 0);
 
-    if (ms->damage) {
-        DamageRegister(&rootPixmap->drawable, ms->damage);
-        ms->dirty_enabled = TRUE;
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
-    }
-    else {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "Failed to create screen damage record\n");
-        return FALSE;
+    if (err != -EINVAL && err != -ENOSYS) {
+        ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
+                                  pScreen, rootPixmap);
+
+        if (ms->damage) {
+            DamageRegister(&rootPixmap->drawable, ms->damage);
+            ms->dirty_enabled = TRUE;
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
+        }
+        else {
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Failed to create screen damage record\n");
+            return FALSE;
+        }
     }
     return ret;
 }
commit 7804305673ca63720e8736c0c88afa711ebe208a
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Dec 19 19:34:34 2014 -0800

    modesetting: Fix damage tracking auto-disable code
    
    dispatch_dirty_region was only returning -EINVAL error codes,
    otherwise it would return 0. The kernel returns -ENOSYS when the
    driver doesn't support damage tracking, so dispatch_dirty would never
    see the error and never disable damage tracking.
    
    Pass all errors back from dispatch_dirty_region and let dispatch_dirty
    deal with them.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Jason Ekstrand <jason.ekstrand at intel.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index d9a2982..5929c03 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -453,11 +453,12 @@ dispatch_dirty_region(ScrnInfoPtr scrn,
     modesettingPtr ms = modesettingPTR(scrn);
     RegionPtr dirty = DamageRegion(damage);
     unsigned num_cliprects = REGION_NUM_RECTS(dirty);
+    int ret = 0;
 
     if (num_cliprects) {
         drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip));
         BoxPtr rect = REGION_RECTS(dirty);
-        int i, ret;
+        int i;
 
         if (!clip)
             return -ENOMEM;
@@ -474,12 +475,8 @@ dispatch_dirty_region(ScrnInfoPtr scrn,
         ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects);
         free(clip);
         DamageEmpty(damage);
-        if (ret) {
-            if (ret == -EINVAL)
-                return ret;
-        }
     }
-    return 0;
+    return ret;
 }
 
 static void
commit 826e7c2b36f192fbbe7ddff37eb559f4d6301146
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Wed Dec 17 20:50:02 2014 -0800

    Solaris: Move shared declarations to xf86_OSlib.h
    
    Gets rid of gcc 4.8 warnings:
     xf86AutoConfig.c:211:9: warning: nested extern declaration of
      'xf86SolarisFbDev' [-Wnested-externs]
     sun_VTsw.c:44:1: warning: no previous prototype for 'xf86VTRelease'
      [-Wmissing-prototypes]
     sun_VTsw.c:59:1: warning: no previous prototype for 'xf86VTAcquire'
      [-Wmissing-prototypes]
    
    and ensures caller & definition stay in sync.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 03dad15..1450afb 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -208,7 +208,6 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
     if (xf86Info.consoleFd >= 0 && (i < (nmatches - 1))) {
         struct vis_identifier visid;
         const char *cp;
-        extern char xf86SolarisFbDev[PATH_MAX];
         int iret;
 
         SYSCALL(iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid));
diff --git a/hw/xfree86/os-support/solaris/sun_init.c b/hw/xfree86/os-support/solaris/sun_init.c
index 2e0af22..cc50f36 100644
--- a/hw/xfree86/os-support/solaris/sun_init.c
+++ b/hw/xfree86/os-support/solaris/sun_init.c
@@ -52,8 +52,6 @@ static Bool UseConsole = FALSE;
 static int VTnum = -1;
 static int xf86StartVT = -1;
 static int vtEnabled = 0;
-extern void xf86VTAcquire(int);
-extern void xf86VTRelease(int);
 #endif
 
 /* Device to open as xf86Info.consoleFd */
diff --git a/hw/xfree86/os-support/xf86_OSlib.h b/hw/xfree86/os-support/xf86_OSlib.h
index 3a83f34..6190fe6 100644
--- a/hw/xfree86/os-support/xf86_OSlib.h
+++ b/hw/xfree86/os-support/xf86_OSlib.h
@@ -134,10 +134,15 @@
 #endif
 #include <sys/kd.h>
 #include <sys/vt.h>
+
+extern _X_HIDDEN void xf86VTAcquire(int);
+extern _X_HIDDEN void xf86VTRelease(int);
 #endif
 
 #if defined(sun)
 #include <sys/fbio.h>
+extern _X_HIDDEN char xf86SolarisFbDev[PATH_MAX];
+
 #include <sys/kbd.h>
 #include <sys/kbio.h>
 
commit bebcac0cf790b220e849e8905139d0744a606928
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Wed Dec 17 20:50:01 2014 -0800

    Move RTLD_DI_SETSIGNAL code into a separate block to quiet warning
    
    Gets rid of gcc 4.8 warning:
     osinit.c:211:9: warning: ISO C90 forbids mixed declarations and code
      [-Wdeclaration-after-statement]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/osinit.c b/os/osinit.c
index ff0979a..91e3e06 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -208,9 +208,11 @@ OsInit(void)
          * for failures to load libraries/modules at runtime so we can clean up
          * after ourselves.
          */
-        int failure_signal = SIGQUIT;
+        {
+            int failure_signal = SIGQUIT;
 
-        dlinfo(RTLD_SELF, RTLD_DI_SETSIGNAL, &failure_signal);
+            dlinfo(RTLD_SELF, RTLD_DI_SETSIGNAL, &failure_signal);
+        }
 #endif
 
 #if !defined(XQUARTZ)    /* STDIN is already /dev/null and STDOUT/STDERR is managed by console_redirect.c */
commit 2c7111235ca5c3bd23cd824589dfbc0ebd477585
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Dec 13 22:22:30 2014 -0800

    modesetting: Enable Xv when using glamor
    
    This just calls the existing function to create the relevant Xv
    adaptor and hook it up.
    
    Signed-off-by: Keith Packard <keithp at keithp.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 cad9000..d9a2982 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1103,6 +1103,19 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
 
     xf86DPMSInit(pScreen, xf86DPMSSet, 0);
 
+#ifdef GLAMOR
+    if (ms->drmmode.glamor) {
+        XF86VideoAdaptorPtr     glamor_adaptor;
+
+        glamor_adaptor = glamor_xv_init(pScreen, 16);
+        if (glamor_adaptor != NULL)
+            xf86XVScreenInit(pScreen, &glamor_adaptor, 1);
+        else
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Failed to initialize XV support.\n");
+    }
+#endif
+
     if (serverGeneration == 1)
         xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
 
commit 5a541bd5e7adc9fdcc1883558be9218f82a284e0
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Dec 16 23:14:34 2014 -0800

    modesetting: [v2] Don't re-enable the cursor when loading the image
    
    Hidden cursors also have their image updated; re-enabling the cursor
    each time the image is set will cause it to re-appear.
    
     * Unifies the code that was in  drmmode_load_cursor_argb and
      drm_mode_show_cursor and moves it to a new drmmode_set_cursor
    
     * Add a new boolean, 'cursor_up', to the per-crtc
       private data to track whether the cursor should be displayed.
    
     * Call drmmode_set_cursor from drm_mode_show_cursor and, if
       the cursor should be displayed, from drm_mode_load_cursor_argb.
    
    v2: Call drmModeSetCursor2 when loading a new cursor image if the
        cursor should be displayed.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    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 13a96dc..8d9bf8b 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -394,25 +394,32 @@ drmmode_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
 }
 
 static void
-drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
+drmmode_set_cursor(xf86CrtcPtr crtc)
 {
-    modesettingPtr ms = modesettingPTR(crtc->scrn);
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-    int i;
-    uint32_t *ptr;
+    drmmode_ptr drmmode = drmmode_crtc->drmmode;
     uint32_t handle = drmmode_crtc->cursor_bo->handle;
+    modesettingPtr ms = modesettingPTR(crtc->scrn);
+    static Bool use_set_cursor2 = TRUE;
     int ret;
 
-    /* cursor should be mapped already */
-    ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr);
+    if (use_set_cursor2) {
+        xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+        CursorPtr cursor = xf86_config->cursor;
 
-    for (i = 0; i < ms->cursor_width * ms->cursor_height; i++)
-        ptr[i] = image[i];      // cpu_to_le32(image[i]);
+        ret =
+            drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+                              handle, ms->cursor_width, ms->cursor_height,
+                              cursor->bits->xhot, cursor->bits->yhot);
+        if (ret == -EINVAL)
+            use_set_cursor2 = FALSE;
+        else
+            return;
+    }
+
+    ret = drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle,
+                           ms->cursor_width, ms->cursor_height);
 
-    ret =
-        drmModeSetCursor(drmmode_crtc->drmmode->fd,
-                         drmmode_crtc->mode_crtc->crtc_id, handle,
-                         ms->cursor_width, ms->cursor_height);
     if (ret) {
         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
         xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
@@ -424,46 +431,44 @@ drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
 }
 
 static void
-drmmode_hide_cursor(xf86CrtcPtr crtc)
+drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
 {
     modesettingPtr ms = modesettingPTR(crtc->scrn);
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-    drmmode_ptr drmmode = drmmode_crtc->drmmode;
+    int i;
+    uint32_t *ptr;
 
-    drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0,
-                     ms->cursor_width, ms->cursor_height);
+    /* cursor should be mapped already */
+    ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr);
+
+    for (i = 0; i < ms->cursor_width * ms->cursor_height; i++)
+        ptr[i] = image[i];      // cpu_to_le32(image[i]);
 
+    if (drmmode_crtc->cursor_up)
+        drmmode_set_cursor(crtc);
 }
 
 static void
-drmmode_show_cursor(xf86CrtcPtr crtc)
+drmmode_hide_cursor(xf86CrtcPtr crtc)
 {
     modesettingPtr ms = modesettingPTR(crtc->scrn);
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
     drmmode_ptr drmmode = drmmode_crtc->drmmode;
-    uint32_t handle = drmmode_crtc->cursor_bo->handle;
-    static Bool use_set_cursor2 = TRUE;
-
-    if (use_set_cursor2) {
-        xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
-        CursorPtr cursor = xf86_config->cursor;
-        int ret;
-
-        ret =
-            drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-                              handle, ms->cursor_width, ms->cursor_height,
-                              cursor->bits->xhot, cursor->bits->yhot);
-        if (ret == -EINVAL)
-            use_set_cursor2 = FALSE;
-        else
-            return;
-    }
 
-    drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle,
+    drmmode_crtc->cursor_up = FALSE;
+    drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0,
                      ms->cursor_width, ms->cursor_height);
 }
 
 static void
+drmmode_show_cursor(xf86CrtcPtr crtc)
+{
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+    drmmode_crtc->cursor_up = TRUE;
+    drmmode_set_cursor(crtc);
+}
+
+static void
 drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t * red, uint16_t * green,
                        uint16_t * blue, int size)
 {
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 6450811..0983cf1 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -87,6 +87,7 @@ typedef struct {
     drmModeCrtcPtr mode_crtc;
     uint32_t vblank_pipe;
     struct dumb_bo *cursor_bo;
+    Bool cursor_up;
     unsigned rotate_fb_id;
     uint16_t lut_r[256], lut_g[256], lut_b[256];
     DamagePtr slave_damage;
commit 0f5fdaf600bfeada966aea942cb3e347d4efee30
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Dec 11 16:50:40 2014 +0900

    glamor: Make sure glamor_egl_close_screen wraps glamor_close_screen
    
    The other way around fails to destroy the screen pixmap EGL image:
    
    ==1782== 80 (32 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 981 of 2,171
    ==1782==    at 0x4C28C20: malloc (vg_replace_malloc.c:296)
    ==1782==    by 0xF9D4BD2: dri2_create_image_from_dri (egl_dri2.c:1264)
    ==1782==    by 0xF9D4BD2: dri2_create_image_dma_buf (egl_dri2.c:1764)
    ==1782==    by 0xF9D4BD2: dri2_create_image_khr (egl_dri2.c:1798)
    ==1782==    by 0xF9C7937: eglCreateImageKHR (eglapi.c:1494)
    ==1782==    by 0x85D5655: _glamor_egl_create_image (glamor_egl.c:134)
    ==1782==    by 0x85D5655: glamor_egl_create_textured_pixmap (glamor_egl.c:302)
    ==1782==    by 0x85D579B: glamor_egl_create_textured_screen (glamor_egl.c:225)
    ==1782==    by 0xC1BE05D: radeon_glamor_create_screen_resources (radeon_glamor.c:67)
    ==1782==    by 0xC1B6153: RADEONCreateScreenResources_KMS (radeon_kms.c:258)
    ==1782==    by 0x4B2105: xf86CrtcCreateScreenResources (xf86Crtc.c:709)
    ==1782==    by 0x43C823: dix_main (main.c:223)
    ==1782==    by 0x6CFAB44: (below main) (libc-start.c:287)
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index d1aa1cf..e6e8647 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -424,6 +424,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
     glamor_set_debug_level(&glamor_debug_level);
 
+    glamor_priv->saved_procs.close_screen = screen->CloseScreen;
+    screen->CloseScreen = glamor_close_screen;
+
     /* If we are using egl screen, call egl screen init to
      * register correct close screen function. */
     if (flags & GLAMOR_USE_EGL_SCREEN) {
@@ -433,9 +436,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
             goto fail;
     }
 
-    glamor_priv->saved_procs.close_screen = screen->CloseScreen;
-    screen->CloseScreen = glamor_close_screen;
-
     glamor_priv->saved_procs.create_screen_resources =
         screen->CreateScreenResources;
     screen->CreateScreenResources = glamor_create_screen_resources;
commit c8d4c0a25dba49d1486761438b96374672b29645
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Dec 11 16:50:39 2014 +0900

    glamor: Make glamor_destroy_textured_pixmap idempotent
    
    For robustness against drivers which may call both
    glamor_(egl_)destroy_textured_pixmap and glamor_destroy_pixmap.
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index cbd0e02..d1aa1cf 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -226,6 +226,7 @@ glamor_destroy_textured_pixmap(PixmapPtr pixmap)
             glamor_egl_destroy_pixmap_image(pixmap);
 #endif
             glamor_pixmap_destroy_fbo(pixmap_priv);
+            glamor_set_pixmap_private(pixmap, NULL);
         }
     }
 }
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 4273826..d2aabb2 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -540,8 +540,6 @@ glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv)
         if (fbo)
             glamor_destroy_fbo(fbo);
     }
-
-    free(priv);
 }
 
 Bool
commit 0355e280a39dee68981b2cbebfa2573cfde2f5bd
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Dec 11 16:50:38 2014 +0900

    glamor: Make glamor_set_pixmap_private not crash if the pixmap has no fbo
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index c4f3f3a..cbd0e02 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -563,8 +563,11 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
     else {
         if (old_priv == NULL)
             return;
-        fbo = glamor_pixmap_detach_fbo(old_priv);
-        glamor_purge_fbo(fbo);
+
+        if (old_priv->base.fbo) {
+            fbo = glamor_pixmap_detach_fbo(old_priv);
+            glamor_purge_fbo(fbo);
+        }
         free(old_priv);
     }
 
commit 45b333525e4626523f2b3b7bb360404b6366750d
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Dec 11 16:50:37 2014 +0900

    glamor: Fix use-after-free in glamor_destroy_textured_pixmap
    
    ==25551== Invalid read of size 8
    ==25551==    at 0x85D5F2C: glamor_egl_destroy_pixmap_image (glamor_egl.c:527)
    ==25551==    by 0x85D7750: glamor_destroy_pixmap (glamor.c:235)
    ==25551==    by 0xC1BDD9B: radeon_glamor_destroy_pixmap (radeon_glamor.c:278)
    ==25551==    by 0x5098F6: FreePicture (picture.c:1425)
    ==25551==    by 0x85DD7A9: glamor_unrealize_glyph_caches (glamor_glyphs.c:257)
    ==25551==    by 0x85D7B50: glamor_close_screen (glamor.c:586)
    ==25551==    by 0x4B1A82: xf86CrtcCloseScreen (xf86Crtc.c:734)
    ==25551==    by 0x4CFFC7: CursorCloseScreen (cursor.c:187)
    ==25551==    by 0x513A44: AnimCurCloseScreen (animcur.c:106)
    ==25551==    by 0x51529B: present_close_screen (present_screen.c:64)
    ==25551==    by 0x43CA83: dix_main (main.c:351)
    ==25551==    by 0x6CFAB44: (below main) (libc-start.c:287)
    ==25551==  Address 0x83dafa0 is 96 bytes inside a block of size 152 free'd
    ==25551==    at 0x4C29E90: free (vg_replace_malloc.c:473)
    ==25551==    by 0x85D76B4: glamor_destroy_textured_pixmap (glamor.c:225)
    ==25551==    by 0x85D7750: glamor_destroy_pixmap (glamor.c:235)
    ==25551==    by 0xC1BDD9B: radeon_glamor_destroy_pixmap (radeon_glamor.c:278)
    ==25551==    by 0x5098F6: FreePicture (picture.c:1425)
    ==25551==    by 0x85DD7A9: glamor_unrealize_glyph_caches (glamor_glyphs.c:257)
    ==25551==    by 0x85D7B50: glamor_close_screen (glamor.c:586)
    ==25551==    by 0x4B1A82: xf86CrtcCloseScreen (xf86Crtc.c:734)
    ==25551==    by 0x4CFFC7: CursorCloseScreen (cursor.c:187)
    ==25551==    by 0x513A44: AnimCurCloseScreen (animcur.c:106)
    ==25551==    by 0x51529B: present_close_screen (present_screen.c:64)
    ==25551==    by 0x43CA83: dix_main (main.c:351)
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index b32cc16..c4f3f3a 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -221,11 +221,12 @@ glamor_destroy_textured_pixmap(PixmapPtr pixmap)
 {
     if (pixmap->refcnt == 1) {
         glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-        if (pixmap_priv != NULL)
-            glamor_pixmap_destroy_fbo(pixmap_priv);
+        if (pixmap_priv != NULL) {
 #if GLAMOR_HAS_GBM
-        glamor_egl_destroy_pixmap_image(pixmap);
+            glamor_egl_destroy_pixmap_image(pixmap);
 #endif
+            glamor_pixmap_destroy_fbo(pixmap_priv);
+        }
     }
 }
 
commit 913416b718e73e7416c2128a82d2e5e5cd962d28
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Dec 9 10:15:08 2014 -0800

    Solaris: delete undocumented, unuseful -protect0 flag
    
    Solaris already makes the page at address 0 inaccessible by default to
    catch NULL pointer bugs, we don't need a double secret undocumented flag
    to try to make our own hacky attempt at it.
    
    As a bonus, deleting this code removes gcc warning of:
    
    sun_init.c: In function 'xf86OpenConsole':
    sun_init.c:103:17: warning: declaration of 'fd' shadows a previous local [-Wshadow]
                 int fd = -1;
                     ^
    sun_init.c:89:9: warning: shadowed declaration is here [-Wshadow]
         int fd;
             ^
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Mark Kettenis <kettenis at openbsd.org>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/os-support/solaris/sun_init.c b/hw/xfree86/os-support/solaris/sun_init.c
index 16fc1b7..2e0af22 100644
--- a/hw/xfree86/os-support/solaris/sun_init.c
+++ b/hw/xfree86/os-support/solaris/sun_init.c
@@ -46,7 +46,6 @@
 #define	SOL_CONSOLE_DEV	"/dev/console"
 
 static Bool KeepTty = FALSE;
-static Bool Protect0 = FALSE;
 static Bool UseConsole = FALSE;
 
 #ifdef HAS_USL_VTS
@@ -97,27 +96,6 @@ xf86OpenConsole(void)
         if (geteuid() != 0)
             FatalError("xf86OpenConsole: Server must be suid root\n");
 
-        /* Protect page 0 to help find NULL dereferencing */
-        /* mprotect() doesn't seem to work */
-        if (Protect0) {
-            int fd = -1;
-
-            if ((fd = open("/dev/zero", O_RDONLY, 0)) < 0) {
-                xf86Msg(X_WARNING,
-                        "xf86OpenConsole: cannot open /dev/zero (%s)\n",
-                        strerror(errno));
-            }
-            else {
-                if (mmap(0, 0x1000, PROT_NONE,
-                         MAP_FIXED | MAP_SHARED, fd, 0) == MAP_FAILED)
-                    xf86Msg(X_WARNING,
-                            "xf86OpenConsole: failed to protect page 0 (%s)\n",
-                            strerror(errno));
-
-                close(fd);
-            }
-        }
-
 #ifdef HAS_USL_VTS
 
         /*
@@ -371,15 +349,6 @@ xf86ProcessArgument(int argc, char **argv, int i)
     }
 
     /*
-     * Undocumented flag to protect page 0 from read/write to help catch NULL
-     * pointer dereferences.  This is purely a debugging flag.
-     */
-    if (!strcmp(argv[i], "-protect0")) {
-        Protect0 = TRUE;
-        return 1;
-    }
-
-    /*
      * Use /dev/console as the console device.
      */
     if (!strcmp(argv[i], "-C")) {
commit 7b784df51bd6be38238d7101b1f5e320eb4aa5b8
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Dec 9 12:43:57 2014 -0800

    modesetting: Use GBM for buffer allocations if Glamor supports it.
    
    For performance, Glamor wants to render to tiled buffers, not linear
    ones.  Using GBM allows us to pick the 3D driver's preferred tiling
    modes.
    
    v2: Declare drmmode->gbm as void * if !GLAMOR_HAS_GBM.
    v3: Just use a forward declaration of struct gbm_device.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index dea709e..cad9000 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -877,7 +877,7 @@ CreateScreenResources(ScreenPtr pScreen)
     modesettingPtr ms = modesettingPTR(pScrn);
     PixmapPtr rootPixmap;
     Bool ret;
-    void *pixels;
+    void *pixels = NULL;
 
     pScreen->CreateScreenResources = ms->createScreenResources;
     ret = pScreen->CreateScreenResources(pScreen);
@@ -893,9 +893,12 @@ CreateScreenResources(ScreenPtr pScreen)
 
     if (!ms->drmmode.sw_cursor)
         drmmode_map_cursor_bos(pScrn, &ms->drmmode);
-    pixels = drmmode_map_front_bo(&ms->drmmode);
-    if (!pixels)
-        return FALSE;
+
+    if (!ms->drmmode.gbm) {
+        pixels = drmmode_map_front_bo(&ms->drmmode);
+        if (!pixels)
+            return FALSE;
+    }
 
     rootPixmap = pScreen->GetScreenPixmap(pScreen);
 
@@ -985,6 +988,11 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
     if (!SetMaster(pScrn))
         return FALSE;
 
+#ifdef GLAMOR_HAS_GBM
+    if (ms->drmmode.glamor)
+        ms->drmmode.gbm = glamor_egl_get_gbm_device(pScreen);
+#endif
+
     /* HW dependent - FIXME */
     pScrn->displayWidth = pScrn->virtualX;
     if (!drmmode_create_initial_bos(pScrn, &ms->drmmode))
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 29b8844..13a96dc 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -53,6 +53,9 @@
 #ifdef GLAMOR
 #define GLAMOR_FOR_XORG 1
 #include "glamor.h"
+#ifdef GLAMOR_HAS_GBM
+#include <gbm.h>
+#endif
 #endif
 
 static int
@@ -60,6 +63,13 @@ drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
 {
     int ret;
 
+#ifdef GLAMOR_HAS_GBM
+    if (bo->gbm) {
+        gbm_bo_destroy(bo->gbm);
+        bo->gbm = NULL;
+    }
+#endif
+
     if (bo->dumb) {
         ret = dumb_bo_destroy(drmmode->fd, bo->dumb);
         if (ret == 0)
@@ -72,12 +82,22 @@ drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
 static uint32_t
 drmmode_bo_get_pitch(drmmode_bo *bo)
 {
+#ifdef GLAMOR_HAS_GBM
+    if (bo->gbm)
+        return gbm_bo_get_stride(bo->gbm);
+#endif
+
     return bo->dumb->pitch;
 }
 
 uint32_t
 drmmode_bo_get_handle(drmmode_bo *bo)
 {
+#ifdef GLAMOR_HAS_GBM
+    if (bo->gbm)
+        return gbm_bo_get_handle(bo->gbm).u32;
+#endif
+
     return bo->dumb->handle;
 }
 
@@ -85,6 +105,15 @@ static Bool
 drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
                   unsigned width, unsigned height, unsigned bpp)
 {
+#ifdef GLAMOR_HAS_GBM
+    if (drmmode->glamor) {
+        bo->gbm = gbm_bo_create(drmmode->gbm, width, height,
+                                GBM_FORMAT_ARGB8888,
+                                GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+        return bo->gbm != NULL;
+    }
+#endif
+
     bo->dumb = dumb_bo_create(drmmode->fd, width, height, bpp);
     return bo->dumb != NULL;
 }
@@ -1110,10 +1139,22 @@ drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
 #ifdef GLAMOR
     ScrnInfoPtr scrn = drmmode->scrn;
     ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn);
+    PixmapPtr screen_pixmap;
+    void *gbm_bo;
 
     if (!drmmode->glamor)
         return TRUE;
 
+#ifdef GLAMOR_HAS_GBM
+    gbm_bo = drmmode->front_bo.gbm;
+    screen_pixmap = screen->GetScreenPixmap(screen);
+
+    if (!glamor_egl_create_textured_pixmap_from_gbm_bo(screen_pixmap, gbm_bo)) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
+        return FALSE;
+    }
+    glamor_set_screen_pixmap(screen_pixmap, NULL);
+#else
     if (!glamor_egl_create_textured_screen(screen,
                                            drmmode_bo_get_handle(&drmmode->front_bo),
                                            scrn->displayWidth *
@@ -1123,6 +1164,7 @@ drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
         return FALSE;
     }
 #endif
+#endif
 
     return TRUE;
 }
@@ -1142,7 +1184,7 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
     int i, pitch, old_width, old_height, old_pitch;
     int cpp = (scrn->bitsPerPixel + 7) / 8;
     PixmapPtr ppix = screen->GetScreenPixmap(screen);
-    void *new_pixels;
+    void *new_pixels = NULL;
 
     if (scrn->virtualX == width && scrn->virtualY == height)
         return TRUE;
@@ -1178,9 +1220,11 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
     if (ret)
         goto fail;
 
-    new_pixels = drmmode_map_front_bo(drmmode);
-    if (!new_pixels)
-        goto fail;
+    if (!drmmode->gbm) {
+        new_pixels = drmmode_map_front_bo(drmmode);
+        if (!new_pixels)
+            goto fail;
+    }
 
     if (drmmode->shadow_enable) {
         uint32_t size = scrn->displayWidth * scrn->virtualY *
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 7c1ff05..6450811 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -34,8 +34,13 @@
 
 #include "dumb_bo.h"
 
+struct gbm_device;
+
 typedef struct {
     struct dumb_bo *dumb;
+#ifdef GLAMOR_HAS_GBM
+    struct gbm_bo *gbm;
+#endif
 } drmmode_bo;
 
 typedef struct {
@@ -46,6 +51,9 @@ typedef struct {
     drmModeFBPtr mode_fb;
     int cpp;
     ScrnInfoPtr scrn;
+
+    struct gbm_device *gbm;
+
 #ifdef CONFIG_UDEV_KMS
     struct udev_monitor *uevent_monitor;
     InputHandlerProc uevent_handler;
commit cfef64b0cabe7677c7584a72d7432c20343d9361
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Dec 9 12:28:38 2014 -0800

    glamor: Add an accessor for the GBM device.
    
    (Originally written by Dave Airlie; split into a separate patch by
    Kenneth Graunke.)
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index 95c4253..206158c 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -172,6 +172,8 @@ extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr,
 
 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
  * glamor_fd_from_pixmap(), glamor_name_from_pixmap(), and
  * glamor_pixmap_from_fd() are supported.
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 898081a..113450c 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -174,6 +174,18 @@ glamor_create_texture_from_image(ScreenPtr screen,
     return TRUE;
 }
 
+void *
+glamor_egl_get_gbm_device(ScreenPtr screen)
+{
+#ifdef GLAMOR_HAS_GBM
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
+    return glamor_egl->gbm;
+#else
+    return NULL;
+#endif
+}
+
 unsigned int
 glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
 {
commit 980535757d38db5c812c8afa32726d8cc36abfa4
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Dec 9 15:20:44 2014 -0800

    modesetting: Create a drmmode_bo wrapper; use it for front_bo.
    
    This code is going to be extended to support GBM BOs soon.  This small
    abstraction removes a lot of direct dumb_bo access, so we can add that
    support in one place, rather than putting conditionals at every
    pitch/handle/etc access.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 61c8032..dea709e 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -861,7 +861,7 @@ msShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
     stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
     *size = stride;
 
-    return ((uint8_t *) ms->drmmode.front_bo->ptr + row * stride + offset);
+    return ((uint8_t *) ms->drmmode.front_bo.dumb->ptr + row * stride + offset);
 }
 
 static void
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 277f60c..29b8844 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -55,6 +55,40 @@
 #include "glamor.h"
 #endif
 
+static int
+drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
+{
+    int ret;
+
+    if (bo->dumb) {
+        ret = dumb_bo_destroy(drmmode->fd, bo->dumb);
+        if (ret == 0)
+            bo->dumb = NULL;
+    }
+
+    return 0;
+}
+
+static uint32_t
+drmmode_bo_get_pitch(drmmode_bo *bo)
+{
+    return bo->dumb->pitch;
+}
+
+uint32_t
+drmmode_bo_get_handle(drmmode_bo *bo)
+{
+    return bo->dumb->handle;
+}
+
+static Bool
+drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
+                  unsigned width, unsigned height, unsigned bpp)
+{
+    bo->dumb = dumb_bo_create(drmmode->fd, width, height, bpp);
+    return bo->dumb != NULL;
+}
+
 Bool
 drmmode_SetSlaveBO(PixmapPtr ppix,
                    drmmode_ptr drmmode, int fd_handle, int pitch, int size)
@@ -213,8 +247,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
         ret = drmModeAddFB(drmmode->fd,
                            pScrn->virtualX, height,
                            pScrn->depth, pScrn->bitsPerPixel,
-                           drmmode->front_bo->pitch,
-                           drmmode->front_bo->handle, &drmmode->fb_id);
+                           drmmode_bo_get_pitch(&drmmode->front_bo),
+                           drmmode_bo_get_handle(&drmmode->front_bo),
+                           &drmmode->fb_id);
         if (ret < 0) {
             ErrorF("failed to add fb %d\n", ret);
             return FALSE;
@@ -1080,7 +1115,7 @@ drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
         return TRUE;
 
     if (!glamor_egl_create_textured_screen(screen,
-                                           drmmode->front_bo->handle,
+                                           drmmode_bo_get_handle(&drmmode->front_bo),
                                            scrn->displayWidth *
                                            scrn->bitsPerPixel / 8)) {
         xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -1100,7 +1135,7 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
     drmmode_crtc_private_ptr
         drmmode_crtc = xf86_config->crtc[0]->driver_private;
     drmmode_ptr drmmode = drmmode_crtc->drmmode;
-    struct dumb_bo *old_front = NULL;
+    drmmode_bo old_front;
     Bool ret;
     ScreenPtr screen = xf86ScrnToScreen(scrn);
     uint32_t old_fb_id;
@@ -1122,16 +1157,15 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
 
     old_width = scrn->virtualX;
     old_height = scrn->virtualY;
-    old_pitch = drmmode->front_bo->pitch;
+    old_pitch = drmmode_bo_get_pitch(&drmmode->front_bo);
     old_fb_id = drmmode->fb_id;
     old_front = drmmode->front_bo;
 
-    drmmode->front_bo =
-        dumb_bo_create(drmmode->fd, width, height, scrn->bitsPerPixel);
-    if (!drmmode->front_bo)
+    if (!drmmode_create_bo(drmmode, &drmmode->front_bo,
+                           width, height, scrn->bitsPerPixel))
         goto fail;
 
-    pitch = drmmode->front_bo->pitch;
+    pitch = drmmode_bo_get_pitch(&drmmode->front_bo);
 
     scrn->virtualX = width;
     scrn->virtualY = height;
@@ -1139,7 +1173,8 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
 
     ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
                        scrn->bitsPerPixel, pitch,
-                       drmmode->front_bo->handle, &drmmode->fb_id);
+                       drmmode_bo_get_handle(&drmmode->front_bo),
+                       &drmmode->fb_id);
     if (ret)
         goto fail;
 
@@ -1174,14 +1209,13 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
 
     if (old_fb_id) {
         drmModeRmFB(drmmode->fd, old_fb_id);
-        dumb_bo_destroy(drmmode->fd, old_front);
+        drmmode_bo_destroy(drmmode, &old_front);
     }
 
     return TRUE;
 
  fail:
-    if (drmmode->front_bo)
-        dumb_bo_destroy(drmmode->fd, drmmode->front_bo);
+    drmmode_bo_destroy(drmmode, &drmmode->front_bo);
     drmmode->front_bo = old_front;
     scrn->virtualX = old_width;
     scrn->virtualY = old_height;
@@ -1467,10 +1501,9 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
     width = pScrn->virtualX;
     height = pScrn->virtualY;
 
-    drmmode->front_bo = dumb_bo_create(drmmode->fd, width, height, bpp);
-    if (!drmmode->front_bo)
+    if (!drmmode_create_bo(drmmode, &drmmode->front_bo, width, height, bpp))
         return FALSE;
-    pScrn->displayWidth = drmmode->front_bo->pitch / cpp;
+    pScrn->displayWidth = drmmode_bo_get_pitch(&drmmode->front_bo) / cpp;
 
     width = ms->cursor_width;
     height = ms->cursor_height;
@@ -1490,14 +1523,14 @@ drmmode_map_front_bo(drmmode_ptr drmmode)
 {
     int ret;
 
-    if (drmmode->front_bo->ptr)
-        return drmmode->front_bo->ptr;
+    if (drmmode->front_bo.dumb->ptr)
+        return drmmode->front_bo.dumb->ptr;
 
-    ret = dumb_bo_map(drmmode->fd, drmmode->front_bo);
+    ret = dumb_bo_map(drmmode->fd, drmmode->front_bo.dumb);
     if (ret)
         return NULL;
 
-    return drmmode->front_bo->ptr;
+    return drmmode->front_bo.dumb->ptr;
 
 }
 
@@ -1544,8 +1577,7 @@ drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
         drmmode->fb_id = 0;
     }
 
-    dumb_bo_destroy(drmmode->fd, drmmode->front_bo);
-    drmmode->front_bo = NULL;
+    drmmode_bo_destroy(drmmode, &drmmode->front_bo);
 
     for (i = 0; i < xf86_config->num_crtc; i++) {
         xf86CrtcPtr crtc = xf86_config->crtc[i];
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index abb93ec..7c1ff05 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -35,6 +35,10 @@
 #include "dumb_bo.h"
 
 typedef struct {
+    struct dumb_bo *dumb;
+} drmmode_bo;
+
+typedef struct {
     int fd;
     unsigned fb_id;
     unsigned old_fb_id;
@@ -47,7 +51,7 @@ typedef struct {
     InputHandlerProc uevent_handler;
 #endif
     drmEventContext event_context;
-    struct dumb_bo *front_bo;
+    drmmode_bo front_bo;
     Bool sw_cursor;
 
     Bool glamor;
@@ -123,6 +127,7 @@ extern DevPrivateKeyRec msPixmapPrivateKeyRec;
 
 #define msGetPixmapPriv(drmmode, p) ((msPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &(drmmode)->pixmapPrivateKeyRec))
 
+uint32_t drmmode_bo_get_handle(drmmode_bo *bo);
 Bool drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode);
 void *drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv);
 Bool drmmode_SetSlaveBO(PixmapPtr ppix,
commit c6388964b079b3828c0b64951ff03008dda8f44a
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Dec 9 11:26:39 2014 -0800

    modesetting: Drop dumb_bo::map_count field and dead unmap code.
    
    The drm kernel API for dumb BOs apparently doesn't include an unmap
    ioctl, so we can't do much here.  It looks like this code was copied
    from libkms, which was also unfinished.
    
    We may as well delete the dead variable that simply gets incremented
    and never read.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/dumb_bo.c b/hw/xfree86/drivers/modesetting/dumb_bo.c
index 9a69aa2..58d420e 100644
--- a/hw/xfree86/drivers/modesetting/dumb_bo.c
+++ b/hw/xfree86/drivers/modesetting/dumb_bo.c
@@ -74,7 +74,6 @@ dumb_bo_map(int fd, struct dumb_bo *bo)
     void *map;
 
     if (bo->ptr) {
-        bo->map_count++;
         return 0;
     }
 
@@ -93,15 +92,6 @@ dumb_bo_map(int fd, struct dumb_bo *bo)
     return 0;
 }
 
-#if 0
-static int
-dumb_bo_unmap(int fd, struct dumb_bo *bo)
-{
-    bo->map_count--;
-    return 0;
-}
-#endif
-
 int
 dumb_bo_destroy(int fd, struct dumb_bo *bo)
 {
diff --git a/hw/xfree86/drivers/modesetting/dumb_bo.h b/hw/xfree86/drivers/modesetting/dumb_bo.h
index 1d401d4..9235e61 100644
--- a/hw/xfree86/drivers/modesetting/dumb_bo.h
+++ b/hw/xfree86/drivers/modesetting/dumb_bo.h
@@ -33,7 +33,6 @@ struct dumb_bo {
     uint32_t handle;
     uint32_t size;
     void *ptr;
-    int map_count;
     uint32_t pitch;
 };
 
commit 87cc0c0d317c5eac4fcf9bf4a7ad36454c05f6b8
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Dec 9 11:17:30 2014 -0800

    modesetting: Move dumb_bo into its own source files.
    
    Eventually, drmmode_display will be able to use GBM for handling
    buffers, and won't need dumb_bo.  Keeping the display related logic
    and buffer object abstraction in separate files seems a bit tidier.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/Makefile.am b/hw/xfree86/drivers/modesetting/Makefile.am
index 5b08600..921ca00 100644
--- a/hw/xfree86/drivers/modesetting/Makefile.am
+++ b/hw/xfree86/drivers/modesetting/Makefile.am
@@ -48,6 +48,8 @@ modesetting_drv_la_SOURCES = \
 	 driver.h \
 	 drmmode_display.c \
 	 drmmode_display.h \
+	 dumb_bo.c \
+	 dumb_bo.h \
 	 vblank.c \
 	 $(NULL)
 
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 6f6eaf3..277f60c 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -33,6 +33,7 @@
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <unistd.h>
+#include "dumb_bo.h"
 #include "xf86str.h"
 #include "X11/Xatom.h"
 #include "micmap.h"
@@ -54,114 +55,6 @@
 #include "glamor.h"
 #endif
 
-static struct dumb_bo *
-dumb_bo_create(int fd,
-               const unsigned width, const unsigned height, const unsigned bpp)
-{
-    struct drm_mode_create_dumb arg;
-    struct dumb_bo *bo;
-    int ret;
-
-    bo = calloc(1, sizeof(*bo));
-    if (!bo)
-        return NULL;
-
-    memset(&arg, 0, sizeof(arg));
-    arg.width = width;
-    arg.height = height;
-    arg.bpp = bpp;
-
-    ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
-    if (ret)
-        goto err_free;
-
-    bo->handle = arg.handle;
-    bo->size = arg.size;
-    bo->pitch = arg.pitch;
-
-    return bo;
- err_free:
-    free(bo);
-    return NULL;
-}
-
-static int
-dumb_bo_map(int fd, struct dumb_bo *bo)
-{
-    struct drm_mode_map_dumb arg;
-    int ret;
-    void *map;
-
-    if (bo->ptr) {
-        bo->map_count++;
-        return 0;
-    }
-
-    memset(&arg, 0, sizeof(arg));
-    arg.handle = bo->handle;
-
-    ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
-    if (ret)
-        return ret;
-
-    map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, arg.offset);
-    if (map == MAP_FAILED)
-        return -errno;
-
-    bo->ptr = map;
-    return 0;
-}
-
-#if 0
-static int
-dumb_bo_unmap(int fd, struct dumb_bo *bo)
-{
-    bo->map_count--;
-    return 0;
-}
-#endif
-
-int
-dumb_bo_destroy(int fd, struct dumb_bo *bo)
-{
-    struct drm_mode_destroy_dumb arg;
-    int ret;
-
-    if (bo->ptr) {
-        munmap(bo->ptr, bo->size);
-        bo->ptr = NULL;
-    }
-
-    memset(&arg, 0, sizeof(arg));
-    arg.handle = bo->handle;
-    ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
-    if (ret)
-        return -errno;
-
-    free(bo);
-    return 0;
-}
-
-struct dumb_bo *
-dumb_get_bo_from_fd(int fd, int handle, int pitch, int size)
-{
-    struct dumb_bo *bo;
-    int ret;
-
-    bo = calloc(1, sizeof(*bo));
-    if (!bo)
-        return NULL;
-
-    ret = drmPrimeFDToHandle(fd, handle, &bo->handle);
-    if (ret) {
-        free(bo);
-        return NULL;
-    }
-    bo->pitch = pitch;
-    bo->size = size;
-    return bo;
-}
-
 Bool
 drmmode_SetSlaveBO(PixmapPtr ppix,
                    drmmode_ptr drmmode, int fd_handle, int pitch, int size)
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index a8df7ca..abb93ec 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -32,13 +32,7 @@
 #include "libudev.h"
 #endif
 
-struct dumb_bo {
-    uint32_t handle;
-    uint32_t size;
-    void *ptr;
-    int map_count;
-    uint32_t pitch;
-};
+#include "dumb_bo.h"
 
 typedef struct {
     int fd;
@@ -149,8 +143,6 @@ Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode,
                              int *depth, int *bpp);
-struct dumb_bo *dumb_get_bo_from_fd(int drm_fd, int fd, int pitch, int size);
-int dumb_bo_destroy(int fd, struct dumb_bo *bo);
 
 
 #ifndef DRM_CAP_DUMB_PREFERRED_DEPTH
diff --git a/hw/xfree86/drivers/modesetting/dumb_bo.c b/hw/xfree86/drivers/modesetting/dumb_bo.c
new file mode 100644
index 0000000..9a69aa2
--- /dev/null
+++ b/hw/xfree86/drivers/modesetting/dumb_bo.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2007 Red Hat, 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 (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:
+ *    Dave Airlie <airlied at redhat.com>
+ *
+ */
+
+#include "dumb_bo.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <xf86drm.h>
+
+struct dumb_bo *
+dumb_bo_create(int fd,
+               const unsigned width, const unsigned height, const unsigned bpp)
+{
+    struct drm_mode_create_dumb arg;
+    struct dumb_bo *bo;
+    int ret;
+
+    bo = calloc(1, sizeof(*bo));
+    if (!bo)
+        return NULL;
+
+    memset(&arg, 0, sizeof(arg));
+    arg.width = width;
+    arg.height = height;
+    arg.bpp = bpp;
+
+    ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
+    if (ret)
+        goto err_free;
+
+    bo->handle = arg.handle;
+    bo->size = arg.size;
+    bo->pitch = arg.pitch;
+
+    return bo;
+ err_free:
+    free(bo);
+    return NULL;
+}
+
+int
+dumb_bo_map(int fd, struct dumb_bo *bo)
+{
+    struct drm_mode_map_dumb arg;
+    int ret;
+    void *map;
+
+    if (bo->ptr) {
+        bo->map_count++;
+        return 0;
+    }
+
+    memset(&arg, 0, sizeof(arg));
+    arg.handle = bo->handle;
+
+    ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
+    if (ret)
+        return ret;
+
+    map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, arg.offset);
+    if (map == MAP_FAILED)
+        return -errno;
+
+    bo->ptr = map;
+    return 0;
+}
+
+#if 0
+static int
+dumb_bo_unmap(int fd, struct dumb_bo *bo)
+{
+    bo->map_count--;
+    return 0;
+}
+#endif
+
+int
+dumb_bo_destroy(int fd, struct dumb_bo *bo)
+{
+    struct drm_mode_destroy_dumb arg;
+    int ret;
+
+    if (bo->ptr) {
+        munmap(bo->ptr, bo->size);
+        bo->ptr = NULL;
+    }
+
+    memset(&arg, 0, sizeof(arg));
+    arg.handle = bo->handle;
+    ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
+    if (ret)
+        return -errno;
+
+    free(bo);
+    return 0;
+}
+
+struct dumb_bo *
+dumb_get_bo_from_fd(int fd, int handle, int pitch, int size)
+{
+    struct dumb_bo *bo;
+    int ret;
+
+    bo = calloc(1, sizeof(*bo));
+    if (!bo)
+        return NULL;
+
+    ret = drmPrimeFDToHandle(fd, handle, &bo->handle);
+    if (ret) {
+        free(bo);
+        return NULL;
+    }
+    bo->pitch = pitch;
+    bo->size = size;
+    return bo;
+}
diff --git a/hw/xfree86/drivers/modesetting/dumb_bo.h b/hw/xfree86/drivers/modesetting/dumb_bo.h
new file mode 100644
index 0000000..1d401d4
--- /dev/null
+++ b/hw/xfree86/drivers/modesetting/dumb_bo.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2007 Red Hat, 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 (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:
+ *     Dave Airlie <airlied at redhat.com>
+ *
+ */
+#ifndef DUMB_BO_H
+#define DUMB_BO_H
+
+#include <stdint.h>
+
+struct dumb_bo {
+    uint32_t handle;
+    uint32_t size;
+    void *ptr;
+    int map_count;
+    uint32_t pitch;
+};
+
+struct dumb_bo *dumb_bo_create(int fd, const unsigned width,
+                               const unsigned height, const unsigned bpp);
+int dumb_bo_map(int fd, struct dumb_bo *bo);
+int dumb_bo_destroy(int fd, struct dumb_bo *bo);
+struct dumb_bo *dumb_get_bo_from_fd(int fd, int handle, int pitch, int size);
+
+#endif
commit af4f94b08eb8e5961799a8a74a06449fd3fe8ad9
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Dec 9 15:18:39 2014 -0800

    modesetting: Create helper for glamor_egl_create_textured_screen call.
    
    This will need to change when we add GBM support; by pulling it into a
    helper function, we should only have to edit one place.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 06b0f21..61c8032 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -886,18 +886,8 @@ CreateScreenResources(ScreenPtr pScreen)
     if (!drmmode_set_desired_modes(pScrn, &ms->drmmode))
         return FALSE;
 
-#ifdef GLAMOR
-    if (ms->drmmode.glamor) {
-        if (!glamor_egl_create_textured_screen(pScreen,
-                                               ms->drmmode.front_bo->handle,
-                                               pScrn->displayWidth *
-                                               pScrn->bitsPerPixel / 8)) {
-            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                       "glamor_egl_create_textured_screen() failed\n");
-            return FALSE;
-        }
-    }
-#endif
+    if (!drmmode_glamor_handle_new_screen_pixmap(&ms->drmmode))
+        return FALSE;
 
     drmmode_uevent_init(pScrn, &ms->drmmode);
 
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index f88148d..6f6eaf3 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1176,6 +1176,29 @@ drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
     }
 }
 
+Bool
+drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
+{
+#ifdef GLAMOR
+    ScrnInfoPtr scrn = drmmode->scrn;
+    ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn);
+
+    if (!drmmode->glamor)
+        return TRUE;
+
+    if (!glamor_egl_create_textured_screen(screen,
+                                           drmmode->front_bo->handle,
+                                           scrn->displayWidth *
+                                           scrn->bitsPerPixel / 8)) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                   "glamor_egl_create_textured_screen() failed\n");
+        return FALSE;
+    }
+#endif
+
+    return TRUE;
+}
+
 static Bool
 drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
 {
@@ -1243,18 +1266,8 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
 
     screen->ModifyPixmapHeader(ppix, width, height, -1, -1, pitch, new_pixels);
 
-#ifdef GLAMOR
-    if (drmmode->glamor) {
-        if (!glamor_egl_create_textured_screen(screen,
-                                               drmmode->front_bo->handle,
-                                               scrn->displayWidth *
-                                               scrn->bitsPerPixel / 8)) {
-            xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-                       "glamor_egl_create_textured_screen() failed\n");
-            goto fail;
-        }
-    }
-#endif
+    if (!drmmode_glamor_handle_new_screen_pixmap(drmmode))
+        goto fail;
 
     for (i = 0; i < xf86_config->num_crtc; i++) {
         xf86CrtcPtr crtc = xf86_config->crtc[i];
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 92e2816..a8df7ca 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -129,6 +129,7 @@ extern DevPrivateKeyRec msPixmapPrivateKeyRec;
 
 #define msGetPixmapPriv(drmmode, p) ((msPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &(drmmode)->pixmapPrivateKeyRec))
 
+Bool drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode);
 void *drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv);
 Bool drmmode_SetSlaveBO(PixmapPtr ppix,
                         drmmode_ptr drmmode,
commit b4324c6a2382dc96295bdb061316f699e4ffabb9
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Dec 9 14:38:39 2014 -0800

    modesetting: Move ModifyPixmapHeader calls out of if/else branches.
    
    Both branches called ModifyPixmapHeader with essentially the same
    parameters.  By using new_pixels in the shadowfb case, we can make
    them completely the same, and move them out a level, for simplicity.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    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 fddbaff..f88148d 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1231,22 +1231,18 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
     if (!new_pixels)
         goto fail;
 
-    if (!drmmode->shadow_enable)
-        screen->ModifyPixmapHeader(ppix, width, height, -1, -1,
-                                   pitch, new_pixels);
-    else {
-        void *new_shadow;
+    if (drmmode->shadow_enable) {
         uint32_t size = scrn->displayWidth * scrn->virtualY *
             ((scrn->bitsPerPixel + 7) >> 3);
-        new_shadow = calloc(1, size);
-        if (new_shadow == NULL)
+        new_pixels = calloc(1, size);
+        if (new_pixels == NULL)
             goto fail;
         free(drmmode->shadow_fb);
-        drmmode->shadow_fb = new_shadow;
-        screen->ModifyPixmapHeader(ppix, width, height, -1, -1,
-                                   pitch, drmmode->shadow_fb);
+        drmmode->shadow_fb = new_pixels;
     }
 
+    screen->ModifyPixmapHeader(ppix, width, height, -1, -1, pitch, new_pixels);
+
 #ifdef GLAMOR
     if (drmmode->glamor) {
         if (!glamor_egl_create_textured_screen(screen,
commit 35e9924484ec7bafb749c88ed7f78e6a71f8dfb3
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Dec 9 13:01:09 2014 -0800

    modesetting: Stop using glamor_egl_create_textured_screen_ext().
    
    The _ext variant takes an additional pointer argument, which it now
    ignores, thanks to Keith's recent patches.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Tested-by: Jason Ekstrand <jason.ekstrand at intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index d1284c6..06b0f21 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -888,13 +888,12 @@ CreateScreenResources(ScreenPtr pScreen)
 
 #ifdef GLAMOR
     if (ms->drmmode.glamor) {
-        if (!glamor_egl_create_textured_screen_ext(pScreen,
-                                                   ms->drmmode.front_bo->handle,
-                                                   pScrn->displayWidth *
-                                                   pScrn->bitsPerPixel / 8,
-                                                   NULL)) {
+        if (!glamor_egl_create_textured_screen(pScreen,
+                                               ms->drmmode.front_bo->handle,
+                                               pScrn->displayWidth *
+                                               pScrn->bitsPerPixel / 8)) {
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                       "glamor_egl_create_textured_screen_ext() failed\n");
+                       "glamor_egl_create_textured_screen() failed\n");
             return FALSE;
         }
     }
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index d5b7d00..fddbaff 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1249,13 +1249,12 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
 
 #ifdef GLAMOR
     if (drmmode->glamor) {
-        if (!glamor_egl_create_textured_screen_ext(screen,
-                                                   drmmode->front_bo->handle,
-                                                   scrn->displayWidth *
-                                                   scrn->bitsPerPixel / 8,
-                                                   NULL)) {
+        if (!glamor_egl_create_textured_screen(screen,
+                                               drmmode->front_bo->handle,
+                                               scrn->displayWidth *
+                                               scrn->bitsPerPixel / 8)) {
             xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-                       "glamor_egl_create_textured_screen_ext() failed\n");
+                       "glamor_egl_create_textured_screen() failed\n");
             goto fail;
         }
     }
commit 91651e7c15892aa846fc406fbb13b37f094dd3f0
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Dec 10 16:21:44 2014 +0900

    glamor: Reinstate glamor_(egl_)destroy_textured_pixmap
    
    They are part of the ABI.
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 6cf9bdf..b32cc16 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -216,8 +216,8 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     return pixmap;
 }
 
-Bool
-glamor_destroy_pixmap(PixmapPtr pixmap)
+void
+glamor_destroy_textured_pixmap(PixmapPtr pixmap)
 {
     if (pixmap->refcnt == 1) {
         glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -227,6 +227,12 @@ glamor_destroy_pixmap(PixmapPtr pixmap)
         glamor_egl_destroy_pixmap_image(pixmap);
 #endif
     }
+}
+
+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 1683414..95c4253 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -132,6 +132,7 @@ 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,
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index e821601..898081a 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -558,6 +558,12 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 
 }
 
+void
+glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+{
+    glamor_destroy_textured_pixmap(pixmap);
+}
+
 static Bool
 glamor_egl_close_screen(ScreenPtr screen)
 {
commit e774663fa5209ff469d920821934bb1f5964a72f
Author: Michele Baldessari <michele at redhat.com>
Date:   Wed Dec 3 11:30:29 2014 -0500

    ephyr: Implement per-screen colormaps
    
    Xephyr's pseudocolor emulation added in:
    
        commit 81a3b6fe27567b4f91033ece69996aa6bf8d01a3
        Author: Matthew Allum <breakfast at 10.am>
        Date:   Mon Nov 8 22:39:47 2004 +0000
    
            Add support to Xephyr for lower depths than hosts
    
    only tracks one global colormap for the whole (Xephyr) display.  Move
    this to per-screen state so each screen's colormap can be correct.
    
    [ajax: rebased to 1.17, cleaned up commit message]
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Michele Baldessari <michele at redhat.com>

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 93a48a9..907bbeb 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -1292,7 +1292,7 @@ ephyrPutColors(ScreenPtr pScreen, int n, xColorItem * pdefs)
         if (p > max)
             max = p;
 
-        hostx_set_cmap_entry(p,
+        hostx_set_cmap_entry(pScreen, p,
                              pdefs->red >> 8,
                              pdefs->green >> 8, pdefs->blue >> 8);
         pdefs++;
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index 2395a7f..18bfe11 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -83,6 +83,7 @@ typedef struct _ephyrScrPriv {
 
     KdScreenInfo *screen;
     int mynum;                  /* Screen number */
+    unsigned long cmap[256];
 
     /**
      * Per-screen Xlib-using state for glamor (private to
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 8d6d5e8..f64861b 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -82,8 +82,6 @@ struct EphyrHostXVars {
     KdScreenInfo **screens;
 
     long damage_debug_msec;
-
-    unsigned long cmap[256];
 };
 
 /* memset ( missing> ) instead of below  */
@@ -751,9 +749,12 @@ hostx_calculate_color_shift(unsigned long mask)
 }
 
 void
-hostx_set_cmap_entry(unsigned char idx,
+hostx_set_cmap_entry(ScreenPtr pScreen, unsigned char idx,
                      unsigned char r, unsigned char g, unsigned char b)
 {
+    KdScreenPriv(pScreen);
+    KdScreenInfo *screen = pScreenPriv->screen;
+    EphyrScrPriv *scrpriv = screen->driver;
 /* need to calculate the shifts for RGB because server could be BGR. */
 /* XXX Not sure if this is correct for 8 on 16, but this works for 8 on 24.*/
     static int rshift, bshift, gshift = 0;
@@ -765,7 +766,7 @@ hostx_set_cmap_entry(unsigned char idx,
         gshift = hostx_calculate_color_shift(HostX.visual->green_mask);
         bshift = hostx_calculate_color_shift(HostX.visual->blue_mask);
     }
-    HostX.cmap[idx] = ((r << rshift) & HostX.visual->red_mask) |
+    scrpriv->cmap[idx] = ((r << rshift) & HostX.visual->red_mask) |
         ((g << gshift) & HostX.visual->green_mask) |
         ((b << bshift) & HostX.visual->blue_mask);
 }
@@ -1017,7 +1018,7 @@ hostx_paint_rect(KdScreenInfo *screen,
                     unsigned char pixel =
                         *(unsigned char *) (scrpriv->fb_data + idx);
                     xcb_image_put_pixel(scrpriv->ximg, x, y,
-                                        HostX.cmap[pixel]);
+                                        scrpriv->cmap[pixel]);
                     break;
                 }
                 default:
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 87acd5a..93aaa50 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -141,7 +141,7 @@ hostx_get_visual_masks(KdScreenInfo *screen,
                        CARD32 *rmsk, CARD32 *gmsk, CARD32 *bmsk);
 void
 
-hostx_set_cmap_entry(unsigned char idx,
+hostx_set_cmap_entry(ScreenPtr pScreen, unsigned char idx,
                      unsigned char r, unsigned char g, unsigned char b);
 
 void *hostx_screen_init(KdScreenInfo *screen,
commit cadd70c809232c9a6601fb8baab665a7ab10045d
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 2 14:52:35 2014 -0500

    glx: Add hack for GLX-1.2-style naked windows to GetDrawableAttributes
    
    Some people like to call this on bare Window XIDs and expect reasonable
    results.  I sure wish they wouldn't, but since they do, if we're given
    a window without any glx decoration just fill in as much as we can. This
    means you won't actually get an answer for GLX_FBCONFIG_ID and friends,
    but there's not much to be done about that, and it matches what NVIDIA's
    driver seems to do.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=54080
    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 4de8643..f5f2bab 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -1916,38 +1916,48 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
 {
     ClientPtr client = cl->client;
     xGLXGetDrawableAttributesReply reply;
-    __GLXdrawable *pGlxDraw;
+    __GLXdrawable *pGlxDraw = NULL;
+    DrawablePtr pDraw;
     CARD32 attributes[14];
     int num = 0, error;
 
     if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
-                          DixGetAttrAccess, &pGlxDraw, &error))
-        return error;
+                          DixGetAttrAccess, &pGlxDraw, &error)) {
+        /* hack for GLX 1.2 naked windows */
+        int err = dixLookupWindow((WindowPtr *)&pDraw, drawId, client,
+                                  DixGetAttrAccess);
+        if (err != Success)
+            return error;
+    }
+    if (pGlxDraw)
+        pDraw = pGlxDraw->pDraw;
 
-    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_Y_INVERTED_EXT;
     attributes[2*num+1] = GL_FALSE;
     num++;
-    attributes[2*num] = GLX_EVENT_MASK;
-    attributes[2*num+1] = pGlxDraw->eventMask;
-    num++;
     attributes[2*num] = GLX_WIDTH;
-    attributes[2*num+1] = pGlxDraw->pDraw->width;
+    attributes[2*num+1] = pDraw->width;
     num++;
     attributes[2*num] = GLX_HEIGHT;
-    attributes[2*num+1] = pGlxDraw->pDraw->height;
-    num++;
-    attributes[2*num] = GLX_FBCONFIG_ID;
-    attributes[2*num+1] = pGlxDraw->config->fbconfigID;
+    attributes[2*num+1] = pDraw->height;
     num++;
-    if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) {
-        attributes[2*num] = GLX_PRESERVED_CONTENTS;
-        attributes[2*num+1] = GL_TRUE;
+    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++;
+        if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) {
+            attributes[2*num] = GLX_PRESERVED_CONTENTS;
+            attributes[2*num+1] = GL_TRUE;
+            num++;
+        }
     }
 
     reply = (xGLXGetDrawableAttributesReply) {
commit f452b4a47b3bebf883e84df804e8d54830ccfe83
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Dec 2 14:47:45 2014 -0500

    glx: Dynamically compute attribute slot in GetDrawableAttributes
    
    No functional change.
    
    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 e836af8..4de8643 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -1918,42 +1918,43 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
     xGLXGetDrawableAttributesReply reply;
     __GLXdrawable *pGlxDraw;
     CARD32 attributes[14];
-    int numAttribs = 0, error;
+    int num = 0, error;
 
     if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
                           DixGetAttrAccess, &pGlxDraw, &error))
         return error;
 
-    attributes[0] = GLX_TEXTURE_TARGET_EXT;
-    attributes[1] = pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT :
+    attributes[2*num] = GLX_TEXTURE_TARGET_EXT;
+    attributes[2*num+1] = pGlxDraw->target == GL_TEXTURE_2D ?
+        GLX_TEXTURE_2D_EXT :
         GLX_TEXTURE_RECTANGLE_EXT;
-    numAttribs++;
-    attributes[2] = GLX_Y_INVERTED_EXT;
-    attributes[3] = GL_FALSE;
-    numAttribs++;
-    attributes[4] = GLX_EVENT_MASK;
-    attributes[5] = pGlxDraw->eventMask;
-    numAttribs++;
-    attributes[6] = GLX_WIDTH;
-    attributes[7] = pGlxDraw->pDraw->width;
-    numAttribs++;
-    attributes[8] = GLX_HEIGHT;
-    attributes[9] = pGlxDraw->pDraw->height;
-    numAttribs++;
-    attributes[10] = GLX_FBCONFIG_ID;
-    attributes[11] = pGlxDraw->config->fbconfigID;
-    numAttribs++;
+    num++;
+    attributes[2*num] = GLX_Y_INVERTED_EXT;
+    attributes[2*num+1] = GL_FALSE;
+    num++;
+    attributes[2*num] = GLX_EVENT_MASK;
+    attributes[2*num+1] = pGlxDraw->eventMask;
+    num++;
+    attributes[2*num] = GLX_WIDTH;
+    attributes[2*num+1] = pGlxDraw->pDraw->width;
+    num++;
+    attributes[2*num] = GLX_HEIGHT;
+    attributes[2*num+1] = pGlxDraw->pDraw->height;
+    num++;
+    attributes[2*num] = GLX_FBCONFIG_ID;
+    attributes[2*num+1] = pGlxDraw->config->fbconfigID;
+    num++;
     if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) {
-        attributes[12] = GLX_PRESERVED_CONTENTS;
-        attributes[13] = GL_TRUE;
-        numAttribs++;
+        attributes[2*num] = GLX_PRESERVED_CONTENTS;
+        attributes[2*num+1] = GL_TRUE;
+        num++;
     }
 
     reply = (xGLXGetDrawableAttributesReply) {
         .type = X_Reply,
         .sequenceNumber = client->sequence,
-        .length = numAttribs << 1,
-        .numAttribs = numAttribs
+        .length = num << 1,
+        .numAttribs = num
     };
 
     if (client->swapped) {
commit c1455f76c6b1aa4ecaacb2221a687244285aa44b
Author: Neil Roberts <neil at linux.intel.com>
Date:   Mon Dec 1 16:06:17 2014 -0500

    glx: Add implementation of __GLXContext->loseCurrent for direct ctxts
    
    This adds a dummy implementation for the loseCurrent function in
    __GLXContext for direct contexts which just returns GL_TRUE. Without
    this then the X server can crash if receives a MakeCurrent message for
    a direct context because it will attempt to call loseCurrent when
    cleaning up the client in the callback for ClientStateGone.
    
    [ajax: added assumed s-o-b line]
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=86531
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Neil Roberts <neil at linux.intel.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index bd6cb8d..e836af8 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -198,6 +198,12 @@ __glXdirectContextDestroy(__GLXcontext * context)
     free(context);
 }
 
+static int
+__glXdirectContextLoseCurrent(__GLXcontext * context)
+{
+    return GL_TRUE;
+}
+
 _X_HIDDEN __GLXcontext *
 __glXdirectContextCreate(__GLXscreen * screen,
                          __GLXconfig * modes, __GLXcontext * shareContext)
@@ -209,6 +215,7 @@ __glXdirectContextCreate(__GLXscreen * screen,
         return NULL;
 
     context->destroy = __glXdirectContextDestroy;
+    context->loseCurrent = __glXdirectContextLoseCurrent;
 
     return context;
 }
commit 6704bb0ed7a10dabe8ef3bb3adf8b8a7f29a78f0
Merge: 8aa23f2 1559a94
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Dec 9 11:47:11 2014 -0800

    Merge remote-tracking branch 'alanc/master'

commit 1559a94395258fd73e369f1a2c98a44bfe21a486
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Dec 9 09:31:00 2014 -0800

    dix: GetHosts bounds check using wrong pointer value [CVE-2014-8092 pt. 6]
    
    GetHosts saves the pointer to allocated memory in *data, and then
    wants to bounds-check writes to that region, but was mistakenly using
    a bare 'data' instead of '*data'. Also, data is declared as void **,
    so we need a cast to turn it into a byte pointer so we can actually do
    pointer comparisons.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/os/access.c b/os/access.c
index f393c8d..28f2d32 100644
--- a/os/access.c
+++ b/os/access.c
@@ -1308,7 +1308,7 @@ GetHosts(void **data, int *pnHosts, int *pLen, BOOL * pEnabled)
         }
         for (host = validhosts; host; host = host->next) {
             len = host->len;
-            if ((ptr + sizeof(xHostEntry) + len) > (data + n))
+            if ((ptr + sizeof(xHostEntry) + len) > ((unsigned char *) *data + n))
                 break;
             ((xHostEntry *) ptr)->family = host->family;
             ((xHostEntry *) ptr)->length = len;
commit 9802a0162f738de03585ca3f3b8a8266494f7d45
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Dec 9 09:30:59 2014 -0800

    Missing parens in REQUEST_FIXED_SIZE macro [CVE-2014-8092 pt. 5]
    
    The 'n' parameter must be surrounded by parens in both places to
    prevent precedence from mis-computing things.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/include/dix.h b/include/dix.h
index 21176a8..921156b 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -80,7 +80,7 @@ SOFTWARE.
 
 #define REQUEST_FIXED_SIZE(req, n)\
     if (((sizeof(req) >> 2) > client->req_len) || \
-        ((n >> 2) >= client->req_len) || \
+        (((n) >> 2) >= client->req_len) ||                              \
         ((((uint64_t) sizeof(req) + (n) + 3) >> 2) != (uint64_t) client->req_len))  \
          return(BadLength)
 
commit 61b17c0f10307e25e51e30e6fb1d3e3127f82d86
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Dec 9 09:30:58 2014 -0800

    glx: Can't mix declarations and code in X.org sources [CVE-2014-8098 pt. 9]
    
    We're using compiler compatibility settings which generate warnings
    when a variable is declared after the first statement.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/clientinfo.c b/glx/clientinfo.c
index c5fef30..74ad919 100644
--- a/glx/clientinfo.c
+++ b/glx/clientinfo.c
@@ -36,13 +36,14 @@ set_client_info(__GLXclientState * cl, xGLXSetClientInfoARBReq * req,
     ClientPtr client = cl->client;
     char *gl_extensions;
     char *glx_extensions;
+    int size;
 
     REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq);
 
     /* Verify that the size of the packet matches the size inferred from the
      * sizes specified for the various fields.
      */
-    int size = sz_xGLXSetClientInfoARBReq;
+    size = sz_xGLXSetClientInfoARBReq;
     size = safe_add(size, safe_mul(req->numVersions, bytes_per_version));
     size = safe_add(size, safe_pad(req->numGLExtensionBytes));
     size = safe_add(size, safe_pad(req->numGLXExtensionBytes));
commit b20912c3d45cbbde3c443e6c3d9e189092fe65e1
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Dec 9 09:30:57 2014 -0800

    dbe: Call to DDX SwapBuffers requires address of int, not unsigned int [CVE-2014-8097 pt. 2]
    
    When the local types used to walk the DBE request were changed, this
    changed the type of the parameter passed to the DDX SwapBuffers API,
    but there wasn't a matching change in the API definition.
    
    At this point, with the API frozen, I just stuck a new variable in
    with the correct type. Because we've already bounds-checked nStuff to
    be smaller than UINT32_MAX / sizeof(DbeSwapInfoRec), we know it will
    fit in a signed int without overflow.
    
    Signed-off-by: Keith Packard <keithp at keithp.com
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/dbe/dbe.c b/dbe/dbe.c
index df2ad5c..e5d928d 100644
--- a/dbe/dbe.c
+++ b/dbe/dbe.c
@@ -452,6 +452,7 @@ ProcDbeSwapBuffers(ClientPtr client)
     int error;
     unsigned int i, j;
     unsigned int nStuff;
+    int nStuff_i;       /* DDX API requires int for nStuff */
 
     REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
     nStuff = stuff->n;          /* use local variable for performance. */
@@ -527,9 +528,10 @@ ProcDbeSwapBuffers(ClientPtr client)
      * could deal with cross-screen synchronization.
      */
 
-    while (nStuff > 0) {
+    nStuff_i = nStuff;
+    while (nStuff_i > 0) {
         pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
-        error = (*pDbeScreenPriv->SwapBuffers) (client, &nStuff, swapInfo);
+        error = (*pDbeScreenPriv->SwapBuffers) (client, &nStuff_i, swapInfo);
         if (error != Success) {
             free(swapInfo);
             return error;
commit 8aa23f27c7e29c62d23867440b0bb00fc288b5ba
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Dec 8 12:59:31 2014 -0800

    glamor: Free existing EGL image when assigning new one
    
    When reallocating the framebuffer on screen resize, the old EGL image
    was getting leaked. Check for an existing EGL image and free it in
    this case.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Revewied-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index e90782e..e821601 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -253,6 +253,24 @@ glamor_egl_check_has_gem(int fd)
     return FALSE;
 }
 
+static void
+glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image)
+{
+    struct glamor_pixmap_private *pixmap_priv =
+        glamor_get_pixmap_private(pixmap);
+    EGLImageKHR old;
+
+    old = pixmap_priv->base.image;
+    if (old) {
+        ScreenPtr                               screen = pixmap->drawable.pScreen;
+        ScrnInfoPtr                             scrn = xf86ScreenToScrn(screen);
+        struct glamor_egl_screen_private        *glamor_egl = glamor_egl_get_screen_private(scrn);
+
+        eglDestroyImageKHR(glamor_egl->display, old);
+    }
+    pixmap_priv->base.image = image;
+}
+
 Bool
 glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 {
@@ -260,8 +278,6 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     struct glamor_screen_private *glamor_priv =
         glamor_get_screen_private(screen);
-    struct glamor_pixmap_private *pixmap_priv =
-        glamor_get_pixmap_private(pixmap);
     struct glamor_egl_screen_private *glamor_egl;
     EGLImageKHR image;
     GLuint texture;
@@ -296,7 +312,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
     glamor_create_texture_from_image(screen, image, &texture);
     glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
     glamor_set_pixmap_texture(pixmap, texture);
-    pixmap_priv->base.image = image;
+    glamor_egl_set_pixmap_image(pixmap, image);
     ret = TRUE;
 
  done:
@@ -310,8 +326,6 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     struct glamor_screen_private *glamor_priv =
         glamor_get_screen_private(screen);
-    struct glamor_pixmap_private *pixmap_priv =
-        glamor_get_pixmap_private(pixmap);
     struct glamor_egl_screen_private *glamor_egl;
     EGLImageKHR image;
     GLuint texture;
@@ -331,7 +345,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
     glamor_create_texture_from_image(screen, image, &texture);
     glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
     glamor_set_pixmap_texture(pixmap, texture);
-    pixmap_priv->base.image = image;
+    glamor_egl_set_pixmap_image(pixmap, image);
     ret = TRUE;
 
  done:
@@ -404,8 +418,8 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
         if (image == EGL_NO_IMAGE_KHR)
             goto failure;
 
-        pixmap_priv->base.image = image;
         glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
+        glamor_egl_set_pixmap_image(pixmap, image);
     }
 
     bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
commit c22433d55ea16e4879b092ee28d284fc895c9956
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Dec 5 11:02:11 2014 -0800

    glamor: Remove redundant reference to screen pixmap EGL image
    
    There's no reason to store this in the egl screen private as the
    screen pixmap will always hold a reference to it anyways.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Revewied-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 8b656fe..e90782e 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -69,7 +69,6 @@ struct glamor_egl_screen_private {
     CreateScreenResourcesProcPtr CreateScreenResources;
     CloseScreenProcPtr CloseScreen;
     int fd;
-    EGLImageKHR front_image;
     int cpp;
 #ifdef GLAMOR_HAS_GBM
     struct gbm_device *gbm;
@@ -219,13 +218,9 @@ Bool
 glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 {
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-    struct glamor_pixmap_private *pixmap_priv;
-    struct glamor_egl_screen_private *glamor_egl;
     PixmapPtr screen_pixmap;
 
-    glamor_egl = glamor_egl_get_screen_private(scrn);
     screen_pixmap = screen->GetScreenPixmap(screen);
-    pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
 
     if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) {
         xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -233,7 +228,6 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
         return FALSE;
     }
 
-    glamor_egl->front_image = pixmap_priv->base.image;
     glamor_set_screen_pixmap(screen_pixmap, NULL);
     return TRUE;
 }
@@ -533,9 +527,6 @@ glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 _X_EXPORT void
 glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 {
-    ScrnInfoPtr scrn = xf86ScreenToScrn(front->drawable.pScreen);
-    struct glamor_egl_screen_private *glamor_egl =
-        glamor_egl_get_screen_private(scrn);
     EGLImageKHR temp;
     struct glamor_pixmap_private *front_priv =
         glamor_get_pixmap_private(front);
@@ -550,7 +541,6 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 
     glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
     glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
-    glamor_egl->front_image = front_priv->base.image;
 
 }
 
@@ -567,9 +557,8 @@ glamor_egl_close_screen(ScreenPtr screen)
     screen_pixmap = screen->GetScreenPixmap(screen);
     pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
 
-    eglDestroyImageKHR(glamor_egl->display, glamor_egl->front_image);
+    eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
     pixmap_priv->base.image = NULL;
-    glamor_egl->front_image = NULL;
 
     screen->CloseScreen = glamor_egl->saved_close_screen;
 
commit 5064ffab631dcbc4265079fb32a02d3e2f1c4cd8
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Dec 5 10:58:28 2014 -0800

    glamor: Always destroy EGL image associated with destroyed pixmap
    
    There were three paths that called eglDestroyImageKHR:
    
     * The front buffer
     * The intel driver's flip buffer
     * pixmaps under DRI3
    
    This patch unifies the second two by having glamor_destroy_pixmap
    always destroy any associaged EGL image. This allows us to stop
    storing the back_pixmap pointer in glamor as that was only used to
    make sure that buffer was freed at server reset time.
    
    v2: check for valid pixmap_priv before using it in
    glamor_egl_destroy_pixmap_image
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index d228e35..6cf9bdf 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -123,8 +123,6 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
 
     pixmap_priv->base.fbo->width = screen_pixmap->drawable.width;
     pixmap_priv->base.fbo->height = screen_pixmap->drawable.height;
-
-    glamor_priv->back_pixmap = back_pixmap;
 }
 
 uint32_t
@@ -218,27 +216,17 @@ 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) {
-        glamor_pixmap_private *pixmap_priv;
-
-        pixmap_priv = glamor_get_pixmap_private(pixmap);
+        glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
         if (pixmap_priv != NULL)
             glamor_pixmap_destroy_fbo(pixmap_priv);
+#if GLAMOR_HAS_GBM
+        glamor_egl_destroy_pixmap_image(pixmap);
+#endif
     }
-}
-
-Bool
-glamor_destroy_pixmap(PixmapPtr pixmap)
-{
-    glamor_screen_private
-        *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-    if (glamor_priv->dri3_enabled)
-        glamor_egl_destroy_textured_pixmap(pixmap);
-    else
-        glamor_destroy_textured_pixmap(pixmap);
     return fbDestroyPixmap(pixmap);
 }
 
@@ -619,8 +607,6 @@ glamor_close_screen(ScreenPtr screen)
 #endif
     screen_pixmap = screen->GetScreenPixmap(screen);
     glamor_set_pixmap_private(screen_pixmap, NULL);
-    if (glamor_priv->back_pixmap && *glamor_priv->back_pixmap)
-        glamor_set_pixmap_private(*glamor_priv->back_pixmap, NULL);
 
     glamor_release_screen_priv(screen);
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 405dbe8..1683414 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -132,7 +132,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,
@@ -170,6 +169,8 @@ 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);
+
 /* @glamor_supports_pixmap_import_export: Returns whether
  * glamor_fd_from_pixmap(), glamor_name_from_pixmap(), and
  * glamor_pixmap_from_fd() are supported.
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 182e2e8..8b656fe 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -70,7 +70,6 @@ struct glamor_egl_screen_private {
     CloseScreenProcPtr CloseScreen;
     int fd;
     EGLImageKHR front_image;
-    PixmapPtr *back_pixmap;
     int cpp;
 #ifdef GLAMOR_HAS_GBM
     struct gbm_device *gbm;
@@ -235,7 +234,7 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
     }
 
     glamor_egl->front_image = pixmap_priv->base.image;
-    glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap);
+    glamor_set_screen_pixmap(screen_pixmap, NULL);
     return TRUE;
 }
 
@@ -244,15 +243,7 @@ glamor_egl_create_textured_screen_ext(ScreenPtr screen,
                                       int handle,
                                       int stride, PixmapPtr *back_pixmap)
 {
-    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-    struct glamor_egl_screen_private *glamor_egl;
-
-    glamor_egl = glamor_egl_get_screen_private(scrn);
-
-    glamor_egl->back_pixmap = back_pixmap;
-    if (!glamor_egl_create_textured_screen(screen, handle, stride))
-        return FALSE;
-    return TRUE;
+    return glamor_egl_create_textured_screen(screen, handle, stride);
 }
 
 static Bool
@@ -519,16 +510,17 @@ glamor_pixmap_from_fd(ScreenPtr screen,
 #endif
 }
 
-static void
-_glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
+void
+glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 {
-    ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
-    struct glamor_egl_screen_private *glamor_egl =
-        glamor_egl_get_screen_private(scrn);
     struct glamor_pixmap_private *pixmap_priv =
         glamor_get_pixmap_private(pixmap);
 
-    if (pixmap_priv->base.image) {
+    if (pixmap_priv && pixmap_priv->base.image) {
+        ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
+        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.*/
@@ -562,14 +554,6 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 
 }
 
-void
-glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
-{
-    if (pixmap->refcnt == 1)
-        _glamor_egl_destroy_pixmap_image(pixmap);
-    glamor_destroy_textured_pixmap(pixmap);
-}
-
 static Bool
 glamor_egl_close_screen(ScreenPtr screen)
 {
@@ -587,14 +571,6 @@ glamor_egl_close_screen(ScreenPtr screen)
     pixmap_priv->base.image = NULL;
     glamor_egl->front_image = NULL;
 
-    if (glamor_egl->back_pixmap && *glamor_egl->back_pixmap) {
-        pixmap_priv = glamor_get_pixmap_private(*glamor_egl->back_pixmap);
-        if (pixmap_priv->base.image) {
-            eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
-            pixmap_priv->base.image = NULL;
-        }
-    }
-
     screen->CloseScreen = glamor_egl->saved_close_screen;
 
     return screen->CloseScreen(screen);
diff --git a/glamor/glamor_egl_stubs.c b/glamor/glamor_egl_stubs.c
index 028d1cc..a93f62d 100644
--- a/glamor/glamor_egl_stubs.c
+++ b/glamor/glamor_egl_stubs.c
@@ -36,7 +36,7 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
 }
 
 void
-glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 {
 }
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 885f12a..ffd327e 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -306,7 +306,6 @@ typedef struct glamor_screen_private {
     int linear_max_nstops;
     int radial_max_nstops;
 
-    PixmapPtr *back_pixmap;
     int screen_fbo;
     struct glamor_saved_procs saved_procs;
     char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 4be883f..09b454f 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -398,9 +398,8 @@ xwl_screen_init_glamor(struct xwl_screen *xwl_screen,
 }
 
 void
-glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 {
-    glamor_destroy_textured_pixmap(pixmap);
 }
 
 int
commit 7e7630bbb775573eea2a2335adb9d190c3e1e971
Author: Robert Morell <rmorell at nvidia.com>
Date:   Wed Nov 12 18:51:43 2014 -0800

    glx: Fix mask truncation in __glXGetAnswerBuffer [CVE-2014-8093 6/6]
    
    On a system where sizeof(unsigned) != sizeof(intptr_t), the unary
    bitwise not operation will result in a mask that clears all high bits
    from temp_buf in the expression:
            temp_buf = (temp_buf + mask) & ~mask;
    
    Signed-off-by: Robert Morell <rmorell at nvidia.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/indirect_util.c b/glx/indirect_util.c
index de81491..9ba2815 100644
--- a/glx/indirect_util.c
+++ b/glx/indirect_util.c
@@ -73,7 +73,7 @@ __glXGetAnswerBuffer(__GLXclientState * cl, size_t required_size,
                      void *local_buffer, size_t local_size, unsigned alignment)
 {
     void *buffer = local_buffer;
-    const unsigned mask = alignment - 1;
+    const intptr_t mask = alignment - 1;
 
     if (local_size < required_size) {
         size_t worst_case_size;
commit e883c170c15493ab3637c0a01890f5a7ca4e16a5
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:48 2014 -0500

    glx: Pass remaining request length into ->varsize (v2) [CVE-2014-8098 8/8]
    
    v2: Handle more multiplies in indirect_reqsize.c (Julien Cristau)
    
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index a7a5172..bd6cb8d 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -2067,7 +2067,8 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
         if (entry.varsize) {
             /* variable size command */
             extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE,
-                                      client->swapped);
+                                      client->swapped,
+                                      left - __GLX_RENDER_HDR_SIZE);
             if (extra < 0) {
                 return BadLength;
             }
@@ -2144,6 +2145,7 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
     if (cl->largeCmdRequestsSoFar == 0) {
         __GLXrenderSizeData entry;
         int extra = 0;
+        int left = (req->length << 2) - sz_xGLXRenderLargeReq;
         size_t cmdlen;
         int err;
 
@@ -2184,7 +2186,8 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
              ** will be in the 1st request, so it's okay to do this.
              */
             extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE,
-                                      client->swapped);
+                                      client->swapped,
+                                      left - __GLX_RENDER_LARGE_HDR_SIZE);
             if (extra < 0) {
                 return BadLength;
             }
diff --git a/glx/glxserver.h b/glx/glxserver.h
index 9482601..9088ec4 100644
--- a/glx/glxserver.h
+++ b/glx/glxserver.h
@@ -177,7 +177,7 @@ typedef int (*__GLXprocPtr) (__GLXclientState *, char *pc);
 /*
  * Tables for computing the size of each rendering command.
  */
-typedef int (*gl_proto_size_func) (const GLbyte *, Bool);
+typedef int (*gl_proto_size_func) (const GLbyte *, Bool, int);
 
 typedef struct {
     int bytes;
diff --git a/glx/indirect_reqsize.c b/glx/indirect_reqsize.c
index abd0766..020aae2 100644
--- a/glx/indirect_reqsize.c
+++ b/glx/indirect_reqsize.c
@@ -31,24 +31,22 @@
 #include "indirect_size.h"
 #include "indirect_reqsize.h"
 
-#define __GLX_PAD(x)  (((x) + 3) & ~3)
-
 #if defined(__CYGWIN__) || defined(__MINGW32__)
 #undef HAVE_ALIAS
 #endif
 #ifdef HAVE_ALIAS
 #define ALIAS2(from,to) \
-    GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \
+    GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \
         __attribute__ ((alias( # to )));
 #define ALIAS(from,to) ALIAS2( from, __glX ## to ## ReqSize )
 #else
 #define ALIAS(from,to) \
-    GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \
-    { return __glX ## to ## ReqSize( pc, swap ); }
+    GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \
+    { return __glX ## to ## ReqSize( pc, swap, reqlen ); }
 #endif
 
 int
-__glXCallListsReqSize(const GLbyte * pc, Bool swap)
+__glXCallListsReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei n = *(GLsizei *) (pc + 0);
     GLenum type = *(GLenum *) (pc + 4);
@@ -60,11 +58,11 @@ __glXCallListsReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glCallLists_size(type);
-    return __GLX_PAD((compsize * n));
+    return safe_pad(safe_mul(compsize, n));
 }
 
 int
-__glXBitmapReqSize(const GLbyte * pc, Bool swap)
+__glXBitmapReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = 0;
@@ -88,7 +86,7 @@ __glXBitmapReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXFogfvReqSize(const GLbyte * pc, Bool swap)
+__glXFogfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum pname = *(GLenum *) (pc + 0);
     GLsizei compsize;
@@ -98,11 +96,11 @@ __glXFogfvReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glFogfv_size(pname);
-    return __GLX_PAD((compsize * 4));
+    return safe_pad(safe_mul(compsize, 4));
 }
 
 int
-__glXLightfvReqSize(const GLbyte * pc, Bool swap)
+__glXLightfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum pname = *(GLenum *) (pc + 4);
     GLsizei compsize;
@@ -112,11 +110,11 @@ __glXLightfvReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glLightfv_size(pname);
-    return __GLX_PAD((compsize * 4));
+    return safe_pad(safe_mul(compsize, 4));
 }
 
 int
-__glXLightModelfvReqSize(const GLbyte * pc, Bool swap)
+__glXLightModelfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum pname = *(GLenum *) (pc + 0);
     GLsizei compsize;
@@ -126,11 +124,11 @@ __glXLightModelfvReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glLightModelfv_size(pname);
-    return __GLX_PAD((compsize * 4));
+    return safe_pad(safe_mul(compsize, 4));
 }
 
 int
-__glXMaterialfvReqSize(const GLbyte * pc, Bool swap)
+__glXMaterialfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum pname = *(GLenum *) (pc + 4);
     GLsizei compsize;
@@ -140,11 +138,11 @@ __glXMaterialfvReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glMaterialfv_size(pname);
-    return __GLX_PAD((compsize * 4));
+    return safe_pad(safe_mul(compsize, 4));
 }
 
 int
-__glXPolygonStippleReqSize(const GLbyte * pc, Bool swap)
+__glXPolygonStippleReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = 0;
@@ -164,7 +162,7 @@ __glXPolygonStippleReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXTexParameterfvReqSize(const GLbyte * pc, Bool swap)
+__glXTexParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum pname = *(GLenum *) (pc + 4);
     GLsizei compsize;
@@ -174,11 +172,11 @@ __glXTexParameterfvReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glTexParameterfv_size(pname);
-    return __GLX_PAD((compsize * 4));
+    return safe_pad(safe_mul(compsize, 4));
 }
 
 int
-__glXTexImage1DReqSize(const GLbyte * pc, Bool swap)
+__glXTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = 0;
@@ -206,7 +204,7 @@ __glXTexImage1DReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXTexImage2DReqSize(const GLbyte * pc, Bool swap)
+__glXTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = 0;
@@ -236,7 +234,7 @@ __glXTexImage2DReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXTexEnvfvReqSize(const GLbyte * pc, Bool swap)
+__glXTexEnvfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum pname = *(GLenum *) (pc + 4);
     GLsizei compsize;
@@ -246,11 +244,11 @@ __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glTexEnvfv_size(pname);
-    return __GLX_PAD((compsize * 4));
+    return safe_pad(safe_mul(compsize, 4));
 }
 
 int
-__glXTexGendvReqSize(const GLbyte * pc, Bool swap)
+__glXTexGendvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum pname = *(GLenum *) (pc + 4);
     GLsizei compsize;
@@ -260,11 +258,11 @@ __glXTexGendvReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glTexGendv_size(pname);
-    return __GLX_PAD((compsize * 8));
+    return safe_pad(safe_mul(compsize, 8));
 }
 
 int
-__glXTexGenfvReqSize(const GLbyte * pc, Bool swap)
+__glXTexGenfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum pname = *(GLenum *) (pc + 4);
     GLsizei compsize;
@@ -274,11 +272,11 @@ __glXTexGenfvReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glTexGenfv_size(pname);
-    return __GLX_PAD((compsize * 4));
+    return safe_pad(safe_mul(compsize, 4));
 }
 
 int
-__glXPixelMapfvReqSize(const GLbyte * pc, Bool swap)
+__glXPixelMapfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei mapsize = *(GLsizei *) (pc + 4);
 
@@ -286,11 +284,11 @@ __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap)
         mapsize = bswap_32(mapsize);
     }
 
-    return __GLX_PAD((mapsize * 4));
+    return safe_pad(safe_mul(mapsize, 4));
 }
 
 int
-__glXPixelMapusvReqSize(const GLbyte * pc, Bool swap)
+__glXPixelMapusvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei mapsize = *(GLsizei *) (pc + 4);
 
@@ -298,11 +296,11 @@ __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap)
         mapsize = bswap_32(mapsize);
     }
 
-    return __GLX_PAD((mapsize * 2));
+    return safe_pad(safe_mul(mapsize, 2));
 }
 
 int
-__glXDrawPixelsReqSize(const GLbyte * pc, Bool swap)
+__glXDrawPixelsReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = 0;
@@ -330,7 +328,7 @@ __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap)
+__glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei n = *(GLsizei *) (pc + 0);
 
@@ -338,11 +336,11 @@ __glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap)
         n = bswap_32(n);
     }
 
-    return __GLX_PAD((n * 4) + (n * 4));
+    return safe_pad(safe_add(safe_mul(n, 4), safe_mul(n, 4)));
 }
 
 int
-__glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap)
+__glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = 0;
@@ -370,7 +368,7 @@ __glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap)
+__glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = 0;
@@ -400,7 +398,7 @@ __glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXColorTableReqSize(const GLbyte * pc, Bool swap)
+__glXColorTableReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = 0;
@@ -428,7 +426,7 @@ __glXColorTableReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap)
+__glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum pname = *(GLenum *) (pc + 4);
     GLsizei compsize;
@@ -438,11 +436,11 @@ __glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glColorTableParameterfv_size(pname);
-    return __GLX_PAD((compsize * 4));
+    return safe_pad(safe_mul(compsize, 4));
 }
 
 int
-__glXColorSubTableReqSize(const GLbyte * pc, Bool swap)
+__glXColorSubTableReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = 0;
@@ -470,7 +468,7 @@ __glXColorSubTableReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap)
+__glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = 0;
@@ -498,7 +496,7 @@ __glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap)
+__glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = 0;
@@ -528,7 +526,7 @@ __glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap)
+__glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum pname = *(GLenum *) (pc + 4);
     GLsizei compsize;
@@ -538,11 +536,11 @@ __glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glConvolutionParameterfv_size(pname);
-    return __GLX_PAD((compsize * 4));
+    return safe_pad(safe_mul(compsize, 4));
 }
 
 int
-__glXTexImage3DReqSize(const GLbyte * pc, Bool swap)
+__glXTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = *(GLint *) (pc + 8);
@@ -579,7 +577,7 @@ __glXTexImage3DReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap)
+__glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLint row_length = *(GLint *) (pc + 4);
     GLint image_height = *(GLint *) (pc + 8);
@@ -613,7 +611,7 @@ __glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap)
+__glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei imageSize = *(GLsizei *) (pc + 20);
 
@@ -621,11 +619,11 @@ __glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap)
         imageSize = bswap_32(imageSize);
     }
 
-    return __GLX_PAD(imageSize);
+    return safe_pad(imageSize);
 }
 
 int
-__glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap)
+__glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei imageSize = *(GLsizei *) (pc + 24);
 
@@ -633,11 +631,11 @@ __glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap)
         imageSize = bswap_32(imageSize);
     }
 
-    return __GLX_PAD(imageSize);
+    return safe_pad(imageSize);
 }
 
 int
-__glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap)
+__glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei imageSize = *(GLsizei *) (pc + 28);
 
@@ -645,11 +643,11 @@ __glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap)
         imageSize = bswap_32(imageSize);
     }
 
-    return __GLX_PAD(imageSize);
+    return safe_pad(imageSize);
 }
 
 int
-__glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap)
+__glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei imageSize = *(GLsizei *) (pc + 36);
 
@@ -657,11 +655,11 @@ __glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap)
         imageSize = bswap_32(imageSize);
     }
 
-    return __GLX_PAD(imageSize);
+    return safe_pad(imageSize);
 }
 
 int
-__glXPointParameterfvReqSize(const GLbyte * pc, Bool swap)
+__glXPointParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum pname = *(GLenum *) (pc + 0);
     GLsizei compsize;
@@ -671,11 +669,11 @@ __glXPointParameterfvReqSize(const GLbyte * pc, Bool swap)
     }
 
     compsize = __glPointParameterfv_size(pname);
-    return __GLX_PAD((compsize * 4));
+    return safe_pad(safe_mul(compsize, 4));
 }
 
 int
-__glXDrawBuffersReqSize(const GLbyte * pc, Bool swap)
+__glXDrawBuffersReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei n = *(GLsizei *) (pc + 0);
 
@@ -683,11 +681,11 @@ __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap)
         n = bswap_32(n);
     }
 
-    return __GLX_PAD((n * 4));
+    return safe_pad(safe_mul(n, 4));
 }
 
 int
-__glXProgramStringARBReqSize(const GLbyte * pc, Bool swap)
+__glXProgramStringARBReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei len = *(GLsizei *) (pc + 8);
 
@@ -695,11 +693,11 @@ __glXProgramStringARBReqSize(const GLbyte * pc, Bool swap)
         len = bswap_32(len);
     }
 
-    return __GLX_PAD(len);
+    return safe_pad(len);
 }
 
 int
-__glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei n = *(GLsizei *) (pc + 4);
 
@@ -707,11 +705,11 @@ __glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap)
         n = bswap_32(n);
     }
 
-    return __GLX_PAD((n * 8));
+    return safe_pad(safe_mul(n, 8));
 }
 
 int
-__glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei n = *(GLsizei *) (pc + 4);
 
@@ -719,11 +717,11 @@ __glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap)
         n = bswap_32(n);
     }
 
-    return __GLX_PAD((n * 16));
+    return safe_pad(safe_mul(n, 16));
 }
 
 int
-__glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei n = *(GLsizei *) (pc + 4);
 
@@ -731,11 +729,11 @@ __glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap)
         n = bswap_32(n);
     }
 
-    return __GLX_PAD((n * 24));
+    return safe_pad(safe_mul(n, 24));
 }
 
 int
-__glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei n = *(GLsizei *) (pc + 4);
 
@@ -743,11 +741,11 @@ __glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap)
         n = bswap_32(n);
     }
 
-    return __GLX_PAD((n * 12));
+    return safe_pad(safe_mul(n, 12));
 }
 
 int
-__glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei n = *(GLsizei *) (pc + 4);
 
@@ -755,11 +753,11 @@ __glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap)
         n = bswap_32(n);
     }
 
-    return __GLX_PAD((n * 6));
+    return safe_pad(safe_mul(n, 6));
 }
 
 int
-__glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap)
+__glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLsizei n = *(GLsizei *) (pc + 4);
 
@@ -767,7 +765,7 @@ __glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap)
         n = bswap_32(n);
     }
 
-    return __GLX_PAD((n * 32));
+    return safe_pad(safe_mul(n, 32));
 }
 
 ALIAS(Fogiv, Fogfv)
diff --git a/glx/indirect_reqsize.h b/glx/indirect_reqsize.h
index 49d400c..632a85b 100644
--- a/glx/indirect_reqsize.h
+++ b/glx/indirect_reqsize.h
@@ -36,115 +36,156 @@
 #define PURE
 #endif
 
-extern PURE _X_HIDDEN int __glXCallListsReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXBitmapReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXFogfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXFogivReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXLightfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXLightivReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXLightModelfvReqSize(const GLbyte * pc,
-                                                   Bool swap);
-extern PURE _X_HIDDEN int __glXLightModelivReqSize(const GLbyte * pc,
-                                                   Bool swap);
-extern PURE _X_HIDDEN int __glXMaterialfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXMaterialivReqSize(const GLbyte * pc, Bool swap);
+extern PURE _X_HIDDEN int __glXCallListsReqSize(const GLbyte * pc, Bool swap,
+                                                int reqlen);
+extern PURE _X_HIDDEN int __glXBitmapReqSize(const GLbyte * pc, Bool swap,
+                                             int reqlen);
+extern PURE _X_HIDDEN int __glXFogfvReqSize(const GLbyte * pc, Bool swap,
+                                            int reqlen);
+extern PURE _X_HIDDEN int __glXFogivReqSize(const GLbyte * pc, Bool swap,
+                                            int reqlen);
+extern PURE _X_HIDDEN int __glXLightfvReqSize(const GLbyte * pc, Bool swap,
+                                              int reqlen);
+extern PURE _X_HIDDEN int __glXLightivReqSize(const GLbyte * pc, Bool swap,
+                                              int reqlen);
+extern PURE _X_HIDDEN int __glXLightModelfvReqSize(const GLbyte * pc, Bool swap,
+                                                   int reqlen);
+extern PURE _X_HIDDEN int __glXLightModelivReqSize(const GLbyte * pc, Bool swap,
+                                                   int reqlen);
+extern PURE _X_HIDDEN int __glXMaterialfvReqSize(const GLbyte * pc, Bool swap,
+                                                 int reqlen);
+extern PURE _X_HIDDEN int __glXMaterialivReqSize(const GLbyte * pc, Bool swap,
+                                                 int reqlen);
 extern PURE _X_HIDDEN int __glXPolygonStippleReqSize(const GLbyte * pc,
-                                                     Bool swap);
+                                                     Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXTexParameterfvReqSize(const GLbyte * pc,
-                                                     Bool swap);
+                                                     Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXTexParameterivReqSize(const GLbyte * pc,
-                                                     Bool swap);
-extern PURE _X_HIDDEN int __glXTexImage1DReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexImage2DReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexEnvivReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexGendvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexGenfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXTexGenivReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXMap1dReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXMap1fReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXMap2dReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXMap2fReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXPixelMapuivReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap);
-extern PURE _X_HIDDEN int __glXDrawArraysReqSize(const GLbyte * pc, Bool swap);
+                                                     Bool swap, int reqlen);
+extern PURE _X_HIDDEN int __glXTexImage1DReqSize(const GLbyte * pc, Bool swap,
+                                                 int reqlen);
+extern PURE _X_HIDDEN int __glXTexImage2DReqSize(const GLbyte * pc, Bool swap,
+                                                 int reqlen);
+extern PURE _X_HIDDEN int __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap,
+                                               int reqlen);
+extern PURE _X_HIDDEN int __glXTexEnvivReqSize(const GLbyte * pc, Bool swap,
+                                               int reqlen);
+extern PURE _X_HIDDEN int __glXTexGendvReqSize(const GLbyte * pc, Bool swap,
+                                               int reqlen);
+extern PURE _X_HIDDEN int __glXTexGenfvReqSize(const GLbyte * pc, Bool swap,
+                                               int reqlen);
+extern PURE _X_HIDDEN int __glXTexGenivReqSize(const GLbyte * pc, Bool swap,
+                                               int reqlen);
+extern PURE _X_HIDDEN int __glXMap1dReqSize(const GLbyte * pc, Bool swap,
+                                            int reqlen);
+extern PURE _X_HIDDEN int __glXMap1fReqSize(const GLbyte * pc, Bool swap,
+                                            int reqlen);
+extern PURE _X_HIDDEN int __glXMap2dReqSize(const GLbyte * pc, Bool swap,
+                                            int reqlen);
+extern PURE _X_HIDDEN int __glXMap2fReqSize(const GLbyte * pc, Bool swap,
+                                            int reqlen);
+extern PURE _X_HIDDEN int __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap,
+                                                 int reqlen);
+extern PURE _X_HIDDEN int __glXPixelMapuivReqSize(const GLbyte * pc, Bool swap,
+                                                  int reqlen);
+extern PURE _X_HIDDEN int __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap,
+                                                  int reqlen);
+extern PURE _X_HIDDEN int __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap,
+                                                 int reqlen);
+extern PURE _X_HIDDEN int __glXDrawArraysReqSize(const GLbyte * pc, Bool swap,
+                                                 int reqlen);
 extern PURE _X_HIDDEN int __glXPrioritizeTexturesReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXTexSubImage1DReqSize(const GLbyte * pc,
-                                                    Bool swap);
+                                                    Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXTexSubImage2DReqSize(const GLbyte * pc,
-                                                    Bool swap);
-extern PURE _X_HIDDEN int __glXColorTableReqSize(const GLbyte * pc, Bool swap);
+                                                    Bool swap, int reqlen);
+extern PURE _X_HIDDEN int __glXColorTableReqSize(const GLbyte * pc, Bool swap,
+                                                 int reqlen);
 extern PURE _X_HIDDEN int __glXColorTableParameterfvReqSize(const GLbyte * pc,
-                                                            Bool swap);
+                                                            Bool swap,
+                                                            int reqlen);
 extern PURE _X_HIDDEN int __glXColorTableParameterivReqSize(const GLbyte * pc,
-                                                            Bool swap);
+                                                            Bool swap,
+                                                            int reqlen);
 extern PURE _X_HIDDEN int __glXColorSubTableReqSize(const GLbyte * pc,
-                                                    Bool swap);
+                                                    Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXConvolutionFilter1DReqSize(const GLbyte * pc,
-                                                          Bool swap);
+                                                          Bool swap,
+                                                          int reqlen);
 extern PURE _X_HIDDEN int __glXConvolutionFilter2DReqSize(const GLbyte * pc,
-                                                          Bool swap);
+                                                          Bool swap,
+                                                          int reqlen);
 extern PURE _X_HIDDEN int __glXConvolutionParameterfvReqSize(const GLbyte * pc,
-                                                             Bool swap);
+                                                             Bool swap,
+                                                             int reqlen);
 extern PURE _X_HIDDEN int __glXConvolutionParameterivReqSize(const GLbyte * pc,
-                                                             Bool swap);
+                                                             Bool swap,
+                                                             int reqlen);
 extern PURE _X_HIDDEN int __glXSeparableFilter2DReqSize(const GLbyte * pc,
-                                                        Bool swap);
-extern PURE _X_HIDDEN int __glXTexImage3DReqSize(const GLbyte * pc, Bool swap);
+                                                        Bool swap, int reqlen);
+extern PURE _X_HIDDEN int __glXTexImage3DReqSize(const GLbyte * pc, Bool swap,
+                                                 int reqlen);
 extern PURE _X_HIDDEN int __glXTexSubImage3DReqSize(const GLbyte * pc,
-                                                    Bool swap);
+                                                    Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXCompressedTexImage1DReqSize(const GLbyte * pc,
-                                                           Bool swap);
+                                                           Bool swap,
+                                                           int reqlen);
 extern PURE _X_HIDDEN int __glXCompressedTexImage2DReqSize(const GLbyte * pc,
-                                                           Bool swap);
+                                                           Bool swap,
+                                                           int reqlen);
 extern PURE _X_HIDDEN int __glXCompressedTexImage3DReqSize(const GLbyte * pc,
-                                                           Bool swap);
+                                                           Bool swap,
+                                                           int reqlen);
 extern PURE _X_HIDDEN int __glXCompressedTexSubImage1DReqSize(const GLbyte * pc,
-                                                              Bool swap);
+                                                              Bool swap,
+                                                              int reqlen);
 extern PURE _X_HIDDEN int __glXCompressedTexSubImage2DReqSize(const GLbyte * pc,
-                                                              Bool swap);
+                                                              Bool swap,
+                                                              int reqlen);
 extern PURE _X_HIDDEN int __glXCompressedTexSubImage3DReqSize(const GLbyte * pc,
-                                                              Bool swap);
+                                                              Bool swap,
+                                                              int reqlen);
 extern PURE _X_HIDDEN int __glXPointParameterfvReqSize(const GLbyte * pc,
-                                                       Bool swap);
+                                                       Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXPointParameterivReqSize(const GLbyte * pc,
-                                                       Bool swap);
-extern PURE _X_HIDDEN int __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap);
+                                                       Bool swap, int reqlen);
+extern PURE _X_HIDDEN int __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap,
+                                                  int reqlen);
 extern PURE _X_HIDDEN int __glXProgramStringARBReqSize(const GLbyte * pc,
-                                                       Bool swap);
+                                                       Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXDeleteFramebuffersReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXDeleteRenderbuffersReqSize(const GLbyte * pc,
-                                                          Bool swap);
+                                                          Bool swap,
+                                                          int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs1dvNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs1fvNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs1svNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs2dvNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs2fvNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs2svNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs3dvNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs3fvNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs3svNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs4dvNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs4fvNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs4svNVReqSize(const GLbyte * pc,
-                                                         Bool swap);
+                                                         Bool swap, int reqlen);
 extern PURE _X_HIDDEN int __glXVertexAttribs4ubvNVReqSize(const GLbyte * pc,
-                                                          Bool swap);
+                                                          Bool swap,
+                                                          int reqlen);
 
 #undef PURE
 
diff --git a/glx/rensize.c b/glx/rensize.c
index d46334a..6bfe99b 100644
--- a/glx/rensize.c
+++ b/glx/rensize.c
@@ -44,7 +44,7 @@
    ((a & 0xff00U)<<8) | ((a & 0xffU)<<24))
 
 int
-__glXMap1dReqSize(const GLbyte * pc, Bool swap)
+__glXMap1dReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum target;
     GLint order;
@@ -61,7 +61,7 @@ __glXMap1dReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXMap1fReqSize(const GLbyte * pc, Bool swap)
+__glXMap1fReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum target;
     GLint order;
@@ -86,7 +86,7 @@ Map2Size(int k, int majorOrder, int minorOrder)
 }
 
 int
-__glXMap2dReqSize(const GLbyte * pc, Bool swap)
+__glXMap2dReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum target;
     GLint uorder, vorder;
@@ -103,7 +103,7 @@ __glXMap2dReqSize(const GLbyte * pc, Bool swap)
 }
 
 int
-__glXMap2fReqSize(const GLbyte * pc, Bool swap)
+__glXMap2fReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     GLenum target;
     GLint uorder, vorder;
@@ -359,13 +359,14 @@ __glXTypeSize(GLenum enm)
 }
 
 int
-__glXDrawArraysReqSize(const GLbyte * pc, Bool swap)
+__glXDrawArraysReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc;
     __GLXdispatchDrawArraysComponentHeader *compHeader;
     GLint numVertexes = hdr->numVertexes;
     GLint numComponents = hdr->numComponents;
     GLint arrayElementSize = 0;
+    GLint x, size;
     int i;
 
     if (swap) {
@@ -374,6 +375,13 @@ __glXDrawArraysReqSize(const GLbyte * pc, Bool swap)
     }
 
     pc += sizeof(__GLXdispatchDrawArraysHeader);
+    reqlen -= sizeof(__GLXdispatchDrawArraysHeader);
+
+    size = safe_mul(sizeof(__GLXdispatchDrawArraysComponentHeader),
+                    numComponents);
+    if (size < 0 || reqlen < 0 || reqlen < size)
+        return -1;
+
     compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc;
 
     for (i = 0; i < numComponents; i++) {
@@ -417,17 +425,18 @@ __glXDrawArraysReqSize(const GLbyte * pc, Bool swap)
             return -1;
         }
 
-        arrayElementSize += __GLX_PAD(numVals * __glXTypeSize(datatype));
+        x = safe_pad(safe_mul(numVals, __glXTypeSize(datatype)));
+        if ((arrayElementSize = safe_add(arrayElementSize, x)) < 0)
+            return -1;
 
         pc += sizeof(__GLXdispatchDrawArraysComponentHeader);
     }
 
-    return ((numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader)) +
-            (numVertexes * arrayElementSize));
+    return safe_add(size, safe_mul(numVertexes, arrayElementSize));
 }
 
 int
-__glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap)
+__glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen)
 {
     __GLXdispatchConvolutionFilterHeader *hdr =
         (__GLXdispatchConvolutionFilterHeader *) pc;
commit 984583a497c813df5827ae22483133e704fee79c
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:47 2014 -0500

    glx: Length checking for non-generated single requests (v2) [CVE-2014-8098 7/8]
    
    v2:
    Fix single versus vendor-private length checking for ARB_imaging subset
    extensions. (Julien Cristau)
    
    v3:
    Fix single versus vendor-private length checking for ARB_imaging subset
    extensions. (Julien Cristau)
    
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/indirect_texture_compression.c b/glx/indirect_texture_compression.c
index cda7656..1ebf7f3 100644
--- a/glx/indirect_texture_compression.c
+++ b/glx/indirect_texture_compression.c
@@ -43,6 +43,8 @@ __glXDisp_GetCompressedTexImage(struct __GLXclientStateRec *cl, GLbyte * pc)
     __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error);
     ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
+
     pc += __GLX_SINGLE_HDR_SIZE;
     if (cx != NULL) {
         const GLenum target = *(GLenum *) (pc + 0);
@@ -87,6 +89,8 @@ __glXDispSwap_GetCompressedTexImage(struct __GLXclientStateRec *cl, GLbyte * pc)
         __glXForceCurrent(cl, bswap_32(req->contextTag), &error);
     ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
+
     pc += __GLX_SINGLE_HDR_SIZE;
     if (cx != NULL) {
         const GLenum target = (GLenum) bswap_32(*(int *) (pc + 0));
diff --git a/glx/single2.c b/glx/single2.c
index 53b661d..a6ea614 100644
--- a/glx/single2.c
+++ b/glx/single2.c
@@ -45,11 +45,14 @@
 int
 __glXDisp_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     GLsizei size;
     GLenum type;
     __GLXcontext *cx;
     int error;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
+
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
         return error;
@@ -76,10 +79,13 @@ __glXDisp_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDisp_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     __GLXcontext *cx;
     GLsizei size;
     int error;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
         return error;
@@ -104,7 +110,7 @@ __glXDisp_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc)
 {
-    ClientPtr client;
+    ClientPtr client = cl->client;
     xGLXRenderModeReply reply;
     __GLXcontext *cx;
     GLint nitems = 0, retBytes = 0, retval, newModeCheck;
@@ -112,6 +118,8 @@ __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc)
     GLenum newMode;
     int error;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
         return error;
@@ -188,7 +196,6 @@ __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc)
      ** selection array, as per the API for glRenderMode itself.
      */
  noChangeAllowed:;
-    client = cl->client;
     reply = (xGLXRenderModeReply) {
         .type = X_Reply,
         .sequenceNumber = client->sequence,
@@ -207,9 +214,12 @@ __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDisp_Flush(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     __GLXcontext *cx;
     int error;
 
+    REQUEST_SIZE_MATCH(xGLXSingleReq);
+
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
         return error;
@@ -223,10 +233,12 @@ __glXDisp_Flush(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDisp_Finish(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     __GLXcontext *cx;
-    ClientPtr client;
     int error;
 
+    REQUEST_SIZE_MATCH(xGLXSingleReq);
+
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
         return error;
@@ -317,7 +329,7 @@ __glXcombine_strings(const char *cext_string, const char *sext_string)
 int
 DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap)
 {
-    ClientPtr client;
+    ClientPtr client = cl->client;
     __GLXcontext *cx;
     GLenum name;
     const char *string;
@@ -327,6 +339,8 @@ DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap)
     char *buf = NULL, *buf1 = NULL;
     GLint length = 0;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
     /* If the client has the opposite byte order, swap the contextTag and
      * the name.
      */
@@ -343,7 +357,6 @@ DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap)
     pc += __GLX_SINGLE_HDR_SIZE;
     name = *(GLenum *) (pc + 0);
     string = (const char *) glGetString(name);
-    client = cl->client;
 
     if (string == NULL)
         string = "";
diff --git a/glx/single2swap.c b/glx/single2swap.c
index 764501f..5349069 100644
--- a/glx/single2swap.c
+++ b/glx/single2swap.c
@@ -41,6 +41,7 @@
 int
 __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     GLsizei size;
     GLenum type;
 
@@ -48,6 +49,8 @@ __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
     __GLXcontext *cx;
     int error;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
+
     __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
@@ -77,12 +80,15 @@ __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     __GLXcontext *cx;
     GLsizei size;
 
     __GLX_DECLARE_SWAP_VARIABLES;
     int error;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
     __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
@@ -109,7 +115,7 @@ __glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
 {
-    ClientPtr client;
+    ClientPtr client = cl->client;
     __GLXcontext *cx;
     xGLXRenderModeReply reply;
     GLint nitems = 0, retBytes = 0, retval, newModeCheck;
@@ -120,6 +126,8 @@ __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
     int error;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
     __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
@@ -200,7 +208,6 @@ __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
      ** selection array, as per the API for glRenderMode itself.
      */
  noChangeAllowed:;
-    client = cl->client;
     reply = (xGLXRenderModeReply) {
         .type = X_Reply,
         .sequenceNumber = client->sequence,
@@ -224,11 +231,14 @@ __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     __GLXcontext *cx;
     int error;
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
+    REQUEST_SIZE_MATCH(xGLXSingleReq);
+
     __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
@@ -243,12 +253,14 @@ __glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     __GLXcontext *cx;
-    ClientPtr client;
     int error;
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
+    REQUEST_SIZE_MATCH(xGLXSingleReq);
+
     __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
@@ -260,7 +272,6 @@ __glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc)
     cx->hasUnflushedCommands = GL_FALSE;
 
     /* Send empty reply packet to indicate finish is finished */
-    client = cl->client;
     __GLX_BEGIN_REPLY(0);
     __GLX_PUT_RETVAL(0);
     __GLX_SWAP_REPLY_HEADER();
diff --git a/glx/singlepix.c b/glx/singlepix.c
index 8b6c261..54ed7fd 100644
--- a/glx/singlepix.c
+++ b/glx/singlepix.c
@@ -51,6 +51,8 @@ __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc)
     int error;
     char *answer, answerBuffer[200];
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 28);
+
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
         return error;
@@ -100,6 +102,8 @@ __glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc)
     char *answer, answerBuffer[200];
     GLint width = 0, height = 0, depth = 1;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 20);
+
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
         return error;
@@ -157,6 +161,8 @@ __glXDisp_GetPolygonStipple(__GLXclientState * cl, GLbyte * pc)
     GLubyte answerBuffer[200];
     char *answer;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
         return error;
@@ -217,15 +223,13 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
     compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
     compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1);
 
-    if (compsize < 0)
+    if ((compsize = safe_pad(compsize)) < 0)
         return BadLength;
-    if (compsize2 < 0)
+    if ((compsize2 = safe_pad(compsize2)) < 0)
         return BadLength;
-    compsize = __GLX_PAD(compsize);
-    compsize2 = __GLX_PAD(compsize2);
 
     glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
-    __GLX_GET_ANSWER_BUFFER(answer, cl, compsize + compsize2, 1);
+    __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1);
     __glXClearErrorOccured();
     glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4),
                          *(GLenum *) (pc + 8), answer, answer + compsize, NULL);
@@ -249,7 +253,8 @@ int
 __glXDisp_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
-
+    ClientPtr client = cl->client;
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
     return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
 }
 
@@ -257,7 +262,8 @@ int
 __glXDisp_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
-
+    ClientPtr client = cl->client;
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
     return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
 }
 
@@ -323,7 +329,8 @@ int
 __glXDisp_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
-
+    ClientPtr client = cl->client;
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
     return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
 }
 
@@ -331,7 +338,8 @@ int
 __glXDisp_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
-
+    ClientPtr client = cl->client;
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
     return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
 }
 
@@ -390,7 +398,8 @@ int
 __glXDisp_GetHistogram(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
-
+    ClientPtr client = cl->client;
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
     return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
 }
 
@@ -398,7 +407,8 @@ int
 __glXDisp_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
-
+    ClientPtr client = cl->client;
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
     return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
 }
 
@@ -450,7 +460,8 @@ int
 __glXDisp_GetMinmax(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
-
+    ClientPtr client = cl->client;
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
     return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
 }
 
@@ -458,7 +469,8 @@ int
 __glXDisp_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
-
+    ClientPtr client = cl->client;
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
     return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
 }
 
@@ -517,7 +529,8 @@ int
 __glXDisp_GetColorTable(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
-
+    ClientPtr client = cl->client;
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
     return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
 }
 
@@ -525,6 +538,7 @@ int
 __glXDisp_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
-
+    ClientPtr client = cl->client;
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
     return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
 }
diff --git a/glx/singlepixswap.c b/glx/singlepixswap.c
index 8dc304f..9eff592 100644
--- a/glx/singlepixswap.c
+++ b/glx/singlepixswap.c
@@ -53,6 +53,8 @@ __glXDispSwap_ReadPixels(__GLXclientState * cl, GLbyte * pc)
     int error;
     char *answer, answerBuffer[200];
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 28);
+
     __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
@@ -114,6 +116,8 @@ __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc)
     char *answer, answerBuffer[200];
     GLint width = 0, height = 0, depth = 1;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 20);
+
     __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
@@ -184,6 +188,8 @@ __glXDispSwap_GetPolygonStipple(__GLXclientState * cl, GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
     __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
     cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
     if (!cx) {
@@ -251,15 +257,13 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
     compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
     compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1);
 
-    if (compsize < 0)
+    if ((compsize = safe_pad(compsize)) < 0)
         return BadLength;
-    if (compsize2 < 0)
+    if ((compsize2 = safe_pad(compsize2)) < 0)
         return BadLength;
-    compsize = __GLX_PAD(compsize);
-    compsize2 = __GLX_PAD(compsize2);
 
     glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
-    __GLX_GET_ANSWER_BUFFER(answer, cl, compsize + compsize2, 1);
+    __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1);
     __glXClearErrorOccured();
     glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4),
                          *(GLenum *) (pc + 8), answer, answer + compsize, NULL);
@@ -285,7 +289,9 @@ int
 __glXDispSwap_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
+    ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
     return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
 }
 
@@ -293,7 +299,9 @@ int
 __glXDispSwap_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
+    ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
     return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
 }
 
@@ -367,7 +375,9 @@ int
 __glXDispSwap_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
+    ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
     return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
 }
 
@@ -375,7 +385,9 @@ int
 __glXDispSwap_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
+    ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
     return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
 }
 
@@ -441,7 +453,9 @@ int
 __glXDispSwap_GetHistogram(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
+    ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
     return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
 }
 
@@ -449,7 +463,9 @@ int
 __glXDispSwap_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
+    ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
     return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
 }
 
@@ -507,7 +523,9 @@ int
 __glXDispSwap_GetMinmax(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
+    ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
     return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
 }
 
@@ -515,7 +533,9 @@ int
 __glXDispSwap_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
+    ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
     return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
 }
 
@@ -581,7 +601,9 @@ int
 __glXDispSwap_GetColorTable(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
+    ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
     return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
 }
 
@@ -589,6 +611,8 @@ int
 __glXDispSwap_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc)
 {
     const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
+    ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
     return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
 }
commit 44ba149f28ece93c2fbfc9cc980588de5322dd4b
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:46 2014 -0500

    glx: Length-checking for non-generated vendor private requests [CVE-2014-8098 6/8]
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/indirect_program.c b/glx/indirect_program.c
index cda139e..5caee7b 100644
--- a/glx/indirect_program.c
+++ b/glx/indirect_program.c
@@ -56,6 +56,8 @@ DoGetProgramString(struct __GLXclientStateRec *cl, GLbyte * pc,
     __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error);
     ClientPtr client = cl->client;
 
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateWithReplyReq, 8);
+
     pc += __GLX_VENDPRIV_HDR_SIZE;
     if (cx != NULL) {
         GLenum target;
diff --git a/glx/swap_interval.c b/glx/swap_interval.c
index 17bc992..2320550 100644
--- a/glx/swap_interval.c
+++ b/glx/swap_interval.c
@@ -46,6 +46,8 @@ DoSwapInterval(__GLXclientState * cl, GLbyte * pc, int do_swap)
     __GLXcontext *cx;
     GLint interval;
 
+    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 4);
+
     cx = __glXLookupContextByTag(cl, tag);
 
     if ((cx == NULL) || (cx->pGlxScreen == NULL)) {
commit afe177020d1fb776c6163f21eddc82cb185b95ca
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:45 2014 -0500

    glx: Request length checks for SetClientInfoARB [CVE-2014-8098 5/8]
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/clientinfo.c b/glx/clientinfo.c
index 4aaa4c9..c5fef30 100644
--- a/glx/clientinfo.c
+++ b/glx/clientinfo.c
@@ -33,18 +33,21 @@ static int
 set_client_info(__GLXclientState * cl, xGLXSetClientInfoARBReq * req,
                 unsigned bytes_per_version)
 {
+    ClientPtr client = cl->client;
     char *gl_extensions;
     char *glx_extensions;
 
+    REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq);
+
     /* Verify that the size of the packet matches the size inferred from the
      * sizes specified for the various fields.
      */
-    const unsigned expected_size = sz_xGLXSetClientInfoARBReq
-        + (req->numVersions * bytes_per_version)
-        + __GLX_PAD(req->numGLExtensionBytes)
-        + __GLX_PAD(req->numGLXExtensionBytes);
+    int size = sz_xGLXSetClientInfoARBReq;
+    size = safe_add(size, safe_mul(req->numVersions, bytes_per_version));
+    size = safe_add(size, safe_pad(req->numGLExtensionBytes));
+    size = safe_add(size, safe_pad(req->numGLXExtensionBytes));
 
-    if (req->length != (expected_size / 4))
+    if (size < 0 || req->length != (size / 4))
         return BadLength;
 
     /* Verify that the actual length of the GL extension string matches what's
@@ -80,8 +83,11 @@ __glXDisp_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDispSwap_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc;
 
+    REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq);
+
     req->length = bswap_16(req->length);
     req->numVersions = bswap_32(req->numVersions);
     req->numGLExtensionBytes = bswap_32(req->numGLExtensionBytes);
@@ -99,8 +105,11 @@ __glXDisp_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDispSwap_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc;
 
+    REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq);
+
     req->length = bswap_16(req->length);
     req->numVersions = bswap_32(req->numVersions);
     req->numGLExtensionBytes = bswap_32(req->numGLExtensionBytes);
commit c91e4abc3b892f42802efa20fef7ada442c2d3f5
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:44 2014 -0500

    glx: Top-level length checking for swapped VendorPrivate requests [CVE-2014-8098 4/8]
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/glxcmdsswap.c b/glx/glxcmdsswap.c
index 5d179f3..9ec1222 100644
--- a/glx/glxcmdsswap.c
+++ b/glx/glxcmdsswap.c
@@ -958,11 +958,13 @@ __glXDispSwap_RenderLarge(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDispSwap_VendorPrivate(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     xGLXVendorPrivateReq *req;
     GLint vendorcode;
     __GLXdispatchVendorPrivProcPtr proc;
 
     __GLX_DECLARE_SWAP_VARIABLES;
+    REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq);
 
     req = (xGLXVendorPrivateReq *) pc;
     __GLX_SWAP_SHORT(&req->length);
@@ -985,11 +987,13 @@ __glXDispSwap_VendorPrivate(__GLXclientState * cl, GLbyte * pc)
 int
 __glXDispSwap_VendorPrivateWithReply(__GLXclientState * cl, GLbyte * pc)
 {
+    ClientPtr client = cl->client;
     xGLXVendorPrivateWithReplyReq *req;
     GLint vendorcode;
     __GLXdispatchVendorPrivProcPtr proc;
 
     __GLX_DECLARE_SWAP_VARIABLES;
+    REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateWithReplyReq);
 
     req = (xGLXVendorPrivateWithReplyReq *) pc;
     __GLX_SWAP_SHORT(&req->length);
commit a33a939e6abb255b14d8dbc85fcbd2c55b958bae
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:43 2014 -0500

    glx: Length checking for RenderLarge requests (v2) [CVE-2014-8098 3/8]
    
    This is a half-measure until we start passing request length into the
    varsize function, but it's better than the nothing we had before.
    
    v2: Verify that there's at least a large render header's worth of
    dataBytes (Julien Cristau)
    
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index ddd9119..a7a5172 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -2109,6 +2109,8 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
+    REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq);
+
     req = (xGLXRenderLargeReq *) pc;
     if (client->swapped) {
         __GLX_SWAP_SHORT(&req->length);
@@ -2124,12 +2126,14 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
         __glXResetLargeCommandStatus(cl);
         return error;
     }
+    if (safe_pad(req->dataBytes) < 0)
+        return BadLength;
     dataBytes = req->dataBytes;
 
     /*
      ** Check the request length.
      */
-    if ((req->length << 2) != __GLX_PAD(dataBytes) + sz_xGLXRenderLargeReq) {
+    if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq) {
         client->errorValue = req->length;
         /* Reset in case this isn't 1st request. */
         __glXResetLargeCommandStatus(cl);
@@ -2139,7 +2143,7 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
 
     if (cl->largeCmdRequestsSoFar == 0) {
         __GLXrenderSizeData entry;
-        int extra;
+        int extra = 0;
         size_t cmdlen;
         int err;
 
@@ -2152,13 +2156,17 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
             return __glXError(GLXBadLargeRequest);
         }
 
+        if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE)
+            return BadLength;
+
         hdr = (__GLXrenderLargeHeader *) pc;
         if (client->swapped) {
             __GLX_SWAP_INT(&hdr->length);
             __GLX_SWAP_INT(&hdr->opcode);
         }
-        cmdlen = hdr->length;
         opcode = hdr->opcode;
+        if ((cmdlen = safe_pad(hdr->length)) < 0)
+            return BadLength;
 
         /*
          ** Check for core opcodes and grab entry data.
@@ -2180,17 +2188,13 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
             if (extra < 0) {
                 return BadLength;
             }
-            /* large command's header is 4 bytes longer, so add 4 */
-            if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) {
-                return BadLength;
-            }
         }
-        else {
-            /* constant size command */
-            if (cmdlen != __GLX_PAD(entry.bytes + 4)) {
-                return BadLength;
-            }
+
+        /* the +4 is safe because we know entry.bytes is small */
+        if (cmdlen != safe_pad(safe_add(entry.bytes + 4, extra))) {
+            return BadLength;
         }
+
         /*
          ** Make enough space in the buffer, then copy the entire request.
          */
@@ -2217,6 +2221,7 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
          ** We are receiving subsequent (i.e. not the first) requests of a
          ** multi request command.
          */
+        int bytesSoFar; /* including this packet */
 
         /*
          ** Check the request number and the total request count.
@@ -2235,11 +2240,18 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
         /*
          ** Check that we didn't get too much data.
          */
-        if ((cl->largeCmdBytesSoFar + dataBytes) > cl->largeCmdBytesTotal) {
+        if ((bytesSoFar = safe_add(cl->largeCmdBytesSoFar, dataBytes)) < 0) {
+            client->errorValue = dataBytes;
+            __glXResetLargeCommandStatus(cl);
+            return __glXError(GLXBadLargeRequest);
+        }
+
+        if (bytesSoFar > cl->largeCmdBytesTotal) {
             client->errorValue = dataBytes;
             __glXResetLargeCommandStatus(cl);
             return __glXError(GLXBadLargeRequest);
         }
+
         memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes);
         cl->largeCmdBytesSoFar += dataBytes;
         cl->largeCmdRequestsSoFar++;
@@ -2251,17 +2263,16 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
              ** This is the last request; it must have enough bytes to complete
              ** the command.
              */
-            /* NOTE: the two pad macros have been added below; they are needed
-             ** because the client library pads the total byte count, but not
-             ** the per-request byte counts.  The Protocol Encoding says the
-             ** total byte count should not be padded, so a proposal will be
-             ** made to the ARB to relax the padding constraint on the total
-             ** byte count, thus preserving backward compatibility.  Meanwhile,
-             ** the padding done below fixes a bug that did not allow
-             ** large commands of odd sizes to be accepted by the server.
+            /* NOTE: the pad macro below is needed because the client library
+             ** pads the total byte count, but not the per-request byte counts.
+             ** The Protocol Encoding says the total byte count should not be
+             ** padded, so a proposal will be made to the ARB to relax the
+             ** padding constraint on the total byte count, thus preserving
+             ** backward compatibility.  Meanwhile, the padding done below
+             ** fixes a bug that did not allow large commands of odd sizes to
+             ** be accepted by the server.
              */
-            if (__GLX_PAD(cl->largeCmdBytesSoFar) !=
-                __GLX_PAD(cl->largeCmdBytesTotal)) {
+            if (safe_pad(cl->largeCmdBytesSoFar) != cl->largeCmdBytesTotal) {
                 client->errorValue = dataBytes;
                 __glXResetLargeCommandStatus(cl);
                 return __glXError(GLXBadLargeRequest);
commit 698888e6671d54c7ae41e9d456f7f5483a3459d2
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:42 2014 -0500

    glx: Integer overflow protection for non-generated render requests (v3) [CVE-2014-8093 5/6]
    
    v2:
    Fix constants in __glXMap2fReqSize (Michal Srb)
    Validate w/h/d for proxy targets too (Keith Packard)
    
    v3:
    Fix Map[12]Size to correctly reject order == 0 (Julien Cristau)
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/rensize.c b/glx/rensize.c
index 9ff73c7..d46334a 100644
--- a/glx/rensize.c
+++ b/glx/rensize.c
@@ -43,19 +43,11 @@
   (((a & 0xff000000U)>>24) | ((a & 0xff0000U)>>8) | \
    ((a & 0xff00U)<<8) | ((a & 0xffU)<<24))
 
-static int
-Map1Size(GLint k, GLint order)
-{
-    if (order <= 0 || k < 0)
-        return -1;
-    return k * order;
-}
-
 int
 __glXMap1dReqSize(const GLbyte * pc, Bool swap)
 {
     GLenum target;
-    GLint order, k;
+    GLint order;
 
     target = *(GLenum *) (pc + 16);
     order = *(GLint *) (pc + 20);
@@ -63,15 +55,16 @@ __glXMap1dReqSize(const GLbyte * pc, Bool swap)
         target = SWAPL(target);
         order = SWAPL(order);
     }
-    k = __glMap1d_size(target);
-    return 8 * Map1Size(k, order);
+    if (order < 1)
+        return -1;
+    return safe_mul(8, safe_mul(__glMap1d_size(target), order));
 }
 
 int
 __glXMap1fReqSize(const GLbyte * pc, Bool swap)
 {
     GLenum target;
-    GLint order, k;
+    GLint order;
 
     target = *(GLenum *) (pc + 0);
     order = *(GLint *) (pc + 12);
@@ -79,23 +72,24 @@ __glXMap1fReqSize(const GLbyte * pc, Bool swap)
         target = SWAPL(target);
         order = SWAPL(order);
     }
-    k = __glMap1f_size(target);
-    return 4 * Map1Size(k, order);
+    if (order < 1)
+        return -1;
+    return safe_mul(4, safe_mul(__glMap1f_size(target), order));
 }
 
 static int
 Map2Size(int k, int majorOrder, int minorOrder)
 {
-    if (majorOrder <= 0 || minorOrder <= 0 || k < 0)
+    if (majorOrder < 1 || minorOrder < 1)
         return -1;
-    return k * majorOrder * minorOrder;
+    return safe_mul(k, safe_mul(majorOrder, minorOrder));
 }
 
 int
 __glXMap2dReqSize(const GLbyte * pc, Bool swap)
 {
     GLenum target;
-    GLint uorder, vorder, k;
+    GLint uorder, vorder;
 
     target = *(GLenum *) (pc + 32);
     uorder = *(GLint *) (pc + 36);
@@ -105,15 +99,14 @@ __glXMap2dReqSize(const GLbyte * pc, Bool swap)
         uorder = SWAPL(uorder);
         vorder = SWAPL(vorder);
     }
-    k = __glMap2d_size(target);
-    return 8 * Map2Size(k, uorder, vorder);
+    return safe_mul(8, Map2Size(__glMap2d_size(target), uorder, vorder));
 }
 
 int
 __glXMap2fReqSize(const GLbyte * pc, Bool swap)
 {
     GLenum target;
-    GLint uorder, vorder, k;
+    GLint uorder, vorder;
 
     target = *(GLenum *) (pc + 0);
     uorder = *(GLint *) (pc + 12);
@@ -123,8 +116,7 @@ __glXMap2fReqSize(const GLbyte * pc, Bool swap)
         uorder = SWAPL(uorder);
         vorder = SWAPL(vorder);
     }
-    k = __glMap2f_size(target);
-    return 4 * Map2Size(k, uorder, vorder);
+    return safe_mul(4, Map2Size(__glMap2f_size(target), uorder, vorder));
 }
 
 /**
@@ -175,14 +167,16 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
     GLint bytesPerElement, elementsPerGroup, groupsPerRow;
     GLint groupSize, rowSize, padding, imageSize;
 
+    if (w == 0 || h == 0 || d == 0)
+        return 0;
+
     if (w < 0 || h < 0 || d < 0 ||
         (type == GL_BITMAP &&
          (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) {
         return -1;
     }
-    if (w == 0 || h == 0 || d == 0)
-        return 0;
 
+    /* proxy targets have no data */
     switch (target) {
     case GL_PROXY_TEXTURE_1D:
     case GL_PROXY_TEXTURE_2D:
@@ -199,6 +193,12 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
         return 0;
     }
 
+    /* real data has to have real sizes */
+    if (imageHeight < 0 || rowLength < 0 || skipImages < 0 || skipRows < 0)
+        return -1;
+    if (alignment != 1 && alignment != 2 && alignment != 4 && alignment != 8)
+        return -1;
+
     if (type == GL_BITMAP) {
         if (rowLength > 0) {
             groupsPerRow = rowLength;
@@ -207,11 +207,14 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
             groupsPerRow = w;
         }
         rowSize = bits_to_bytes(groupsPerRow);
+        if (rowSize < 0)
+            return -1;
         padding = (rowSize % alignment);
         if (padding) {
             rowSize += alignment - padding;
         }
-        return ((h + skipRows) * rowSize);
+
+        return safe_mul(safe_add(h, skipRows), rowSize);
     }
     else {
         switch (format) {
@@ -303,6 +306,7 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
         default:
             return -1;
         }
+        /* known safe by the switches above, not checked */
         groupSize = bytesPerElement * elementsPerGroup;
         if (rowLength > 0) {
             groupsPerRow = rowLength;
@@ -310,18 +314,21 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
         else {
             groupsPerRow = w;
         }
-        rowSize = groupsPerRow * groupSize;
+
+        if ((rowSize = safe_mul(groupsPerRow, groupSize)) < 0)
+            return -1;
         padding = (rowSize % alignment);
         if (padding) {
             rowSize += alignment - padding;
         }
-        if (imageHeight > 0) {
-            imageSize = (imageHeight + skipRows) * rowSize;
-        }
-        else {
-            imageSize = (h + skipRows) * rowSize;
-        }
-        return ((d + skipImages) * imageSize);
+
+        if (imageHeight > 0)
+            h = imageHeight;
+        h = safe_add(h, skipRows);
+
+        imageSize = safe_mul(h, rowSize);
+
+        return safe_mul(safe_add(d, skipImages), imageSize);
     }
 }
 
@@ -445,9 +452,7 @@ __glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap)
     /* XXX Should rowLength be used for either or both image? */
     image1size = __glXImageSize(format, type, 0, w, 1, 1,
                                 0, rowLength, 0, 0, alignment);
-    image1size = __GLX_PAD(image1size);
     image2size = __glXImageSize(format, type, 0, h, 1, 1,
                                 0, rowLength, 0, 0, alignment);
-    return image1size + image2size;
-
+    return safe_add(safe_pad(image1size), image2size);
 }
commit be09e0c988ffdb0371293af49fb4ea8f49ed324a
Author: Julien Cristau <jcristau at debian.org>
Date:   Mon Nov 10 12:13:41 2014 -0500

    glx: Length checking for GLXRender requests (v2) [CVE-2014-8098 2/8]
    
    v2:
    Remove can't-happen comparison for cmdlen < 0 (Michal Srb)
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index ea42e2a..ddd9119 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -2025,7 +2025,7 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
     left = (req->length << 2) - sz_xGLXRenderReq;
     while (left > 0) {
         __GLXrenderSizeData entry;
-        int extra;
+        int extra = 0;
         __GLXdispatchRenderProcPtr proc;
         int err;
 
@@ -2044,6 +2044,9 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
         cmdlen = hdr->length;
         opcode = hdr->opcode;
 
+        if (left < cmdlen)
+            return BadLength;
+
         /*
          ** Check for core opcodes and grab entry data.
          */
@@ -2057,6 +2060,10 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
             return __glXError(GLXBadRenderRequest);
         }
 
+        if (cmdlen < entry.bytes) {
+            return BadLength;
+        }
+
         if (entry.varsize) {
             /* variable size command */
             extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE,
@@ -2064,17 +2071,9 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
             if (extra < 0) {
                 return BadLength;
             }
-            if (cmdlen != __GLX_PAD(entry.bytes + extra)) {
-                return BadLength;
-            }
         }
-        else {
-            /* constant size command */
-            if (cmdlen != __GLX_PAD(entry.bytes)) {
-                return BadLength;
-            }
-        }
-        if (left < cmdlen) {
+
+        if (cmdlen != safe_pad(safe_add(entry.bytes, extra))) {
             return BadLength;
         }
 
commit 2a5cbc17fc72185bf0fa06fef26d1f782de72595
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:40 2014 -0500

    glx: Add safe_{add,mul,pad} (v3) [CVE-2014-8093 4/6]
    
    These are paranoid about integer overflow, and will return -1 if their
    operation would overflow a (signed) integer or if either argument is
    negative.
    
    Note that RenderLarge requests are sized with a uint32_t so in principle
    this could be sketchy there, but dix limits bigreqs to 128M so you
    shouldn't ever notice, and honestly if you're sending more than 2G of
    rendering commands you're already doing something very wrong.
    
    v2: Use INT_MAX for consistency with the rest of the server (jcristau)
    v3: Reject negative arguments (anholt)
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/glxserver.h b/glx/glxserver.h
index a324b29..9482601 100644
--- a/glx/glxserver.h
+++ b/glx/glxserver.h
@@ -228,6 +228,47 @@ extern void glxSwapQueryServerStringReply(ClientPtr client,
  * Routines for computing the size of variably-sized rendering commands.
  */
 
+static _X_INLINE int
+safe_add(int a, int b)
+{
+    if (a < 0 || b < 0)
+        return -1;
+
+    if (INT_MAX - a < b)
+        return -1;
+
+    return a + b;
+}
+
+static _X_INLINE int
+safe_mul(int a, int b)
+{
+    if (a < 0 || b < 0)
+        return -1;
+
+    if (a == 0 || b == 0)
+        return 0;
+
+    if (a > INT_MAX / b)
+        return -1;
+
+    return a * b;
+}
+
+static _X_INLINE int
+safe_pad(int a)
+{
+    int ret;
+
+    if (a < 0)
+        return -1;
+
+    if ((ret = safe_add(a, 3)) < 0)
+        return -1;
+
+    return ret & (GLuint)~3;
+}
+
 extern int __glXTypeSize(GLenum enm);
 extern int __glXImageSize(GLenum format, GLenum type,
                           GLenum target, GLsizei w, GLsizei h, GLsizei d,
commit 13d36923e0ddb077f4854e354c3d5c80590b5d9d
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:39 2014 -0500

    glx: Fix image size computation for EXT_texture_integer [CVE-2014-8098 1/8]
    
    Without this we'd reject the request with BadLength.  Note that some old
    versions of Mesa had a bug in the same place, and would _send_ zero
    bytes of image data; these will now be rejected, correctly.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/rensize.c b/glx/rensize.c
index ba22d10..9ff73c7 100644
--- a/glx/rensize.c
+++ b/glx/rensize.c
@@ -224,6 +224,11 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
         case GL_ALPHA:
         case GL_LUMINANCE:
         case GL_INTENSITY:
+        case GL_RED_INTEGER_EXT:
+        case GL_GREEN_INTEGER_EXT:
+        case GL_BLUE_INTEGER_EXT:
+        case GL_ALPHA_INTEGER_EXT:
+        case GL_LUMINANCE_INTEGER_EXT:
             elementsPerGroup = 1;
             break;
         case GL_422_EXT:
@@ -234,14 +239,19 @@ __glXImageSize(GLenum format, GLenum type, GLenum target,
         case GL_DEPTH_STENCIL_MESA:
         case GL_YCBCR_MESA:
         case GL_LUMINANCE_ALPHA:
+        case GL_LUMINANCE_ALPHA_INTEGER_EXT:
             elementsPerGroup = 2;
             break;
         case GL_RGB:
         case GL_BGR:
+        case GL_RGB_INTEGER_EXT:
+        case GL_BGR_INTEGER_EXT:
             elementsPerGroup = 3;
             break;
         case GL_RGBA:
         case GL_BGRA:
+        case GL_RGBA_INTEGER_EXT:
+        case GL_BGRA_INTEGER_EXT:
         case GL_ABGR_EXT:
             elementsPerGroup = 4;
             break;
commit 717a1b37767b41e14859e5022ae9e679152821a9
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:38 2014 -0500

    glx: Additional paranoia in __glXGetAnswerBuffer / __GLX_GET_ANSWER_BUFFER (v2) [CVE-2014-8093 3/6]
    
    If the computed reply size is negative, something went wrong, treat it
    as an error.
    
    v2: Be more careful about size_t being unsigned (Matthieu Herrb)
    v3: SIZE_MAX not SIZE_T_MAX (Alan Coopersmith)
    
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/indirect_util.c b/glx/indirect_util.c
index 926e57c..de81491 100644
--- a/glx/indirect_util.c
+++ b/glx/indirect_util.c
@@ -76,9 +76,14 @@ __glXGetAnswerBuffer(__GLXclientState * cl, size_t required_size,
     const unsigned mask = alignment - 1;
 
     if (local_size < required_size) {
-        const size_t worst_case_size = required_size + alignment;
+        size_t worst_case_size;
         intptr_t temp_buf;
 
+        if (required_size < SIZE_MAX - alignment)
+            worst_case_size = required_size + alignment;
+        else
+            return NULL;
+
         if (cl->returnBufSize < worst_case_size) {
             void *temp = realloc(cl->returnBuf, worst_case_size);
 
diff --git a/glx/unpack.h b/glx/unpack.h
index 52fba74..2b1ebcf 100644
--- a/glx/unpack.h
+++ b/glx/unpack.h
@@ -83,7 +83,8 @@ extern xGLXSingleReply __glXReply;
 ** pointer.
 */
 #define __GLX_GET_ANSWER_BUFFER(res,cl,size,align)			 \
-    if ((size) > sizeof(answerBuffer)) {				 \
+    if (size < 0) return BadLength;                                      \
+    else if ((size) > sizeof(answerBuffer)) {				 \
 	int bump;							 \
 	if ((cl)->returnBufSize < (size)+(align)) {			 \
 	    (cl)->returnBuf = (GLbyte*)realloc((cl)->returnBuf,	 	 \
commit ab2ba9338aa5e85b4487bc7fbe69985c76483e01
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:37 2014 -0500

    glx: Be more strict about rejecting invalid image sizes [CVE-2014-8093 2/6]
    
    Before this we'd just clamp the image size to 0, which was just
    hideously stupid; if the parameters were such that they'd overflow an
    integer, you'd allocate a small buffer, then pass huge values into (say)
    ReadPixels, and now you're scribbling over arbitrary server memory.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/singlepix.c b/glx/singlepix.c
index 506fdaa..8b6c261 100644
--- a/glx/singlepix.c
+++ b/glx/singlepix.c
@@ -65,7 +65,7 @@ __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc)
     lsbFirst = *(GLboolean *) (pc + 25);
     compsize = __glReadPixels_size(format, type, width, height);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
     glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
@@ -124,7 +124,7 @@ __glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc)
     compsize =
         __glGetTexImage_size(target, level, format, type, width, height, depth);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
     __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -218,9 +218,9 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
     compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1);
 
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
     if (compsize2 < 0)
-        compsize2 = 0;
+        return BadLength;
     compsize = __GLX_PAD(compsize);
     compsize2 = __GLX_PAD(compsize2);
 
@@ -296,7 +296,7 @@ GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
      */
     compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
     __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -365,7 +365,7 @@ GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
      */
     compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
     __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -426,7 +426,7 @@ GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
 
     compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
     __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -491,7 +491,7 @@ GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
      */
     compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
     __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
diff --git a/glx/singlepixswap.c b/glx/singlepixswap.c
index 8469101..8dc304f 100644
--- a/glx/singlepixswap.c
+++ b/glx/singlepixswap.c
@@ -75,7 +75,7 @@ __glXDispSwap_ReadPixels(__GLXclientState * cl, GLbyte * pc)
     lsbFirst = *(GLboolean *) (pc + 25);
     compsize = __glReadPixels_size(format, type, width, height);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
     glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
@@ -144,7 +144,7 @@ __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc)
     compsize =
         __glGetTexImage_size(target, level, format, type, width, height, depth);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
     __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -252,9 +252,9 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
     compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1);
 
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
     if (compsize2 < 0)
-        compsize2 = 0;
+        return BadLength;
     compsize = __GLX_PAD(compsize);
     compsize2 = __GLX_PAD(compsize2);
 
@@ -338,7 +338,7 @@ GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
      */
     compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
     __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -415,7 +415,7 @@ GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
      */
     compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
     __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -483,7 +483,7 @@ GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
 
     compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
     __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
@@ -554,7 +554,7 @@ GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
      */
     compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
     if (compsize < 0)
-        compsize = 0;
+        return BadLength;
 
     glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
     __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
commit 23fe7718bb171e71db2d1a30505c2ca2988799d9
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 10 12:13:36 2014 -0500

    glx: Be more paranoid about variable-length requests [CVE-2014-8093 1/6]
    
    If the size computation routine returns -1 we should just reject the
    request outright.  Clamping it to zero could give an attacker the
    opportunity to also mangle cmdlen in such a way that the subsequent
    length check passes, and the request would get executed, thus passing
    data we wanted to reject to the renderer.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Andy Ritger <aritger at nvidia.com>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 009fd9b..ea42e2a 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -2062,7 +2062,7 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
             extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE,
                                       client->swapped);
             if (extra < 0) {
-                extra = 0;
+                return BadLength;
             }
             if (cmdlen != __GLX_PAD(entry.bytes + extra)) {
                 return BadLength;
@@ -2179,7 +2179,7 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
             extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE,
                                       client->swapped);
             if (extra < 0) {
-                extra = 0;
+                return BadLength;
             }
             /* large command's header is 4 bytes longer, so add 4 */
             if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) {
commit f4afd53f2aeaddf509bf9f71d1716dd273fd6e14
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Feb 9 22:42:47 2014 -0800

    Add REQUEST_FIXED_SIZE testcases to test/misc.c
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/misc.c b/test/misc.c
index dd792e6..66330a1 100644
--- a/test/misc.c
+++ b/test/misc.c
@@ -28,6 +28,8 @@
 #include <stdint.h>
 #include "misc.h"
 #include "scrnintstr.h"
+#include "dix.h"
+#include "dixstruct.h"
 
 ScreenInfo screenInfo;
 
@@ -155,11 +157,46 @@ dix_update_desktop_dimensions(void)
     assert_dimensions(-w2, -h2, w2, h2);
 }
 
+static int
+dix_request_fixed_size_overflow(ClientRec *client)
+{
+    xReq req = { 0 };
+
+    client->req_len = req.length = 1;
+    REQUEST_FIXED_SIZE(req, SIZE_MAX);
+    return Success;
+}
+
+static int
+dix_request_fixed_size_match(ClientRec *client)
+{
+    xReq req = { 0 };
+
+    client->req_len = req.length = 9;
+    REQUEST_FIXED_SIZE(req, 30);
+    return Success;
+}
+
+static void
+dix_request_size_checks(void)
+{
+    ClientRec client = { 0 };
+    int rc;
+
+    rc = dix_request_fixed_size_overflow(&client);
+    assert(rc == BadLength);
+
+    rc = dix_request_fixed_size_match(&client);
+    assert(rc == Success);
+}
+
+
 int
 main(int argc, char **argv)
 {
     dix_version_compare();
     dix_update_desktop_dimensions();
+    dix_request_size_checks();
 
     return 0;
 }
commit 2df83bb122debc3c20cfc3d3b0edc85cd0270f79
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Feb 9 21:28:05 2014 -0800

    Add request length checking test cases for some Xinput 2.x requests
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/xi2/protocol-xigetclientpointer.c b/test/xi2/protocol-xigetclientpointer.c
index 28eb8d3..570c53e 100644
--- a/test/xi2/protocol-xigetclientpointer.c
+++ b/test/xi2/protocol-xigetclientpointer.c
@@ -124,6 +124,11 @@ test_XIGetClientPointer(void)
     request.win = INVALID_WINDOW_ID;
     request_XIGetClientPointer(&client_request, &request, BadWindow);
 
+    printf("Testing invalid length\n");
+    client_request.req_len -= 4;
+    request_XIGetClientPointer(&client_request, &request, BadLength);
+    client_request.req_len += 4;
+
     test_data.cp_is_set = FALSE;
 
     printf("Testing window None, unset ClientPointer.\n");
diff --git a/test/xi2/protocol-xipassivegrabdevice.c b/test/xi2/protocol-xipassivegrabdevice.c
index c747ddf..95d8ebf 100644
--- a/test/xi2/protocol-xipassivegrabdevice.c
+++ b/test/xi2/protocol-xipassivegrabdevice.c
@@ -139,6 +139,7 @@ request_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req,
     int local_modifiers;
     int mask_len;
 
+    client_request.req_len = req->length;
     rc = ProcXIPassiveGrabDevice(&client_request);
     assert(rc == error);
 
@@ -190,6 +191,13 @@ test_XIPassiveGrabDevice(void)
     request_XIPassiveGrabDevice(&client_request, request, BadDevice,
                                 request->deviceid);
 
+    printf("Testing invalid length\n");
+    request->length -= 2;
+    request_XIPassiveGrabDevice(&client_request, request, BadLength,
+                                client_request.errorValue);
+    /* re-init request since swapped length test leaves some values swapped */
+    request_init(request, XIPassiveGrabDevice);
+    request->grab_window = CLIENT_WINDOW_ID;
     request->deviceid = XIAllMasterDevices;
 
     printf("Testing invalid grab types\n");
diff --git a/test/xi2/protocol-xiquerypointer.c b/test/xi2/protocol-xiquerypointer.c
index fc66b64..c0421f6 100644
--- a/test/xi2/protocol-xiquerypointer.c
+++ b/test/xi2/protocol-xiquerypointer.c
@@ -201,6 +201,10 @@ test_XIQueryPointer(void)
     test_data.dev = devices.mouse;
     request.deviceid = devices.mouse->id;
     request_XIQueryPointer(&client_request, &request, Success);
+
+    /* test REQUEST_SIZE_MATCH */
+    client_request.req_len -= 4;
+    request_XIQueryPointer(&client_request, &request, BadLength);
 }
 
 int
diff --git a/test/xi2/protocol-xiwarppointer.c b/test/xi2/protocol-xiwarppointer.c
index f7986c1..3aaaae6 100644
--- a/test/xi2/protocol-xiwarppointer.c
+++ b/test/xi2/protocol-xiwarppointer.c
@@ -198,6 +198,9 @@ test_XIWarpPointer(void)
     request_XIWarpPointer(&client_request, &request, Success);
 
     /* FIXME: src_x/y checks */
+
+    client_request.req_len -= 2; /* invalid length */
+    request_XIWarpPointer(&client_request, &request, BadLength);
 }
 
 int
commit d153a85f7478a7a67ccb02fbca6390b0ab1732ee
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Feb 9 21:27:27 2014 -0800

    Add request length checking test cases for some Xinput 1.x requests
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/configure.ac b/configure.ac
index 140e33e..96524c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2621,6 +2621,7 @@ hw/kdrive/linux/Makefile
 hw/kdrive/src/Makefile
 hw/xwayland/Makefile
 test/Makefile
+test/xi1/Makefile
 test/xi2/Makefile
 xserver.ent
 xorg-server.pc
diff --git a/test/Makefile.am b/test/Makefile.am
index 8344276..82578d9 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -4,7 +4,7 @@ noinst_PROGRAMS = list string
 if XORG
 # Tests that require at least some DDX functions in order to fully link
 # For now, requires xf86 ddx, could be adjusted to use another
-SUBDIRS += xi2
+SUBDIRS += xi1 xi2
 noinst_PROGRAMS += xkb input xtest misc fixes xfree86 os signal-logging touch
 if RES
 noinst_PROGRAMS += hashtabletest
diff --git a/test/xi1/Makefile.am b/test/xi1/Makefile.am
new file mode 100644
index 0000000..907fa7a
--- /dev/null
+++ b/test/xi1/Makefile.am
@@ -0,0 +1,34 @@
+if ENABLE_UNIT_TESTS
+if HAVE_LD_WRAP
+noinst_PROGRAMS =  \
+	protocol-xchangedevicecontrol
+
+TESTS=$(noinst_PROGRAMS)
+TESTS_ENVIRONMENT = $(XORG_MALLOC_DEBUG_ENV)
+
+AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
+AM_CPPFLAGS = @XORG_INCS@ -I$(srcdir)/../xi2
+TEST_LDADD=../libxservertest.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) $(GLX_SYS_LIBS)
+COMMON_SOURCES=$(srcdir)/../xi2/protocol-common.c
+
+if SPECIAL_DTRACE_OBJECTS
+TEST_LDADD += $(OS_LIB) $(DIX_LIB)
+endif
+
+protocol_xchangedevicecontrol_LDADD=$(TEST_LDADD)
+
+protocol_xchangedevicecontrol_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient
+
+protocol_xchangedevicecontrol_SOURCES=$(COMMON_SOURCES) protocol-xchangedevicecontrol.c
+
+else
+# Print that xi1-tests were skipped (exit code 77 for automake test harness)
+TESTS = xi1-tests
+CLEANFILES = $(TESTS)
+
+xi1-tests:
+	@echo 'echo "ld -wrap support required for xi1 unit tests, skipping"' > $@
+	@echo 'exit 77' >> $@
+	$(AM_V_GEN)chmod +x $@
+endif
+endif
diff --git a/test/xi1/protocol-xchangedevicecontrol.c b/test/xi1/protocol-xchangedevicecontrol.c
new file mode 100644
index 0000000..8e638b2
--- /dev/null
+++ b/test/xi1/protocol-xchangedevicecontrol.c
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+/*
+ * Protocol testing for ChangeDeviceControl request.
+ */
+#include <stdint.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/extensions/XIproto.h>
+#include "inputstr.h"
+#include "chgdctl.h"
+
+#include "protocol-common.h"
+
+static ClientRec client_request;
+
+static void
+reply_ChangeDeviceControl(ClientPtr client, int len, char *data, void *userdata)
+{
+    xChangeDeviceControlReply *rep = (xChangeDeviceControlReply *) data;
+
+    if (client->swapped) {
+        swapl(&rep->length);
+        swaps(&rep->sequenceNumber);
+    }
+
+    reply_check_defaults(rep, len, ChangeDeviceControl);
+
+    /* XXX: check status code in reply */
+}
+
+static void
+request_ChangeDeviceControl(ClientPtr client, xChangeDeviceControlReq * req,
+                            xDeviceCtl *ctl, int error)
+{
+    int rc;
+
+    client_request.req_len = req->length;
+    rc = ProcXChangeDeviceControl(&client_request);
+    assert(rc == error);
+
+    /* XXX: ChangeDeviceControl doesn't seem to fill in errorValue to check */
+
+    client_request.swapped = TRUE;
+    swaps(&req->length);
+    swaps(&req->control);
+    swaps(&ctl->length);
+    swaps(&ctl->control);
+    /* XXX: swap other contents of ctl, depending on type */
+    rc = SProcXChangeDeviceControl(&client_request);
+    assert(rc == error);
+}
+
+static unsigned char *data[4096];       /* the request buffer */
+
+static void
+test_ChangeDeviceControl(void)
+{
+    xChangeDeviceControlReq *request = (xChangeDeviceControlReq *) data;
+    xDeviceCtl *control = (xDeviceCtl *) (&request[1]);
+
+    request_init(request, ChangeDeviceControl);
+
+    reply_handler = reply_ChangeDeviceControl;
+
+    client_request = init_client(request->length, request);
+
+    printf("Testing invalid lengths:\n");
+    printf(" -- no control struct\n");
+    request_ChangeDeviceControl(&client_request, request, control, BadLength);
+
+    printf(" -- xDeviceResolutionCtl\n");
+    request_init(request, ChangeDeviceControl);
+    request->control = DEVICE_RESOLUTION;
+    control->length = (sizeof(xDeviceResolutionCtl) >> 2);
+    request->length += control->length - 2;
+    request_ChangeDeviceControl(&client_request, request, control, BadLength);
+
+    printf(" -- xDeviceEnableCtl\n");
+    request_init(request, ChangeDeviceControl);
+    request->control = DEVICE_ENABLE;
+    control->length = (sizeof(xDeviceEnableCtl) >> 2);
+    request->length += control->length - 2;
+    request_ChangeDeviceControl(&client_request, request, control, BadLength);
+
+    /* XXX: Test functionality! */
+}
+
+int
+main(int argc, char **argv)
+{
+    init_simple();
+
+    test_ChangeDeviceControl();
+
+    return 0;
+}
commit a0ece23a8bd300c8be10812d368dc8058c97c63e
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Jan 26 20:02:20 2014 -0800

    xfixes: unvalidated length in SProcXFixesSelectSelectionInput [CVE-2014-8102]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xfixes/select.c b/xfixes/select.c
index c088ed3..e964d58 100644
--- a/xfixes/select.c
+++ b/xfixes/select.c
@@ -201,6 +201,7 @@ SProcXFixesSelectSelectionInput(ClientPtr client)
 {
     REQUEST(xXFixesSelectSelectionInputReq);
 
+    REQUEST_SIZE_MATCH(xXFixesSelectSelectionInputReq);
     swaps(&stuff->length);
     swapl(&stuff->window);
     swapl(&stuff->selection);
commit 5d3a788aeb2fbd3ca2812747dc18c94a8b981c63
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Jan 26 19:51:29 2014 -0800

    render: unvalidated lengths in Render extn. swapped procs [CVE-2014-8100 2/2]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/render/render.c b/render/render.c
index 200e0c8..723f380 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1995,7 +1995,7 @@ static int
 SProcRenderQueryVersion(ClientPtr client)
 {
     REQUEST(xRenderQueryVersionReq);
-
+    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
     swaps(&stuff->length);
     swapl(&stuff->majorVersion);
     swapl(&stuff->minorVersion);
@@ -2006,6 +2006,7 @@ static int
 SProcRenderQueryPictFormats(ClientPtr client)
 {
     REQUEST(xRenderQueryPictFormatsReq);
+    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
     swaps(&stuff->length);
     return (*ProcRenderVector[stuff->renderReqType]) (client);
 }
@@ -2014,6 +2015,7 @@ static int
 SProcRenderQueryPictIndexValues(ClientPtr client)
 {
     REQUEST(xRenderQueryPictIndexValuesReq);
+    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
     swaps(&stuff->length);
     swapl(&stuff->format);
     return (*ProcRenderVector[stuff->renderReqType]) (client);
@@ -2029,6 +2031,7 @@ static int
 SProcRenderCreatePicture(ClientPtr client)
 {
     REQUEST(xRenderCreatePictureReq);
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
     swaps(&stuff->length);
     swapl(&stuff->pid);
     swapl(&stuff->drawable);
@@ -2042,6 +2045,7 @@ static int
 SProcRenderChangePicture(ClientPtr client)
 {
     REQUEST(xRenderChangePictureReq);
+    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
     swaps(&stuff->length);
     swapl(&stuff->picture);
     swapl(&stuff->mask);
@@ -2053,6 +2057,7 @@ static int
 SProcRenderSetPictureClipRectangles(ClientPtr client)
 {
     REQUEST(xRenderSetPictureClipRectanglesReq);
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
     swaps(&stuff->length);
     swapl(&stuff->picture);
     swaps(&stuff->xOrigin);
@@ -2065,6 +2070,7 @@ static int
 SProcRenderFreePicture(ClientPtr client)
 {
     REQUEST(xRenderFreePictureReq);
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
     swaps(&stuff->length);
     swapl(&stuff->picture);
     return (*ProcRenderVector[stuff->renderReqType]) (client);
@@ -2074,6 +2080,7 @@ static int
 SProcRenderComposite(ClientPtr client)
 {
     REQUEST(xRenderCompositeReq);
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
     swaps(&stuff->length);
     swapl(&stuff->src);
     swapl(&stuff->mask);
@@ -2093,6 +2100,7 @@ static int
 SProcRenderScale(ClientPtr client)
 {
     REQUEST(xRenderScaleReq);
+    REQUEST_SIZE_MATCH(xRenderScaleReq);
     swaps(&stuff->length);
     swapl(&stuff->src);
     swapl(&stuff->dst);
@@ -2193,6 +2201,7 @@ static int
 SProcRenderCreateGlyphSet(ClientPtr client)
 {
     REQUEST(xRenderCreateGlyphSetReq);
+    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
     swaps(&stuff->length);
     swapl(&stuff->gsid);
     swapl(&stuff->format);
@@ -2203,6 +2212,7 @@ static int
 SProcRenderReferenceGlyphSet(ClientPtr client)
 {
     REQUEST(xRenderReferenceGlyphSetReq);
+    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
     swaps(&stuff->length);
     swapl(&stuff->gsid);
     swapl(&stuff->existing);
@@ -2213,6 +2223,7 @@ static int
 SProcRenderFreeGlyphSet(ClientPtr client)
 {
     REQUEST(xRenderFreeGlyphSetReq);
+    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
     swaps(&stuff->length);
     swapl(&stuff->glyphset);
     return (*ProcRenderVector[stuff->renderReqType]) (client);
@@ -2227,6 +2238,7 @@ SProcRenderAddGlyphs(ClientPtr client)
     xGlyphInfo *gi;
 
     REQUEST(xRenderAddGlyphsReq);
+    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
     swaps(&stuff->length);
     swapl(&stuff->glyphset);
     swapl(&stuff->nglyphs);
@@ -2261,6 +2273,7 @@ static int
 SProcRenderFreeGlyphs(ClientPtr client)
 {
     REQUEST(xRenderFreeGlyphsReq);
+    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
     swaps(&stuff->length);
     swapl(&stuff->glyphset);
     SwapRestL(stuff);
@@ -2278,6 +2291,7 @@ SProcRenderCompositeGlyphs(ClientPtr client)
     int size;
 
     REQUEST(xRenderCompositeGlyphsReq);
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
 
     switch (stuff->renderReqType) {
     default:
commit b5f9ef03df6a650571b29d3d1c1d2b67c6e84336
Author: Julien Cristau <jcristau at debian.org>
Date:   Tue Oct 28 10:30:04 2014 +0100

    render: check request size before reading it [CVE-2014-8100 1/2]
    
    Otherwise we may be reading outside of the client request.
    
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/render/render.c b/render/render.c
index e3031da..200e0c8 100644
--- a/render/render.c
+++ b/render/render.c
@@ -276,11 +276,11 @@ ProcRenderQueryVersion(ClientPtr client)
 
     REQUEST(xRenderQueryVersionReq);
 
+    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+
     pRenderClient->major_version = stuff->majorVersion;
     pRenderClient->minor_version = stuff->minorVersion;
 
-    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
-
     if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
         (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) {
         rep.majorVersion = stuff->majorVersion;
commit 3df2fcf12499ebdb26b9b67419ea485a42041f33
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Jan 26 19:38:09 2014 -0800

    randr: unvalidated lengths in RandR extension swapped procs [CVE-2014-8101]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c
index 08c3b6a..47558cf 100644
--- a/randr/rrsdispatch.c
+++ b/randr/rrsdispatch.c
@@ -27,6 +27,7 @@ SProcRRQueryVersion(ClientPtr client)
 {
     REQUEST(xRRQueryVersionReq);
 
+    REQUEST_SIZE_MATCH(xRRQueryVersionReq);
     swaps(&stuff->length);
     swapl(&stuff->majorVersion);
     swapl(&stuff->minorVersion);
@@ -38,6 +39,7 @@ SProcRRGetScreenInfo(ClientPtr client)
 {
     REQUEST(xRRGetScreenInfoReq);
 
+    REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
     swaps(&stuff->length);
     swapl(&stuff->window);
     return (*ProcRandrVector[stuff->randrReqType]) (client);
@@ -69,6 +71,7 @@ SProcRRSelectInput(ClientPtr client)
 {
     REQUEST(xRRSelectInputReq);
 
+    REQUEST_SIZE_MATCH(xRRSelectInputReq);
     swaps(&stuff->length);
     swapl(&stuff->window);
     swaps(&stuff->enable);
@@ -152,6 +155,7 @@ SProcRRConfigureOutputProperty(ClientPtr client)
 {
     REQUEST(xRRConfigureOutputPropertyReq);
 
+    REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq);
     swaps(&stuff->length);
     swapl(&stuff->output);
     swapl(&stuff->property);
commit d155b7a8e38e74aee96bf52c20c8b6a330d7d462
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Jan 26 19:33:34 2014 -0800

    present: unvalidated lengths in Present extension procs [CVE-2014-8103 2/2]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Julien Cristau <jcristau at debian.org>

diff --git a/present/present_request.c b/present/present_request.c
index 835890d..7c53e72 100644
--- a/present/present_request.c
+++ b/present/present_request.c
@@ -210,6 +210,7 @@ proc_present_query_capabilities (ClientPtr client)
     RRCrtcPtr   crtc = NULL;
     int         r;
 
+    REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq);
     r = dixLookupWindow(&window, stuff->target, client, DixGetAttrAccess);
     switch (r) {
     case Success:
@@ -254,6 +255,7 @@ static int
 sproc_present_query_version(ClientPtr client)
 {
     REQUEST(xPresentQueryVersionReq);
+    REQUEST_SIZE_MATCH(xPresentQueryVersionReq);
 
     swaps(&stuff->length);
     swapl(&stuff->majorVersion);
@@ -265,6 +267,7 @@ static int
 sproc_present_pixmap(ClientPtr client)
 {
     REQUEST(xPresentPixmapReq);
+    REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
 
     swaps(&stuff->length);
     swapl(&stuff->window);
@@ -284,6 +287,7 @@ static int
 sproc_present_notify_msc(ClientPtr client)
 {
     REQUEST(xPresentNotifyMSCReq);
+    REQUEST_SIZE_MATCH(xPresentNotifyMSCReq);
 
     swaps(&stuff->length);
     swapl(&stuff->window);
@@ -297,6 +301,7 @@ static int
 sproc_present_select_input (ClientPtr client)
 {
     REQUEST(xPresentSelectInputReq);
+    REQUEST_SIZE_MATCH(xPresentSelectInputReq);
 
     swaps(&stuff->length);
     swapl(&stuff->window);
@@ -308,6 +313,7 @@ static int
 sproc_present_query_capabilities (ClientPtr client)
 {
     REQUEST(xPresentQueryCapabilitiesReq);
+    REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq);
     swaps(&stuff->length);
     swapl(&stuff->target);
     return (*proc_present_vector[stuff->presentReqType]) (client);
commit 0a6085aaf3581cca558d960ea176ddf3a41a2213
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Jan 26 19:28:05 2014 -0800

    dri3: unvalidated lengths in DRI3 extension swapped procs [CVE-2014-8103 1/2]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c
index fe45620..2d75588 100644
--- a/dri3/dri3_request.c
+++ b/dri3/dri3_request.c
@@ -321,6 +321,7 @@ static int
 sproc_dri3_query_version(ClientPtr client)
 {
     REQUEST(xDRI3QueryVersionReq);
+    REQUEST_SIZE_MATCH(xDRI3QueryVersionReq);
 
     swaps(&stuff->length);
     swapl(&stuff->majorVersion);
@@ -332,6 +333,7 @@ static int
 sproc_dri3_open(ClientPtr client)
 {
     REQUEST(xDRI3OpenReq);
+    REQUEST_SIZE_MATCH(xDRI3OpenReq);
 
     swaps(&stuff->length);
     swapl(&stuff->drawable);
@@ -343,6 +345,7 @@ static int
 sproc_dri3_pixmap_from_buffer(ClientPtr client)
 {
     REQUEST(xDRI3PixmapFromBufferReq);
+    REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
 
     swaps(&stuff->length);
     swapl(&stuff->pixmap);
@@ -358,6 +361,7 @@ static int
 sproc_dri3_buffer_from_pixmap(ClientPtr client)
 {
     REQUEST(xDRI3BufferFromPixmapReq);
+    REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
 
     swaps(&stuff->length);
     swapl(&stuff->pixmap);
@@ -368,6 +372,7 @@ static int
 sproc_dri3_fence_from_fd(ClientPtr client)
 {
     REQUEST(xDRI3FenceFromFDReq);
+    REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
 
     swaps(&stuff->length);
     swapl(&stuff->drawable);
@@ -379,6 +384,7 @@ static int
 sproc_dri3_fd_from_fence(ClientPtr client)
 {
     REQUEST(xDRI3FDFromFenceReq);
+    REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq);
 
     swaps(&stuff->length);
     swapl(&stuff->drawable);
commit 32a95fb7c7dbe22c9441c62762dfa4a8ec54d6c3
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Jan 26 19:23:17 2014 -0800

    Xv: unvalidated lengths in XVideo extension swapped procs [CVE-2014-8099]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/xvdisp.c b/Xext/xvdisp.c
index 86f982a..c2d0fc9 100644
--- a/Xext/xvdisp.c
+++ b/Xext/xvdisp.c
@@ -1121,6 +1121,7 @@ static int
 SProcXvQueryExtension(ClientPtr client)
 {
     REQUEST(xvQueryExtensionReq);
+    REQUEST_SIZE_MATCH(xvQueryExtensionReq);
     swaps(&stuff->length);
     return XvProcVector[xv_QueryExtension] (client);
 }
@@ -1129,6 +1130,7 @@ static int
 SProcXvQueryAdaptors(ClientPtr client)
 {
     REQUEST(xvQueryAdaptorsReq);
+    REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
     swaps(&stuff->length);
     swapl(&stuff->window);
     return XvProcVector[xv_QueryAdaptors] (client);
@@ -1138,6 +1140,7 @@ static int
 SProcXvQueryEncodings(ClientPtr client)
 {
     REQUEST(xvQueryEncodingsReq);
+    REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     return XvProcVector[xv_QueryEncodings] (client);
@@ -1147,6 +1150,7 @@ static int
 SProcXvGrabPort(ClientPtr client)
 {
     REQUEST(xvGrabPortReq);
+    REQUEST_SIZE_MATCH(xvGrabPortReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->time);
@@ -1157,6 +1161,7 @@ static int
 SProcXvUngrabPort(ClientPtr client)
 {
     REQUEST(xvUngrabPortReq);
+    REQUEST_SIZE_MATCH(xvUngrabPortReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->time);
@@ -1167,6 +1172,7 @@ static int
 SProcXvPutVideo(ClientPtr client)
 {
     REQUEST(xvPutVideoReq);
+    REQUEST_SIZE_MATCH(xvPutVideoReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->drawable);
@@ -1186,6 +1192,7 @@ static int
 SProcXvPutStill(ClientPtr client)
 {
     REQUEST(xvPutStillReq);
+    REQUEST_SIZE_MATCH(xvPutStillReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->drawable);
@@ -1205,6 +1212,7 @@ static int
 SProcXvGetVideo(ClientPtr client)
 {
     REQUEST(xvGetVideoReq);
+    REQUEST_SIZE_MATCH(xvGetVideoReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->drawable);
@@ -1224,6 +1232,7 @@ static int
 SProcXvGetStill(ClientPtr client)
 {
     REQUEST(xvGetStillReq);
+    REQUEST_SIZE_MATCH(xvGetStillReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->drawable);
@@ -1243,6 +1252,7 @@ static int
 SProcXvPutImage(ClientPtr client)
 {
     REQUEST(xvPutImageReq);
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->drawable);
@@ -1266,6 +1276,7 @@ static int
 SProcXvShmPutImage(ClientPtr client)
 {
     REQUEST(xvShmPutImageReq);
+    REQUEST_SIZE_MATCH(xvShmPutImageReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->drawable);
@@ -1293,6 +1304,7 @@ static int
 SProcXvSelectVideoNotify(ClientPtr client)
 {
     REQUEST(xvSelectVideoNotifyReq);
+    REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
     swaps(&stuff->length);
     swapl(&stuff->drawable);
     return XvProcVector[xv_SelectVideoNotify] (client);
@@ -1302,6 +1314,7 @@ static int
 SProcXvSelectPortNotify(ClientPtr client)
 {
     REQUEST(xvSelectPortNotifyReq);
+    REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     return XvProcVector[xv_SelectPortNotify] (client);
@@ -1311,6 +1324,7 @@ static int
 SProcXvStopVideo(ClientPtr client)
 {
     REQUEST(xvStopVideoReq);
+    REQUEST_SIZE_MATCH(xvStopVideoReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->drawable);
@@ -1321,6 +1335,7 @@ static int
 SProcXvSetPortAttribute(ClientPtr client)
 {
     REQUEST(xvSetPortAttributeReq);
+    REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->attribute);
@@ -1332,6 +1347,7 @@ static int
 SProcXvGetPortAttribute(ClientPtr client)
 {
     REQUEST(xvGetPortAttributeReq);
+    REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->attribute);
@@ -1342,6 +1358,7 @@ static int
 SProcXvQueryBestSize(ClientPtr client)
 {
     REQUEST(xvQueryBestSizeReq);
+    REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swaps(&stuff->vid_w);
@@ -1355,6 +1372,7 @@ static int
 SProcXvQueryPortAttributes(ClientPtr client)
 {
     REQUEST(xvQueryPortAttributesReq);
+    REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     return XvProcVector[xv_QueryPortAttributes] (client);
@@ -1364,6 +1382,7 @@ static int
 SProcXvQueryImageAttributes(ClientPtr client)
 {
     REQUEST(xvQueryImageAttributesReq);
+    REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     swapl(&stuff->id);
@@ -1376,6 +1395,7 @@ static int
 SProcXvListImageFormats(ClientPtr client)
 {
     REQUEST(xvListImageFormatsReq);
+    REQUEST_SIZE_MATCH(xvListImageFormatsReq);
     swaps(&stuff->length);
     swapl(&stuff->port);
     return XvProcVector[xv_ListImageFormats] (client);
commit 7553082b9b883b5f130044f3d53bce2f0b660e52
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Jan 26 17:18:54 2014 -0800

    xcmisc: unvalidated length in SProcXCMiscGetXIDList() [CVE-2014-8096]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/xcmisc.c b/Xext/xcmisc.c
index 034bfb6..1e91010 100644
--- a/Xext/xcmisc.c
+++ b/Xext/xcmisc.c
@@ -167,6 +167,7 @@ static int
 SProcXCMiscGetXIDList(ClientPtr client)
 {
     REQUEST(xXCMiscGetXIDListReq);
+    REQUEST_SIZE_MATCH(xXCMiscGetXIDListReq);
 
     swaps(&stuff->length);
     swapl(&stuff->count);
commit 73c63afb93c0af1bfd1969bf6e71c9edca586c77
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Jan 26 10:54:41 2014 -0800

    Xi: unvalidated lengths in Xinput extension [CVE-2014-8095]
    
    Multiple functions in the Xinput extension handling of requests from
    clients failed to check that the length of the request sent by the
    client was large enough to perform all the required operations and
    thus could read or write to memory outside the bounds of the request
    buffer.
    
    This commit includes the creation of a new REQUEST_AT_LEAST_EXTRA_SIZE
    macro in include/dix.h for the common case of needing to ensure a
    request is large enough to include both the request itself and a
    minimum amount of extra data following the request header.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/chgdctl.c b/Xi/chgdctl.c
index d078aa2..b3ee867 100644
--- a/Xi/chgdctl.c
+++ b/Xi/chgdctl.c
@@ -78,7 +78,7 @@ SProcXChangeDeviceControl(ClientPtr client)
 
     REQUEST(xChangeDeviceControlReq);
     swaps(&stuff->length);
-    REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
+    REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
     swaps(&stuff->control);
     ctl = (xDeviceCtl *) &stuff[1];
     swaps(&ctl->control);
@@ -115,7 +115,7 @@ ProcXChangeDeviceControl(ClientPtr client)
     xDeviceEnableCtl *e;
 
     REQUEST(xChangeDeviceControlReq);
-    REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
+    REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
 
     len = stuff->length - bytes_to_int32(sizeof(xChangeDeviceControlReq));
     ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
@@ -192,6 +192,10 @@ ProcXChangeDeviceControl(ClientPtr client)
         break;
     case DEVICE_ENABLE:
         e = (xDeviceEnableCtl *) &stuff[1];
+        if ((len != bytes_to_int32(sizeof(xDeviceEnableCtl)))) {
+            ret = BadLength;
+            goto out;
+        }
 
         if (IsXTestDevice(dev, NULL))
             status = !Success;
diff --git a/Xi/chgfctl.c b/Xi/chgfctl.c
index 6dcf60c..224c2ba 100644
--- a/Xi/chgfctl.c
+++ b/Xi/chgfctl.c
@@ -467,6 +467,8 @@ ProcXChangeFeedbackControl(ClientPtr client)
         xStringFeedbackCtl *f = ((xStringFeedbackCtl *) &stuff[1]);
 
         if (client->swapped) {
+            if (len < bytes_to_int32(sizeof(xStringFeedbackCtl)))
+                return BadLength;
             swaps(&f->num_keysyms);
         }
         if (len !=
diff --git a/Xi/sendexev.c b/Xi/sendexev.c
index 3c21386..183f88d 100644
--- a/Xi/sendexev.c
+++ b/Xi/sendexev.c
@@ -135,6 +135,9 @@ ProcXSendExtensionEvent(ClientPtr client)
     if (ret != Success)
         return ret;
 
+    if (stuff->num_events == 0)
+        return ret;
+
     /* The client's event type must be one defined by an extension. */
 
     first = ((xEvent *) &stuff[1]);
diff --git a/Xi/xiallowev.c b/Xi/xiallowev.c
index ebef233..ca263ef 100644
--- a/Xi/xiallowev.c
+++ b/Xi/xiallowev.c
@@ -48,6 +48,7 @@ int
 SProcXIAllowEvents(ClientPtr client)
 {
     REQUEST(xXIAllowEventsReq);
+    REQUEST_AT_LEAST_SIZE(xXIAllowEventsReq);
 
     swaps(&stuff->length);
     swaps(&stuff->deviceid);
@@ -55,6 +56,7 @@ SProcXIAllowEvents(ClientPtr client)
     if (stuff->length > 3) {
         xXI2_2AllowEventsReq *req_xi22 = (xXI2_2AllowEventsReq *) stuff;
 
+        REQUEST_AT_LEAST_SIZE(xXI2_2AllowEventsReq);
         swapl(&req_xi22->touchid);
         swapl(&req_xi22->grab_window);
     }
diff --git a/Xi/xichangecursor.c b/Xi/xichangecursor.c
index 7a1bb7a..8e6255b 100644
--- a/Xi/xichangecursor.c
+++ b/Xi/xichangecursor.c
@@ -57,11 +57,11 @@ int
 SProcXIChangeCursor(ClientPtr client)
 {
     REQUEST(xXIChangeCursorReq);
+    REQUEST_SIZE_MATCH(xXIChangeCursorReq);
     swaps(&stuff->length);
     swapl(&stuff->win);
     swapl(&stuff->cursor);
     swaps(&stuff->deviceid);
-    REQUEST_SIZE_MATCH(xXIChangeCursorReq);
     return (ProcXIChangeCursor(client));
 }
 
diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
index 9e36354..2732445 100644
--- a/Xi/xichangehierarchy.c
+++ b/Xi/xichangehierarchy.c
@@ -411,7 +411,7 @@ int
 ProcXIChangeHierarchy(ClientPtr client)
 {
     xXIAnyHierarchyChangeInfo *any;
-    int required_len = sizeof(xXIChangeHierarchyReq);
+    size_t len;			/* length of data remaining in request */
     int rc = Success;
     int flags[MAXDEVICES] = { 0 };
 
@@ -421,21 +421,46 @@ ProcXIChangeHierarchy(ClientPtr client)
     if (!stuff->num_changes)
         return rc;
 
+    if (stuff->length > (INT_MAX >> 2))
+        return BadAlloc;
+    len = (stuff->length << 2) - sizeof(xXIAnyHierarchyChangeInfo);
+
     any = (xXIAnyHierarchyChangeInfo *) &stuff[1];
     while (stuff->num_changes--) {
+        if (len < sizeof(xXIAnyHierarchyChangeInfo)) {
+            rc = BadLength;
+            goto unwind;
+        }
+
         SWAPIF(swaps(&any->type));
         SWAPIF(swaps(&any->length));
 
-        required_len += any->length;
-        if ((stuff->length * 4) < required_len)
+        if ((any->length > (INT_MAX >> 2)) || (len < (any->length << 2)))
             return BadLength;
 
+#define CHANGE_SIZE_MATCH(type) \
+    do { \
+        if ((len < sizeof(type)) || (any->length != (sizeof(type) >> 2))) { \
+            rc = BadLength; \
+            goto unwind; \
+        } \
+    } while(0)
+
         switch (any->type) {
         case XIAddMaster:
         {
             xXIAddMasterInfo *c = (xXIAddMasterInfo *) any;
 
+            /* Variable length, due to appended name string */
+            if (len < sizeof(xXIAddMasterInfo)) {
+                rc = BadLength;
+                goto unwind;
+            }
             SWAPIF(swaps(&c->name_len));
+            if (c->name_len > (len - sizeof(xXIAddMasterInfo))) {
+                rc = BadLength;
+                goto unwind;
+            }
 
             rc = add_master(client, c, flags);
             if (rc != Success)
@@ -446,6 +471,7 @@ ProcXIChangeHierarchy(ClientPtr client)
         {
             xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any;
 
+            CHANGE_SIZE_MATCH(xXIRemoveMasterInfo);
             rc = remove_master(client, r, flags);
             if (rc != Success)
                 goto unwind;
@@ -455,6 +481,7 @@ ProcXIChangeHierarchy(ClientPtr client)
         {
             xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any;
 
+            CHANGE_SIZE_MATCH(xXIDetachSlaveInfo);
             rc = detach_slave(client, c, flags);
             if (rc != Success)
                 goto unwind;
@@ -464,6 +491,7 @@ ProcXIChangeHierarchy(ClientPtr client)
         {
             xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any;
 
+            CHANGE_SIZE_MATCH(xXIAttachSlaveInfo);
             rc = attach_slave(client, c, flags);
             if (rc != Success)
                 goto unwind;
@@ -471,6 +499,7 @@ ProcXIChangeHierarchy(ClientPtr client)
             break;
         }
 
+        len -= any->length * 4;
         any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4);
     }
 
diff --git a/Xi/xigetclientpointer.c b/Xi/xigetclientpointer.c
index 3c90d58..306dd39 100644
--- a/Xi/xigetclientpointer.c
+++ b/Xi/xigetclientpointer.c
@@ -50,6 +50,7 @@ int
 SProcXIGetClientPointer(ClientPtr client)
 {
     REQUEST(xXIGetClientPointerReq);
+    REQUEST_SIZE_MATCH(xXIGetClientPointerReq);
 
     swaps(&stuff->length);
     swapl(&stuff->win);
diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c
index 63d95bc..e2a2ae3 100644
--- a/Xi/xigrabdev.c
+++ b/Xi/xigrabdev.c
@@ -47,6 +47,11 @@ int
 SProcXIGrabDevice(ClientPtr client)
 {
     REQUEST(xXIGrabDeviceReq);
+    /*
+     * Check here for at least the length of the struct we swap, then
+     * let ProcXIGrabDevice check the full size after we swap mask_len.
+     */
+    REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
 
     swaps(&stuff->length);
     swaps(&stuff->deviceid);
@@ -71,7 +76,7 @@ ProcXIGrabDevice(ClientPtr client)
     unsigned int pointer_mode;
 
     REQUEST(xXIGrabDeviceReq);
-    REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
+    REQUEST_FIXED_SIZE(xXIGrabDeviceReq, ((size_t) stuff->mask_len) * 4);
 
     ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
     if (ret != Success)
@@ -131,6 +136,7 @@ int
 SProcXIUngrabDevice(ClientPtr client)
 {
     REQUEST(xXIUngrabDeviceReq);
+    REQUEST_SIZE_MATCH(xXIUngrabDeviceReq);
 
     swaps(&stuff->length);
     swaps(&stuff->deviceid);
@@ -148,6 +154,7 @@ ProcXIUngrabDevice(ClientPtr client)
     TimeStamp time;
 
     REQUEST(xXIUngrabDeviceReq);
+    REQUEST_SIZE_MATCH(xXIUngrabDeviceReq);
 
     ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
     if (ret != Success)
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 700622d..9241ffd 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -53,6 +53,7 @@ SProcXIPassiveGrabDevice(ClientPtr client)
     uint32_t *mods;
 
     REQUEST(xXIPassiveGrabDeviceReq);
+    REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
 
     swaps(&stuff->length);
     swaps(&stuff->deviceid);
@@ -63,6 +64,8 @@ SProcXIPassiveGrabDevice(ClientPtr client)
     swaps(&stuff->mask_len);
     swaps(&stuff->num_modifiers);
 
+    REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
+        ((uint32_t) stuff->mask_len + stuff->num_modifiers) *4);
     mods = (uint32_t *) &stuff[1] + stuff->mask_len;
 
     for (i = 0; i < stuff->num_modifiers; i++, mods++) {
@@ -92,7 +95,8 @@ ProcXIPassiveGrabDevice(ClientPtr client)
     int mask_len;
 
     REQUEST(xXIPassiveGrabDeviceReq);
-    REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
+    REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
+        ((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4);
 
     if (stuff->deviceid == XIAllDevices)
         dev = inputInfo.all_devices;
@@ -252,6 +256,7 @@ SProcXIPassiveUngrabDevice(ClientPtr client)
     uint32_t *modifiers;
 
     REQUEST(xXIPassiveUngrabDeviceReq);
+    REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
 
     swaps(&stuff->length);
     swapl(&stuff->grab_window);
@@ -259,6 +264,8 @@ SProcXIPassiveUngrabDevice(ClientPtr client)
     swapl(&stuff->detail);
     swaps(&stuff->num_modifiers);
 
+    REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
+                       ((uint32_t) stuff->num_modifiers) << 2);
     modifiers = (uint32_t *) &stuff[1];
 
     for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
@@ -277,7 +284,8 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
     int i, rc;
 
     REQUEST(xXIPassiveUngrabDeviceReq);
-    REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
+    REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
+                       ((uint32_t) stuff->num_modifiers) << 2);
 
     if (stuff->deviceid == XIAllDevices)
         dev = inputInfo.all_devices;
diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 463607d..8e8e4b0 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -1013,10 +1013,9 @@ int
 SProcXListDeviceProperties(ClientPtr client)
 {
     REQUEST(xListDevicePropertiesReq);
+    REQUEST_SIZE_MATCH(xListDevicePropertiesReq);
 
     swaps(&stuff->length);
-
-    REQUEST_SIZE_MATCH(xListDevicePropertiesReq);
     return (ProcXListDeviceProperties(client));
 }
 
@@ -1037,10 +1036,10 @@ int
 SProcXDeleteDeviceProperty(ClientPtr client)
 {
     REQUEST(xDeleteDevicePropertyReq);
+    REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq);
 
     swaps(&stuff->length);
     swapl(&stuff->property);
-    REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq);
     return (ProcXDeleteDeviceProperty(client));
 }
 
@@ -1048,13 +1047,13 @@ int
 SProcXGetDeviceProperty(ClientPtr client)
 {
     REQUEST(xGetDevicePropertyReq);
+    REQUEST_SIZE_MATCH(xGetDevicePropertyReq);
 
     swaps(&stuff->length);
     swapl(&stuff->property);
     swapl(&stuff->type);
     swapl(&stuff->longOffset);
     swapl(&stuff->longLength);
-    REQUEST_SIZE_MATCH(xGetDevicePropertyReq);
     return (ProcXGetDeviceProperty(client));
 }
 
@@ -1253,11 +1252,10 @@ int
 SProcXIListProperties(ClientPtr client)
 {
     REQUEST(xXIListPropertiesReq);
+    REQUEST_SIZE_MATCH(xXIListPropertiesReq);
 
     swaps(&stuff->length);
     swaps(&stuff->deviceid);
-
-    REQUEST_SIZE_MATCH(xXIListPropertiesReq);
     return (ProcXIListProperties(client));
 }
 
@@ -1279,11 +1277,11 @@ int
 SProcXIDeleteProperty(ClientPtr client)
 {
     REQUEST(xXIDeletePropertyReq);
+    REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
 
     swaps(&stuff->length);
     swaps(&stuff->deviceid);
     swapl(&stuff->property);
-    REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
     return (ProcXIDeleteProperty(client));
 }
 
@@ -1291,6 +1289,7 @@ int
 SProcXIGetProperty(ClientPtr client)
 {
     REQUEST(xXIGetPropertyReq);
+    REQUEST_SIZE_MATCH(xXIGetPropertyReq);
 
     swaps(&stuff->length);
     swaps(&stuff->deviceid);
@@ -1298,7 +1297,6 @@ SProcXIGetProperty(ClientPtr client)
     swapl(&stuff->type);
     swapl(&stuff->offset);
     swapl(&stuff->len);
-    REQUEST_SIZE_MATCH(xXIGetPropertyReq);
     return (ProcXIGetProperty(client));
 }
 
diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c
index 4e544f0..67a9a4f 100644
--- a/Xi/xiquerydevice.c
+++ b/Xi/xiquerydevice.c
@@ -54,6 +54,7 @@ int
 SProcXIQueryDevice(ClientPtr client)
 {
     REQUEST(xXIQueryDeviceReq);
+    REQUEST_SIZE_MATCH(xXIQueryDeviceReq);
 
     swaps(&stuff->length);
     swaps(&stuff->deviceid);
diff --git a/Xi/xiquerypointer.c b/Xi/xiquerypointer.c
index e9bdd42..7ec0c85 100644
--- a/Xi/xiquerypointer.c
+++ b/Xi/xiquerypointer.c
@@ -63,6 +63,8 @@ int
 SProcXIQueryPointer(ClientPtr client)
 {
     REQUEST(xXIQueryPointerReq);
+    REQUEST_SIZE_MATCH(xXIQueryPointerReq);
+
     swaps(&stuff->length);
     swaps(&stuff->deviceid);
     swapl(&stuff->win);
diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
index 45a996e..168579f 100644
--- a/Xi/xiselectev.c
+++ b/Xi/xiselectev.c
@@ -114,6 +114,7 @@ int
 SProcXISelectEvents(ClientPtr client)
 {
     int i;
+    int len;
     xXIEventMask *evmask;
 
     REQUEST(xXISelectEventsReq);
@@ -122,10 +123,17 @@ SProcXISelectEvents(ClientPtr client)
     swapl(&stuff->win);
     swaps(&stuff->num_masks);
 
+    len = stuff->length - bytes_to_int32(sizeof(xXISelectEventsReq));
     evmask = (xXIEventMask *) &stuff[1];
     for (i = 0; i < stuff->num_masks; i++) {
+        if (len < bytes_to_int32(sizeof(xXIEventMask)))
+            return BadLength;
+        len -= bytes_to_int32(sizeof(xXIEventMask));
         swaps(&evmask->deviceid);
         swaps(&evmask->mask_len);
+        if (len < evmask->mask_len)
+            return BadLength;
+        len -= evmask->mask_len;
         evmask =
             (xXIEventMask *) (((char *) &evmask[1]) + evmask->mask_len * 4);
     }
diff --git a/Xi/xisetclientpointer.c b/Xi/xisetclientpointer.c
index 38ff51e..24d4a53 100644
--- a/Xi/xisetclientpointer.c
+++ b/Xi/xisetclientpointer.c
@@ -51,10 +51,11 @@ int
 SProcXISetClientPointer(ClientPtr client)
 {
     REQUEST(xXISetClientPointerReq);
+    REQUEST_SIZE_MATCH(xXISetClientPointerReq);
+
     swaps(&stuff->length);
     swapl(&stuff->win);
     swaps(&stuff->deviceid);
-    REQUEST_SIZE_MATCH(xXISetClientPointerReq);
     return (ProcXISetClientPointer(client));
 }
 
diff --git a/Xi/xisetdevfocus.c b/Xi/xisetdevfocus.c
index 372ec24..96a9a16 100644
--- a/Xi/xisetdevfocus.c
+++ b/Xi/xisetdevfocus.c
@@ -44,6 +44,8 @@ int
 SProcXISetFocus(ClientPtr client)
 {
     REQUEST(xXISetFocusReq);
+    REQUEST_AT_LEAST_SIZE(xXISetFocusReq);
+
     swaps(&stuff->length);
     swaps(&stuff->deviceid);
     swapl(&stuff->focus);
@@ -56,6 +58,8 @@ int
 SProcXIGetFocus(ClientPtr client)
 {
     REQUEST(xXIGetFocusReq);
+    REQUEST_AT_LEAST_SIZE(xXIGetFocusReq);
+
     swaps(&stuff->length);
     swaps(&stuff->deviceid);
 
diff --git a/Xi/xiwarppointer.c b/Xi/xiwarppointer.c
index 3f051f7..780758a 100644
--- a/Xi/xiwarppointer.c
+++ b/Xi/xiwarppointer.c
@@ -56,6 +56,8 @@ int
 SProcXIWarpPointer(ClientPtr client)
 {
     REQUEST(xXIWarpPointerReq);
+    REQUEST_SIZE_MATCH(xXIWarpPointerReq);
+
     swaps(&stuff->length);
     swapl(&stuff->src_win);
     swapl(&stuff->dst_win);
diff --git a/include/dix.h b/include/dix.h
index e0c6ed8..21176a8 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -74,6 +74,10 @@ SOFTWARE.
     if ((sizeof(req) >> 2) > client->req_len )\
          return(BadLength)
 
+#define REQUEST_AT_LEAST_EXTRA_SIZE(req, extra)  \
+    if (((sizeof(req) + ((uint64_t) extra)) >> 2) > client->req_len ) \
+         return(BadLength)
+
 #define REQUEST_FIXED_SIZE(req, n)\
     if (((sizeof(req) >> 2) > client->req_len) || \
         ((n >> 2) >= client->req_len) || \
commit 2ef42519c41e793579c9cea699c866fee3d9321f
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Wed Jan 22 23:12:04 2014 -0800

    dbe: unvalidated lengths in DbeSwapBuffers calls [CVE-2014-8097]
    
    ProcDbeSwapBuffers() has a 32bit (n) length value that it uses to read
    from a buffer. The length is never validated, which can lead to out of
    bound reads, and possibly returning the data read from out of bounds to
    the misbehaving client via an X Error packet.
    
    SProcDbeSwapBuffers() swaps data (for correct endianness) before
    handing it off to the real proc.  While doing the swapping, the
    length field is not validated, which can cause memory corruption.
    
    v2: reorder checks to avoid compilers optimizing out checks for overflow
    that happen after we'd already have done the overflowing multiplications.
    
    Reported-by: Ilja Van Sprundel <ivansprundel at ioactive.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dbe/dbe.c b/dbe/dbe.c
index 527588c..df2ad5c 100644
--- a/dbe/dbe.c
+++ b/dbe/dbe.c
@@ -450,18 +450,20 @@ ProcDbeSwapBuffers(ClientPtr client)
     DbeSwapInfoPtr swapInfo;
     xDbeSwapInfo *dbeSwapInfo;
     int error;
-    register int i, j;
-    int nStuff;
+    unsigned int i, j;
+    unsigned int nStuff;
 
     REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
     nStuff = stuff->n;          /* use local variable for performance. */
 
     if (nStuff == 0) {
+        REQUEST_SIZE_MATCH(xDbeSwapBuffersReq);
         return Success;
     }
 
     if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
         return BadAlloc;
+    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo));
 
     /* Get to the swap info appended to the end of the request. */
     dbeSwapInfo = (xDbeSwapInfo *) &stuff[1];
@@ -914,13 +916,16 @@ static int
 SProcDbeSwapBuffers(ClientPtr client)
 {
     REQUEST(xDbeSwapBuffersReq);
-    register int i;
+    unsigned int i;
     xDbeSwapInfo *pSwapInfo;
 
     swaps(&stuff->length);
     REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
 
     swapl(&stuff->n);
+    if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec))
+        return BadAlloc;
+    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo));
 
     if (stuff->n != 0) {
         pSwapInfo = (xDbeSwapInfo *) stuff + 1;
commit 6692670fde081bbfe9313f17d84037ae9116702a
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Wed Jan 22 23:40:18 2014 -0800

    dri2: integer overflow in ProcDRI2GetBuffers() [CVE-2014-8094]
    
    ProcDRI2GetBuffers() tries to validate a length field (count).
    There is an integer overflow in the validation. This can cause
    out of bound reads and memory corruption later on.
    
    Reported-by: Ilja Van Sprundel <ivansprundel at ioactive.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Julien Cristau <jcristau at debian.org>

diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index ffd66fa..221ec53 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -270,6 +270,9 @@ ProcDRI2GetBuffers(ClientPtr client)
     unsigned int *attachments;
 
     REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
+    if (stuff->count > (INT_MAX / 4))
+        return BadLength;
+
     if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess,
                        &pDrawable, &status))
         return status;
commit e0e11644622a589129a01e11e5d105dc74a098de
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Wed Jan 22 23:44:46 2014 -0800

    dix: integer overflow in REQUEST_FIXED_SIZE() [CVE-2014-8092 4/4]
    
    Force use of 64-bit integers when evaluating data provided by clients
    in 32-bit fields which can overflow when added or multiplied during
    checks.
    
    Reported-by: Ilja Van Sprundel <ivansprundel at ioactive.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/dix.h b/include/dix.h
index 991a3ce..e0c6ed8 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -76,7 +76,8 @@ SOFTWARE.
 
 #define REQUEST_FIXED_SIZE(req, n)\
     if (((sizeof(req) >> 2) > client->req_len) || \
-        (((sizeof(req) + (n) + 3) >> 2) != client->req_len)) \
+        ((n >> 2) >= client->req_len) || \
+        ((((uint64_t) sizeof(req) + (n) + 3) >> 2) != (uint64_t) client->req_len))  \
          return(BadLength)
 
 #define LEGAL_NEW_RESOURCE(id,client)\
commit 97015a07b9e15d8ec5608b95d95ec0eb51202acb
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Wed Jan 22 22:37:15 2014 -0800

    dix: integer overflow in RegionSizeof() [CVE-2014-8092 3/4]
    
    RegionSizeof contains several integer overflows if a large length
    value is passed in.  Once we fix it to return 0 on overflow, we
    also have to fix the callers to handle this error condition
    
    v2: Fixed limit calculation in RegionSizeof as pointed out by jcristau.
    
    Reported-by: Ilja Van Sprundel <ivansprundel at ioactive.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Julien Cristau <jcristau at debian.org>

diff --git a/dix/region.c b/dix/region.c
index ce1014e..04e5901 100644
--- a/dix/region.c
+++ b/dix/region.c
@@ -169,7 +169,6 @@ Equipment Corporation.
         ((r1)->y1 <= (r2)->y1) && \
         ((r1)->y2 >= (r2)->y2) )
 
-#define xallocData(n) malloc(RegionSizeof(n))
 #define xfreeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data)
 
 #define RECTALLOC_BAIL(pReg,n,bail) \
@@ -205,8 +204,9 @@ if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
 #define DOWNSIZE(reg,numRects)						 \
 if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
 {									 \
-    RegDataPtr NewData;							 \
-    NewData = (RegDataPtr)realloc((reg)->data, RegionSizeof(numRects));	 \
+    size_t NewSize = RegionSizeof(numRects);				 \
+    RegDataPtr NewData =						 \
+        (NewSize > 0) ? realloc((reg)->data, NewSize) : NULL ;		 \
     if (NewData)							 \
     {									 \
 	NewData->size = (numRects);					 \
@@ -345,17 +345,20 @@ Bool
 RegionRectAlloc(RegionPtr pRgn, int n)
 {
     RegDataPtr data;
+    size_t rgnSize;
 
     if (!pRgn->data) {
         n++;
-        pRgn->data = xallocData(n);
+        rgnSize = RegionSizeof(n);
+        pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
         if (!pRgn->data)
             return RegionBreak(pRgn);
         pRgn->data->numRects = 1;
         *RegionBoxptr(pRgn) = pRgn->extents;
     }
     else if (!pRgn->data->size) {
-        pRgn->data = xallocData(n);
+        rgnSize = RegionSizeof(n);
+        pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
         if (!pRgn->data)
             return RegionBreak(pRgn);
         pRgn->data->numRects = 0;
@@ -367,7 +370,8 @@ RegionRectAlloc(RegionPtr pRgn, int n)
                 n = 250;
         }
         n += pRgn->data->numRects;
-        data = (RegDataPtr) realloc(pRgn->data, RegionSizeof(n));
+        rgnSize = RegionSizeof(n);
+        data = (rgnSize > 0) ? realloc(pRgn->data, rgnSize) : NULL;
         if (!data)
             return RegionBreak(pRgn);
         pRgn->data = data;
@@ -1312,6 +1316,7 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype)
 {
 
     RegionPtr pRgn;
+    size_t rgnSize;
     RegDataPtr pData;
     BoxPtr pBox;
     int i;
@@ -1338,7 +1343,8 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype)
         }
         return pRgn;
     }
-    pData = xallocData(nrects);
+    rgnSize = RegionSizeof(nrects);
+    pData = (rgnSize > 0) ? malloc(rgnSize) : NULL;
     if (!pData) {
         RegionBreak(pRgn);
         return pRgn;
diff --git a/include/regionstr.h b/include/regionstr.h
index 515e93f..079375d 100644
--- a/include/regionstr.h
+++ b/include/regionstr.h
@@ -127,7 +127,10 @@ RegionEnd(RegionPtr reg)
 static inline size_t
 RegionSizeof(size_t n)
 {
-    return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
+    if (n < ((INT_MAX - sizeof(RegDataRec)) / sizeof(BoxRec)))
+        return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
+    else
+        return 0;
 }
 
 static inline void
@@ -138,9 +141,10 @@ RegionInit(RegionPtr _pReg, BoxPtr _rect, int _size)
         (_pReg)->data = (RegDataPtr) NULL;
     }
     else {
+        size_t rgnSize;
         (_pReg)->extents = RegionEmptyBox;
-        if (((_size) > 1) && ((_pReg)->data =
-                              (RegDataPtr) malloc(RegionSizeof(_size)))) {
+        if (((_size) > 1) && ((rgnSize = RegionSizeof(_size)) > 0) &&
+            (((_pReg)->data = malloc(rgnSize)) != NULL)) {
             (_pReg)->data->size = (_size);
             (_pReg)->data->numRects = 0;
         }
commit bc8e20430b6f6378daf6ce4329029248a88af08b
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Mon Jan 6 23:30:14 2014 -0800

    dix: integer overflow in GetHosts() [CVE-2014-8092 2/4]
    
    GetHosts() iterates over all the hosts it has in memory, and copies
    them to a buffer. The buffer length is calculated by iterating over
    all the hosts and adding up all of their combined length. There is a
    potential integer overflow, if there are lots and lots of hosts (with
    a combined length of > ~4 gig). This should be possible by repeatedly
    calling ProcChangeHosts() on 64bit machines with enough memory.
    
    This patch caps the list at 1mb, because multi-megabyte hostname
    lists for X access control are insane.
    
    Reported-by: Ilja Van Sprundel <ivansprundel at ioactive.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/os/access.c b/os/access.c
index 5c510de..f393c8d 100644
--- a/os/access.c
+++ b/os/access.c
@@ -1296,6 +1296,10 @@ GetHosts(void **data, int *pnHosts, int *pLen, BOOL * pEnabled)
     for (host = validhosts; host; host = host->next) {
         nHosts++;
         n += pad_to_int32(host->len) + sizeof(xHostEntry);
+        /* Could check for INT_MAX, but in reality having more than 1mb of
+           hostnames in the access list is ridiculous */
+        if (n >= 1048576)
+            break;
     }
     if (n) {
         *data = ptr = malloc(n);
@@ -1304,6 +1308,8 @@ GetHosts(void **data, int *pnHosts, int *pLen, BOOL * pEnabled)
         }
         for (host = validhosts; host; host = host->next) {
             len = host->len;
+            if ((ptr + sizeof(xHostEntry) + len) > (data + n))
+                break;
             ((xHostEntry *) ptr)->family = host->family;
             ((xHostEntry *) ptr)->length = len;
             ptr += sizeof(xHostEntry);
commit eeae42d60bf3d5663ea088581f6c28a82cd17829
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Wed Jan 22 21:11:16 2014 -0800

    dix: integer overflow in ProcPutImage() [CVE-2014-8092 1/4]
    
    ProcPutImage() calculates a length field from a width, left pad and depth
    specified by the client (if the specified format is XYPixmap).
    
    The calculations for the total amount of memory the server needs for the
    pixmap can overflow a 32-bit number, causing out-of-bounds memory writes
    on 32-bit systems (since the length is stored in a long int variable).
    
    Reported-by: Ilja Van Sprundel <ivansprundel at ioactive.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/dispatch.c b/dix/dispatch.c
index d844a09..55b978d 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -2000,6 +2000,9 @@ ProcPutImage(ClientPtr client)
     tmpImage = (char *) &stuff[1];
     lengthProto = length;
 
+    if (lengthProto >= (INT32_MAX / stuff->height))
+        return BadLength;
+
     if ((bytes_to_int32(lengthProto * stuff->height) +
          bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
         return BadLength;
commit 90cc925c5991fcb203f72d00b04419cd754a9b2c
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Jan 17 18:54:03 2014 -0800

    unchecked malloc may allow unauthed client to crash Xserver [CVE-2014-8091]
    
    authdes_ezdecode() calls malloc() using a length provided by the
    connection handshake sent by a newly connected client in order
    to authenticate to the server, so should be treated as untrusted.
    
    It didn't check if malloc() failed before writing to the newly
    allocated buffer, so could lead to a server crash if the server
    fails to allocate memory (up to UINT16_MAX bytes, since the len
    field is a CARD16 in the X protocol).
    
    Reported-by: Ilja Van Sprundel <ivansprundel at ioactive.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/os/rpcauth.c b/os/rpcauth.c
index d60ea35..413cc61 100644
--- a/os/rpcauth.c
+++ b/os/rpcauth.c
@@ -66,6 +66,10 @@ authdes_ezdecode(const char *inmsg, int len)
     SVCXPRT xprt;
 
     temp_inmsg = malloc(len);
+    if (temp_inmsg == NULL) {
+        why = AUTH_FAILED; /* generic error, since there is no AUTH_BADALLOC */
+        return NULL;
+    }
     memmove(temp_inmsg, inmsg, len);
 
     memset((char *) &msg, 0, sizeof(msg));
commit 3e7218a6c23354d66f508b18164cac98a346b3ee
Merge: 6f4c398 bc71081
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Dec 8 18:07:55 2014 -0800

    Merge remote-tracking branch 'jturney/indirect-glx-fixes'

commit 6f4c398a0e632b0c92e3cb8ee03ca7f5b5cc018e
Merge: aae6460 5920433
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Dec 8 18:04:08 2014 -0800

    Merge remote-tracking branch 'jturney/master'

commit aae6460694ac3667abb8c34fdf3a7dae524827a4
Author: Mario Kleiner <mario.kleiner.de at gmail.com>
Date:   Sat Dec 6 05:40:08 2014 +0100

    present: Fix use of vsynced pageflips and honor PresentOptionAsync. (v4)
    
    Pageflips for Pixmap presents were not synchronized to vblank on
    drivers with support for PresentCapabilityAsync, due to some
    missing init for vblank->sync_flips. The PresentOptionAsync
    flag was completely ignored for pageflipped presents.
    
    Vsynced flips only worked by accident on the intel-ddx, as that
    driver doesn't have PresentCapabilityAsync support.
    
    On nouveau-ddx, which supports PresentCapabilityAsync, this
    always caused non-vsynced pageflips with pretty ugly tearing.
    
    This patch fixes the problem, as tested on top of XOrg 1.16.2
    on nouveau and intel.
    
    v4: Add additional PresentCapabilityAsync caps check, as
    suggested by Eric Anholt.
    
    Please also apply to XOrg 1.17 and XOrg 1.16.2 stable.
    
    Applying on top of XOrg 1.16.2 requires cherry-picking
    commit 2051514652481a83bd7cf22e57cb0fcd40333f33
    which trivially fixes lack of support for protocol option
    PresentOptionCopy - get two bug fixes for the price of one!
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/present/present.c b/present/present.c
index e5d3fd5..e27fe30 100644
--- a/present/present.c
+++ b/present/present.c
@@ -834,10 +834,13 @@ present_pixmap(WindowPtr window,
     vblank->notifies = notifies;
     vblank->num_notifies = num_notifies;
 
-    if (!screen_priv->info || !(screen_priv->info->capabilities & PresentCapabilityAsync))
+    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))
     {
commit 32d3100bd78efe41d468f7d66861296aee468b6f
Author: Mario Kleiner <mario.kleiner.de at gmail.com>
Date:   Sat Dec 6 05:40:07 2014 +0100

    present: Avoid crashes in DebugPresent(), a bit more info.
    
    DebugPresent() crashed the server when a dri3 drawable
    was closed while a pageflipped present was still pending,
    due to vblank->window-> Null-Ptr deref, so debug builds
    caused new problems to debug.
    
    E.g.,
    
    glXSwapBuffers(...);
    glXDestroyWindow(...);
    -> Pageflip for non-existent window completes -> boom.
    
    Also often happens when switching desktop compositor on/off
    due to Present unflips, or when logging out of session.
    
    Also add info if a Present is queued for copyswap or pageflip,
    if the present is vsynced, and the serial no of the Present
    request, to aid debugging of pageflip and vsync issues. The
    serial number is useful as Mesa's dri3/present backend encodes
    its sendSBC in the serial number, so one can easily correlate
    server debug output with Mesa and with the SBC values returned
    to actual OpenGL client applications via OML_sync_control and
    INTEL_swap_events extension, makes debugging quite a bit more
    easy.
    
    Please also cherry-pick this for a 1.16.x stable update.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/present/present.c b/present/present.c
index ac9047e..e5d3fd5 100644
--- a/present/present.c
+++ b/present/present.c
@@ -440,7 +440,7 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     DebugPresent(("\tn %lld %p %8lld: %08lx -> %08lx\n",
                   vblank->event_id, vblank, vblank->target_msc,
                   vblank->pixmap ? vblank->pixmap->drawable.id : 0,
-                  vblank->window->drawable.id));
+                  vblank->window ? vblank->window->drawable.id : 0));
 
     assert (vblank == screen_priv->flip_pending);
 
@@ -859,10 +859,10 @@ present_pixmap(WindowPtr window,
     }
 
     if (pixmap)
-        DebugPresent(("q %lld %p %8lld: %08lx -> %08lx (crtc %p)\n",
+        DebugPresent(("q %lld %p %8lld: %08lx -> %08lx (crtc %p) flip %d vsync %d serial %d\n",
                       vblank->event_id, vblank, target_msc,
                       vblank->pixmap->drawable.id, vblank->window->drawable.id,
-                      target_crtc));
+                      target_crtc, vblank->flip, vblank->sync_flip, vblank->serial));
 
     xorg_list_add(&vblank->event_queue, &present_exec_queue);
     vblank->queued = TRUE;
@@ -955,7 +955,7 @@ present_vblank_destroy(present_vblank_ptr vblank)
     DebugPresent(("\td %lld %p %8lld: %08lx -> %08lx\n",
                   vblank->event_id, vblank, vblank->target_msc,
                   vblank->pixmap ? vblank->pixmap->drawable.id : 0,
-                  vblank->window->drawable.id));
+                  vblank->window ? vblank->window->drawable.id : 0));
 
     /* Drop pixmap reference */
     if (vblank->pixmap)
commit 32ca85c9e075e40b8a4712a79a51702facba0332
Author: Daniel Martin <consume.noise at gmail.com>
Date:   Fri Nov 28 11:20:50 2014 +0100

    modesetting: Remove unused params from drmmode_output_init()
    
    drmmode_output_init() doesn't touch (the int*) num_dvi and num_hdmi.
    Remove both parameters.
    
    Signed-off-by: Daniel Martin <consume.noise at gmail.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 40c9ed3..d5b7d00 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1024,8 +1024,7 @@ static const char *const output_names[] = {
 };
 
 static void
-drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num,
-                    int *num_dvi, int *num_hdmi)
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 {
     xf86OutputPtr output;
     drmModeConnectorPtr koutput;
@@ -1298,7 +1297,7 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
 Bool
 drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 {
-    int i, num_dvi = 0, num_hdmi = 0;
+    int i;
     int ret;
     uint64_t value = 0;
 
@@ -1326,7 +1325,7 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
             drmmode_crtc_init(pScrn, drmmode, i);
 
     for (i = 0; i < drmmode->mode_res->count_connectors; i++)
-        drmmode_output_init(pScrn, drmmode, i, &num_dvi, &num_hdmi);
+        drmmode_output_init(pScrn, drmmode, i);
 
     /* workout clones */
     drmmode_clones_init(pScrn, drmmode);
commit c0ea476b9bb91f03061b891ffb897c438fa03879
Author: Daniel Martin <consume.noise at gmail.com>
Date:   Fri Nov 28 11:20:49 2014 +0100

    modesetting: Fix ifdefs s/HAVE_UDEV/CONFIG_UDEV_KMS/
    
    We don't define HAVE_UDEV, that's a remnant from xf86-video-modesetting.
    But, we have CONFIG_UDEV_KMS.
    
    Signed-off-by: Daniel Martin <consume.noise at gmail.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 5561df4..40c9ed3 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1487,7 +1487,7 @@ drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
     return TRUE;
 }
 
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
 static void
 drmmode_handle_uevents(int fd, void *closure)
 {
@@ -1507,7 +1507,7 @@ drmmode_handle_uevents(int fd, void *closure)
 void
 drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
 {
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
     struct udev *u;
     struct udev_monitor *mon;
 
@@ -1540,7 +1540,7 @@ drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
 void
 drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
 {
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
     if (drmmode->uevent_handler) {
         struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor);
 
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 528123a..92e2816 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -28,7 +28,7 @@
 #define DRMMODE_DISPLAY_H
 
 #include "xf86drmMode.h"
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
 #include "libudev.h"
 #endif
 
@@ -48,7 +48,7 @@ typedef struct {
     drmModeFBPtr mode_fb;
     int cpp;
     ScrnInfoPtr scrn;
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
     struct udev_monitor *uevent_monitor;
     InputHandlerProc uevent_handler;
 #endif
commit 8a16620dcd7a22fd9b38876ffc711629c4fbda0a
Author: Daniel Martin <consume.noise at gmail.com>
Date:   Fri Nov 28 11:20:48 2014 +0100

    modesetting: Create new EGL screen in drmmode_xf86crtc_resize
    
    If we don't glamor_egl_create_textured_screen_ext() in
    drmmode_xf86crtc_resize() we end up with a black screen and no client
    window(s) visible.
    
    Signed-off-by: Daniel Martin <consume.noise at gmail.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index ef9009e..5561df4 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -49,6 +49,11 @@
 
 #include "driver.h"
 
+#ifdef GLAMOR
+#define GLAMOR_FOR_XORG 1
+#include "glamor.h"
+#endif
+
 static struct dumb_bo *
 dumb_bo_create(int fd,
                const unsigned width, const unsigned height, const unsigned bpp)
@@ -1243,6 +1248,20 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
                                    pitch, drmmode->shadow_fb);
     }
 
+#ifdef GLAMOR
+    if (drmmode->glamor) {
+        if (!glamor_egl_create_textured_screen_ext(screen,
+                                                   drmmode->front_bo->handle,
+                                                   scrn->displayWidth *
+                                                   scrn->bitsPerPixel / 8,
+                                                   NULL)) {
+            xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                       "glamor_egl_create_textured_screen_ext() failed\n");
+            goto fail;
+        }
+    }
+#endif
+
     for (i = 0; i < xf86_config->num_crtc; i++) {
         xf86CrtcPtr crtc = xf86_config->crtc[i];
 
commit 0d63fa5850fe9d8b045b8f1a83e72b75f9065a7a
Author: Daniel Martin <consume.noise at gmail.com>
Date:   Fri Nov 28 11:20:47 2014 +0100

    modesetting: Move Bool glamor into drmmode struct
    
    Move the boolean glamor from struct modesetting into struct drmmode for
    later re-use in drmmode_display.
    
    Signed-off-by: Daniel Martin <consume.noise at gmail.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 592f246..d1284c6 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -593,7 +593,7 @@ try_enable_glamor(ScrnInfoPtr pScrn)
     Bool do_glamor = (!accel_method_str ||
                       strcmp(accel_method_str, "glamor") == 0);
 
-    ms->glamor = FALSE;
+    ms->drmmode.glamor = FALSE;
 
 #ifdef GLAMOR
     if (!do_glamor) {
@@ -604,7 +604,7 @@ try_enable_glamor(ScrnInfoPtr pScrn)
     if (xf86LoadSubModule(pScrn, GLAMOR_EGL_MODULE_NAME)) {
         if (glamor_egl_init(pScrn, ms->fd)) {
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "glamor initialized\n");
-            ms->glamor = TRUE;
+            ms->drmmode.glamor = TRUE;
         } else {
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                        "glamor initialization failed\n");
@@ -788,7 +788,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 
     try_enable_glamor(pScrn);
 
-    if (ms->glamor) {
+    if (ms->drmmode.glamor) {
         xf86LoadSubModule(pScrn, "dri2");
     } else {
         Bool prefer_shadow = TRUE;
@@ -887,7 +887,7 @@ CreateScreenResources(ScreenPtr pScreen)
         return FALSE;
 
 #ifdef GLAMOR
-    if (ms->glamor) {
+    if (ms->drmmode.glamor) {
         if (!glamor_egl_create_textured_screen_ext(pScreen,
                                                    ms->drmmode.front_bo->handle,
                                                    pScrn->displayWidth *
@@ -1053,7 +1053,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
     fbPictureInit(pScreen, NULL, 0);
 
 #ifdef GLAMOR
-    if (ms->glamor) {
+    if (ms->drmmode.glamor) {
         if (!glamor_init(pScreen,
                          GLAMOR_USE_EGL_SCREEN |
                          GLAMOR_USE_SCREEN |
@@ -1116,7 +1116,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
     }
 
 #ifdef GLAMOR
-    if (ms->glamor) {
+    if (ms->drmmode.glamor) {
         if (!ms_dri2_screen_init(pScreen)) {
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                        "Failed to initialize the DRI2 extension.\n");
@@ -1190,7 +1190,7 @@ CloseScreen(ScreenPtr pScreen)
     modesettingPtr ms = modesettingPTR(pScrn);
 
 #ifdef GLAMOR
-    if (ms->glamor) {
+    if (ms->drmmode.glamor) {
         ms_dri2_close_screen(pScreen);
     }
 #endif
diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index 9eda1c4..bbf1ae0 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -97,7 +97,6 @@ typedef struct _modesettingRec {
     Bool dirty_enabled;
 
     uint32_t cursor_width, cursor_height;
-    Bool glamor;
 } modesettingRec, *modesettingPtr;
 
 #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 987608c..528123a 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -56,6 +56,7 @@ typedef struct {
     struct dumb_bo *front_bo;
     Bool sw_cursor;
 
+    Bool glamor;
     Bool shadow_enable;
     void *shadow_fb;
 
commit 62a4eeaa25099872682d6c2f9f13a0e73fc5ce1e
Author: Daniel Martin <consume.noise at gmail.com>
Date:   Fri Nov 28 11:20:46 2014 +0100

    config/udev: Prefix and shift "removing GPU" message
    
    The message "removing GPU device ..." appeared even if the removal was
    skipped (when path == NULL). Move it below the path check and make it a
    LogMessage with config/udev prefix.
    
    Signed-off-by: Daniel Martin <consume.noise at gmail.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/config/udev.c b/config/udev.c
index 1e4a9d7..1d2140a 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -300,12 +300,11 @@ device_removed(struct udev_device *device)
         const char *path = udev_device_get_devnode(device);
         dev_t devnum = udev_device_get_devnum(device);
 
-        if (strncmp(sysname,"card", 4) != 0)
-            return;
-        ErrorF("removing GPU device %s %s\n", syspath, path);
-        if (!path)
+        if ((strncmp(sysname,"card", 4) != 0) || (path == NULL))
             return;
 
+        LogMessage(X_INFO, "config/udev: removing GPU device %s %s\n",
+                   syspath, path);
         config_udev_odev_setup_attribs(path, syspath, major(devnum),
                                        minor(devnum), DeleteGPUDeviceRequest);
         /* Retry vtenter after a drm node removal */
commit bc71081f0e3d8ce3aecf2cb168431dbc9fe6a87b
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Fri Apr 18 12:17:06 2014 +0100

    glx: Fix crash when a client exits without deleting GL contexts
    
    With the previous patches applied, we now have crash due to use-after-free when
    a client exits without deleting all it's GL contexts
    
    On client exit, CloseDownClient first calls glxClientCallback() with
    ClientStateGone, which calls __glXFreeContext() directly.
    
    Subsequently CloseDownClient() frees all the clients resources, which leads to
    ContextGone() being called for a context resource where the context has already
    been freed.
    
    Fix this by modifiying glxClientCallback() to free the context resource.
    
    Also make __glXFreeContext() static, as calling it directly leads to this
    problem, instead the context resource should be released.
    
    With the previous patches applied, this can be demonstrated with e.g. glxinfo,
    which doesn't delete it's context before exit.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxext.c b/glx/glxext.c
index 978d271..e41b881 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -66,6 +66,7 @@ static DevPrivateKeyRec glxClientPrivateKeyRec;
 ** Forward declarations.
 */
 static int __glXDispatch(ClientPtr);
+static GLboolean __glXFreeContext(__GLXcontext * cx);
 
 /*
 ** Called when the extension is reset.
@@ -189,7 +190,7 @@ __glXRemoveFromContextList(__GLXcontext * cx)
 /*
 ** Free a context.
 */
-GLboolean
+static GLboolean
 __glXFreeContext(__GLXcontext * cx)
 {
     if (cx->idExists || cx->currentClient)
@@ -294,7 +295,7 @@ glxClientCallback(CallbackListPtr *list, void *closure, void *data)
                 c->loseCurrent(c);
                 lastGLContext = NULL;
                 c->currentClient = NULL;
-                __glXFreeContext(c);
+                FreeResourceByType(c->id, __glXContextRes, FALSE);
             }
         }
 
diff --git a/glx/glxext.h b/glx/glxext.h
index 3f2dee6..cde0e15 100644
--- a/glx/glxext.h
+++ b/glx/glxext.h
@@ -51,7 +51,6 @@
 #define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT   0x20B1
 #endif
 
-extern GLboolean __glXFreeContext(__GLXcontext * glxc);
 extern void __glXFlushContextCache(void);
 
 extern Bool __glXAddContext(__GLXcontext * cx);
commit 5c606c0a89e74fa223a99864be11cc3be60a159b
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Fri Apr 18 12:17:05 2014 +0100

    glx: Flush context which is being made non-current due to drawable going away
    
    Some sequences of glean tests fail with GLXBadCurrentWindow when using indirect
    rendering, e.g. glean -t 'fpexceptions getString'.
    
    Flush a context which is being made non-current due to the drawable on which is
    it is current going away.  Waiting until another context is made current is too
    late, as the drawable no longer exists.
    
    v2: Rewrite for direct GL dispatch
    
    v3: Inline FlushContext(), doesn't need to be a separate function
    
    e.g. LIBGL_ALWAYS_INDIRECT=1  ./glean -r results -o --quick -t "fpexceptions
    getString" fails with a BadContextTag error.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxext.c b/glx/glxext.c
index c2de3ce..978d271 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -133,6 +133,9 @@ DrawableGone(__GLXdrawable * glxPriv, XID xid)
         next = c->next;
         if (c->currentClient &&
 		(c->drawPriv == glxPriv || c->readPriv == glxPriv)) {
+            /* flush the context */
+            glFlush();
+            c->hasUnflushedCommands = GL_FALSE;
             /* just force a re-bind the next time through */
             (*c->loseCurrent) (c);
             lastGLContext = NULL;
commit 437b27494f127854d75e59b4e2aac264e9f913e9
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Fri Apr 18 12:17:04 2014 +0100

    Revert "glx: Simplify glXDestroyContext"
    
    This reverts commit 7f5adf73a0f9a951a6df201532b4031d38054369.
    
    This seems to miss the whole point of the idExists flag, as it makes the
    lifetime of that being true the same as the lifetime of the Context resource.
    
    The previously current context tag is always given in a MakeContextCurrent
    request, even if that context tag is no longer valid (for example, the context
    has been deleted), so this leads to BadContextTag errors.
    
    See fd.o bug #30089 for the makecurrenttest.c testcase, and some discussion of
    previous manifestations of this bug.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 8d3fa9f..009fd9b 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -413,7 +413,9 @@ __glXDisp_DestroyContext(__GLXclientState * cl, GLbyte * pc)
                          &glxc, &err))
         return err;
 
-    FreeResourceByType(req->context, __glXContextRes, FALSE);
+    glxc->idExists = GL_FALSE;
+    if (!glxc->currentClient)
+        FreeResourceByType(req->context, __glXContextRes, FALSE);
 
     return Success;
 }
commit 4b0d0df34f10a88c10cb23dd50087b59f5c4fece
Author: Peter Harris <pharris at opentext.com>
Date:   Mon Nov 17 14:31:24 2014 -0500

    Fix overflow of ConnectionOutput->size and ->count
    
    When (long) is larger than (int), and when realloc succeeds with sizes
    larger than INT_MAX, ConnectionOutput->size and ConnectionOutput->count
    overflow and become negative.
    
    When ConnectionOutput->count is negative, InsertIOV does not actually
    insert an IOV, and FlushClient goes into an infinite loop of writev(fd,
    iov, 0) [an empty list].
    
    Avoid this situation by killing the client when it has more than INT_MAX
    unread bytes of data.
    
    Signed-off-by: Peter Harris <pharris at opentext.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/io.c b/os/io.c
index bb273bb..96a243d 100644
--- a/os/io.c
+++ b/os/io.c
@@ -971,10 +971,11 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
             }
 
             if (notWritten > oco->size) {
-                unsigned char *obuf;
+                unsigned char *obuf = NULL;
 
-                obuf = (unsigned char *) realloc(oco->buf,
-                                                 notWritten + BUFSIZE);
+                if (notWritten + BUFSIZE <= INT_MAX) {
+                    obuf = realloc(oco->buf, notWritten + BUFSIZE);
+                }
                 if (!obuf) {
                     _XSERVTransDisconnect(oc->trans_conn);
                     _XSERVTransClose(oc->trans_conn);
commit 802932d112a3f6a09420be9e4a13fa78ac43840b
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Nov 17 15:28:58 2014 -0500

    render: fix ChangePicture when Xinerama is active (v2) (#49170)
    
    ChangePicture takes wire XIDs, but didn't do any Xinerama translation,
    which meant setting a clip pixmap or a separate alpha picture would
    result in those elements pointing at the instance of the pixmap on
    screen 0.  Which is, you know, bad.
    
    v2: This one actually builds.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=49170
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/render/picture.c b/render/picture.c
index 711cbc7..6ff31ba 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -41,6 +41,9 @@
 #include "servermd.h"
 #include "picturestr.h"
 #include "xace.h"
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
 
 DevPrivateKeyRec PictureScreenPrivateKeyRec;
 DevPrivateKeyRec PictureWindowPrivateKeyRec;
@@ -1007,6 +1010,38 @@ CreateConicalGradientPicture(Picture pid, xPointFixed * center, xFixed angle,
     return pPicture;
 }
 
+static int
+cpAlphaMap(void **result, XID id, ScreenPtr screen, ClientPtr client, Mask mode)
+{
+#ifdef PANORAMIX
+    if (!noPanoramiXExtension) {
+        PanoramiXRes *res;
+        int err = dixLookupResourceByType((void **)&res, id, XRT_PICTURE,
+                                          client, mode);
+        if (err != Success)
+            return err;
+        id = res->info[screen->myNum].id;
+    }
+#endif
+    return dixLookupResourceByType(result, id, PictureType, client, mode);
+}
+
+static int
+cpClipMask(void **result, XID id, ScreenPtr screen, ClientPtr client, Mask mode)
+{
+#ifdef PANORAMIX
+    if (!noPanoramiXExtension) {
+        PanoramiXRes *res;
+        int err = dixLookupResourceByType((void **)&res, id, XRT_PIXMAP,
+                                          client, mode);
+        if (err != Success)
+            return err;
+        id = res->info[screen->myNum].id;
+    }
+#endif
+    return dixLookupResourceByType(result, id, RT_PIXMAP, client, mode);
+}
+
 #define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
 
 #define NEXT_PTR(_type) ((_type) ulist++->ptr)
@@ -1053,9 +1088,8 @@ ChangePicture(PicturePtr pPicture,
                 if (pid == None)
                     pAlpha = 0;
                 else {
-                    error = dixLookupResourceByType((void **) &pAlpha, pid,
-                                                    PictureType, client,
-                                                    DixReadAccess);
+                    error = cpAlphaMap((void **) &pAlpha, pid, pScreen,
+                                       client, DixReadAccess);
                     if (error != Success) {
                         client->errorValue = pid;
                         break;
@@ -1112,9 +1146,8 @@ ChangePicture(PicturePtr pPicture,
                 }
                 else {
                     clipType = CT_PIXMAP;
-                    error = dixLookupResourceByType((void **) &pPixmap, pid,
-                                                    RT_PIXMAP, client,
-                                                    DixReadAccess);
+                    error = cpClipMask((void **) &pPixmap, pid, pScreen,
+                                       client, DixReadAccess);
                     if (error != Success) {
                         client->errorValue = pid;
                         break;
commit c2994001680a7dcf9c167886d49b7326c97cd5d1
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Fri Nov 21 08:39:02 2014 -0800

    os: "Server terminated successfully" is not an error
    
    ErrorFSigSafe calls LogVMessageVerbSigSafe with the message type set to X_ERROR.
    That generates this in the log:
    
      (EE) Server terminated successfully (0). Closing log file.
    
    People periodically report this as an error, sometimes quoting this "error"
    rather than an earlier error that actually caused a problem.
    
    v2: Use X_INFO instead of X_NOTICE
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/log.c b/os/log.c
index 2e3b3f6..0532c2e 100644
--- a/os/log.c
+++ b/os/log.c
@@ -257,8 +257,11 @@ void
 LogClose(enum ExitCode error)
 {
     if (logFile) {
-        ErrorFSigSafe("Server terminated %s (%d). Closing log file.\n",
-               (error == EXIT_NO_ERROR) ? "successfully" : "with error", error);
+        int msgtype = (error == EXIT_NO_ERROR) ? X_INFO : X_ERROR;
+        LogMessageVerbSigSafe(msgtype, -1,
+                "Server terminated %s (%d). Closing log file.\n",
+                (error == EXIT_NO_ERROR) ? "successfully" : "with error",
+                error);
         fclose(logFile);
         logFile = NULL;
         logFileFd = -1;
commit b09d59342804db7dbb8056dca43dd39f54e290aa
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Wed Nov 26 13:01:29 2014 -0800

    Add -iglx & +iglx to Xserver.man
    
    Covers the current state after commits 99f0365b1fbdfd9238b9f,
    d0da0e9c3bb8fe0cd4879, & e3aa13b8d63ea2fba6eb4 were all applied.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: James Jones <jajones at nvidia.com>
    Reviewed-by: Robert Morell <rmorell at nvidia.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/man/Xserver.man b/man/Xserver.man
index c03830c..3bf844f 100644
--- a/man/Xserver.man
+++ b/man/Xserver.man
@@ -181,6 +181,16 @@ prints a usage message.
 .B \-I
 causes all remaining command line arguments to be ignored.
 .TP 8
+.B \-iglx
+Prohibit creating indirect GLX contexts.  Indirect GLX is of limited use,
+since it lacks support for many modern OpenGL features and extensions;
+it's slower than direct contexts; and it opens a large attack surface for
+protocol parsing errors.
+This is the default unless +iglx is specified.
+.TP 8
+.B +iglx
+Allow creating indirect GLX contexts.
+.TP 8
 .B \-maxbigreqsize \fIsize\fP
 sets the maximum big request to
 .I size
commit c52a2b1ebad56820af932dfbc871701a8b04fd9c
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Nov 11 12:30:07 2014 -0500

    mi: Fix regression in arc drawing
    
    xts' XDrawArcs/15 regressed (turning into a server-side infinite loop)
    after:
    
        commit 7679afd4da8b86aed27e5916ba723116a3c8bb4a
        Author: Adam Jackson <ajax at redhat.com>
        Date:   Fri Sep 26 12:01:37 2014 -0400
    
            mi: Fold mifpolycon.c into miarc.c
    
    The reason is miarc.c provided its own definitions (sigh) of min/max,
    that both accept int arguments and return an int.  Since miFillSppPoly
    uses a double (sigh) and some min-involving math for its loop index
    variable, things do not go well.
    
    Since the integer versions of min/max are redundant, nuke 'em.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
    Tested-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/mi/miarc.c b/mi/miarc.c
index 288bea3..e8bc87e 100644
--- a/mi/miarc.c
+++ b/mi/miarc.c
@@ -115,21 +115,6 @@ cbrt(double x)
  *
  */
 
-#undef max
-#undef min
-
-_X_INLINE static int
-max(const int x, const int y)
-{
-    return x > y ? x : y;
-}
-
-_X_INLINE static int
-min(const int x, const int y)
-{
-    return x < y ? x : y;
-}
-
 struct bound {
     double min, max;
 };
commit ec0ac8970b508adcbc3d104b14a127118e4979d0
Merge: 65cc098 0f88d4e
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Nov 24 15:39:51 2014 -0800

    Merge remote-tracking branch 'whot/for-keith'

commit 65cc0982afb1d47d17e655efaef40d4a82e7574a
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 13 10:31:52 2014 -0700

    glamor: Don't insert fbos from external objects into fbo cache
    
    Mark fbos created from external buffers so that when the associated
    pixmap is destroyed, they aren't put into the fbo cache for later
    re-use and are instead freed immediately.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index fc24b1b..d228e35 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -106,6 +106,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
         ErrorF("XXX fail to create fbo.\n");
         return;
     }
+    fbo->external = TRUE;
 
     glamor_pixmap_attach_fbo(pixmap, fbo);
 }
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 090dfd8..4273826 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -153,7 +153,7 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 #else
     n_format = cache_format(fbo->format);
 
-    if (fbo->fb == 0 || n_format == -1
+    if (fbo->fb == 0 || fbo->external || n_format == -1
         || fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
         fbo->glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX;
         glamor_fbo_expire(fbo->glamor_priv);
@@ -237,6 +237,7 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
     fbo->tex = tex;
     fbo->width = w;
     fbo->height = h;
+    fbo->external = FALSE;
     fbo->format = format;
     fbo->glamor_priv = glamor_priv;
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index c089db8..885f12a 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -352,6 +352,7 @@ enum glamor_fbo_state {
  * @pbo:     attached pbo.
  * @width:   width of this fbo.
  * @height:  height of this fbo.
+ * @external set when the texture was not created by glamor
  * @format:  internal format of this fbo's texture.
  * @type:    internal type of this fbo's texture.
  * @glamor_priv: point to glamor private data.
@@ -365,6 +366,7 @@ typedef struct glamor_pixmap_fbo {
     GLuint pbo;
     int width;
     int height;
+    Bool external;
     GLenum format;
     GLenum type;
     glamor_screen_private *glamor_priv;
commit 0f88d4e7937116dbc438f98ddf1f3d94cfc5bead
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Nov 12 10:29:36 2014 +1000

    mi: fix documentation for miPointerSetPosition
    
    Changed when we added barriers, documentation didn't get updated.
    
    Reported-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/mi/mipointer.c b/mi/mipointer.c
index 9805425..2bdd6ca 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -553,10 +553,15 @@ miPointerMoveNoEvent(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
  * The coordinates provided are always absolute. The parameter mode whether
  * it was relative or absolute movement that landed us at those coordinates.
  *
+ * If the cursor was constrained by a barrier, ET_Barrier* events may be
+ * generated and appended to the InternalEvent list provided.
+ *
  * @param pDev The device to move
  * @param mode Movement mode (Absolute or Relative)
  * @param[in,out] screenx The x coordinate in desktop coordinates
  * @param[in,out] screeny The y coordinate in desktop coordinates
+ * @param[in,out] nevents The number of events in events (before/after)
+ * @param[in,out] events The list of events before/after being constrained
  */
 ScreenPtr
 miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx,
commit 6a117af7e7ef6eac796ff0680a915c866fce4019
Author: John Hunter <zhaojunwang at pku.edu.cn>
Date:   Mon Nov 3 15:45:38 2014 +0800

    fix an annotation mistake
    
    Signed-off-by: John Hunter <zhaojunwang at pku.edu.cn>
    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/devices.c b/dix/devices.c
index 3fb7ca0..c4fdbe1 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2622,7 +2622,7 @@ GetPairedDevice(DeviceIntPtr dev)
  *   slave.
  * - MASTER_KEYBOARD: the master keyboard for this device or NULL for a
  *   floating slave
- * - MASTER_POINTER: the master keyboard for this device or NULL for a
+ * - MASTER_POINTER: the master pointer for this device or NULL for a
  *   floating slave
  * - POINTER_OR_FLOAT: the master pointer for this device or the device for
  *   a floating slave
commit 5920433c3a30f5f1c0ba1ab39a0c2ff388df6b23
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Sat Sep 27 11:50:11 2014 +0100

    hw/xwin: Don't allocate one wchar_t too much for unicode text placed on the Windows clipboard
    
    The count of wchar_t returned by MultiByteToWideChar() includes the terminating
    null character, so don't add one to it.
    
    Also, reduce the scope of various length variables
    
    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/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c
index daf11a1..835195b 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -44,6 +44,7 @@
 #endif
 
 #include <limits.h>
+#include <wchar.h>
 #include <X11/Xutil.h>
 #include <X11/Xatom.h>
 #include <X11/extensions/Xfixes.h>
@@ -208,14 +209,11 @@ winClipboardFlushXEvents(HWND hwnd,
         int iReturn;
         HGLOBAL hGlobal = NULL;
         XICCEncodingStyle xiccesStyle;
-        int iConvertDataLen = 0;
         char *pszConvertData = NULL;
         char *pszTextList[2] = { NULL };
         int iCount;
         char **ppszTextList = NULL;
         wchar_t *pwszUnicodeStr = NULL;
-        int iUnicodeLen = 0;
-        int iReturnDataLen = 0;
         Bool fAbort = FALSE;
         Bool fCloseClipboard = FALSE;
         Bool fSetClipboardData = TRUE;
@@ -381,7 +379,7 @@ winClipboardFlushXEvents(HWND hwnd,
 
             /* Convert the Unicode string to UTF8 (MBCS) */
             if (data->fUseUnicode) {
-                iConvertDataLen = WideCharToMultiByte(CP_UTF8,
+                int iConvertDataLen = WideCharToMultiByte(CP_UTF8,
                                                       0,
                                                       (LPCWSTR) pszGlobalData,
                                                       -1, NULL, 0, NULL, NULL);
@@ -396,7 +394,6 @@ winClipboardFlushXEvents(HWND hwnd,
             }
             else {
                 pszConvertData = strdup(pszGlobalData);
-                iConvertDataLen = strlen(pszConvertData) + 1;
             }
 
             /* Convert DOS string to UNIX string */
@@ -541,7 +538,6 @@ winClipboardFlushXEvents(HWND hwnd,
              */
 
         case SelectionNotify:
-
             winDebug("winClipboardFlushXEvents - SelectionNotify\n");
             {
                 char *pszAtomName;
@@ -620,8 +616,7 @@ winClipboardFlushXEvents(HWND hwnd,
                 /* Conversion succeeded or some unconvertible characters */
                 if (ppszTextList != NULL) {
                     int i;
-
-                    iReturnDataLen = 0;
+                    int iReturnDataLen = 0;
                     for (i = 0; i < iCount; i++) {
                         iReturnDataLen += strlen(ppszTextList[i]);
                     }
@@ -672,12 +667,12 @@ winClipboardFlushXEvents(HWND hwnd,
 
             if (data->fUseUnicode) {
                 /* Find out how much space needed to convert MBCS to Unicode */
-                iUnicodeLen = MultiByteToWideChar(CP_UTF8,
+                int iUnicodeLen = MultiByteToWideChar(CP_UTF8,
                                                   0,
                                                   pszReturnData, -1, NULL, 0);
 
-                /* Allocate memory for the Unicode string */
-                pwszUnicodeStr = malloc(sizeof(wchar_t) * (iUnicodeLen + 1));
+                /* NOTE: iUnicodeLen includes space for null terminator */
+                pwszUnicodeStr = malloc(sizeof(wchar_t) * iUnicodeLen);
                 if (!pwszUnicodeStr) {
                     ErrorF("winClipboardFlushXEvents - SelectionNotify "
                            "malloc failed for pwszUnicodeStr, aborting.\n");
@@ -695,9 +690,10 @@ winClipboardFlushXEvents(HWND hwnd,
 
                 /* Allocate global memory for the X clipboard data */
                 hGlobal = GlobalAlloc(GMEM_MOVEABLE,
-                                      sizeof(wchar_t) * (iUnicodeLen + 1));
+                                      sizeof(wchar_t) * iUnicodeLen);
             }
             else {
+                int iConvertDataLen = 0;
                 pszConvertData = strdup(pszReturnData);
                 iConvertDataLen = strlen(pszConvertData) + 1;
 
@@ -730,8 +726,7 @@ winClipboardFlushXEvents(HWND hwnd,
 
             /* Copy the returned string into the global memory */
             if (data->fUseUnicode) {
-                memcpy(pszGlobalData,
-                       pwszUnicodeStr, sizeof(wchar_t) * (iUnicodeLen + 1));
+                wcscpy((wchar_t *)pszGlobalData, pwszUnicodeStr);
                 free(pwszUnicodeStr);
                 pwszUnicodeStr = NULL;
             }
commit d172cd630dae9c991b84b4c367a4caf8199266ac
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Apr 28 12:48:15 2014 +0100

    hw/xwin: Fix hang on shutdown when we own the clipboard.
    
    If we are the clipboard owner when we are shutdown, we recieve a
    WM_RENDERALLFORMATS, to render the clipboard, so it's contents will remain
    available to other applications.  Unfortunately, this is far too late to do
    anything useful with, as the server is waiting for the clipboard thread to exit,
    and so can't process requests to convert clipboard contents.
    
    Change so we just do nothing on WM_RENDERALLFORMATS. (I'm not convinced that
    WM_RENDERALLFORMATS has ever worked usefully, in any case).
    
    (To make this work, I guess we would need to rearrange the way shutdown works
    completely: first synchronously stop the clipboard, then stop the X server)
    
    We also then receive a WM_DRAWCLIPBOARD, perhaps telling us that the available
    clipboard formats have changed (as ones which haven't been rendered are now
    removed), but the clipboard owner is now the system, not us, which we have to
    arrange to ignore.
    
    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/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index a17f8a9..1ea5bc6 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -143,6 +143,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     static Display *pDisplay;
     static Window iWindow;
     static ClipboardAtoms *atoms;
+    static Bool fRunning;
 
     /* Branch on message type */
     switch (message) {
@@ -160,7 +161,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     case WM_WM_QUIT:
     {
         winDebug("winClipboardWindowProc - WM_WM_QUIT\n");
-
+        fRunning = FALSE;
         PostQuitMessage(0);
     }
         return 0;
@@ -176,6 +177,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         pDisplay = cwcp->pClipboardDisplay;
         iWindow = cwcp->iClipboardWindow;
         atoms = cwcp->atoms;
+        fRunning = TRUE;
 
         first = GetClipboardViewer();   /* Get handle to first viewer in chain. */
         if (first == hwnd)
@@ -308,6 +310,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             return 0;
         }
 
+        /* Bail when shutting down */
+        if (!fRunning)
+            return 0;
+
         /*
          * Do not take ownership of the X11 selections when something
          * other than CF_TEXT or CF_UNICODETEXT has been copied
@@ -411,8 +417,21 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         winDebug("winClipboardWindowProc - WM_DESTROYCLIPBOARD - Ignored.\n");
         return 0;
 
-    case WM_RENDERFORMAT:
     case WM_RENDERALLFORMATS:
+        winDebug("winClipboardWindowProc - WM_RENDERALLFORMATS - Hello.\n");
+
+        /*
+          WM_RENDERALLFORMATS is sent as we are shutting down, to render the
+          clipboard so it's contents remains available to other applications.
+
+          Unfortunately, this can't work without major changes. The server is
+          already waiting for us to stop, so we can't ask for the rendering of
+          clipboard text now.
+        */
+
+        return 0;
+
+    case WM_RENDERFORMAT:
     {
         int iReturn;
         Bool fConvertToUnicode;
@@ -421,13 +440,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         ClipboardConversionData data;
         int best_target = 0;
 
-        winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n");
+        winDebug("winClipboardWindowProc - WM_RENDERFORMAT %d - Hello.\n",
+                 wParam);
 
         /* Flag whether to convert to Unicode or not */
-        if (message == WM_RENDERALLFORMATS)
-            fConvertToUnicode = FALSE;
-        else
-            fConvertToUnicode = (CF_UNICODETEXT == wParam);
+        fConvertToUnicode = (CF_UNICODETEXT == wParam);
 
         selection = winClipboardGetLastOwnedSelectionAtom(atoms);
         if (selection == None) {
@@ -511,28 +528,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                           atoms->atomLocalProperty,
                           iWindow, CurrentTime);
 
-        /* Special handling for WM_RENDERALLFORMATS */
-        if (message == WM_RENDERALLFORMATS) {
-            /* We must open and empty the clipboard */
-
-            /* Close clipboard if we have it open already */
-            if (GetOpenClipboardWindow() == hwnd) {
-                CloseClipboard();
-            }
-
-            if (!OpenClipboard(hwnd)) {
-                ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
-                       "OpenClipboard () failed: %08x\n",
-                       GetLastError());
-            }
-
-            if (!EmptyClipboard()) {
-                ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
-                       "EmptyClipboard () failed: %08x\n",
-                       GetLastError());
-            }
-        }
-
         /* Process X events */
         iReturn = winProcessXEventsTimeout(hwnd,
                                            iWindow,
@@ -566,18 +561,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             SetClipboardData(CF_TEXT, NULL);
           }
 
-        /* Special handling for WM_RENDERALLFORMATS */
-        if (message == WM_RENDERALLFORMATS) {
-            /* We must close the clipboard */
-
-            if (!CloseClipboard()) {
-                ErrorF("winClipboardWindowProc - WM_RENDERALLFORMATS - "
-                       "CloseClipboard () failed: %08x\n",
-                       GetLastError());
-            }
-        }
-
-        winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Returning.\n");
+        winDebug("winClipboardWindowProc - WM_RENDERFORMAT - Returning.\n");
         return 0;
     }
     }
commit 94d433c8cb64c9167050d02473176f888decf1d8
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Fri Feb 21 23:20:00 2014 +0000

    hw/xwin: Fix clipboard thread restart
    
    It seems that the clipboard thread restart mechanism has been broken for a
    while, which can be demonstrated using XDMCP with KDM (e.g. to a Kubutunu 12.04
    host)
    
    KDM kills all attached clients, including the clipboard integration client,
    which restarts, but then exits on WM_QUIT.
    
    Using PostQuitMessage() in WM_DESTROY is unhelpful, as we may not actually be
    quitting the thread, if we just destroyed the window because the clipboard
    thread is about to retry, because he WM_QUIT message sticks around, and is
    noticed the next time we look at the window message queue and confuses us into
    thinking we need to quit.
    
    Sending a WM_DESTROY is apparently never correct anyhow, see [1]
    
    So:
    
    1/ Use DestroyWindow() to destroy the clipboard messaging window when cleaning
    up for retry or exit in winClipboardProc (the clipboard thread main proc)
    
    2/ Send a special WM_WM_QUIT message in winClipboardWindowDestroy() from the X
    server thread when the X server is resetting.
    
    3/ When processing that WM_WM_QUIT message in the clipboard thread, cause the
    clipboard window to PostQuitMessage(), which causes the clipboard thread to
    exit.
    
    [1] http://blogs.msdn.com/b/oldnewthing/archive/2011/09/26/10216420.aspx
    
    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 bcf45ca..c6bde84 100644
--- a/hw/xwin/winclipboard/internal.h
+++ b/hw/xwin/winclipboard/internal.h
@@ -44,6 +44,7 @@
 #define WIN_XEVENTS_NOTIFY_TARGETS		4
 
 #define WM_WM_REINIT                           (WM_USER + 1)
+#define WM_WM_QUIT                             (WM_USER + 2)
 
 /*
  * References to external symbols
diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c
index 786b889..50e1e8c 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -351,7 +351,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
  winClipboardProc_Done:
     /* Close our Windows window */
     if (g_hwndClipboard) {
-        winClipboardWindowDestroy();
+        DestroyWindow(g_hwndClipboard);
     }
 
     /* Close our X window */
@@ -491,7 +491,7 @@ void
 winClipboardWindowDestroy(void)
 {
   if (g_hwndClipboard) {
-    SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0);
+    SendMessage(g_hwndClipboard, WM_WM_QUIT, 0, 0);
   }
 }
 
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index b63a1dc..a17f8a9 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -154,6 +154,12 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         ChangeClipboardChain(hwnd, s_hwndNextViewer);
 
         s_hwndNextViewer = NULL;
+    }
+        return 0;
+
+    case WM_WM_QUIT:
+    {
+        winDebug("winClipboardWindowProc - WM_WM_QUIT\n");
 
         PostQuitMessage(0);
     }
commit b4a08e642b977b4bbc892ff1d96ecc0cf6e2ca54
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Nov 21 15:18:48 2013 +0000

    hw/xwin: Improve reliability of clipboard X->Windows pastes
    
    Sometimes, particularly with large clipboard pastes to Windows, we could end up
    waiting for the timeout to expire, rather than pasting the data.
    
    Various changes to improve reliability:
    
    1. Use XFlush() not XSync() in winProcessXEventsTimeout().
    
    It makes no sense to ensure we have received replies to outstanding requests if
    we are going to wait for them using select()
    
    2. Add XFlush() to winClipboardProc()
    
    Make sure we have sent any requests before we wait using select()
    
    3. Don't use FD_ISSET() to check which fd is ready
    
    This looks like a Cygwin select() bug in that it sometimes returns 0 with an
    empty fd set before the timeout expires, but a fd appears to be ready.
    
    Add select() return value to debug output when we are warning that this has
    happened.
    
    4. Drain event queues before entering select()
    
    Unconditionally drain event queues before entering select().  This seems to be
    the recommended way of writing select() and X event processing loops.
    
    winClipboardFlushXEvents() checks using XPending(), and
    winClipboardFlushWindowsMessageQueue() checks using PeekMessage() so this is
    safe against blocking, but means that may not need to enter select() at all
    sometimes.
    
    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/thread.c b/hw/xwin/winclipboard/thread.c
index be05357..786b889 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -255,22 +255,25 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
         }
     }
 
-    /* Pre-flush X events */
-    /*
-     * NOTE: Apparently you'll freeze if you don't do this,
-     *       because there may be events in local data structures
-     *       already.
-     */
     data.fUseUnicode = fUseUnicode;
-    winClipboardFlushXEvents(hwnd, iWindow, pDisplay, &data, &atoms);
-
-    /* Pre-flush Windows messages */
-    if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
-        ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n");
-    }
 
-    /* Loop for X events */
+    /* Loop for events */
     while (1) {
+
+        /* Process X events */
+        winClipboardFlushXEvents(hwnd,
+                                 iWindow, pDisplay, &data, &atoms);
+
+        /* Process Windows messages */
+        if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
+          ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue trapped "
+                       "WM_QUIT message, exiting main loop.\n");
+          break;
+        }
+
+        /* We need to ensure that all pending requests are sent */
+        XFlush(pDisplay);
+
         /* Setup the file descriptor set */
         /*
          * NOTE: You have to do this before every call to select
@@ -317,10 +320,9 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
             break;
         }
 
-        /* Branch on which descriptor became active */
         if (FD_ISSET(iConnectionNumber, &fdsRead)) {
-            /* Process X events */
-            winClipboardFlushXEvents(hwnd, iWindow, pDisplay, &data, &atoms);
+            winDebug
+                ("winClipboardProc - X connection ready, pumping X event queue\n");
         }
 
 #ifdef HAS_DEVWINDOWS
@@ -330,14 +332,16 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
         if (1)
 #endif
         {
-            /* Process Windows messages */
-            if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
-                ErrorF("winClipboardProc - "
-                       "winClipboardFlushWindowsMessageQueue trapped "
-                       "WM_QUIT message, exiting main loop.\n");
-                break;
-            }
+            winDebug
+                ("winClipboardProc - /dev/windows ready, pumping Windows message queue\n");
         }
+
+#ifdef HAS_DEVWINDOWS
+        if (!(FD_ISSET(iConnectionNumber, &fdsRead)) &&
+            !(FD_ISSET(fdMessageQueue, &fdsRead))) {
+            winDebug("winClipboardProc - Spurious wake, select() returned %d\n", iReturn);
+        }
+#endif
     }
 
  winClipboardProc_Exit:
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index 23a0ac9..b63a1dc 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -83,8 +83,18 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
         fd_set fdsRead;
         long remainingTime;
 
-        /* We need to ensure that all pending events are processed */
-        XSync(pDisplay, FALSE);
+        /* Process X events */
+        iReturn = winClipboardFlushXEvents(hwnd, iWindow, pDisplay, data, atoms);
+
+        winDebug("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n", iReturn);
+
+        if ((WIN_XEVENTS_NOTIFY_DATA == iReturn) || (WIN_XEVENTS_NOTIFY_TARGETS == iReturn) || (WIN_XEVENTS_FAILED == iReturn)) {
+          /* Bail out */
+          return iReturn;
+        }
+
+        /* We need to ensure that all pending requests are sent */
+        XFlush(pDisplay);
 
         /* Setup the file descriptor set */
         FD_ZERO(&fdsRead);
@@ -113,24 +123,8 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
             break;
         }
 
-        /* Branch on which descriptor became active */
-        if (FD_ISSET(iConnNumber, &fdsRead)) {
-            /* Process X events */
-            /* Exit when we see that server is shutting down */
-            iReturn = winClipboardFlushXEvents(hwnd,
-                                               iWindow, pDisplay, data, atoms);
-
-            winDebug
-                ("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
-                 iReturn);
-
-            if ((WIN_XEVENTS_NOTIFY_DATA == iReturn) || (WIN_XEVENTS_NOTIFY_TARGETS == iReturn) || (WIN_XEVENTS_FAILED == iReturn)) {
-                /* Bail out */
-                return iReturn;
-            }
-        }
-        else {
-            winDebug("winProcessXEventsTimeout - Spurious wake\n");
+        if (!FD_ISSET(iConnNumber, &fdsRead)) {
+            winDebug("winProcessXEventsTimeout - Spurious wake, select() returned %d\n", iReturn);
         }
     }
 
commit c03f9e23c2b75af410b2fc76ca3f1aa9e979dcc4
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Sep 24 15:09:22 2013 +0100

    hw/xwin: Add controls for enabling/disabling monitoring of PRIMARY selection
    
    xwinclip: Add -noprimary option
    Xwin: Add -primary and -noprimary options and tray-menu control
    
    v2:
    Use Bool type for fPrimarySelection
    Add -noprimary to usage message
    Fix indentation in hw/xwin/winwndproc.c
    
    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 eb19dce..6d3f5a5 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -793,6 +793,10 @@ winUseMsg(void)
 #ifdef XWIN_CLIPBOARD
     ErrorF("-nounicodeclipboard\n"
            "\tDo not use Unicode clipboard even if on a NT-based platform.\n");
+
+    ErrorF("-[no]primary\n"
+           "\tWhen clipboard integration is enabled, map the X11 PRIMARY selection\n"
+           "\tto the Windows clipboard. Default is enabled.\n");
 #endif
 
     ErrorF("-refresh rate_in_Hz\n"
diff --git a/hw/xwin/XWin.rc b/hw/xwin/XWin.rc
index a142f30..a54e0fd 100644
--- a/hw/xwin/XWin.rc
+++ b/hw/xwin/XWin.rc
@@ -93,6 +93,7 @@ BEGIN
 	POPUP "TRAYICON_MENU"
 	BEGIN
 		MENUITEM "&Hide Root Window", ID_APP_HIDE_ROOT
+		MENUITEM "Clipboard may use &PRIMARY selection", ID_APP_MONITOR_PRIMARY
 		MENUITEM "&About...", ID_APP_ABOUT
 		MENUITEM SEPARATOR
 		MENUITEM "E&xit...", ID_APP_EXIT
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index a043ac2..15a57db 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -174,7 +174,7 @@ on remote hosts, when that information is available and it's useful to do so.
 .SH OPTIONS CONTROLLING WINDOWS INTEGRATION
 .TP 8
 .B \-[no]clipboard
-Enables [disables] the integration between the Cygwin/X clipboard and
+Enables [disables] the integration between the X11 clipboard and
 \fIWindows\fP clipboard.  The default is enabled.
 .TP 8
 .B "\-emulate3buttons [\fItimeout\fP]"
@@ -200,6 +200,10 @@ prevents the \fIWindows\fP mouse cursor from being drawn on top of the X
 cursor.
 This parameter has no effect unless \fB-swcursor\fP is also specified.
 .TP 8
+.B \-[no]primary
+Clipboard integration may [will not] use the PRIMARY selection.
+The default is enabled.
+.TP 8
 .B \-swcursor
 Disable the usage of the \fIWindows\fP cursor and use the X11 software cursor instead.
 .TP 8
diff --git a/hw/xwin/winclipboard/winclipboard.h b/hw/xwin/winclipboard/winclipboard.h
index 5248130..9c5c568 100644
--- a/hw/xwin/winclipboard/winclipboard.h
+++ b/hw/xwin/winclipboard/winclipboard.h
@@ -33,4 +33,6 @@ void winFixClipboardChain(void);
 
 void winClipboardWindowDestroy(void);
 
+extern Bool fPrimarySelection;
+
 #endif
diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c
index 3dca354..daf11a1 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -44,11 +44,13 @@
 #endif
 
 #include <limits.h>
-#include "internal.h"
 #include <X11/Xutil.h>
 #include <X11/Xatom.h>
 #include <X11/extensions/Xfixes.h>
 
+#include "winclipboard.h"
+#include "internal.h"
+
 /*
  * Constants
  */
@@ -63,6 +65,7 @@
  */
 
 extern int xfixes_event_base;
+Bool fPrimarySelection = TRUE;
 
 /*
  * Local variables
@@ -793,7 +796,7 @@ winClipboardFlushXEvents(HWND hwnd,
                 winDebug("winClipboardFlushXEvents - XFixesSetSelectionOwnerNotify\n");
 
                 /* Save selection owners for monitored selections, ignore other selections */
-                if (e->selection == XA_PRIMARY) {
+                if ((e->selection == XA_PRIMARY) && fPrimarySelection) {
                     MonitorSelection(e, CLIP_OWN_PRIMARY);
                 }
                 else if (e->selection == atomClipboard) {
diff --git a/hw/xwin/winclipboard/xwinclip.c b/hw/xwin/winclipboard/xwinclip.c
index 3677974..856c4dd 100644
--- a/hw/xwin/winclipboard/xwinclip.c
+++ b/hw/xwin/winclipboard/xwinclip.c
@@ -92,6 +92,13 @@ main (int argc, char *argv[])
 	  continue;
 	}
 
+      /* Look for -noprimary */
+      if (!strcmp (argv[i], "-noprimary"))
+	{
+	  fPrimarySelection = False;
+	  continue;
+	}
+
       /* Yack when we find a parameter that we don't know about */
       printf ("Unknown parameter: %s\nExiting.\n", argv[i]);
       exit (1);
diff --git a/hw/xwin/winclipboard/xwinclip.man b/hw/xwin/winclipboard/xwinclip.man
index 822db91..a53dc30 100644
--- a/hw/xwin/winclipboard/xwinclip.man
+++ b/hw/xwin/winclipboard/xwinclip.man
@@ -29,6 +29,9 @@ Specifies the X server display to connect to.
 .TP 8
 .B \-nounicodeclipboard
 Do not use unicode text on the clipboard.
+.TP 8
+.B \-noprimary
+Do not monitor the PRIMARY selection.
 
 .SH "SEE ALSO"
 XWin(1)
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index f6d14a1..e8cccb4 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -37,6 +37,10 @@ from The Open Group.
 #include "winmsg.h"
 #include "winmonitors.h"
 
+#ifdef XWIN_CLIPBOARD
+#include "winclipboard/winclipboard.h"
+#endif
+
 /*
  * Function prototypes
  */
@@ -707,6 +711,26 @@ ddxProcessArgument(int argc, char *argv[], int i)
         /* Indicate that we have processed this argument */
         return 1;
     }
+
+    /*
+     * Look for the '-primary' argument
+     */
+    if (IS_OPTION("-primary")) {
+        fPrimarySelection = TRUE;
+
+        /* Indicate that we have processed this argument */
+        return 1;
+    }
+
+    /*
+     * Look for the '-noprimary' argument
+     */
+    if (IS_OPTION("-noprimary")) {
+        fPrimarySelection = FALSE;
+
+        /* Indicate that we have processed this argument */
+        return 1;
+    }
 #endif
 
     /*
diff --git a/hw/xwin/winresource.h b/hw/xwin/winresource.h
index afbf9f2..37e92ce 100644
--- a/hw/xwin/winresource.h
+++ b/hw/xwin/winresource.h
@@ -43,6 +43,7 @@
 #define ID_APP_HIDE_ROOT	201
 #define ID_APP_ALWAYS_ON_TOP	202
 #define ID_APP_ABOUT		203
+#define ID_APP_MONITOR_PRIMARY	204
 
 #define ID_ABOUT_WEBSITE	303
 
diff --git a/hw/xwin/wintrayicon.c b/hw/xwin/wintrayicon.c
index e0aa7e5..6acc0d7 100644
--- a/hw/xwin/wintrayicon.c
+++ b/hw/xwin/wintrayicon.c
@@ -32,9 +32,13 @@
 #ifdef HAVE_XWIN_CONFIG_H
 #include <xwin-config.h>
 #endif
+
 #include "win.h"
 #include <shellapi.h>
 #include "winprefs.h"
+#ifdef XWIN_CLIPBOARD
+#include "winclipboard/winclipboard.h"
+#endif
 
 /*
  * Initialize the tray icon
@@ -170,6 +174,21 @@ winHandleIconMessage(HWND hwnd, UINT message,
             RemoveMenu(hmenuTray, ID_APP_HIDE_ROOT, MF_BYCOMMAND);
         }
 
+#ifdef XWIN_CLIPBOARD
+        if (g_fClipboard) {
+            /* Set menu state to indicate if 'Monitor Primary' is enabled or not */
+            MENUITEMINFO mii = { 0 };
+            mii.cbSize = sizeof(MENUITEMINFO);
+            mii.fMask = MIIM_STATE;
+            mii.fState = fPrimarySelection ? MFS_CHECKED : MFS_UNCHECKED;
+            SetMenuItemInfo(hmenuTray, ID_APP_MONITOR_PRIMARY, FALSE, &mii);
+        }
+        else {
+            /* Remove 'Monitor Primary' menu item */
+            RemoveMenu(hmenuTray, ID_APP_MONITOR_PRIMARY, MF_BYCOMMAND);
+        }
+#endif
+
         SetupRootMenu(hmenuTray);
 
         /*
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 76e487c..d4a9536 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -1218,6 +1218,12 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             return 0;
 #endif
 
+#ifdef XWIN_CLIPBOARD
+        case ID_APP_MONITOR_PRIMARY:
+            fPrimarySelection = !fPrimarySelection;
+            return 0;
+#endif
+
         case ID_APP_ABOUT:
             /* Display the About box */
             winDisplayAboutDialog(s_pScreenPriv);
commit 851b50419907276fdc781b6be2d42b38849bbd77
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Sep 24 16:02:37 2013 +0100

    hw/xwin: Retrieve TARGETS to avoid unnecessary failing conversion attempts
    
    See http://cygwin.com/ml/cygwin-xfree/2013-07/msg00016.html
    
    It looks like the change in a9aca218f557c723e637287272819a7c17174e1e had some
    unforseen consequences.
    
    If the X11 selection contents are not convertable to COMPOUND_TEXT, UTF8_STRING
    or STRING format (for example, if it is an image), after those conversion
    attempts have failed, we sit in winProcessXEventsTimeout() until the timeout
    expires.
    
    It also seems that maybe gnuplot doesn't respond correctly to this sequence of
    conversion requests and doesn't reply to some of them, which also causes us to
    sit in winProcessXEventsTimeout() until the timeout expires.
    
    The Windows application which has requested the clipboard contents via
    GetClipboardContents() is blocked until we return from WM_RENDERFORMAT, so
    sitting waiting for this timeout to expire should be avoided.
    
    So instead, explicitly request conversion to the TARGETS target, choose
    the most preferred format, and request conversion to that.
    
    Also: if there is no owned selection, there is nothing to paste, so don't bother
    trying to convert it.
    
    v2: Fix compilation with -Werror=declaration-after-statement
    
    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 94956f8..bcf45ca 100644
--- a/hw/xwin/winclipboard/internal.h
+++ b/hw/xwin/winclipboard/internal.h
@@ -39,8 +39,9 @@
 #include <X11/Xwindows.h>
 
 #define WIN_XEVENTS_SUCCESS			0
-#define WIN_XEVENTS_CONVERT			2
-#define WIN_XEVENTS_NOTIFY			3
+#define WIN_XEVENTS_FAILED			1
+#define WIN_XEVENTS_NOTIFY_DATA			3
+#define WIN_XEVENTS_NOTIFY_TARGETS		4
 
 #define WM_WM_REINIT                           (WM_USER + 1)
 
@@ -95,9 +96,15 @@ typedef struct
  * winclipboardxevents.c
  */
 
+typedef struct
+{
+  Bool fUseUnicode;
+  Atom *targetList;
+} ClipboardConversionData;
+
 int
 winClipboardFlushXEvents(HWND hwnd,
-                         Window iWindow, Display * pDisplay, Bool fUnicodeSupport, ClipboardAtoms *atom);
+                         Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atom);
 
 
 Atom
diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c
index c179e3f..be05357 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -123,6 +123,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
     int iSelectError;
     Bool fShutdown = FALSE;
     static Bool fErrorHandlerSet = FALSE;
+    ClipboardConversionData data;
 
     winDebug("winClipboardProc - Hello\n");
 
@@ -260,7 +261,8 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
      *       because there may be events in local data structures
      *       already.
      */
-    winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms);
+    data.fUseUnicode = fUseUnicode;
+    winClipboardFlushXEvents(hwnd, iWindow, pDisplay, &data, &atoms);
 
     /* Pre-flush Windows messages */
     if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
@@ -318,7 +320,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
         /* Branch on which descriptor became active */
         if (FD_ISSET(iConnectionNumber, &fdsRead)) {
             /* Process X events */
-            winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms);
+            winClipboardFlushXEvents(hwnd, iWindow, pDisplay, &data, &atoms);
         }
 
 #ifdef HAS_DEVWINDOWS
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index 165ff55..23a0ac9 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -45,6 +45,7 @@
 
 #include <sys/types.h>
 #include <sys/time.h>
+#include <limits.h>
 
 #include <X11/Xatom.h>
 
@@ -64,7 +65,7 @@
 
 static int
 winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
-                         Bool fUseUnicode, ClipboardAtoms *atoms, int iTimeoutSec)
+                         ClipboardConversionData *data, ClipboardAtoms *atoms, int iTimeoutSec)
 {
     int iConnNumber;
     struct timeval tv;
@@ -117,14 +118,14 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
             /* Process X events */
             /* Exit when we see that server is shutting down */
             iReturn = winClipboardFlushXEvents(hwnd,
-                                               iWindow, pDisplay, fUseUnicode, atoms);
+                                               iWindow, pDisplay, data, atoms);
 
             winDebug
                 ("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
                  iReturn);
 
-            if (WIN_XEVENTS_NOTIFY == iReturn) {
-                /* Bail out if notify processed */
+            if ((WIN_XEVENTS_NOTIFY_DATA == iReturn) || (WIN_XEVENTS_NOTIFY_TARGETS == iReturn) || (WIN_XEVENTS_FAILED == iReturn)) {
+                /* Bail out */
                 return iReturn;
             }
         }
@@ -415,6 +416,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     {
         int iReturn;
         Bool fConvertToUnicode;
+        Bool pasted = FALSE;
+        Atom selection;
+        ClipboardConversionData data;
+        int best_target = 0;
 
         winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n");
 
@@ -424,18 +429,88 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         else
             fConvertToUnicode = (CF_UNICODETEXT == wParam);
 
-        /* Request the selection contents */
-        iReturn = XConvertSelection(pDisplay,
-                                    winClipboardGetLastOwnedSelectionAtom(atoms),
-                                    atoms->atomCompoundText,
-                                    atoms->atomLocalProperty,
-                                    iWindow, CurrentTime);
-        if (iReturn == BadAtom || iReturn == BadWindow) {
-            ErrorF("winClipboardWindowProc - WM_RENDER*FORMAT - "
-                   "XConvertSelection () failed\n");
-            break;
+        selection = winClipboardGetLastOwnedSelectionAtom(atoms);
+        if (selection == None) {
+            ErrorF("winClipboardWindowProc - no monitored selection is owned\n");
+            goto fake_paste;
+        }
+
+        winDebug("winClipboardWindowProc - requesting targets for selection from owner\n");
+
+        /* Request the selection's supported conversion targets */
+        XConvertSelection(pDisplay,
+                          selection,
+                          atoms->atomTargets,
+                          atoms->atomLocalProperty,
+                          iWindow, CurrentTime);
+
+        /* Process X events */
+        data.fUseUnicode = fConvertToUnicode;
+        iReturn = winProcessXEventsTimeout(hwnd,
+                                           iWindow,
+                                           pDisplay,
+                                           &data,
+                                           atoms,
+                                           WIN_POLL_TIMEOUT);
+
+        if (WIN_XEVENTS_NOTIFY_TARGETS != iReturn) {
+            ErrorF
+                ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY_TARGETS\n");
+            goto fake_paste;
+        }
+
+        /* Choose the most preferred target */
+        {
+            struct target_priority
+            {
+                Atom target;
+                unsigned int priority;
+            };
+
+            struct target_priority target_priority_table[] =
+                {
+                    { atoms->atomCompoundText, 0 },
+#ifdef X_HAVE_UTF8_STRING
+                    { atoms->atomUTF8String,   1 },
+#endif
+                    { XA_STRING,               2 },
+                };
+
+            int best_priority = INT_MAX;
+
+            int i,j;
+            for (i = 0 ; data.targetList[i] != 0; i++)
+                {
+                    for (j = 0; j < sizeof(target_priority_table)/sizeof(struct target_priority); j ++)
+                        {
+                            if ((data.targetList[i] == target_priority_table[j].target) &&
+                                (target_priority_table[j].priority < best_priority))
+                                {
+                                    best_target = target_priority_table[j].target;
+                                    best_priority = target_priority_table[j].priority;
+                                }
+                        }
+                }
         }
 
+        free(data.targetList);
+        data.targetList = 0;
+
+        winDebug("winClipboardWindowProc - best target is %d\n", best_target);
+
+        /* No useful targets found */
+        if (best_target == 0)
+          goto fake_paste;
+
+        winDebug("winClipboardWindowProc - requesting selection from owner\n");
+
+        /* Request the selection contents */
+        XConvertSelection(pDisplay,
+                          selection,
+                          best_target,
+                          atoms->atomLocalProperty,
+                          iWindow, CurrentTime);
+
         /* Special handling for WM_RENDERALLFORMATS */
         if (message == WM_RENDERALLFORMATS) {
             /* We must open and empty the clipboard */
@@ -449,40 +524,47 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                 ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
                        "OpenClipboard () failed: %08x\n",
                        GetLastError());
-                break;
             }
 
             if (!EmptyClipboard()) {
                 ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
                        "EmptyClipboard () failed: %08x\n",
                        GetLastError());
-                break;
             }
         }
 
-        /* Process the SelectionNotify event */
+        /* Process X events */
         iReturn = winProcessXEventsTimeout(hwnd,
                                            iWindow,
                                            pDisplay,
-                                           fConvertToUnicode,
+                                           &data,
                                            atoms,
                                            WIN_POLL_TIMEOUT);
 
         /*
-         * The last call to winProcessXEventsTimeout
-         * from above had better have seen a notify event, or else we
-         * are dealing with a buggy or old X11 app.  In these cases we
-         * have to paste some fake data to the Win32 clipboard to
-         * satisfy the requirement that we write something to it.
+         * winProcessXEventsTimeout had better have seen a notify event,
+         * or else we are dealing with a buggy or old X11 app.
          */
-        if (WIN_XEVENTS_NOTIFY != iReturn) {
+        if (WIN_XEVENTS_NOTIFY_DATA != iReturn) {
+            ErrorF
+                ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY_DATA\n");
+        }
+        else {
+            pasted = TRUE;
+        }
+
+         /*
+          * If we couldn't get the data from the X clipboard, we
+          * have to paste some fake data to the Win32 clipboard to
+          * satisfy the requirement that we write something to it.
+          */
+    fake_paste:
+        if (!pasted)
+          {
             /* Paste no data, to satisfy required call to SetClipboardData */
             SetClipboardData(CF_UNICODETEXT, NULL);
             SetClipboardData(CF_TEXT, NULL);
-
-            ErrorF
-                ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY\n");
-        }
+          }
 
         /* Special handling for WM_RENDERALLFORMATS */
         if (message == WM_RENDERALLFORMATS) {
@@ -492,7 +574,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                 ErrorF("winClipboardWindowProc - WM_RENDERALLFORMATS - "
                        "CloseClipboard () failed: %08x\n",
                        GetLastError());
-                break;
             }
         }
 
diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c
index 42e9147..3dca354 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -134,13 +134,59 @@ winClipboardInitMonitoredSelections(void)
     lastOwnedSelectionIndex = CLIP_OWN_NONE;
 }
 
+static int
+winClipboardSelectionNotifyTargets(HWND hwnd, Window iWindow, Display *pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
+{
+  Atom type;
+  int format;
+  unsigned long nitems;
+  unsigned long after;
+  Atom *prop;
+
+  /* Retrieve the selection data and delete the property */
+  int iReturn = XGetWindowProperty(pDisplay,
+                                   iWindow,
+                                   atoms->atomLocalProperty,
+                                   0,
+                                   INT_MAX,
+                                   True,
+                                   AnyPropertyType,
+                                   &type,
+                                   &format,
+                                   &nitems,
+                                   &after,
+                                   (unsigned char **)&prop);
+  if (iReturn != Success) {
+    ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+           "XGetWindowProperty () failed, aborting: %d\n", iReturn);
+  } else {
+    int i;
+    data->targetList = malloc((nitems+1)*sizeof(Atom));
+
+    for (i = 0; i < nitems; i++)
+      {
+        Atom atom = prop[i];
+        char *pszAtomName = XGetAtomName(pDisplay, atom);
+        data->targetList[i] = atom;
+        winDebug("winClipboardFlushXEvents - SelectionNotify - target[%d] %d = %s\n", i, atom, pszAtomName);
+        XFree(pszAtomName);
+      }
+
+    data->targetList[nitems] = 0;
+
+    XFree(prop);
+  }
+
+  return WIN_XEVENTS_NOTIFY_TARGETS;
+}
+
 /*
  * Process any pending X events
  */
 
 int
 winClipboardFlushXEvents(HWND hwnd,
-                         Window iWindow, Display * pDisplay, Bool fUseUnicode, ClipboardAtoms *atoms)
+                         Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
 {
     Atom atomClipboard = atoms->atomClipboard;
     Atom atomLocalProperty = atoms->atomLocalProperty;
@@ -273,7 +319,7 @@ winClipboardFlushXEvents(HWND hwnd,
             fCloseClipboard = TRUE;
 
             /* Check that clipboard format is available */
-            if (fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+            if (data->fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
                 static int count;       /* Hack to stop acroread spamming the log */
                 static HWND lasthwnd;   /* I've not seen any other client get here repeatedly? */
 
@@ -290,7 +336,7 @@ winClipboardFlushXEvents(HWND hwnd,
                 fAbort = TRUE;
                 goto winClipboardFlushXEvents_SelectionRequest_Done;
             }
-            else if (!fUseUnicode && !IsClipboardFormatAvailable(CF_TEXT)) {
+            else if (!data->fUseUnicode && !IsClipboardFormatAvailable(CF_TEXT)) {
                 ErrorF("winClipboardFlushXEvents - CF_TEXT is not "
                        "available from Win32 clipboard.  Aborting.\n");
 
@@ -312,7 +358,7 @@ winClipboardFlushXEvents(HWND hwnd,
                 xiccesStyle = XStringStyle;
 
             /* Get a pointer to the clipboard text, in desired format */
-            if (fUseUnicode) {
+            if (data->fUseUnicode) {
                 /* Retrieve clipboard data */
                 hGlobal = GetClipboardData(CF_UNICODETEXT);
             }
@@ -331,7 +377,7 @@ winClipboardFlushXEvents(HWND hwnd,
             pszGlobalData = (char *) GlobalLock(hGlobal);
 
             /* Convert the Unicode string to UTF8 (MBCS) */
-            if (fUseUnicode) {
+            if (data->fUseUnicode) {
                 iConvertDataLen = WideCharToMultiByte(CP_UTF8,
                                                       0,
                                                       (LPCWSTR) pszGlobalData,
@@ -362,7 +408,7 @@ winClipboardFlushXEvents(HWND hwnd,
             xtpText.nitems = 0;
 
             /* Create the text property from the text list */
-            if (fUseUnicode) {
+            if (data->fUseUnicode) {
 #ifdef X_HAVE_UTF8_STRING
                 iReturn = Xutf8TextListToTextProperty(pDisplay,
                                                       pszTextList,
@@ -507,49 +553,22 @@ winClipboardFlushXEvents(HWND hwnd,
             }
 
             /*
-             * Request conversion of UTF8 and CompoundText targets.
-             */
-            if (event.xselection.property == None) {
-                if (event.xselection.target == XA_STRING) {
-                    winDebug("winClipboardFlushXEvents - SelectionNotify - "
-                             "XA_STRING\n");
+              SelectionNotify with property of None indicates either:
 
-                    return WIN_XEVENTS_CONVERT;
-                }
-                else if (event.xselection.target == atomUTF8String) {
-                    winDebug("winClipboardFlushXEvents - SelectionNotify - "
-                             "Requesting conversion of UTF8 target.\n");
-
-                    XConvertSelection(pDisplay,
-                                      event.xselection.selection,
-                                      XA_STRING,
-                                      atomLocalProperty, iWindow, CurrentTime);
-
-                    /* Process the ConvertSelection event */
-                    XFlush(pDisplay);
-                    return WIN_XEVENTS_CONVERT;
-                }
-#ifdef X_HAVE_UTF8_STRING
-                else if (event.xselection.target == atomCompoundText) {
-                    winDebug("winClipboardFlushXEvents - SelectionNotify - "
-                             "Requesting conversion of CompoundText target.\n");
-
-                    XConvertSelection(pDisplay,
-                                      event.xselection.selection,
-                                      atomUTF8String,
-                                      atomLocalProperty, iWindow, CurrentTime);
-
-                    /* Process the ConvertSelection event */
-                    XFlush(pDisplay);
-                    return WIN_XEVENTS_CONVERT;
-                }
-#endif
-                else {
+              (i) Generated by the X server if no owner for the specified selection exists
+                  (perhaps it's disappeared on us mid-transaction), or
+              (ii) Sent by the selection owner when the requested selection conversion could
+                   not be performed or server errors prevented the conversion data being returned
+            */
+            if (event.xselection.property == None) {
                     ErrorF("winClipboardFlushXEvents - SelectionNotify - "
-                           "Unknown format.  Cannot request conversion, "
-                           "aborting.\n");
-                    break;
+                           "Conversion to format %d refused.\n",
+                           event.xselection.target);
+                    return WIN_XEVENTS_FAILED;
                 }
+
+            if (event.xselection.target == atomTargets) {
+              return winClipboardSelectionNotifyTargets(hwnd, iWindow, pDisplay, data, atoms);
             }
 
             /* Retrieve the selection data and delete the property */
@@ -567,7 +586,7 @@ winClipboardFlushXEvents(HWND hwnd,
             if (iReturn != Success) {
                 ErrorF("winClipboardFlushXEvents - SelectionNotify - "
                        "XGetWindowProperty () failed, aborting: %d\n", iReturn);
-                break;
+                goto winClipboardFlushXEvents_SelectionNotify_Done;
             }
 
             {
@@ -581,7 +600,7 @@ winClipboardFlushXEvents(HWND hwnd,
                 pszAtomName = NULL;
             }
 
-            if (fUseUnicode) {
+            if (data->fUseUnicode) {
 #ifdef X_HAVE_UTF8_STRING
                 /* Convert the text property to a text list */
                 iReturn = Xutf8TextPropertyToTextList(pDisplay,
@@ -648,7 +667,7 @@ winClipboardFlushXEvents(HWND hwnd,
             /* Convert the X clipboard string to DOS format */
             winClipboardUNIXtoDOS(&pszReturnData, strlen(pszReturnData));
 
-            if (fUseUnicode) {
+            if (data->fUseUnicode) {
                 /* Find out how much space needed to convert MBCS to Unicode */
                 iUnicodeLen = MultiByteToWideChar(CP_UTF8,
                                                   0,
@@ -707,7 +726,7 @@ winClipboardFlushXEvents(HWND hwnd,
             }
 
             /* Copy the returned string into the global memory */
-            if (fUseUnicode) {
+            if (data->fUseUnicode) {
                 memcpy(pszGlobalData,
                        pwszUnicodeStr, sizeof(wchar_t) * (iUnicodeLen + 1));
                 free(pwszUnicodeStr);
@@ -724,7 +743,7 @@ winClipboardFlushXEvents(HWND hwnd,
             pszGlobalData = NULL;
 
             /* Push the selection data to the Windows clipboard */
-            if (fUseUnicode)
+            if (data->fUseUnicode)
                 SetClipboardData(CF_UNICODETEXT, hGlobal);
             else
                 SetClipboardData(CF_TEXT, hGlobal);
@@ -754,7 +773,7 @@ winClipboardFlushXEvents(HWND hwnd,
                 SetClipboardData(CF_UNICODETEXT, NULL);
                 SetClipboardData(CF_TEXT, NULL);
             }
-            return WIN_XEVENTS_NOTIFY;
+            return WIN_XEVENTS_NOTIFY_DATA;
 
         case SelectionClear:
             winDebug("SelectionClear - doing nothing\n");
commit 4db1241037e3fe8f0a46888377b8fef40bae9065
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Sep 24 13:30:32 2013 +0100

    hw/xwin: In SelectionNotify, don't pointlessly retrieve just the size of the property
    
    Don't pointlessly retrieve just the size of the property, if we are then going
    to assume we can retrieve the whole property in one request anyhow...
    
    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/xevents.c b/hw/xwin/winclipboard/xevents.c
index f4212b4..42e9147 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -43,6 +43,7 @@
 #undef _XSERVER64
 #endif
 
+#include <limits.h>
 #include "internal.h"
 #include <X11/Xutil.h>
 #include <X11/Xatom.h>
@@ -551,29 +552,12 @@ winClipboardFlushXEvents(HWND hwnd,
                 }
             }
 
-            /* Retrieve the size of the stored data */
-            iReturn = XGetWindowProperty(pDisplay, iWindow, atomLocalProperty, 0, 0,    /* Don't get data, just size */
-                                         False,
-                                         AnyPropertyType,
-                                         &xtpText.encoding,
-                                         &xtpText.format,
-                                         &xtpText.nitems,
-                                         &ulReturnBytesLeft, &xtpText.value);
-            if (iReturn != Success) {
-                ErrorF("winClipboardFlushXEvents - SelectionNotify - "
-                       "XGetWindowProperty () failed, aborting: %d\n", iReturn);
-                break;
-            }
-
-            winDebug("SelectionNotify - returned data %d left %d\n",
-                     xtpText.nitems, ulReturnBytesLeft);
-
             /* Retrieve the selection data and delete the property */
             iReturn = XGetWindowProperty(pDisplay,
                                          iWindow,
                                          atomLocalProperty,
                                          0,
-                                         ulReturnBytesLeft,
+                                         INT_MAX,
                                          True,
                                          AnyPropertyType,
                                          &xtpText.encoding,
commit c5ad92077e7eb32590fafa92d697cc4173f7e57b
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Sep 24 12:23:42 2013 +0100

    hw/xwin: In SelectionNotify, delete the property containing returned data after we have retrieved it
    
    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/xevents.c b/hw/xwin/winclipboard/xevents.c
index 33d52aa..f4212b4 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -568,13 +568,13 @@ winClipboardFlushXEvents(HWND hwnd,
             winDebug("SelectionNotify - returned data %d left %d\n",
                      xtpText.nitems, ulReturnBytesLeft);
 
-            /* Request the selection data */
+            /* Retrieve the selection data and delete the property */
             iReturn = XGetWindowProperty(pDisplay,
                                          iWindow,
                                          atomLocalProperty,
                                          0,
                                          ulReturnBytesLeft,
-                                         False,
+                                         True,
                                          AnyPropertyType,
                                          &xtpText.encoding,
                                          &xtpText.format,
commit ff018d88b9f0fe23ba96c81b53d58532baf4df42
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Oct 2 14:10:50 2014 +0100

    hw/xwin: Remove some redundant clipboard externs, now defined in winglobals.h
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winclipboardwrappers.c b/hw/xwin/winclipboardwrappers.c
index 2679f4f..2e6b632 100644
--- a/hw/xwin/winclipboardwrappers.c
+++ b/hw/xwin/winclipboardwrappers.c
@@ -44,12 +44,6 @@
 DISPATCH_PROC(winProcEstablishConnection);
 
 /*
- * References to external symbols
- */
-
-extern Bool g_fClipboard;
-
-/*
  * Wrapper for internal EstablishConnection function.
  * Initializes internal clients that must not be started until
  * an external client has connected.
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index f2bf05b..f6d14a1 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -38,15 +38,6 @@ from The Open Group.
 #include "winmonitors.h"
 
 /*
- * References to external symbols
- */
-
-#ifdef XWIN_CLIPBOARD
-extern Bool g_fUnicodeClipboard;
-extern Bool g_fClipboard;
-#endif
-
-/*
  * Function prototypes
  */
 
commit 63bb5c5ef16edf652179770294dcca4fc07dc992
Author: Thierry Reding <treding at nvidia.com>
Date:   Wed Oct 29 16:59:27 2014 +0100

    xv: Add missing gcstruct.h include
    
    Commit ea3f3b0786d5 (xv: Move xf86 XV color key helper to core.) added
    code that uses internals of struct _GC. This structure is defined in the
    include/gcstruct.h header which wasn't included by the source file, only
    gc.h was. That caused the following build failure:
    
    	  CC       xvmain.lo
    	Xext/xvmain.c: In function 'XvFillColorKey':
    	Xext/xvmain.c:1114:13: error: dereferencing pointer to incomplete type
    	         (*gc->ops->PolyFillRect) (pDraw, gc, nbox, rects);
    	             ^
    
    Fix this by including the correct header file.
    
    Signed-off-by: Thierry Reding <treding at nvidia.com>
    Tested-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/Xext/xvmain.c b/Xext/xvmain.c
index bc176c8..1f42440 100644
--- a/Xext/xvmain.c
+++ b/Xext/xvmain.c
@@ -86,7 +86,7 @@ SOFTWARE.
 #include "scrnintstr.h"
 #include "windowstr.h"
 #include "pixmapstr.h"
-#include "gc.h"
+#include "gcstruct.h"
 #include "extnsionst.h"
 #include "extinit.h"
 #include "dixstruct.h"
commit 882f2d10d99a04a96afc0ce0c8937e16bec3afb5
Author: Axel Davy <axel.davy at ens.fr>
Date:   Wed Oct 29 13:31:42 2014 +0100

    Fix present_notify to return right away when querying current or past msc.
    
    When the target msc is past or is the current one, we want to get immediate
    feedback. This patch fixes this behaviour.
    
    Signed-off-by: Axel Davy <axel.davy at ens.fr>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/present/present.c b/present/present.c
index 47566c7..a9f2214 100644
--- a/present/present.c
+++ b/present/present.c
@@ -866,7 +866,7 @@ present_pixmap(WindowPtr window,
 
     xorg_list_add(&vblank->event_queue, &present_exec_queue);
     vblank->queued = TRUE;
-    if (target_msc >= crtc_msc) {
+    if ((pixmap && target_msc >= crtc_msc) || (!pixmap && target_msc > crtc_msc)) {
         ret = present_queue_vblank(screen, target_crtc, vblank->event_id, target_msc);
         if (ret != Success) {
             xorg_list_del(&vblank->event_queue);
@@ -929,7 +929,7 @@ present_notify_msc(WindowPtr window,
                           0, 0,
                           NULL,
                           NULL, NULL,
-                          0,
+                          PresentOptionAsync,
                           target_msc, divisor, remainder, NULL, 0);
 }
 
commit 72a0754f4605493fd60471557422f88a97eb356a
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Wed Oct 29 19:19:18 2014 -0700

    xfree86: Bump ABI versions (video: 19, extension: 9)
    
    Among other things, commit b851ca968b7cce6d1a6438c05d3d5c8832249704 added a
    NameWindowPixmap function pointer to ScreenRec, shifting some of the fields
    around.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index b848f53..e68fe9c 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -80,9 +80,9 @@ typedef enum {
  * mask is 0xFFFF0000.
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
-#define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(18, 0)
+#define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(19, 0)
 #define ABI_XINPUT_VERSION	SET_ABI_VERSION(21, 0)
-#define ABI_EXTENSION_VERSION	SET_ABI_VERSION(8, 0)
+#define ABI_EXTENSION_VERSION	SET_ABI_VERSION(9, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
 #define MODINFOSTRING1	0xef23fdc5


More information about the Xquartz-changes mailing list