[Xquartz-changes] xserver: Branch 'server-1.14-apple' - 241 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Tue Oct 29 10:32:04 PDT 2013


Rebased ref, commits from common ancestor:
commit b69ceb5c616bc4676c7688b0fcd5b849ee715511
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue Dec 18 01:03:38 2012 -0800

    fb: Revert fb changes that broke XQuartz
    
        http://bugs.freedesktop.org/show_bug.cgi?id=26124
    
    Revert "Use new pixman_glyph_cache_t API that will be in pixman 0.28.0"
    
    This reverts commit 9cbcb5bd6a5360a128d15b77a02d8d3351f74366.

diff --git a/configure.ac b/configure.ac
index 92aa25a..3ff559f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -811,7 +811,7 @@ LIBPCIACCESS="pciaccess >= 0.12.901"
 LIBUDEV="libudev >= 143"
 LIBSELINUX="libselinux >= 2.0.86"
 LIBDBUS="dbus-1 >= 1.0"
-LIBPIXMAN="pixman-1 >= 0.27.2"
+LIBPIXMAN="pixman-1 >= 0.21.8"
 
 dnl Pixman is always required, but we separate it out so we can link
 dnl specific modules against it
diff --git a/fb/fb.h b/fb/fb.h
index 895b148..cc5759c 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -1344,9 +1344,6 @@ extern _X_EXPORT void
 extern _X_EXPORT Bool
  fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats);
 
-extern _X_EXPORT void
-fbDestroyGlyphCache(void);
-
 /*
  * fbpixmap.c
  */
diff --git a/fb/fbpict.c b/fb/fbpict.c
index 80c2a91..dc0ca3c 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -65,156 +65,6 @@ fbComposite(CARD8 op,
     free_pixman_pict(pDst, dest);
 }
 
-static pixman_glyph_cache_t *glyphCache;
-
-void
-fbDestroyGlyphCache(void)
-{
-    if (glyphCache)
-    {
-	pixman_glyph_cache_destroy (glyphCache);
-	glyphCache = NULL;
-    }
-}
-
-static void
-fbUnrealizeGlyph(ScreenPtr pScreen,
-		 GlyphPtr pGlyph)
-{
-    if (glyphCache)
-	pixman_glyph_cache_remove (glyphCache, pGlyph, NULL);
-}
-
-static void
-fbGlyphs(CARD8 op,
-	 PicturePtr pSrc,
-	 PicturePtr pDst,
-	 PictFormatPtr maskFormat,
-	 INT16 xSrc,
-	 INT16 ySrc, int nlist,
-	 GlyphListPtr list,
-	 GlyphPtr *glyphs)
-{
-#define N_STACK_GLYPHS 512
-    ScreenPtr pScreen = pDst->pDrawable->pScreen;
-    pixman_glyph_t stack_glyphs[N_STACK_GLYPHS];
-    pixman_glyph_t *pglyphs = stack_glyphs;
-    pixman_image_t *srcImage, *dstImage;
-    int srcXoff, srcYoff, dstXoff, dstYoff;
-    GlyphPtr glyph;
-    int n_glyphs;
-    int x, y;
-    int i, n;
-    int xDst = list->xOff, yDst = list->yOff;
-
-    miCompositeSourceValidate(pSrc);
-    
-    n_glyphs = 0;
-    for (i = 0; i < nlist; ++i)
-	n_glyphs += list[i].len;
-
-    if (!glyphCache)
-	glyphCache = pixman_glyph_cache_create();
-
-    pixman_glyph_cache_freeze (glyphCache);
-    
-    if (n_glyphs > N_STACK_GLYPHS) {
-	if (!(pglyphs = malloc (n_glyphs * sizeof (pixman_glyph_t))))
-	    goto out;
-    }
-    
-    i = 0;
-    x = y = 0;
-    while (nlist--) {
-        x += list->xOff;
-        y += list->yOff;
-        n = list->len;
-        while (n--) {
-	    const void *g;
-
-            glyph = *glyphs++;
-
-	    if (!(g = pixman_glyph_cache_lookup (glyphCache, glyph, NULL))) {
-		pixman_image_t *glyphImage;
-		PicturePtr pPicture;
-		int xoff, yoff;
-
-		pPicture = GetGlyphPicture(glyph, pScreen);
-		if (!pPicture) {
-		    n_glyphs--;
-		    goto next;
-		}
-
-		if (!(glyphImage = image_from_pict(pPicture, FALSE, &xoff, &yoff)))
-		    goto out;
-
-		g = pixman_glyph_cache_insert(glyphCache, glyph, NULL,
-					      glyph->info.x,
-					      glyph->info.y,
-					      glyphImage);
-
-		free_pixman_pict(pPicture, glyphImage);
-
-		if (!g)
-		    goto out;
-	    }
-
-	    pglyphs[i].x = x;
-	    pglyphs[i].y = y;
-	    pglyphs[i].glyph = g;
-	    i++;
-
-	next:
-            x += glyph->info.xOff;
-            y += glyph->info.yOff;
-	}
-	list++;
-    }
-
-    if (!(srcImage = image_from_pict(pSrc, FALSE, &srcXoff, &srcYoff)))
-	goto out;
-
-    if (!(dstImage = image_from_pict(pDst, TRUE, &dstXoff, &dstYoff)))
-	goto out_free_src;
-
-    if (maskFormat) {
-	pixman_format_code_t format;
-	pixman_box32_t extents;
-	int x, y;
-
-	format = maskFormat->format | (maskFormat->depth << 24);
-
-	pixman_glyph_get_extents(glyphCache, n_glyphs, pglyphs, &extents);
-
-	x = extents.x1;
-	y = extents.y1;
-
-	pixman_composite_glyphs(op, srcImage, dstImage, format,
-				xSrc + srcXoff + xDst, ySrc + srcYoff + yDst,
-				x, y,
-				x + dstXoff, y + dstYoff,
-				extents.x2 - extents.x1,
-				extents.y2 - extents.y1,
-				glyphCache, n_glyphs, pglyphs);
-    }
-    else {
-	pixman_composite_glyphs_no_mask(op, srcImage, dstImage,
-					xSrc + srcXoff - xDst, ySrc + srcYoff - yDst,
-					dstXoff, dstYoff,
-					glyphCache, n_glyphs, pglyphs);
-    }
-
-    free_pixman_pict(pDst, dstImage);
-
-out_free_src:
-    free_pixman_pict(pSrc, srcImage);
-
-out:
-    pixman_glyph_cache_thaw(glyphCache);
-    if (pglyphs != stack_glyphs)
-	free(pglyphs);
-}
-
 static pixman_image_t *
 create_solid_fill_image(PicturePtr pict)
 {
@@ -473,8 +323,7 @@ fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
         return FALSE;
     ps = GetPictureScreen(pScreen);
     ps->Composite = fbComposite;
-    ps->Glyphs = fbGlyphs;
-    ps->UnrealizeGlyph = fbUnrealizeGlyph;
+    ps->Glyphs = miGlyphs;
     ps->CompositeRects = miCompositeRects;
     ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
     ps->Trapezoids = fbTrapezoids;
diff --git a/fb/fbscreen.c b/fb/fbscreen.c
index f9080a4..7c7d656 100644
--- a/fb/fbscreen.c
+++ b/fb/fbscreen.c
@@ -32,7 +32,6 @@ fbCloseScreen(ScreenPtr pScreen)
     int d;
     DepthPtr depths = pScreen->allowedDepths;
 
-    fbDestroyGlyphCache();
     for (d = 0; d < pScreen->numDepths; d++)
         free(depths[d].vids);
     free(depths);
commit 75d5afd9b9cc71fbe49daa52e4994315dc18f860
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Fri Feb 12 19:48:52 2010 -0800

    fb: Revert fb changes that broke XQuartz
    
    http://bugs.freedesktop.org/show_bug.cgi?id=26124
    
    Revert "Fix source pictures getting random transforms after 2d6a8f668342a5190cdf43b5."
    Revert "fb: Adjust transform or composite coordinates for pixman operations"
    
    http://bugs.freedesktop.org/26124
    
    This reverts commit a72c65e9176c51de95db2fdbf4c5d946a4911695.
    This reverts commit a6bd5d2e482a5aa84acb3d4932e2a166d8670ef1.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/fb/fb.h b/fb/fb.h
index b869d12..895b148 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -1686,8 +1686,7 @@ fbFillRegionSolid(DrawablePtr pDrawable,
                   RegionPtr pRegion, FbBits and, FbBits xor);
 
 extern _X_EXPORT pixman_image_t *image_from_pict(PicturePtr pict,
-                                                 Bool has_clip,
-                                                 int *xoff, int *yoff);
+                                                 Bool has_clip);
 
 extern _X_EXPORT void free_pixman_pict(PicturePtr, pixman_image_t *);
 
diff --git a/fb/fbpict.c b/fb/fbpict.c
index 2804ff4..80c2a91 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -46,23 +46,18 @@ fbComposite(CARD8 op,
             INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
 {
     pixman_image_t *src, *mask, *dest;
-    int src_xoff, src_yoff;
-    int msk_xoff, msk_yoff;
-    int dst_xoff, dst_yoff;
-
     miCompositeSourceValidate(pSrc);
     if (pMask)
         miCompositeSourceValidate(pMask);
 
-    src = image_from_pict(pSrc, FALSE, &src_xoff, &src_yoff);
-    mask = image_from_pict(pMask, FALSE, &msk_xoff, &msk_yoff);
-    dest = image_from_pict(pDst, TRUE, &dst_xoff, &dst_yoff);
+    src = image_from_pict(pSrc, TRUE);
+    mask = image_from_pict(pMask, TRUE);
+    dest = image_from_pict(pDst, TRUE);
 
     if (src && dest && !(pMask && !mask)) {
         pixman_image_composite(op, src, mask, dest,
-                               xSrc + src_xoff, ySrc + src_yoff,
-                               xMask + msk_xoff, yMask + msk_yoff,
-                               xDst + dst_xoff, yDst + dst_yoff, width, height);
+                               xSrc, ySrc, xMask, yMask, xDst, yDst,
+                               width, height);
     }
 
     free_pixman_pict(pSrc, src);
@@ -293,20 +288,22 @@ create_conical_gradient_image(PictGradient * gradient)
 }
 
 static pixman_image_t *
-create_bits_picture(PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+create_bits_picture(PicturePtr pict, Bool has_clip)
 {
-    PixmapPtr pixmap;
     FbBits *bits;
     FbStride stride;
-    int bpp;
+    int bpp, xoff, yoff;
     pixman_image_t *image;
 
-    fbGetDrawablePixmap(pict->pDrawable, pixmap, *xoff, *yoff);
-    fbGetPixmapBitsData(pixmap, bits, stride, bpp);
+    fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
+
+    bits = (FbBits*)((CARD8*)bits +
+                     (pict->pDrawable->y + yoff) * stride * sizeof(FbBits) +
+                     (pict->pDrawable->x + xoff) * (bpp / 8));
 
     image = pixman_image_create_bits((pixman_format_code_t) pict->format,
-                                     pixmap->drawable.width,
-                                     pixmap->drawable.height, (uint32_t *) bits,
+                                     pict->pDrawable->width,
+                                     pict->pDrawable->height, (uint32_t *) bits,
                                      stride * sizeof(FbStride));
 
     if (!image)
@@ -333,57 +330,31 @@ create_bits_picture(PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
         if (pict->clientClipType != CT_NONE)
             pixman_image_set_has_client_clip(image, TRUE);
 
-        if (*xoff || *yoff)
-            pixman_region_translate(pict->pCompositeClip, *xoff, *yoff);
+        pixman_region_translate (pict->pCompositeClip, - pict->pDrawable->x, - pict->pDrawable->y);
 
         pixman_image_set_clip_region(image, pict->pCompositeClip);
 
-        if (*xoff || *yoff)
-            pixman_region_translate(pict->pCompositeClip, -*xoff, -*yoff);
+        pixman_region_translate (pict->pCompositeClip, pict->pDrawable->x, pict->pDrawable->y);
     }
 
     /* Indexed table */
     if (pict->pFormat->index.devPrivate)
         pixman_image_set_indexed(image, pict->pFormat->index.devPrivate);
 
-    /* Add in drawable origin to position within the image */
-    *xoff += pict->pDrawable->x;
-    *yoff += pict->pDrawable->y;
-
     return image;
 }
 
 static pixman_image_t *image_from_pict_internal(PicturePtr pict, Bool has_clip,
-                                                int *xoff, int *yoff,
                                                 Bool is_alpha_map);
 
 static void
-set_image_properties(pixman_image_t * image, PicturePtr pict, Bool has_clip,
-                     int *xoff, int *yoff, Bool is_alpha_map)
+set_image_properties(pixman_image_t * image, PicturePtr pict, Bool is_alpha_map)
 {
     pixman_repeat_t repeat;
     pixman_filter_t filter;
 
     if (pict->transform) {
-        /* For source images, adjust the transform to account
-         * for the drawable offset within the pixman image,
-         * then set the offset to 0 as it will be used
-         * to compute positions within the transformed image.
-         */
-        if (!has_clip) {
-            struct pixman_transform adjusted;
-
-            adjusted = *pict->transform;
-            pixman_transform_translate(&adjusted,
-                                       NULL,
-                                       pixman_int_to_fixed(*xoff),
-                                       pixman_int_to_fixed(*yoff));
-            pixman_image_set_transform(image, &adjusted);
-            *xoff = 0;
-            *yoff = 0;
-        }
-        else
-            pixman_image_set_transform(image, pict->transform);
+        pixman_image_set_transform(image, pict->transform);
     }
 
     switch (pict->repeatType) {
@@ -411,10 +382,8 @@ set_image_properties(pixman_image_t * image, PicturePtr pict, Bool has_clip,
      * as the alpha map for this operation
      */
     if (pict->alphaMap && !is_alpha_map) {
-        int alpha_xoff, alpha_yoff;
         pixman_image_t *alpha_map =
-            image_from_pict_internal(pict->alphaMap, FALSE, &alpha_xoff,
-                                     &alpha_yoff, TRUE);
+            image_from_pict_internal(pict->alphaMap, TRUE, TRUE);
 
         pixman_image_set_alpha_map(image, alpha_map, pict->alphaOrigin.x,
                                    pict->alphaOrigin.y);
@@ -448,8 +417,7 @@ set_image_properties(pixman_image_t * image, PicturePtr pict, Bool has_clip,
 }
 
 static pixman_image_t *
-image_from_pict_internal(PicturePtr pict, Bool has_clip, int *xoff, int *yoff,
-                         Bool is_alpha_map)
+image_from_pict_internal(PicturePtr pict, Bool has_clip, Bool is_alpha_map)
 {
     pixman_image_t *image = NULL;
 
@@ -457,7 +425,7 @@ image_from_pict_internal(PicturePtr pict, Bool has_clip, int *xoff, int *yoff,
         return NULL;
 
     if (pict->pDrawable) {
-        image = create_bits_picture(pict, has_clip, xoff, yoff);
+        image = create_bits_picture(pict, has_clip);
     }
     else if (pict->pSourcePict) {
         SourcePict *sp = pict->pSourcePict;
@@ -475,19 +443,17 @@ image_from_pict_internal(PicturePtr pict, Bool has_clip, int *xoff, int *yoff,
             else if (sp->type == SourcePictTypeConical)
                 image = create_conical_gradient_image(gradient);
         }
-        *xoff = *yoff = 0;
     }
 
     if (image)
-        set_image_properties(image, pict, has_clip, xoff, yoff, is_alpha_map);
-
+        set_image_properties (image, pict, is_alpha_map);
     return image;
 }
 
 pixman_image_t *
-image_from_pict(PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+image_from_pict (PicturePtr pict, Bool has_clip)
 {
-    return image_from_pict_internal(pict, has_clip, xoff, yoff, FALSE);
+    return image_from_pict_internal (pict, has_clip, FALSE);
 }
 
 void
diff --git a/fb/fbtrap.c b/fb/fbtrap.c
index bf82f8f..0145ce9 100644
--- a/fb/fbtrap.c
+++ b/fb/fbtrap.c
@@ -36,13 +36,12 @@ fbAddTraps(PicturePtr pPicture,
            INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
 {
     pixman_image_t *image;
-    int dst_xoff, dst_yoff;
 
-    if (!(image = image_from_pict(pPicture, FALSE, &dst_xoff, &dst_yoff)))
-        return;
-
-    pixman_add_traps(image, x_off + dst_xoff, y_off + dst_yoff,
-                     ntrap, (pixman_trap_t *) traps);
+    if (!(image = image_from_pict (pPicture, FALSE)))
+	return;
+    
+    pixman_add_traps(image, x_off, y_off,
+                     ntrap, (pixman_trap_t *)traps);
 
     free_pixman_pict(pPicture, image);
 }
@@ -52,13 +51,12 @@ fbRasterizeTrapezoid(PicturePtr pPicture,
                      xTrapezoid * trap, int x_off, int y_off)
 {
     pixman_image_t *image;
-    int dst_xoff, dst_yoff;
 
-    if (!(image = image_from_pict(pPicture, FALSE, &dst_xoff, &dst_yoff)))
+    if (!(image = image_from_pict (pPicture, FALSE)))
         return;
 
-    pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) trap,
-                               x_off + dst_xoff, y_off + dst_yoff);
+    pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *)trap,
+                               x_off, y_off);
 
     free_pixman_pict(pPicture, image);
 }
@@ -68,14 +66,12 @@ fbAddTriangles(PicturePtr pPicture,
                INT16 x_off, INT16 y_off, int ntri, xTriangle * tris)
 {
     pixman_image_t *image;
-    int dst_xoff, dst_yoff;
 
-    if (!(image = image_from_pict(pPicture, FALSE, &dst_xoff, &dst_yoff)))
+    if (!(image = image_from_pict (pPicture, FALSE)))
         return;
-
-    pixman_add_triangles(image,
-                         dst_xoff + x_off, dst_yoff + y_off,
-                         ntri, (pixman_triangle_t *) tris);
+    
+    pixman_add_triangles(image, x_off, y_off, ntri,
+                         (pixman_triangle_t *)tris);
 
     free_pixman_pict(pPicture, image);
 }
@@ -98,13 +94,11 @@ fbShapes(CompositeShapesFunc composite,
          int16_t ySrc, int nshapes, int shape_size, const uint8_t * shapes)
 {
     pixman_image_t *src, *dst;
-    int src_xoff, src_yoff;
-    int dst_xoff, dst_yoff;
 
     miCompositeSourceValidate(pSrc);
 
-    src = image_from_pict(pSrc, FALSE, &src_xoff, &src_yoff);
-    dst = image_from_pict(pDst, TRUE, &dst_xoff, &dst_yoff);
+    src = image_from_pict(pSrc, FALSE);
+    dst = image_from_pict(pDst, TRUE);
 
     if (src && dst) {
         pixman_format_code_t format;
@@ -121,9 +115,8 @@ fbShapes(CompositeShapesFunc composite,
 
             for (i = 0; i < nshapes; ++i) {
                 composite(op, src, dst, format,
-                          xSrc + src_xoff,
-                          ySrc + src_yoff,
-                          dst_xoff, dst_yoff, 1, shapes + i * shape_size);
+                          xSrc, ySrc, 0, 0, 
+                          1, shapes + i * shape_size);
             }
         }
         else {
@@ -143,8 +136,8 @@ fbShapes(CompositeShapesFunc composite,
             }
 
             composite(op, src, dst, format,
-                      xSrc + src_xoff,
-                      ySrc + src_yoff, dst_xoff, dst_yoff, nshapes, shapes);
+                      xSrc, ySrc, 0, 0,
+                      nshapes, shapes);
         }
 
         DamageRegionProcessPending(pDst->pDrawable);
commit ae18f114cb8a47d75ebc54e1b0c5ffaac58b1bc6
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Fri Apr 30 13:08:25 2010 -0700

    Workaround the GC clipping problem in miPaintWindow and add some debugging output.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/mi/miexpose.c b/mi/miexpose.c
index 8b7c93f..3e972f7 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -489,7 +489,8 @@ void RootlessSetPixmapOfAncestors(WindowPtr pWin);
 void RootlessStartDrawing(WindowPtr pWin);
 void RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn);
 Bool IsFramedWindow(WindowPtr pWin);
-#endif
+#include "../fb/fb.h"
+#endif 
 
 void
 miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
@@ -518,23 +519,37 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     Bool solid = TRUE;
     DrawablePtr drawable = &pWin->drawable;
 
+#ifdef XQUARTZ_CLIP_DEBUG
+    ErrorF("START %d BS %d (pR = %ld)\n", what, pWin->backgroundState, ParentRelative);
+    ErrorF("      Rgn: %d %d %d %d\n", prgn->extents.x1, prgn->extents.y1,
+	                               prgn->extents.x2 - prgn->extents.x1,
+	                               prgn->extents.y2 - prgn->extents.y1);
+    ErrorF("      Win: %d %d (%d %d) %d %d\n", pWin->origin.x, pWin->origin.y,
+	                                       pWin->winSize.extents.x1, pWin->winSize.extents.y1,
+	                                       pWin->winSize.extents.x2 - pWin->winSize.extents.x1,
+					       pWin->winSize.extents.y2 - pWin->winSize.extents.y1);
+    ErrorF("     Draw: %d %d %d %d\n", pWin->drawable.x, pWin->drawable.y,
+				       pWin->drawable.width, pWin->drawable.height);
+#endif
+
 #ifdef ROOTLESS
     if (!drawable || drawable->type == UNDRAWABLE_WINDOW)
         return;
+#endif
+    
+    if (what == PW_BACKGROUND)
+    {
+#ifdef ROOTLESS
+        if(IsFramedWindow(pWin)) {
+            RootlessStartDrawing(pWin);
+            RootlessDamageRegion(pWin, prgn);
 
-    if (IsFramedWindow(pWin)) {
-        RootlessStartDrawing(pWin);
-        RootlessDamageRegion(pWin, prgn);
-
-        if (pWin->backgroundState == ParentRelative) {
-            if ((what == PW_BACKGROUND) ||
-                (what == PW_BORDER && !pWin->borderIsPixel))
+            if(pWin->backgroundState == ParentRelative) {
                 RootlessSetPixmapOfAncestors(pWin);
+            }
         }
-    }
 #endif
 
-    if (what == PW_BACKGROUND) {
         while (pWin->backgroundState == ParentRelative)
             pWin = pWin->parent;
 
@@ -559,6 +574,18 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     else {
         PixmapPtr pixmap;
 
+#ifdef ROOTLESS
+	if(IsFramedWindow(pWin)) {
+	    RootlessStartDrawing(pWin);
+	    RootlessDamageRegion(pWin, prgn);
+	    
+	    if(!pWin->borderIsPixel &&
+		pWin->backgroundState == ParentRelative) {
+		RootlessSetPixmapOfAncestors(pWin);
+	    }
+	}
+#endif
+
         tile_x_off = drawable->x;
         tile_y_off = drawable->y;
 
@@ -567,6 +594,12 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
             return;
         pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable);
         drawable = &pixmap->drawable;
+
+#ifdef XQUARTZ_CLIP_DEBUG
+        ErrorF("     Draw: %d %d %d %d\n",
+               drawable->x, drawable->y, drawable->width, drawable->height);    
+#endif
+	
 #ifdef COMPOSITE
         draw_x_off = pixmap->screen_x;
         draw_y_off = pixmap->screen_y;
@@ -629,6 +662,57 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     ChangeGC(NullClient, pGC, gcmask, gcval);
     ValidateGC(drawable, pGC);
 
+#ifdef XQUARTZ_CLIP_DEBUG
+    ErrorF("       GC: %d %d %d %d\n",
+	   pGC->pCompositeClip->extents.x1, pGC->pCompositeClip->extents.y1,
+	   pGC->pCompositeClip->extents.x2 - pGC->pCompositeClip->extents.x1,
+	   pGC->pCompositeClip->extents.y2 - pGC->pCompositeClip->extents.y1);
+#endif
+    
+#ifdef XQUARTZ
+    /* Looks like our clipping isn't set right for some reason:
+     * http://xquartz.macosforge.org/trac/ticket/290
+     */
+    if(what == PW_BORDER) {
+
+#if 0
+	if(solid) {
+#if 1
+	    fbFillRegionSolid(&pWin->drawable,
+			      prgn,
+			      0,
+			      fbReplicatePixel(fill.pixel,
+					       pWin->drawable.bitsPerPixel));
+#else
+	    fbFillRegionSolid(drawable,
+			      prgn,
+			      0,
+			      fbReplicatePixel(fill.pixel,
+					       drawable->bitsPerPixel));
+#endif
+	    return;
+	}
+#endif
+    
+	pGC->pCompositeClip->extents.x1 += prgn->extents.x1;
+	pGC->pCompositeClip->extents.y1 += prgn->extents.y1;
+	pGC->pCompositeClip->extents.x2 += prgn->extents.x1;
+	pGC->pCompositeClip->extents.y2 += prgn->extents.y1;
+	
+	if(pGC->pCompositeClip->extents.x2 > drawable->pScreen->width)
+	    pGC->pCompositeClip->extents.x2 = drawable->pScreen->width;
+	if(pGC->pCompositeClip->extents.y2 > drawable->pScreen->height)
+	    pGC->pCompositeClip->extents.y2 = drawable->pScreen->height;
+    }
+#endif
+
+#ifdef XQUARTZ_CLIP_DEBUG
+    ErrorF("       GC: %d %d %d %d\n",
+	   pGC->pCompositeClip->extents.x1, pGC->pCompositeClip->extents.y1,
+	   pGC->pCompositeClip->extents.x2 - pGC->pCompositeClip->extents.x1,
+	   pGC->pCompositeClip->extents.y2 - pGC->pCompositeClip->extents.y1);    
+#endif
+
     numRects = RegionNumRects(prgn);
     pbox = RegionRects(prgn);
     for (i = numRects; --i >= 0; pbox++, prect++) {
commit f72f89b1eefefc84d2b673dbb363dabb843e08de
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Fri Jan 13 12:00:57 2012 -0800

    sdksyms.sh: Use CPPFLAGS, not CFLAGS
    
    CFLAGS can include flags which are not useful to the preprocessor
    or can even cause it to fail.  This fixes a build issue on darwin
    when building for more than one architecture.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index c3899b5..4f48b85 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -38,7 +38,7 @@ DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
 bin_PROGRAMS = Xorg
 nodist_Xorg_SOURCES = sdksyms.c
 
-AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
+AM_CPPFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
 INCLUDES = $(XORG_INCS) -I$(srcdir)/parser -I$(top_srcdir)/miext/cw \
 	-I$(srcdir)/ddc -I$(srcdir)/i2c -I$(srcdir)/modes -I$(srcdir)/ramdac \
 	-I$(srcdir)/dri -I$(srcdir)/dri2
@@ -115,7 +115,7 @@ CLEANFILES = sdksyms.c sdksyms.dep
 EXTRA_DIST += sdksyms.sh
 
 sdksyms.dep sdksyms.c: sdksyms.sh
-	$(AM_V_GEN)CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $(srcdir)/sdksyms.sh $(top_srcdir) $(CFLAGS) $(AM_CFLAGS) $(INCLUDES)
+	$(AM_V_GEN)CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $(srcdir)/sdksyms.sh $(top_srcdir) $(CPPFLAGS) $(AM_CPPFLAGS) $(INCLUDES)
 
 SDKSYMS_DEP = sdksyms.dep
 include $(SDKSYMS_DEP)
commit ca11bdc890f14fbe2ab4c32fb7a36ae50672b81a
Author: Matt Dew <marcoz at osource.org>
Date:   Sat Oct 26 13:51:05 2013 -0600

    Bump version from 1.14.3 to 1.14.3.901.

diff --git a/configure.ac b/configure.ac
index 8ac9cb5..92aa25a 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.14.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-09-12"
-RELEASE_NAME="September Rain"
+AC_INIT([xorg-server], 1.14.3.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-10-26"
+RELEASE_NAME="October Flood-rc1"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
commit 07069f5d71dd0869fe9a6f9ab87c467e7ec75011
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Oct 17 12:02:27 2013 +1000

    sync: split updating and triggering a counter up
    
    Now that the brackets are always the nearest change points (regardless of
    transition) we need to update the counters whenever we check for any updates.
    
    Otherwise we end up with a situation where counter->value is out of date and
    an alarm doesn't trigger because we're still using the value from last time
    something actually triggered.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 2523a445a09a75a8baf642608d099a5e12d5437f)

diff --git a/Xext/sync.c b/Xext/sync.c
index 7d6b4e0..9b4d0a4 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -699,6 +699,14 @@ SyncAwaitTriggerFired(SyncTrigger * pTrigger)
     FreeResource(pAwaitUnion->header.delete_id, RT_NONE);
 }
 
+static CARD64
+SyncUpdateCounter(SyncCounter *pCounter, CARD64 newval)
+{
+    CARD64 oldval = pCounter->value;
+    pCounter->value = newval;
+    return oldval;
+}
+
 /*  This function should always be used to change a counter's value so that
  *  any triggers depending on the counter will be checked.
  */
@@ -708,8 +716,7 @@ SyncChangeCounter(SyncCounter * pCounter, CARD64 newval)
     SyncTriggerList *ptl, *pnext;
     CARD64 oldval;
 
-    oldval = pCounter->value;
-    pCounter->value = newval;
+    oldval = SyncUpdateCounter(pCounter, newval);
 
     /* run through triggers to see if any become true */
     for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) {
@@ -2712,6 +2719,8 @@ IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, X
         (less && XSyncValueLessOrEqual(idle, *less))) {
         SyncChangeCounter(counter, idle);
     }
+    else
+        SyncUpdateCounter(counter, idle);
 }
 
 static void
commit fa5e4dcfb6236b8be0bf57edd1ff4f59cb2f8f6b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Oct 16 16:31:15 2013 +1000

    sync: always set the brackets (#59644)
    
    The current code sets bracket_greater to the first trigger after the current
    value, and bracket_less to the last trigger before the current value.
    
    For example, the idle timer with three negative and three positive transitions
    would set this:
    
             nt1       nt2                 nt3
    |--------|------|--|------- idle --|---|--|-----> t
                   pt1                pt2    pt3
    bracket_less == nt2
    bracket_greater == pt2
    
    This is an optimization so we can skip code paths in the block/wakeup handlers
    if the current value doesn't meet any of the trigger requirements. Those
    handlers largely do a
       if (bracket_less is less than current value &&
           bracket_greater is greater than current value)
            return, nothing to do
    
    However, unless the bracket values are updated at the correct time, the
    following may happen:
    
                                          nt
    |--------------|---------- idle ------|--------> t
                   pt
    
    In this case, neither bracket is set, we're past the pos transition and not
    yet at the neg transition. idle may now go past nt, but the brackets are not
    updated. If idle is then reset to 0, no alarm is triggered for nt. Likewise,
    idle may now go past pt and no alarm is triggered.
    
    Changing an alarm or triggering an alarm will re-calculate the brackets, so
    this bug is somewhat random. If any other client triggers an alarm when the
    brackets are wrongly NULL, the recalculation will set them this bug may not
    appear.
    
    This patch changes the behavior, so that the brackets are always the nearest
    positive or negative transitions to the current counter value. In the example
    above, nt will trigger a wakeup and a re-calculation of the brackets, so that
    going past it in the negative direction will then cause the proper alarm
    triggers.
    
    Or, in Keith's words:
    
      Timer currently past a positive trigger
          No bracket values, because no trigger in range
    
      Timer moves backwards before the positive trigger
          Brackets not reset, even though there is now a trigger in range
    
      Timer moves forward past the positive trigger
          Trigger doesn't fire because brackets not set
    
    Setting the LT bracket in this case will cause everything to get
    re-evaluated when the sync value moves backwards before the trigger
    value.
    
    X.Org Bug 59644 <http://bugs.freedesktop.org/show_bug.cgi?id=59644>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit e57ec99b03b2ad840c384a97ab2766ce9da0f5cc)

diff --git a/Xext/sync.c b/Xext/sync.c
index 2b8a794..7d6b4e0 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -1019,6 +1019,11 @@ SyncComputeBracketValues(SyncCounter * pCounter)
                 psci->bracket_greater = pTrigger->test_value;
                 pnewgtval = &psci->bracket_greater;
             }
+            else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
+                     XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
+                    psci->bracket_less = pTrigger->test_value;
+                    pnewltval = &psci->bracket_less;
+            }
         }
         else if (pTrigger->test_type == XSyncNegativeComparison &&
                  ct != XSyncCounterNeverDecreases) {
@@ -1028,6 +1033,11 @@ SyncComputeBracketValues(SyncCounter * pCounter)
                 psci->bracket_less = pTrigger->test_value;
                 pnewltval = &psci->bracket_less;
             }
+            else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
+                     XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
+                    psci->bracket_greater = pTrigger->test_value;
+                    pnewgtval = &psci->bracket_greater;
+            }
         }
         else if (pTrigger->test_type == XSyncNegativeTransition &&
                  ct != XSyncCounterNeverIncreases) {
@@ -1041,6 +1051,11 @@ SyncComputeBracketValues(SyncCounter * pCounter)
                     psci->bracket_less = pTrigger->test_value;
                     pnewltval = &psci->bracket_less;
             }
+            else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
+                     XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
+                    psci->bracket_greater = pTrigger->test_value;
+                    pnewgtval = &psci->bracket_greater;
+            }
         }
         else if (pTrigger->test_type == XSyncPositiveTransition &&
                  ct != XSyncCounterNeverDecreases) {
@@ -1055,6 +1070,11 @@ SyncComputeBracketValues(SyncCounter * pCounter)
                     psci->bracket_greater = pTrigger->test_value;
                     pnewgtval = &psci->bracket_greater;
             }
+            else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
+                     XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
+                    psci->bracket_less = pTrigger->test_value;
+                    pnewltval = &psci->bracket_less;
+            }
         }
     }                           /* end for each trigger */
 
commit 7b7753e97f0dfadfdcf28ce18b17a759b57f6be1
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Oct 16 10:08:46 2013 +1000

    sync: if the idle time was reset, force alarms to trigger (#70476)
    
    The time between the idle reset and the IdleTimeWakeupHandler to be called is
    indeterminate. Clients with an PositiveTransition or NegativeTransition alarm
    on a low threshold may miss an alarm.
    
    Work around this by keeping a reset flag for each device. When the
    WakeupHandler triggers and the reset flag is set, we force a re-calculation of
    everything and pretend the current idle time is zero. Immediately after is the
    next calculation with the real idle time.
    
    Relatively reproducible test case: Set up a XSyncNegativeTransition alarm for
    a threshold of 1 ms. May trigger, may not.
    
    X.Org Bug 70476 <http://bugs.freedesktop.org/show_bug.cgi?id=70476>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 06b87aa528d7a739ba20101a1f83b1a428691a01)

diff --git a/Xext/sync.c b/Xext/sync.c
index e289361..2b8a794 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -2686,6 +2686,15 @@ IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMa
 }
 
 static void
+IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, XSyncValue *greater)
+{
+    if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) ||
+        (less && XSyncValueLessOrEqual(idle, *less))) {
+        SyncChangeCounter(counter, idle);
+    }
+}
+
+static void
 IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask)
 {
     SyncCounter *counter = pCounter;
@@ -2699,10 +2708,24 @@ IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask)
 
     IdleTimeQueryValue(pCounter, &idle);
 
-    if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) ||
-        (less && XSyncValueLessOrEqual(idle, *less))) {
-        SyncChangeCounter(counter, idle);
+    /*
+      There is no guarantee for the WakeupHandler to be called within a specific
+      timeframe. Idletime may go to 0, but by the time we get here, it may be
+      non-zero and alarms for a pos. transition on 0 won't get triggered.
+      https://bugs.freedesktop.org/show_bug.cgi?id=70476
+      */
+    if (LastEventTimeWasReset(priv->deviceid)) {
+        LastEventTimeToggleResetFlag(priv->deviceid, FALSE);
+        if (!XSyncValueIsZero(idle)) {
+            XSyncValue zero;
+            XSyncIntsToValue(&zero, 0, 0);
+            IdleTimeCheckBrackets(counter, zero, less, greater);
+            less = priv->value_less;
+            greater = priv->value_greater;
+        }
     }
+
+    IdleTimeCheckBrackets(counter, idle, less, greater);
 }
 
 static void
@@ -2720,6 +2743,9 @@ IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less,
                                      IdleTimeWakeupHandler, pCounter);
     }
     else if (!registered && (pbracket_less || pbracket_greater)) {
+        /* Reset flag must be zero so we don't force a idle timer reset on
+           the first wakeup */
+        LastEventTimeToggleResetAll(FALSE);
         RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler,
                                        IdleTimeWakeupHandler, pCounter);
     }
diff --git a/dix/events.c b/dix/events.c
index 8bcc6bf..e3c0edf 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -262,7 +262,10 @@ InputInfo inputInfo;
 
 EventSyncInfoRec syncEvents;
 
-static TimeStamp lastDeviceEventTime[MAXDEVICES];
+static struct DeviceEventTime {
+    Bool reset;
+    TimeStamp time;
+} lastDeviceEventTime[MAXDEVICES];
 
 /**
  * The root window the given device is currently on.
@@ -1060,8 +1063,11 @@ MonthChangedOrBadTime(CARD32 *ms)
 void
 NoticeTime(const DeviceIntPtr dev, TimeStamp time)
 {
-    lastDeviceEventTime[XIAllDevices] = currentTime;
-    lastDeviceEventTime[dev->id] = currentTime;
+    lastDeviceEventTime[XIAllDevices].time = currentTime;
+    lastDeviceEventTime[dev->id].time = currentTime;
+
+    LastEventTimeToggleResetFlag(dev->id, TRUE);
+    LastEventTimeToggleResetFlag(XIAllDevices, TRUE);
 }
 
 static void
@@ -1085,7 +1091,30 @@ NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev)
 TimeStamp
 LastEventTime(int deviceid)
 {
-    return lastDeviceEventTime[deviceid];
+    return lastDeviceEventTime[deviceid].time;
+}
+
+Bool
+LastEventTimeWasReset(int deviceid)
+{
+    return lastDeviceEventTime[deviceid].reset;
+}
+
+void
+LastEventTimeToggleResetFlag(int deviceid, Bool state)
+{
+    lastDeviceEventTime[deviceid].reset = state;
+}
+
+void
+LastEventTimeToggleResetAll(Bool state)
+{
+    DeviceIntPtr dev;
+    nt_list_for_each_entry(dev, inputInfo.devices, next) {
+        LastEventTimeToggleResetFlag(dev->id, FALSE);
+    }
+    LastEventTimeToggleResetFlag(XIAllDevices, FALSE);
+    LastEventTimeToggleResetFlag(XIAllMasterDevices, FALSE);
 }
 
 /**************************************************************************
@@ -5294,6 +5323,7 @@ InitEvents(void)
 
         dummy.id = i;
         NoticeTime(&dummy, currentTime);
+        LastEventTimeToggleResetFlag(i, FALSE);
     }
 
     syncEvents.replayDev = (DeviceIntPtr) NULL;
diff --git a/include/dix.h b/include/dix.h
index fd2490f..fa7ccd4 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -322,6 +322,12 @@ NoticeEventTime(InternalEvent *ev,
                 DeviceIntPtr dev);
 extern _X_EXPORT TimeStamp
 LastEventTime(int deviceid);
+extern _X_EXPORT Bool
+LastEventTimeWasReset(int deviceid);
+extern _X_EXPORT void
+LastEventTimeToggleResetFlag(int deviceid, Bool state);
+extern _X_EXPORT void
+LastEventTimeToggleResetAll(Bool state);
 
 extern void
 EnqueueEvent(InternalEvent * /* ev */ ,
commit 3866624a45074ba37a2e605d00df602c0222cd85
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Oct 16 09:36:01 2013 +1000

    dix: provide accessor methods for the last device event time
    
    And now that we have the accessors, localize it. No functional changes, just
    preparing for a future change.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit efc1035ca958f2c9d266338a308518a0834b1773)

diff --git a/Xext/saver.c b/Xext/saver.c
index fe81bc4..e06f408 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -392,9 +392,7 @@ ScreenSaverFreeSuspend(pointer value, XID id)
             DeviceIntPtr dev;
             UpdateCurrentTimeIf();
             nt_list_for_each_entry(dev, inputInfo.devices, next)
-                lastDeviceEventTime[dev->id] = currentTime;
-            lastDeviceEventTime[XIAllDevices] = currentTime;
-            lastDeviceEventTime[XIAllMasterDevices] = currentTime;
+                NoticeTime(dev, currentTime);
             SetScreenSaverTimer();
         }
     }
@@ -681,7 +679,7 @@ ProcScreenSaverQueryInfo(ClientPtr client)
     pPriv = GetScreenPrivate(pDraw->pScreen);
 
     UpdateCurrentTime();
-    lastInput = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds;
+    lastInput = GetTimeInMillis() - LastEventTime(XIAllDevices).milliseconds;
 
     rep = (xScreenSaverQueryInfoReply) {
         .type = X_Reply,
diff --git a/Xext/sync.c b/Xext/sync.c
index 02fcbd1..e289361 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -2605,7 +2605,7 @@ IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return)
     }
     else
         deviceid = XIAllDevices;
-    idle = GetTimeInMillis() - lastDeviceEventTime[deviceid].milliseconds;
+    idle = GetTimeInMillis() - LastEventTime(deviceid).milliseconds;
     XSyncIntsToValue(pValue_return, idle, 0);
 }
 
diff --git a/dix/events.c b/dix/events.c
index e126549..8bcc6bf 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -262,6 +262,8 @@ InputInfo inputInfo;
 
 EventSyncInfoRec syncEvents;
 
+static TimeStamp lastDeviceEventTime[MAXDEVICES];
+
 /**
  * The root window the given device is currently on.
  */
@@ -1043,33 +1045,47 @@ XineramaGetCursorScreen(DeviceIntPtr pDev)
 #define TIMESLOP (5 * 60 * 1000)        /* 5 minutes */
 
 static void
-MonthChangedOrBadTime(InternalEvent *ev)
+MonthChangedOrBadTime(CARD32 *ms)
 {
     /* If the ddx/OS is careless about not processing timestamped events from
      * different sources in sorted order, then it's possible for time to go
      * backwards when it should not.  Here we ensure a decent time.
      */
-    if ((currentTime.milliseconds - ev->any.time) > TIMESLOP)
+    if ((currentTime.milliseconds - *ms) > TIMESLOP)
         currentTime.months++;
     else
-        ev->any.time = currentTime.milliseconds;
+        *ms = currentTime.milliseconds;
 }
 
-static void
-NoticeTime(InternalEvent *ev, DeviceIntPtr dev)
+void
+NoticeTime(const DeviceIntPtr dev, TimeStamp time)
 {
-    if (ev->any.time < currentTime.milliseconds)
-        MonthChangedOrBadTime(ev);
-    currentTime.milliseconds = ev->any.time;
     lastDeviceEventTime[XIAllDevices] = currentTime;
     lastDeviceEventTime[dev->id] = currentTime;
 }
 
+static void
+NoticeTimeMillis(const DeviceIntPtr dev, CARD32 *ms)
+{
+    TimeStamp time;
+    if (*ms < currentTime.milliseconds)
+        MonthChangedOrBadTime(ms);
+    time.months = currentTime.months;
+    time.milliseconds = *ms;
+    NoticeTime(dev, time);
+}
+
 void
 NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev)
 {
     if (!syncEvents.playingEvents)
-        NoticeTime(ev, dev);
+        NoticeTimeMillis(dev, &ev->any.time);
+}
+
+TimeStamp
+LastEventTime(int deviceid)
+{
+    return lastDeviceEventTime[deviceid];
 }
 
 /**************************************************************************
@@ -1093,7 +1109,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
     if (!xorg_list_is_empty(&syncEvents.pending))
         tail = xorg_list_last_entry(&syncEvents.pending, QdEventRec, next);
 
-    NoticeTime((InternalEvent *)event, device);
+    NoticeTimeMillis(device, &ev->any.time);
 
     /* Fix for key repeating bug. */
     if (device->key != NULL && device->key->xkbInfo != NULL &&
@@ -5273,8 +5289,11 @@ InitEvents(void)
     inputInfo.pointer = (DeviceIntPtr) NULL;
 
     for (i = 0; i < MAXDEVICES; i++) {
+        DeviceIntRec dummy;
         memcpy(&event_filters[i], default_filter, sizeof(default_filter));
-        lastDeviceEventTime[i] = currentTime;
+
+        dummy.id = i;
+        NoticeTime(&dummy, currentTime);
     }
 
     syncEvents.replayDev = (DeviceIntPtr) NULL;
diff --git a/dix/globals.c b/dix/globals.c
index 332b91f..ad9145b 100644
--- a/dix/globals.c
+++ b/dix/globals.c
@@ -122,7 +122,6 @@ Bool party_like_its_1989 = FALSE;
 Bool whiteRoot = FALSE;
 
 TimeStamp currentTime;
-TimeStamp lastDeviceEventTime[MAXDEVICES];
 
 int defaultColorVisualClass = -1;
 int monitorResolution = 0;
diff --git a/dix/window.c b/dix/window.c
index 1cf46dc..19cfcd6 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -3093,9 +3093,7 @@ dixSaveScreens(ClientPtr client, int on, int mode)
             DeviceIntPtr dev;
             UpdateCurrentTimeIf();
             nt_list_for_each_entry(dev, inputInfo.devices, next)
-                lastDeviceEventTime[dev->id] = currentTime;
-            lastDeviceEventTime[XIAllDevices] = currentTime;
-            lastDeviceEventTime[XIAllMasterDevices] = currentTime;
+                NoticeTime(dev, currentTime);
         }
         SetScreenSaverTimer();
     }
diff --git a/include/dix.h b/include/dix.h
index 171e56e..fd2490f 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -315,8 +315,13 @@ extern _X_EXPORT WindowPtr
 GetSpriteWindow(DeviceIntPtr pDev);
 
 extern _X_EXPORT void
+NoticeTime(const DeviceIntPtr dev,
+           TimeStamp time);
+extern _X_EXPORT void
 NoticeEventTime(InternalEvent *ev,
                 DeviceIntPtr dev);
+extern _X_EXPORT TimeStamp
+LastEventTime(int deviceid);
 
 extern void
 EnqueueEvent(InternalEvent * /* ev */ ,
diff --git a/include/dixstruct.h b/include/dixstruct.h
index aef822c..492f960 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -155,7 +155,6 @@ typedef struct _WorkQueue {
 } WorkQueueRec;
 
 extern _X_EXPORT TimeStamp currentTime;
-extern _X_EXPORT TimeStamp lastDeviceEventTime[MAXDEVICES];
 
 extern _X_EXPORT int
 CompareTimeStamps(TimeStamp /*a */ ,
diff --git a/os/WaitFor.c b/os/WaitFor.c
index 393890f..c5f4cd7 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -561,7 +561,7 @@ NextDPMSTimeout(INT32 timeout)
 static CARD32
 ScreenSaverTimeoutExpire(OsTimerPtr timer, CARD32 now, pointer arg)
 {
-    INT32 timeout = now - lastDeviceEventTime[XIAllDevices].milliseconds;
+    INT32 timeout = now - LastEventTime(XIAllDevices).milliseconds;
     CARD32 nextTimeout = 0;
 
 #ifdef DPMSExtension
diff --git a/os/xdmcp.c b/os/xdmcp.c
index 0538ac5..11f1133 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -1391,7 +1391,7 @@ recv_alive_msg(unsigned length)
         if (SessionRunning && AliveSessionID == SessionID) {
             /* backoff dormancy period */
             state = XDM_RUN_SESSION;
-            if ((GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds) >
+            if ((GetTimeInMillis() - LastEventTime(XIAllDevices).milliseconds) >
                 keepaliveDormancy * 1000) {
                 keepaliveDormancy <<= 1;
                 if (keepaliveDormancy > XDM_MAX_DORMANCY)
commit 47e30b3649fc15efbc8cf06c604254d84652ede0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Oct 16 09:21:47 2013 +1000

    sync: supply the counter from IdleTimeBlockHandler
    
    The main idletime counter has an initialized deviceid, might as well be
    supplying it properly. Without this, we'd only ever check the XIAllDevices
    counter, so the wait would never be adjusted for the device-specific triggers.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit b7c9bd9cf276e92a73be57ff2ed32b47a80f13fb)

diff --git a/Xext/sync.c b/Xext/sync.c
index fa7a5c9..02fcbd1 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -2624,7 +2624,7 @@ IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMa
         return;
 
     old_idle = counter->value;
-    IdleTimeQueryValue(NULL, &idle);
+    IdleTimeQueryValue(counter, &idle);
     counter->value = idle;      /* push, so CheckTrigger works */
 
     if (less && XSyncValueLessOrEqual(idle, *less)) {
commit b47c02f21660bd99a5af5aa374294a22813d6679
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Oct 16 13:01:01 2013 +1000

    sync: always call BracketValues when recalculating upper/lower brackets
    
    Both ServertimeBracketValues and IdleTimeBracketValues copy the value into
    there SysCounter privates. Call it for a NULL set as well, so we don't end up
    with stale pointers and we can remove the block/wakeup handlers.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 2efe49c1029f959fe80879bcf50df42e8b80451d)

diff --git a/Xext/sync.c b/Xext/sync.c
index 17826c2..fa7a5c9 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -1058,9 +1058,8 @@ SyncComputeBracketValues(SyncCounter * pCounter)
         }
     }                           /* end for each trigger */
 
-    if (pnewgtval || pnewltval) {
-        (*psci->BracketValues) ((pointer) pCounter, pnewltval, pnewgtval);
-    }
+    (*psci->BracketValues) ((pointer) pCounter, pnewltval, pnewgtval);
+
 }
 
 /*
commit 0033e969f4de84aa08ae321bc268a1461e12824b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Oct 15 10:11:20 2013 +1000

    sync: compress two if statements
    
    No functional changes, just merges a > and == condition into a >= condition.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 5c7cfd4c6978834551848e1be62af240102e39b5)

diff --git a/Xext/sync.c b/Xext/sync.c
index 4d11992..17826c2 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -1031,42 +1031,29 @@ SyncComputeBracketValues(SyncCounter * pCounter)
         }
         else if (pTrigger->test_type == XSyncNegativeTransition &&
                  ct != XSyncCounterNeverIncreases) {
-            if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
-                XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less))
-            {
-                psci->bracket_less = pTrigger->test_value;
-                pnewltval = &psci->bracket_less;
-            }
-            else if (XSyncValueEqual(pCounter->value, pTrigger->test_value) &&
-                     XSyncValueGreaterThan(pTrigger->test_value,
-                                           psci->bracket_less)) {
-                /*
-                 * The value is exactly equal to our threshold.  We want one
-                 * more event in the negative direction to ensure we pick up
-                 * when the value is less than this threshold.
-                 */
-                psci->bracket_less = pTrigger->test_value;
-                pnewltval = &psci->bracket_less;
+            if (XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value) &&
+                XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
+                    /*
+                     * If the value is exactly equal to our threshold, we want one
+                     * more event in the negative direction to ensure we pick up
+                     * when the value is less than this threshold.
+                     */
+                    psci->bracket_less = pTrigger->test_value;
+                    pnewltval = &psci->bracket_less;
             }
         }
         else if (pTrigger->test_type == XSyncPositiveTransition &&
                  ct != XSyncCounterNeverDecreases) {
-            if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
-                XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater))
-            {
-                psci->bracket_greater = pTrigger->test_value;
-                pnewgtval = &psci->bracket_greater;
-            }
-            else if (XSyncValueEqual(pCounter->value, pTrigger->test_value) &&
-                     XSyncValueLessThan(pTrigger->test_value,
-                                        psci->bracket_greater)) {
-                /*
-                 * The value is exactly equal to our threshold.  We want one
-                 * more event in the positive direction to ensure we pick up
-                 * when the value *exceeds* this threshold.
-                 */
-                psci->bracket_greater = pTrigger->test_value;
-                pnewgtval = &psci->bracket_greater;
+            if (XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value) &&
+                XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
+                    /*
+                     * If the value is exactly equal to our threshold, we
+                     * want one more event in the positive direction to
+                     * ensure we pick up when the value *exceeds* this
+                     * threshold.
+                     */
+                    psci->bracket_greater = pTrigger->test_value;
+                    pnewgtval = &psci->bracket_greater;
             }
         }
     }                           /* end for each trigger */
commit 0c809f459c9997f743961081bc089fd2999fdcdb
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 4 15:34:29 2013 +1000

    dix: only deliver for the current grab type
    
    Use the grabtype to determine which type of event to send - all other events
    are pointless and may result in erroneous events being delivered.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 7cf1b595c8c8f9776a39559d2878cf90af3f2859)

diff --git a/dix/events.c b/dix/events.c
index 5a2d0a8..e126549 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4253,17 +4253,8 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
 
         sendCore = (IsMaster(thisDev) && thisDev->coreEvents);
         /* try core event */
-        if (sendCore && grab->grabtype == CORE) {
-            deliveries = DeliverOneGrabbedEvent(event, thisDev, CORE);
-        }
-
-        if (!deliveries) {
-            deliveries = DeliverOneGrabbedEvent(event, thisDev, XI2);
-        }
-
-        if (!deliveries) {
-            deliveries = DeliverOneGrabbedEvent(event, thisDev, XI);
-        }
+        if ((sendCore && grab->grabtype == CORE) || grab->grabtype != CORE)
+            deliveries = DeliverOneGrabbedEvent(event, thisDev, grab->grabtype);
 
         if (deliveries && (event->any.type == ET_Motion))
             thisDev->valuator->motionHintWindow = grab->window;
commit acb447ef69bdfcae4fe7de4eef880c3bae0f7d4c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 4 15:34:28 2013 +1000

    dix: don't attempt to deliver an event for a different grabtype
    
    For an active grab, grab->eventMask can be either the core or the XI1 mask.
    With the overlap of event filters, calling DeliverOneGrabbedEvent(XI1) for a
    ProximityOut event will trigger if the client has selected for enter events -
    the filter is the same for both.
    
    Thus, we end up delivering a proximity event to a client not expecting one.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 78944d62ffc7fec6f75b6f514ab7a139ba9bc77b)

diff --git a/dix/events.c b/dix/events.c
index 63d24da..5a2d0a8 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4139,6 +4139,9 @@ DeliverOneGrabbedEvent(InternalEvent *event, DeviceIntPtr dev,
     GrabPtr grab = grabinfo->grab;
     Mask filter;
 
+    if (grab->grabtype != level)
+        return 0;
+
     switch (level) {
     case XI2:
         rc = EventToXI2(event, &xE);
commit f5b22ee8ba829aa095df3d091ec0a74e0aa42778
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 4 15:34:27 2013 +1000

    include: change grabtypes to start at 1
    
    Avoid erroneous detection of an unset grabtype as CORE
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 6159811a1aaf848016dbfa7bde68df097027870c)

diff --git a/include/input.h b/include/input.h
index 7eed60b..bff7ffe 100644
--- a/include/input.h
+++ b/include/input.h
@@ -113,9 +113,9 @@ SOFTWARE.
 #endif
 
 enum InputLevel {
-    CORE,
-    XI,
-    XI2,
+    CORE = 1,
+    XI = 2,
+    XI2 = 3,
 };
 
 typedef unsigned long Leds;
commit d409cc884c53e7f66ee9266c85cdb7c100365c8f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 4 15:34:26 2013 +1000

    dix: only allow button and key events to freeze a sync'd pointer
    
    If a client calls XAllowEvents(SyncPointer) it expects events as normal until
    the next button press or release event - that freezes the device. An e.g.
    proximity event must thus not freeze the pointer.
    
    As per the spec, only button and key events may do so, so narrow it to these
    cases.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit be6ea80b79b3d6eb97106ea142e01acbdf059995)

diff --git a/dix/events.c b/dix/events.c
index 5027a72..63d24da 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4265,7 +4265,11 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
         if (deliveries && (event->any.type == ET_Motion))
             thisDev->valuator->motionHintWindow = grab->window;
     }
-    if (deliveries && !deactivateGrab && event->any.type != ET_Motion) {
+    if (deliveries && !deactivateGrab &&
+        (event->any.type == ET_KeyPress ||
+         event->any.type == ET_KeyRelease ||
+         event->any.type == ET_ButtonPress ||
+         event->any.type == ET_ButtonRelease)) {
         switch (grabinfo->sync.state) {
         case FREEZE_BOTH_NEXT_EVENT:
             dev = GetPairedDevice(thisDev);
commit 551dbf744b38a3da3d39b9154cb30d1197297eb1
Author: Egbert Eich <eich at freedesktop.org>
Date:   Fri Aug 16 19:52:16 2013 +0200

    DIX/Xi: Pass correct client to CheckDeviceGrabAndHintWindow()
    
    If we have a client which has registered for a DeviceButton grab
    be sure to pass this to CheckDeviceGrabAndHintWindow(). Since the
    order of clients is arbitrary there is no guarantee that the last
    client in the list is the one that belongs to this class.
    
    Signed-off-by: Egbert Eich <eich at freedesktop.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 05ea6307fa4f0bee3d3bf536396059f3906791a0)

diff --git a/dix/events.c b/dix/events.c
index c53a648..5027a72 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2102,6 +2102,7 @@ DeliverEventToInputClients(DeviceIntPtr dev, InputClients * inputclients,
 {
     int attempt;
     enum EventDeliveryState rc = EVENT_NOT_DELIVERED;
+    Bool have_device_button_grab_class_client = FALSE;
 
     for (; inputclients; inputclients = inputclients->next) {
         Mask mask;
@@ -2121,13 +2122,21 @@ DeliverEventToInputClients(DeviceIntPtr dev, InputClients * inputclients,
                                             events, count,
                                             mask, filter, grab))) {
             if (attempt > 0) {
-                rc = EVENT_DELIVERED;
-                *client_return = client;
-                *mask_return = mask;
-                /* Success overrides non-success, so if we've been
-                 * successful on one client, return that */
-            }
-            else if (rc == EVENT_NOT_DELIVERED)
+                /*
+                 * The order of clients is arbitrary therefore if one
+                 * client belongs to DeviceButtonGrabClass make sure to
+                 * catch it.
+                 */
+                if (!have_device_button_grab_class_client) {
+                    rc = EVENT_DELIVERED;
+                    *client_return = client;
+                    *mask_return = mask;
+                    /* Success overrides non-success, so if we've been
+                     * successful on one client, return that */
+                    if (mask & DeviceButtonGrabMask)
+                        have_device_button_grab_class_client = TRUE;
+                }
+            } else if (rc == EVENT_NOT_DELIVERED)
                 rc = EVENT_REJECTED;
         }
     }
commit cc7084af0d61e88ec0a62e14d6eef10c0b2b8b38
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Aug 26 15:51:46 2013 +1000

    Xi: allow for XIAllowEvent requests larger than XI < 2.2 size (#68554)
    
    XIAllowEvents changed length in XI 2.2 (for the touchid). A bug in libXi
    causes libXi to always use the new request length if the server supports
    2.2, regardless of the client's XIQueryVersion request.
    
    The server takes the client's XIQueryVersion request into account though,
    resulting in a BadLength error if a 2.[0,1] client calls XIAllowEvents on a
    XI 2.2+ server.
    
    Can't fix this in libXi, so work around this in the server.
    
    X.Org Bug 68554 <http://bugs.freedesktop.org/show_bug.cgi?id=68554>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit 94d4e29aedc69431fa9b299ca1b67947173d7a24)

diff --git a/Xi/xiallowev.c b/Xi/xiallowev.c
index 62a0727..ebef233 100644
--- a/Xi/xiallowev.c
+++ b/Xi/xiallowev.c
@@ -81,7 +81,7 @@ ProcXIAllowEvents(ClientPtr client)
         have_xi22 = TRUE;
     }
     else {
-        REQUEST_SIZE_MATCH(xXIAllowEventsReq);
+        REQUEST_AT_LEAST_SIZE(xXIAllowEventsReq);
     }
 
     ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
commit 2ac257d845e7f52975123741292056b3df02f908
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Aug 16 15:30:59 2013 +1000

    dix: check for grab type before checking XI2 mask
    
    if the grab type isn't XI2, grab->xi2mask is random. That random data may
    have the enter/leave mask set, leading to events sent to the client that the
    client can't handler.
    
    Source of these errors:
      _xgeWireToEvent: Unknown extension 131, this should never happen.
    
    Simplest reproducer:
       Start Xephyr, press button inside window, move out. As the pointer leaves
       the Xephyr window, the errors appear.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit 82939e02392cbb880313fe92957091ff89ce2f2b)

diff --git a/dix/events.c b/dix/events.c
index c079f97..c53a648 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4641,7 +4641,7 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
 
     filter = GetEventFilter(mouse, (xEvent *) event);
 
-    if (grab) {
+    if (grab && grab->type == XI2) {
         Mask mask;
 
         mask = xi2mask_isset(grab->xi2mask, mouse, type);
commit 3ac50dca8b4b9b6b3a7e16c5855ca246a70c9232
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Aug 23 09:04:01 2013 +1000

    test: fix the gcc diagnostics pragma
    
    pop without push restores the commandline options. The proper way is to
    push, then ignore, then pop.
    
    And while we're at it, change the pop argument to a comment - pop ignores
    the argument, but be proper about it.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit d803f296c616ccf55711cf0af9e7d3eae2edda16)

diff --git a/test/signal-logging.c b/test/signal-logging.c
index f6bc85c..a03c5ac 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -150,6 +150,7 @@ number_formatting(void)
         assert(check_float_format_test(float_tests[i]));
 }
 
+#pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wformat-security"
 static void logging_format(void)
 {
@@ -378,7 +379,7 @@ static void logging_format(void)
 
 #undef read_log_msg
 }
-#pragma GCC diagnostic pop "-Wformat-security"
+#pragma GCC diagnostic pop /* "-Wformat-security" */
 
 int
 main(int argc, char **argv)
commit ec6de521161d5c45885c8751c250d3fabcbc2194
Merge: 1427621 a1985e8
Author: Matt Dew <marcoz at osource.org>
Date:   Mon Oct 21 21:03:29 2013 -0600

    Merge commit 'a1985e892f5b5f0959235a631d8bcf676b78bfbc' into server-1.14-branch

commit 14276213ac4d59316d5745ccb9a2fb23eb10cf99
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Mon Aug 5 20:46:45 2013 -0700

    Allow disabling XFree86-DGA, DRI, VidModeExtension extensions
    
    Code to recognize these in extension enable/disable options was wrapped
    in #ifdef XorgLoader, but that's not defined when building miinitext.c
    since the great module merge of 1.13.  Change to an #ifdef that is defined.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Robert Hooker <robert.hooker at canonical.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/mi/miinitext.c b/mi/miinitext.c
index 81c663a..dbca9f7 100644
--- a/mi/miinitext.c
+++ b/mi/miinitext.c
@@ -157,7 +157,7 @@ static ExtensionToggle ExtensionToggleList[] = {
 #ifdef XF86BIGFONT
     {"XFree86-Bigfont", &noXFree86BigfontExtension},
 #endif
-#ifdef XorgLoader
+#ifdef XORGSERVER
 #ifdef XFreeXDGA
     {"XFree86-DGA", &noXFree86DGAExtension},
 #endif
commit 296057914570bd319bce9b718e6b90f46e6cc661
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Mon Sep 16 21:47:16 2013 -0700

    Avoid use-after-free in dix/dixfonts.c: doImageText() [CVE-2013-4396]
    
    Save a pointer to the passed in closure structure before copying it
    and overwriting the *c pointer to point to our copy instead of the
    original.  If we hit an error, once we free(c), reset c to point to
    the original structure before jumping to the cleanup code that
    references *c.
    
    Since one of the errors being checked for is whether the server was
    able to malloc(c->nChars * itemSize), the client can potentially pass
    a number of characters chosen to cause the malloc to fail and the
    error path to be taken, resulting in the read from freed memory.
    
    Since the memory is accessed almost immediately afterwards, and the
    X server is mostly single threaded, the odds of the free memory having
    invalid contents are low with most malloc implementations when not using
    memory debugging features, but some allocators will definitely overwrite
    the memory there, leading to a likely crash.
    
    Reported-by: Pedro Ribeiro <pedrib at gmail.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>

diff --git a/dix/dixfonts.c b/dix/dixfonts.c
index feb765d..2e34d37 100644
--- a/dix/dixfonts.c
+++ b/dix/dixfonts.c
@@ -1425,6 +1425,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
             GC *pGC;
             unsigned char *data;
             ITclosurePtr new_closure;
+            ITclosurePtr old_closure;
 
             /* We're putting the client to sleep.  We need to
                save some state.  Similar problem to that handled
@@ -1436,12 +1437,14 @@ doImageText(ClientPtr client, ITclosurePtr c)
                 err = BadAlloc;
                 goto bail;
             }
+            old_closure = c;
             *new_closure = *c;
             c = new_closure;
 
             data = malloc(c->nChars * itemSize);
             if (!data) {
                 free(c);
+                c = old_closure;
                 err = BadAlloc;
                 goto bail;
             }
@@ -1452,6 +1455,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
             if (!pGC) {
                 free(c->data);
                 free(c);
+                c = old_closure;
                 err = BadAlloc;
                 goto bail;
             }
@@ -1464,6 +1468,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
                 FreeScratchGC(pGC);
                 free(c->data);
                 free(c);
+                c = old_closure;
                 err = BadAlloc;
                 goto bail;
             }
commit a1985e892f5b5f0959235a631d8bcf676b78bfbc
Author: Julien Cristau <jcristau at debian.org>
Date:   Sat Jul 27 12:09:07 2013 +0200

    dix: add missing include for DeleteWindowFromAnySelections
    
    Fixes build error with XACE disabled:
    window.c:886:5: error: implicit declaration of function 'DeleteWindowFromAnySelections' [-Werror=implicit-function-declaration]
         DeleteWindowFromAnySelections(pWin);
         ^
    
    Debian bug#701372
    
    Reported-by: Matthias Klose <doko at debian.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit fe7463b8ce0de301c2f82b108c93963424f77219)

diff --git a/dix/window.c b/dix/window.c
index 8e61779..1cf46dc 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -126,6 +126,7 @@ Equipment Corporation.
 #ifdef COMPOSITE
 #include "compint.h"
 #endif
+#include "selection.h"
 
 #include "privates.h"
 #include "xace.h"
commit 19c2d516c2b5182e8b45649485aa3123b229b66a
Author: Julien Cristau <jcristau at debian.org>
Date:   Fri Aug 2 20:07:36 2013 +0200

    xfree86: improve check for posix saved ids
    
    Replace hardcoded SVR4 || linux || CSRG_BASED with an autoconf check and
    the _POSIX_SAVED_IDS macro.
    
    Suggested-by: Mark Kettenis <mark.kettenis at xs4all.nl>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Mark Kettenis <kettenis at openbsd.org>.
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit c218ba8423a73a7a643cb17789db8a1dd0901ca6)

diff --git a/configure.ac b/configure.ac
index 9bc7c73..8ac9cb5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -215,7 +215,7 @@ AC_SUBST(DLOPEN_LIBS)
 dnl Checks for library functions.
 AC_CHECK_FUNCS([backtrace ffs geteuid getuid issetugid getresuid \
 	getdtablesize getifaddrs getpeereid getpeerucred getzoneid \
-	mmap shmctl64 strncasecmp vasprintf vsnprintf walkcontext])
+	mmap seteuid shmctl64 strncasecmp vasprintf vsnprintf walkcontext])
 AC_REPLACE_FUNCS([strcasecmp strcasestr strlcat strlcpy strndup])
 
 dnl Find the math libary, then check for cbrt function in it.
diff --git a/hw/xfree86/parser/write.c b/hw/xfree86/parser/write.c
index 9c706a0..26739b9 100644
--- a/hw/xfree86/parser/write.c
+++ b/hw/xfree86/parser/write.c
@@ -55,6 +55,7 @@
 #include <xorg-config.h>
 #endif
 
+#include "os.h"
 #include "xf86Parser.h"
 #include "xf86tokens.h"
 #include "Configint.h"
@@ -65,7 +66,7 @@
 #include <signal.h>
 #include <errno.h>
 
-#if defined(SVR4) || defined(__linux__) || defined(CSRG_BASED)
+#if defined(HAVE_SETEUID) && defined(_POSIX_SAVED_IDS) && _POSIX_SAVED_IDS > 0
 #define HAS_SAVED_IDS_AND_SETEUID
 #endif
 #if defined(WIN32)
diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in
index a71b25d..0df31ae 100644
--- a/include/xorg-config.h.in
+++ b/include/xorg-config.h.in
@@ -139,4 +139,7 @@
 /* Have X server platform bus support */
 #undef XSERVER_PLATFORM_BUS
 
+/* Define to 1 if you have the `seteuid' function. */
+#undef HAVE_SETEUID
+
 #endif /* _XORG_CONFIG_H_ */
commit b39a6ab645815a6012d9b2feaa049336ea09aa76
Author: Julien Cristau <jcristau at debian.org>
Date:   Fri Aug 2 23:46:00 2013 +0200

    test: include dix-config.h in hashtabletest.c
    
    Missing _XSERVER64 define caused inconsistent sizeof(XID) between the
    test and hashtable code, leading to test failures on 64bit big endian
    archs like s390x or ppc64.
    
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 930c6ff15d437dfb0f897e8cb4253abba70819cc)

diff --git a/test/hashtabletest.c b/test/hashtabletest.c
index 64c7091..6af14a8 100644
--- a/test/hashtabletest.c
+++ b/test/hashtabletest.c
@@ -1,3 +1,7 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
 #include <misc.h>
 #include <stdlib.h>
 #include <stdio.h>
commit 9acb64f54ee9dd2fe41afda159b919280850ad8e
Author: Matt Dew <marcoz at osource.org>
Date:   Thu Sep 12 21:17:40 2013 -0600

    bump version from 1.14.2.902 to 1.14.3

diff --git a/configure.ac b/configure.ac
index 68484db..9bc7c73 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.14.2.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-08-22"
-RELEASE_NAME="Act semi-normal-rc2"
+AC_INIT([xorg-server], 1.14.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-09-12"
+RELEASE_NAME="September Rain"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
commit af1c57152e10cfa55843e6330cffc6a3c8c517d3
Author: Chris Clayton <chris2553 at googlemail.com>
Date:   Wed Sep 4 15:42:04 2013 +1000

    kdrive: fix build error on gcc 4.8 for out-of-bounds array access
    
    I'm getting a error building xorg-server-1.14.1.902 with thelatest snapshot
    of gcc-4.8:
    
    input.c:225:43: error: array subscript is above array bounds
    [-Werror=array-bounds]
    
    This is because kdNumInputFds can become equal to KD_MAX_INPUT_FDS in
    KdRegisterFd(). This means that in KdUnregisterFd(), kdInputFds[j + 1] can
    be beyond the end of the array.
    
    Signed-off-by: Chris Clayton <chris2553 at googlemail.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index b1068bb..09aae44 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -221,7 +221,7 @@ KdUnregisterFd(void *closure, int fd, Bool do_close)
             if (do_close)
                 close(kdInputFds[i].fd);
             kdNumInputFds--;
-            for (j = i; j < kdNumInputFds; j++)
+            for (j = i; j < (kdNumInputFds - 1); j++)
                 kdInputFds[j] = kdInputFds[j + 1];
             break;
         }
commit 0e37fefea5e91dfdcd18ffd941daa7d05cc3180d
Author: Matt Dew <marcoz at osource.org>
Date:   Thu Aug 22 17:43:51 2013 -0600

    bump rev number from 1.14.2.901 to 1.14.2.902

diff --git a/configure.ac b/configure.ac
index 271e49d..68484db 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.14.2.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-07-25"
-RELEASE_NAME="Act semi-normal-rc1"
+AC_INIT([xorg-server], 1.14.2.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-08-22"
+RELEASE_NAME="Act semi-normal-rc2"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
commit 917c11ff97eb302d3c2d0565c8dd6d93101d6466
Author: Maarten Lankhorst <maarten.lankhorst at canonical.com>
Date:   Tue Jul 30 15:31:24 2013 +0200

    test/xi2: fix protocol-xiqueryversion test
    
    The old code was broken and allowed setting client version >= XIVersion,
    this was fixed in the previous patch, but updating the value for XIVersion
    broke the tests, so fix the tests too.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit b6e5c4669e0db391966deb397e8c975ec7f0124d)

diff --git a/test/xi2/protocol-xiqueryversion.c b/test/xi2/protocol-xiqueryversion.c
index aff0237..ed75c89 100644
--- a/test/xi2/protocol-xiqueryversion.c
+++ b/test/xi2/protocol-xiqueryversion.c
@@ -44,8 +44,8 @@
 #include "extinit.h"            /* for XInputExtensionInit */
 #include "scrnintstr.h"
 #include "xiqueryversion.h"
-
 #include "protocol-common.h"
+#include "exglobals.h"
 
 extern XExtensionVersion XIVersion;
 
@@ -54,8 +54,8 @@ struct test_data {
     int minor_client;
     int major_server;
     int minor_server;
-    int major_cached;
-    int minor_cached;
+    int major_expected;
+    int minor_expected;
 };
 
 static void
@@ -93,13 +93,8 @@ reply_XIQueryVersion_multiple(ClientPtr client, int len, char *data, void *closu
     reply_check_defaults(rep, len, XIQueryVersion);
     assert(rep->length == 0);
 
-    if (versions->major_cached == -1) {
-        versions->major_cached = rep->major_version;
-        versions->minor_cached = rep->minor_version;
-    }
-
-    assert(versions->major_cached == rep->major_version);
-    assert(versions->minor_cached == rep->minor_version);
+    assert(versions->major_expected == rep->major_version);
+    assert(versions->minor_expected == rep->minor_version);
 }
 
 /**
@@ -199,6 +194,7 @@ test_XIQueryVersion_multiple(void)
 {
     xXIQueryVersionReq request;
     ClientRec client;
+    XIClientPtr pXIClient;
     struct test_data versions;
     int rc;
 
@@ -213,28 +209,26 @@ test_XIQueryVersion_multiple(void)
     userdata = (void *) &versions;
 
     /* run 1 */
-    versions.major_cached = -1;
-    versions.minor_cached = -1;
 
-    /* client is lower than server, noncached */
-    request.major_version = 2;
-    request.minor_version = 1;
+    /* client is lower than server, nonexpected */
+    versions.major_expected = request.major_version = 2;
+    versions.minor_expected = request.minor_version = 1;
     rc = ProcXIQueryVersion(&client);
     assert(rc == Success);
 
-    /* client is higher than server, cached */
+    /* client is higher than server, no change */
     request.major_version = 2;
     request.minor_version = 3;
     rc = ProcXIQueryVersion(&client);
     assert(rc == Success);
 
-    /* client is equal, cached */
+    /* client tries to set higher version, stays same */
     request.major_version = 2;
     request.minor_version = 2;
     rc = ProcXIQueryVersion(&client);
     assert(rc == Success);
 
-    /* client is low than cached */
+    /* client tries to set lower version, no change */
     request.major_version = 2;
     request.minor_version = 0;
     rc = ProcXIQueryVersion(&client);
@@ -243,20 +237,24 @@ test_XIQueryVersion_multiple(void)
     /* run 2 */
     client = init_client(request.length, &request);
     XIVersion.major_version = 2;
-    XIVersion.minor_version = 2;
-    versions.major_cached = -1;
-    versions.minor_cached = -1;
+    XIVersion.minor_version = 3;
 
-    request.major_version = 2;
-    request.minor_version = 2;
+    versions.major_expected = request.major_version = 2;
+    versions.minor_expected = request.minor_version = 2;
     rc = ProcXIQueryVersion(&client);
     assert(rc == Success);
 
+    /* client bumps version from 2.2 to 2.3 */
     request.major_version = 2;
-    request.minor_version = 3;
+    versions.minor_expected = request.minor_version = 3;
     rc = ProcXIQueryVersion(&client);
     assert(rc == Success);
 
+    /* real version is changed, too! */
+    pXIClient = dixLookupPrivate(&client.devPrivates, XIClientPrivateKey);
+    assert(pXIClient->minor_version == 3);
+
+    /* client tries to set lower version, no change */
     request.major_version = 2;
     request.minor_version = 1;
     rc = ProcXIQueryVersion(&client);
@@ -265,20 +263,22 @@ test_XIQueryVersion_multiple(void)
     /* run 3 */
     client = init_client(request.length, &request);
     XIVersion.major_version = 2;
-    XIVersion.minor_version = 2;
-    versions.major_cached = -1;
-    versions.minor_cached = -1;
+    XIVersion.minor_version = 3;
 
-    request.major_version = 2;
-    request.minor_version = 3;
+    versions.major_expected = request.major_version = 2;
+    versions.minor_expected = request.minor_version = 3;
     rc = ProcXIQueryVersion(&client);
     assert(rc == Success);
 
     request.major_version = 2;
-    request.minor_version = 2;
+    versions.minor_expected = request.minor_version = 2;
     rc = ProcXIQueryVersion(&client);
     assert(rc == Success);
 
+    /* but real client version must not be lowered */
+    pXIClient = dixLookupPrivate(&client.devPrivates, XIClientPrivateKey);
+    assert(pXIClient->minor_version == 3);
+
     request.major_version = 2;
     request.minor_version = 1;
     rc = ProcXIQueryVersion(&client);
commit 804836c53083fdb9f43be6f51740df5d12d57cb4
Author: Maarten Lankhorst <maarten.lankhorst at canonical.com>
Date:   Tue Jul 30 14:45:21 2013 +0200

    Xi: Clamp XIClient maximal version to XIVersion
    
    Do not allow setting client version to an arbitrary value >= XIVersion.
    Fixes a test error with test/xi2/protocol-xiqueryversion.c, introduced by
    commit 4360514d1c "Xi: Allow clients to ask for 2.3 and then 2.2 without failing"
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 500e844a24962c9e70abb3d614f1973013b2de73)

diff --git a/Xi/xiqueryversion.c b/Xi/xiqueryversion.c
index 6c7b9c0..c705f78 100644
--- a/Xi/xiqueryversion.c
+++ b/Xi/xiqueryversion.c
@@ -70,12 +70,21 @@ ProcXIQueryVersion(ClientPtr client)
 
     pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
 
+    if (version_compare(XIVersion.major_version, XIVersion.minor_version,
+                stuff->major_version, stuff->minor_version) > 0) {
+        major = stuff->major_version;
+        minor = stuff->minor_version;
+    } else {
+        major = XIVersion.major_version;
+        minor = XIVersion.minor_version;
+    }
+
     if (pXIClient->major_version) {
 
         /* Check to see if the client has only ever asked
          * for version 2.2 or higher
          */
-        if (version_compare(stuff->major_version, stuff->minor_version, 2, 2) >= 0 &&
+        if (version_compare(major, minor, 2, 2) >= 0 &&
             version_compare(pXIClient->major_version, pXIClient->minor_version, 2, 2) >= 0)
         {
 
@@ -84,16 +93,14 @@ ProcXIQueryVersion(ClientPtr client)
              * version to the client but leave the server internal
              * version set to the highest requested value
              */
-            major = stuff->major_version;
-            minor = stuff->minor_version;
-            if (version_compare(stuff->major_version, stuff->minor_version,
+            if (version_compare(major, minor,
                                 pXIClient->major_version, pXIClient->minor_version) > 0)
             {
-                pXIClient->major_version = stuff->major_version;
-                pXIClient->minor_version = stuff->minor_version;
+                pXIClient->major_version = major;
+                pXIClient->minor_version = minor;
             }
         } else {
-            if (version_compare(stuff->major_version, stuff->minor_version,
+            if (version_compare(major, minor,
                                 pXIClient->major_version, pXIClient->minor_version) < 0) {
 
                 client->errorValue = stuff->major_version;
@@ -103,16 +110,6 @@ ProcXIQueryVersion(ClientPtr client)
             minor = pXIClient->minor_version;
         }
     } else {
-        if (version_compare(XIVersion.major_version, XIVersion.minor_version,
-                    stuff->major_version, stuff->minor_version) > 0) {
-            major = stuff->major_version;
-            minor = stuff->minor_version;
-        }
-        else {
-            major = XIVersion.major_version;
-            minor = XIVersion.minor_version;
-        }
-
         pXIClient->major_version = major;
         pXIClient->minor_version = minor;
     }
commit 7250c310b50c96709f2082e7752fc889557abc26
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Aug 13 10:50:25 2013 +1000

    Revert "test: fix XIQueryVersion check for new behaviour"
    
    This reverts commit cdcb708678c4785cd7b026b90e316691176e5244.

diff --git a/test/xi2/protocol-xiqueryversion.c b/test/xi2/protocol-xiqueryversion.c
index 2289c8d..aff0237 100644
--- a/test/xi2/protocol-xiqueryversion.c
+++ b/test/xi2/protocol-xiqueryversion.c
@@ -96,16 +96,10 @@ reply_XIQueryVersion_multiple(ClientPtr client, int len, char *data, void *closu
     if (versions->major_cached == -1) {
         versions->major_cached = rep->major_version;
         versions->minor_cached = rep->minor_version;
-    } else if (versions->major_cached >= 2 &&
-               versions->minor_cached >= 2) {
-        /* First request was for 2.2 or higher, reply
-           must be 2.2 or higher, whichever requested */
-        assert(rep->major_version >= 2);
-        assert(rep->minor_version >= 2);
-    } else {
-        assert(versions->major_cached == rep->major_version);
-        assert(versions->minor_cached == rep->minor_version);
     }
+
+    assert(versions->major_cached == rep->major_version);
+    assert(versions->minor_cached == rep->minor_version);
 }
 
 /**
commit cdcb708678c4785cd7b026b90e316691176e5244
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jul 30 08:03:12 2013 +1000

    test: fix XIQueryVersion check for new behaviour
    
    As of 4360514d1cc8e3132f93f56172d291074e8c770f, XIQueryVersion supports
    requesting versions 2.2+ in random order, only 2.0 and 2.1 are restricted.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit a5abf790183798ad8aa2c29c056df3647777cfbd)

diff --git a/test/xi2/protocol-xiqueryversion.c b/test/xi2/protocol-xiqueryversion.c
index aff0237..2289c8d 100644
--- a/test/xi2/protocol-xiqueryversion.c
+++ b/test/xi2/protocol-xiqueryversion.c
@@ -96,10 +96,16 @@ reply_XIQueryVersion_multiple(ClientPtr client, int len, char *data, void *closu
     if (versions->major_cached == -1) {
         versions->major_cached = rep->major_version;
         versions->minor_cached = rep->minor_version;
+    } else if (versions->major_cached >= 2 &&
+               versions->minor_cached >= 2) {
+        /* First request was for 2.2 or higher, reply
+           must be 2.2 or higher, whichever requested */
+        assert(rep->major_version >= 2);
+        assert(rep->minor_version >= 2);
+    } else {
+        assert(versions->major_cached == rep->major_version);
+        assert(versions->minor_cached == rep->minor_version);
     }
-
-    assert(versions->major_cached == rep->major_version);
-    assert(versions->minor_cached == rep->minor_version);
 }
 
 /**
commit e6da18f67516dcee394cd0eff591a255b59fe544
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Jul 10 22:42:55 2013 -0700

    Xi: Allow clients to ask for 2.3 and then 2.2 without failing
    
    This allows different sub-systems within the same application to
    request different Xi versions without either getting old behaviour
    everywhere or simply failing with a BadValue.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 4360514d1cc8e3132f93f56172d291074e8c770f)

diff --git a/Xi/xiqueryversion.c b/Xi/xiqueryversion.c
index b807a53..6c7b9c0 100644
--- a/Xi/xiqueryversion.c
+++ b/Xi/xiqueryversion.c
@@ -71,13 +71,37 @@ ProcXIQueryVersion(ClientPtr client)
     pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
 
     if (pXIClient->major_version) {
-        if (version_compare(stuff->major_version, stuff->minor_version,
-                            pXIClient->major_version, pXIClient->minor_version) < 0) {
-            client->errorValue = stuff->major_version;
-            return BadValue;
+
+        /* Check to see if the client has only ever asked
+         * for version 2.2 or higher
+         */
+        if (version_compare(stuff->major_version, stuff->minor_version, 2, 2) >= 0 &&
+            version_compare(pXIClient->major_version, pXIClient->minor_version, 2, 2) >= 0)
+        {
+
+            /* As of version 2.2, Peter promises to never again break
+             * backward compatibility, so we'll return the requested
+             * version to the client but leave the server internal
+             * version set to the highest requested value
+             */
+            major = stuff->major_version;
+            minor = stuff->minor_version;
+            if (version_compare(stuff->major_version, stuff->minor_version,
+                                pXIClient->major_version, pXIClient->minor_version) > 0)
+            {
+                pXIClient->major_version = stuff->major_version;
+                pXIClient->minor_version = stuff->minor_version;
+            }
+        } else {
+            if (version_compare(stuff->major_version, stuff->minor_version,
+                                pXIClient->major_version, pXIClient->minor_version) < 0) {
+
+                client->errorValue = stuff->major_version;
+                return BadValue;
+            }
+            major = pXIClient->major_version;
+            minor = pXIClient->minor_version;
         }
-        major = pXIClient->major_version;
-        minor = pXIClient->minor_version;
     } else {
         if (version_compare(XIVersion.major_version, XIVersion.minor_version,
                     stuff->major_version, stuff->minor_version) > 0) {
commit 0857f3c72d0d1bf5eac52f084e9a1adf077e7397
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jul 22 13:43:07 2013 +1000

    dix: set the valuator mask to ensure XI 1.x events have data
    
    XI 1.x only allows for first + num valuators, so if a device sends data for
    valuators 0 and 2+ only (i.e. valuator 1 is missing) we still need to get
    the data for that from somewhere.
    XI 1.x uses the hack of an unset valuator mask to get the right coordinates,
    i.e. we set the value but don't set the mask for it so XI2 events have the
    right mask.
    
    For an absolute device in relative mode, this broke in b28a1af55cf, the
    value was now always 0. This wasn't visible on the cursor, only in an XI 1.x
    client. The GIMP e.g. sees jumps to x/0 every few events.
    
    Drop the condition introduced in b28a1af55cf, data in valuators is always
    absolute, regardless of the mode.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 3d8756631070c440cefa31b35fea3d407f187810)

diff --git a/dix/getevents.c b/dix/getevents.c
index dfe4652..dd1b253 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -239,7 +239,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent *event, ValuatorMask *mask)
                 SetBit(event->valuators.mode, i);
             event->valuators.data[i] = valuator_mask_get_double(mask, i);
         }
-        else if (valuator_get_mode(dev, i) == Absolute)
+        else
             event->valuators.data[i] = dev->valuator->axisVal[i];
     }
 }
commit ef54bd89b17f3dd1f854435339f66d357121c64c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jul 24 11:50:00 2013 +1000

    dix: check the xi2mask, not the grab type for touch listeners
    
    grab->type is only non-zero for passive grabs. We're checking an active grab
    here, so we need to check if the touch mask is set on the grab.
    
    Test case: grab the device, then start two simultaneous touches. The
    grabbing client won't see the second touchpoints because grab->type is 0
    and the second touch is not an emulating pointer.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 4fb686d6a6777950f0e0d55b848cd2af4cbad372)

diff --git a/dix/touch.c b/dix/touch.c
index a4b6d7e..a7ea213 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -895,8 +895,7 @@ TouchAddActiveGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
 
     if (!ti->emulate_pointer &&
         grab->grabtype == XI2 &&
-        (grab->type != XI_TouchBegin && grab->type != XI_TouchEnd &&
-         grab->type != XI_TouchUpdate))
+        !xi2mask_isset(grab->xi2mask, dev, XI_TouchBegin))
         return;
 
     TouchAddGrabListener(dev, ti, ev, grab);
diff --git a/include/inputstr.h b/include/inputstr.h
index 85be885..2da72c1 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -195,7 +195,7 @@ typedef struct _GrabRec {
     unsigned keyboardMode:1;
     unsigned pointerMode:1;
     enum InputLevel grabtype;
-    CARD8 type;                 /* event type */
+    CARD8 type;                 /* event type for passive grabs, 0 for active grabs */
     DetailRec modifiersDetail;
     DeviceIntPtr modifierDevice;
     DetailRec detail;           /* key or button */
commit bc41226f7741098e55a3b0df924986991576d50a
Merge: 4ebd618 2cd62dc
Author: Matt Dew <marcoz at osource.org>
Date:   Thu Jul 25 22:56:24 2013 -0600

    Merge branch 'server-1.14-touch-fixes' of git://people.freedesktop.org/~whot/xserver into server-1.14-branch

commit 4ebd618bc5ef71507e708e7191091828eca3a7e8
Author: Matt Dew <marcoz at osource.org>
Date:   Thu Jul 25 22:24:00 2013 -0600

    Bah, bad rev number. Fixed:  changed 1.14.3-rc1 to 1.14.2.901

diff --git a/configure.ac b/configure.ac
index 8738813..271e49d 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.14.3-rc1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+AC_INIT([xorg-server], 1.14.2.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
 RELEASE_DATE="2013-07-25"
 RELEASE_NAME="Act semi-normal-rc1"
 AC_CONFIG_SRCDIR([Makefile.am])
commit fef66ffe7a7e899a9126a1e431b94d881163b00d
Author: Matt Dew <marcoz at osource.org>
Date:   Thu Jul 25 22:02:26 2013 -0600

    bump rev from 1.14.2 to 1.14.3-rc1

diff --git a/configure.ac b/configure.ac
index 99e3cd6..8738813 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.14.2, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-06-25"
-RELEASE_NAME="Act Abnormal"
+AC_INIT([xorg-server], 1.14.3-rc1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-07-25"
+RELEASE_NAME="Act semi-normal-rc1"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
commit 2cd62dc02b67c70d2417b2ccd307ead9596a2967
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Mar 1 08:43:58 2013 +1000

    Xi: return !Success from DeliverTouchEmulatedEvent if we didn't deliver
    
    All callers currently ignore the new value, so this patch has no effect.
    Inverse call graph:
    
    DeliverTouchEmulatedEvent
            DeliverEmulatedMotionEvent              Ignores value
            DeliverTouchBeginEvent
                    DeliverTouchEvent
                            DeliverTouchEvents      Ignores value
            DeliverTouchEndEvent
                    DeliverTouchEvent
                            DeliverTouchEvents      Ignores value
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 9978b57b8d94f061d72a67b99a02b0ba16a11429)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 91281ae..067e6b3 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1373,7 +1373,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
 
     /* We don't deliver pointer events to non-owners */
     if (!TouchResourceIsOwner(ti, listener->listener))
-        return Success;
+        return !Success;
 
     nevents = TouchConvertToPointerEvent(ev, &motion, &button);
     BUG_RETURN_VAL(nevents == 0, BadValue);
@@ -1395,7 +1395,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
             /* 'grab' is the passive grab, but if the grab isn't active,
              * don't deliver */
             if (!dev->deviceGrab.grab)
-                return Success;
+                return !Success;
 
             if (grab->ownerEvents) {
                 WindowPtr focus = NullWindow;
commit c203568905bcbb65fb1e079b626d2c1e90ecb72d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 13 15:22:12 2013 +1000

    Xi: fix warning - remove unused 'rc'
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit fd5ea0237db6d725a48f76b706135df9d3246b82)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 30e48f0..91281ae 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1036,7 +1036,6 @@ DeliverOneTouchEvent(ClientPtr client, DeviceIntPtr dev, TouchPointInfoPtr ti,
 static void
 ActivateEarlyAccept(DeviceIntPtr dev, TouchPointInfoPtr ti)
 {
-    int rc;
     ClientPtr client;
     XID error;
     GrabPtr grab = ti->listeners[0].grab;
commit 93f063c40dc4b339ae9114551071c57b52d98dba
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jul 12 14:10:10 2013 +1000

    dix: UpdateTouchesForGrab must only free the listener grab if it is non-NULL
    
    If a client calls XIGrabDevice in response to a ButtonPress event (regular
    event selection), the device will have a grab, but listener->grab is NULL.
    
    Check for that, to avoid logspam.
    
    [ 26293.863] (EE) BUG: triggered 'if (!pGrab)'
    [ 26293.863] (EE) BUG: grabs.c:256 in FreeGrab()
    [ 26293.863] (EE)
    [ 26293.863] (EE) Backtrace:
    [ 26293.864] (EE) 0: /usr/bin/Xorg (FreeGrab+0x54) [0x45d3fc]
    [ 26293.864] (EE) 1: /usr/bin/Xorg (UpdateTouchesForGrab+0x135) [0x447d4e]
    [ 26293.864] (EE) 2: /usr/bin/Xorg (ActivatePointerGrab+0x1ba) [0x447f3d]
    [ 26293.864] (EE) 3: /usr/bin/Xorg (GrabDevice+0x3e6) [0x4503bc]
    [ 26293.864] (EE) 4: /usr/bin/Xorg (ProcXIGrabDevice+0x1f9) [0x5981b1]
    [ 26293.865] (EE) 5: /usr/bin/Xorg (ProcIDispatch+0x78) [0x58aa17]
    [ 26293.865] (EE) 6: /usr/bin/Xorg (Dispatch+0x30d) [0x43347e]
    [ 26293.865] (EE) 7: /usr/bin/Xorg (main+0x61d) [0x498175]
    [ 26293.865] (EE) 8: /lib64/libc.so.6 (__libc_start_main+0xf5) [0x3df5621b75]
    [ 26293.865] (EE) 9: /usr/bin/Xorg (_start+0x29) [0x423a19]
    [ 26293.866] (EE) 10: ? (?+0x29) [0x29]
    [ 26293.866] (EE)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 0e3be0b25fcfeff386bad132526352c2e45f1932)

diff --git a/dix/events.c b/dix/events.c
index f9b2ed7..c079f97 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1438,7 +1438,8 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
                 listener->type = LISTENER_POINTER_GRAB;
             else
                 listener->type = LISTENER_GRAB;
-            FreeGrab(listener->grab);
+            if (listener->grab)
+                FreeGrab(listener->grab);
             listener->grab = AllocGrab(grab);
         }
     }
commit ecd178e632a99ae2f12d2d9b6e9a48eaa421335d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jul 9 13:27:19 2013 +1000

    dix: when ungrabbing an active grab, accept pointer grabs (#66720)
    
    Ungrabbing a device during an active touch grab rejects the grab. Ungrabbing
    a device during an active pointer grab accepts the grab.
    
    Rejection is not really an option for a pointer-emulated grab, if a client
    has a button mask on the window it would get a ButtonPress emulated after
    UngrabDevice. That is against the core grab behaviour.
    
    X.Org Bug 66720 <http://bugs.freedesktop.org/show_bug.cgi?id=66720>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>
    (cherry picked from commit 8eeaa74bc241acb41f1d3ed64971e0b01e794776)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index e1945b9..30e48f0 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1224,9 +1224,13 @@ ProcessTouchOwnershipEvent(TouchOwnershipEvent *ev,
     else if (ev->reason == XIAcceptTouch) {
         int i;
 
-        /* Go through the motions of ending the touch if the listener has
+
+        /* For pointer-emulated listeners that ungrabbed the active grab,
+         * the state was forced to LISTENER_HAS_END. Still go
+         * through the motions of ending the touch if the listener has
          * already seen the end. This ensures that the touch record is ended in
-         * the server. */
+         * the server.
+         */
         if (ti->listeners[0].state == LISTENER_HAS_END)
             TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
 
@@ -1884,16 +1888,23 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
 
     if (listener->type == LISTENER_POINTER_REGULAR ||
         listener->type == LISTENER_POINTER_GRAB) {
-        rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
-                                       grab, xi2mask);
-
-         /* Once we send a TouchEnd to a legacy listener, we're already well
-          * past the accepting/rejecting stage (can only happen on
-          * GrabModeSync + replay. This listener now gets the end event,
-          * and we can continue.
-          */
-        if (rc == Success)
-            listener->state = LISTENER_HAS_END;
+        /* Note: If the active grab was ungrabbed, we already changed the
+         * state to LISTENER_HAS_END but still get here. So we mustn't
+         * actually send the event.
+         * This is part two of the hack in DeactivatePointerGrab
+         */
+        if (listener->state != LISTENER_HAS_END) {
+            rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
+                                           grab, xi2mask);
+
+             /* Once we send a TouchEnd to a legacy listener, we're already well
+              * past the accepting/rejecting stage (can only happen on
+              * GrabModeSync + replay. This listener now gets the end event,
+              * and we can continue.
+              */
+            if (rc == Success)
+                listener->state = LISTENER_HAS_END;
+        }
         goto out;
     }
 
diff --git a/dix/events.c b/dix/events.c
index 4d50a24..f9b2ed7 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1519,13 +1519,20 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
     for (i = 0; !wasPassive && mouse->touch && i < mouse->touch->num_touches; i++) {
         TouchPointInfoPtr ti = mouse->touch->touches + i;
         if (ti->active && TouchResourceIsOwner(ti, grab_resource)) {
+            int mode = XIRejectTouch;
             /* Rejecting will generate a TouchEnd, but we must not
                emulate a ButtonRelease here. So pretend the listener
                already has the end event */
             if (grab->grabtype == CORE || grab->grabtype == XI ||
-                    !xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin))
+                    !xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin)) {
+                mode = XIAcceptTouch;
+                /* NOTE: we set the state here, but
+                 * ProcessTouchOwnershipEvent() will still call
+                 * TouchEmitTouchEnd for this listener. The other half of
+                 * this hack is in DeliverTouchEndEvent */
                 ti->listeners[0].state = LISTENER_HAS_END;
-            TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
+            }
+            TouchListenerAcceptReject(mouse, ti, 0, mode);
         }
     }
 
commit 54a7ae04a8475df6ce87e52ff995de22fafc7c92
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 27 13:46:49 2013 +1000

    dix: remove logspam in RefCursor()
    
    This shouldn't have been in the patch
    
    Reported-by: Colin Harrison <colin.harrison at virgin.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit c21344add2fc589df83b29be5831c36a372201bd)

diff --git a/dix/cursor.c b/dix/cursor.c
index 0820b18..cd8305c 100644
--- a/dix/cursor.c
+++ b/dix/cursor.c
@@ -134,12 +134,8 @@ FreeCursor(pointer value, XID cid)
 CursorPtr
 RefCursor(CursorPtr cursor)
 {
-    ErrorF("%s ::::: cursor is %p", __func__, cursor);
-    if (cursor) {
-        xorg_backtrace();
+    if (cursor)
         cursor->refcnt++;
-    }
-    ErrorF("\n");
     return cursor;
 }
 
commit 1e29b269fd712ae1e3552eeddd3529015baee7ae
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 15 19:01:11 2013 +1000

    Abstract cursor refcounting
    
    Too many callers relied on the refcnt being handled correctly. Use a simple
    wrapper to handle that case.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 9a5ad65330693b3273972b63d10f2907d9ab954a)

diff --git a/Xext/saver.c b/Xext/saver.c
index 8de043f..fe81bc4 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -531,15 +531,16 @@ CreateSaverWindow(ScreenPtr pScreen)
         mask |= CWBorderPixmap;
     }
     if (pAttr->pCursor) {
+        CursorPtr cursor;
         if (!pWin->optional)
             if (!MakeWindowOptional(pWin)) {
                 FreeResource(pWin->drawable.id, RT_NONE);
                 return FALSE;
             }
-        pAttr->pCursor->refcnt++;
+        cursor = RefCursor(pAttr->pCursor);
         if (pWin->optional->cursor)
             FreeCursor(pWin->optional->cursor, (Cursor) 0);
-        pWin->optional->cursor = pAttr->pCursor;
+        pWin->optional->cursor = cursor;
         pWin->cursorIsNone = FALSE;
         CheckWindowOptionalNeed(pWin);
         mask |= CWCursor;
@@ -1065,8 +1066,7 @@ ScreenSaverSetAttributes(ClientPtr client)
                     client->errorValue = cursorID;
                     goto PatchUp;
                 }
-                pCursor->refcnt++;
-                pAttr->pCursor = pCursor;
+                pAttr->pCursor = RefCursor(pCursor);
                 pAttr->mask &= ~CWCursor;
             }
             break;
diff --git a/dix/cursor.c b/dix/cursor.c
index 1ee127a..0820b18 100644
--- a/dix/cursor.c
+++ b/dix/cursor.c
@@ -114,9 +114,13 @@ FreeCursor(pointer value, XID cid)
     ScreenPtr pscr;
     DeviceIntPtr pDev = NULL;   /* unused anyway */
 
-    if (--pCurs->refcnt != 0)
+
+    UnrefCursor(pCurs);
+    if (CursorRefCount(pCurs) != 0)
         return Success;
 
+    BUG_WARN(CursorRefCount(pCurs) < 0);
+
     for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
         pscr = screenInfo.screens[nscr];
         (void) (*pscr->UnrealizeCursor) (pDev, pscr, pCurs);
@@ -127,6 +131,33 @@ FreeCursor(pointer value, XID cid)
     return Success;
 }
 
+CursorPtr
+RefCursor(CursorPtr cursor)
+{
+    ErrorF("%s ::::: cursor is %p", __func__, cursor);
+    if (cursor) {
+        xorg_backtrace();
+        cursor->refcnt++;
+    }
+    ErrorF("\n");
+    return cursor;
+}
+
+CursorPtr
+UnrefCursor(CursorPtr cursor)
+{
+    if (cursor)
+        cursor->refcnt--;
+    return cursor;
+}
+
+int
+CursorRefCount(const CursorPtr cursor)
+{
+    return cursor ? cursor->refcnt : 0;
+}
+
+
 /*
  * We check for empty cursors so that we won't have to display them
  */
diff --git a/dix/events.c b/dix/events.c
index 64a8f15..4d50a24 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -931,8 +931,7 @@ ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
 
         (*pScreen->DisplayCursor) (pDev, pScreen, cursor);
         FreeCursor(pSprite->current, (Cursor) 0);
-        pSprite->current = cursor;
-        pSprite->current->refcnt++;
+        pSprite->current = RefCursor(cursor);
     }
 }
 
@@ -3207,11 +3206,10 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin)
         pSprite->pEnqueueScreen = screenInfo.screens[0];
         pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
     }
-    if (pCursor)
-        pCursor->refcnt++;
+    pCursor = RefCursor(pCursor);
     if (pSprite->current)
         FreeCursor(pSprite->current, None);
-    pSprite->current = pCursor;
+    pSprite->current = RefCursor(pCursor);
 
     if (pScreen) {
         (*pScreen->RealizeCursor) (pDev, pScreen, pSprite->current);
@@ -3290,9 +3288,7 @@ UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen)
     pSprite->hotLimits.x2 = pScreen->width;
     pSprite->hotLimits.y2 = pScreen->height;
     pSprite->win = win;
-    pCursor = wCursor(win);
-    if (pCursor)
-        pCursor->refcnt++;
+    pCursor = RefCursor(wCursor(win));
     if (pSprite->current)
         FreeCursor(pSprite->current, 0);
     pSprite->current = pCursor;
@@ -4942,9 +4938,7 @@ ProcChangeActivePointerGrab(ClientPtr client)
         (CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER))
         return Success;
     oldCursor = grab->cursor;
-    grab->cursor = newCursor;
-    if (newCursor)
-        newCursor->refcnt++;
+    grab->cursor = RefCursor(newCursor);
     PostNewCursor(device);
     if (oldCursor)
         FreeCursor(oldCursor, (Cursor) 0);
@@ -5089,9 +5083,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
         else
             xi2mask_merge(tempGrab->xi2mask, mask->xi2mask);
         tempGrab->device = dev;
-        tempGrab->cursor = cursor;
-        if (cursor)
-            tempGrab->cursor->refcnt++;
+        tempGrab->cursor = RefCursor(cursor);
         tempGrab->confineTo = confineTo;
         tempGrab->grabtype = grabtype;
         (*grabInfo->ActivateGrab) (dev, tempGrab, time, FALSE);
diff --git a/dix/grabs.c b/dix/grabs.c
index b254ddc..a03897a 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -241,13 +241,11 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
     grab->detail.exact = keybut;
     grab->detail.pMask = NULL;
     grab->confineTo = confineTo;
-    grab->cursor = cursor;
+    grab->cursor = RefCursor(cursor);
     grab->next = NULL;
 
     if (grabtype == XI2)
         xi2mask_merge(grab->xi2mask, mask->xi2mask);
-    if (cursor)
-        cursor->refcnt++;
     return grab;
 
 }
@@ -274,9 +272,6 @@ CopyGrab(GrabPtr dst, const GrabPtr src)
     Mask *details_mask = NULL;
     XI2Mask *xi2mask;
 
-    if (src->cursor)
-        src->cursor->refcnt++;
-
     if (src->modifiersDetail.pMask) {
         int len = MasksPerDetailMask * sizeof(Mask);
 
@@ -314,6 +309,7 @@ CopyGrab(GrabPtr dst, const GrabPtr src)
     dst->modifiersDetail.pMask = mdetails_mask;
     dst->detail.pMask = details_mask;
     dst->xi2mask = xi2mask;
+    dst->cursor = RefCursor(src->cursor);
 
     xi2mask_merge(dst->xi2mask, src->xi2mask);
 
diff --git a/dix/window.c b/dix/window.c
index a5b28a6..8e61779 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -547,8 +547,7 @@ InitRootWindow(WindowPtr pWin)
     (*pScreen->PositionWindow) (pWin, 0, 0);
 
     pWin->cursorIsNone = FALSE;
-    pWin->optional->cursor = rootCursor;
-    rootCursor->refcnt++;
+    pWin->optional->cursor = RefCursor(rootCursor);
 
     if (party_like_its_1989) {
         MakeRootTile(pWin);
@@ -1416,8 +1415,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
                     else if (pWin->parent && pCursor == wCursor(pWin->parent))
                         checkOptional = TRUE;
                     pOldCursor = pWin->optional->cursor;
-                    pWin->optional->cursor = pCursor;
-                    pCursor->refcnt++;
+                    pWin->optional->cursor = RefCursor(pCursor);
                     pWin->cursorIsNone = FALSE;
                     /*
                      * check on any children now matching the new cursor
@@ -3321,8 +3319,7 @@ MakeWindowOptional(WindowPtr pWin)
     parentOptional = FindWindowWithOptional(pWin)->optional;
     optional->visual = parentOptional->visual;
     if (!pWin->cursorIsNone) {
-        optional->cursor = parentOptional->cursor;
-        optional->cursor->refcnt++;
+        optional->cursor = RefCursor(parentOptional->cursor);
     }
     else {
         optional->cursor = None;
@@ -3410,8 +3407,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
     if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor))
         pNode->cursor = None;
     else {
-        pNode->cursor = pCursor;
-        pCursor->refcnt++;
+        pNode->cursor = RefCursor(pCursor);
     }
 
     pNode = pPrev = NULL;
@@ -3419,8 +3415,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
     for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
         if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) {
             if (pNode->cursor == None) {        /* inherited from parent */
-                pNode->cursor = pOldCursor;
-                pOldCursor->refcnt++;
+                pNode->cursor = RefCursor(pOldCursor);
             }
             else if (pNode->cursor == pCursor) {
                 pNode->cursor = None;
diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
index 634ee3f..2b0db34 100644
--- a/hw/xfree86/modes/xf86Cursors.c
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -481,7 +481,7 @@ xf86_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
     xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
 
-    ++cursor->refcnt;
+    cursor = RefCursor(cursor);
     if (xf86_config->cursor)
         FreeCursor(xf86_config->cursor, None);
     xf86_config->cursor = cursor;
@@ -500,7 +500,7 @@ xf86_use_hw_cursor_argb(ScreenPtr screen, CursorPtr cursor)
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
     xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
 
-    ++cursor->refcnt;
+    cursor = RefCursor(cursor);
     if (xf86_config->cursor)
         FreeCursor(xf86_config->cursor, None);
     xf86_config->cursor = cursor;
diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index 8d48a75..f30bd33 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -272,7 +272,7 @@ xf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
                                                xf86CursorScreenKey);
 
-    if (pCurs->refcnt <= 1)
+    if (CursorRefCount(pCurs) <= 1)
         dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
                             NULL);
 
@@ -286,7 +286,7 @@ xf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
                                                xf86CursorScreenKey);
 
-    if (pCurs->refcnt <= 1) {
+    if (CursorRefCount(pCurs) <= 1) {
         free(dixLookupScreenPrivate
              (&pCurs->devPrivates, CursorScreenKey, pScreen));
         dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
@@ -323,37 +323,37 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
     /* only update for VCP, otherwise we get cursor jumps when removing a
        sprite. The second cursor is never HW rendered anyway. */
     if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) {
-        pCurs->refcnt++;
+        CursorPtr cursor = RefCursor(pCurs);
         if (ScreenPriv->CurrentCursor)
             FreeCursor(ScreenPriv->CurrentCursor, None);
-        ScreenPriv->CurrentCursor = pCurs;
+        ScreenPriv->CurrentCursor = cursor;
         ScreenPriv->x = x;
         ScreenPriv->y = y;
         ScreenPriv->CursorToRestore = NULL;
-        ScreenPriv->HotX = pCurs->bits->xhot;
-        ScreenPriv->HotY = pCurs->bits->yhot;
+        ScreenPriv->HotX = cursor->bits->xhot;
+        ScreenPriv->HotY = cursor->bits->yhot;
 
         if (!infoPtr->pScrn->vtSema)
-            ScreenPriv->SavedCursor = pCurs;
+            ScreenPriv->SavedCursor = cursor;
 
         if (infoPtr->pScrn->vtSema && xorg_list_is_empty(&pScreen->pixmap_dirty_list) &&
             (ScreenPriv->ForceHWCursorCount ||
              ((
 #ifdef ARGB_CURSOR
-               pCurs->bits->argb &&
+               cursor->bits->argb &&
                infoPtr->UseHWCursorARGB &&
-               (*infoPtr->UseHWCursorARGB)(pScreen, pCurs)) ||
-              (pCurs->bits->argb == 0 &&
+               (*infoPtr->UseHWCursorARGB)(pScreen, cursor)) ||
+              (cursor->bits->argb == 0 &&
 #endif
-               (pCurs->bits->height <= infoPtr->MaxHeight) &&
-               (pCurs->bits->width <= infoPtr->MaxWidth) &&
-               (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, pCurs)))))) {
+               (cursor->bits->height <= infoPtr->MaxHeight) &&
+               (cursor->bits->width <= infoPtr->MaxWidth) &&
+               (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, cursor)))))) {
             
             if (ScreenPriv->SWCursor)   /* remove the SW cursor */
                 (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
                                                        NullCursor, x, y);
 
-            xf86SetCursor(pScreen, pCurs, x, y);
+            xf86SetCursor(pScreen, cursor, x, y);
             ScreenPriv->SWCursor = FALSE;
             ScreenPriv->isUp = TRUE;
 
diff --git a/include/cursor.h b/include/cursor.h
index 0823251..89a650f 100644
--- a/include/cursor.h
+++ b/include/cursor.h
@@ -71,6 +71,10 @@ extern _X_EXPORT CursorPtr rootCursor;
 extern _X_EXPORT int FreeCursor(pointer /*pCurs */ ,
                                 XID /*cid */ );
 
+extern _X_EXPORT CursorPtr RefCursor(CursorPtr /* cursor */);
+extern _X_EXPORT CursorPtr UnrefCursor(CursorPtr /* cursor */);
+extern _X_EXPORT int CursorRefCount(const CursorPtr /* cursor */);
+
 extern _X_EXPORT int AllocARGBCursor(unsigned char * /*psrcbits */ ,
                                      unsigned char * /*pmaskbits */ ,
                                      CARD32 * /*argb */ ,
diff --git a/render/animcur.c b/render/animcur.c
index 9cbba83..038c5b9 100644
--- a/render/animcur.c
+++ b/render/animcur.c
@@ -383,8 +383,7 @@ AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
     ac->elts = (AnimCurElt *) (ac + 1);
 
     for (i = 0; i < ncursor; i++) {
-        cursors[i]->refcnt++;
-        ac->elts[i].pCursor = cursors[i];
+        ac->elts[i].pCursor = RefCursor(cursors[i]);
         ac->elts[i].delay = deltas[i];
     }
 
diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index 568e717..cc6e059 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -619,12 +619,12 @@ ReplaceCursorLookup(pointer value, XID id, pointer closure)
     }
     if (pCursor && pCursor != rcl->pNew) {
         if ((*rcl->testCursor) (pCursor, rcl->closure)) {
-            rcl->pNew->refcnt++;
+            CursorPtr curs = RefCursor(rcl->pNew);
             /* either redirect reference or update resource database */
             if (pCursorRef)
-                *pCursorRef = rcl->pNew;
+                *pCursorRef = curs;
             else
-                ChangeResourceValue(id, RT_CURSOR, rcl->pNew);
+                ChangeResourceValue(id, RT_CURSOR, curs);
             FreeCursor(pCursor, cursor);
         }
     }
commit c0be1168fd3dd2eb01187789ddc30d7aab909a98
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 14 14:51:31 2013 +1000

    dix: call UpdateDeviceState() for emulated TouchEndEvents
    
    ProcessTouchEvents() calls UDS for all touch events, but if the event type
    was switched to TouchUpdate(pending end) UDS is a noop.
    
    Daniel Drake found this can cause stuck buttons if a touch grab is
    activated, rejected and the touch event is passed to a regular listener.
    This sequence causes the TouchEnd to be changed to TouchUpdate(pending end).
    
    The actual TouchEnd event is later generated by the server once it is passed
    to the next listener. UDS is never called for this event, thus the button
    remains logically down.
    
    A previous patch suggested for UDS to handle TouchUpdate events [1], however
    this would release the button when the first TouchEvent is processed, not
    when the last grab has been released (as is the case for sync pointer
    grabs). A client may thus have the grab on the device, receive a ButtonPress
    but see the button logically up in an XQueryPointer request.
    
    This patch adds a call to UDS to TouchEmitTouchEnd(). The device state must
    be updated once a TouchEnd event was sent to the last grabbing listener and
    the number of grabs on the touchpoint is 0.
    
    [1] http://patchwork.freedesktop.org/patch/13464/
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 35c2e263db01b2b61354298e5e85aa3cae8ac317)

diff --git a/dix/touch.c b/dix/touch.c
index 110b1cc..a4b6d7e 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -1122,6 +1122,8 @@ TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resourc
     TouchDeliverDeviceClassesChangedEvent(ti, GetTimeInMillis(), resource);
     GetDixTouchEnd(&event, dev, ti, flags);
     DeliverTouchEvents(dev, ti, &event, resource);
+    if (ti->num_grabs == 0)
+        UpdateDeviceState(dev, &event.device_event);
 }
 
 void
commit 5c32bd0e2c104deaa2820c62289916fff6a4e3cd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 3 15:07:58 2013 +1000

    dix: fix cursor refcounting
    
    The cursor is referenced during CopyGrab(), thus doesn't need to be handled
    manually anymore. It does need to be refcounted for temp grabs though.
    
    The oldGrab handling in ProcGrabPointer is a leftover from the cursor in the
    grab being refcounted, but the grab itself being a static struct in the
    DeviceIntRec. Now that all grabs are copied, this lead to a double-free of
    the cursor (Reproduced in Thunderbird, dragging an email twice (or more
    often) causes a crash).
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 481702101b86fff003430e952dc65fb41eb56400)

diff --git a/dix/events.c b/dix/events.c
index 24fd6b9..64a8f15 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1488,9 +1488,6 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
         grabinfo->grabTime = syncEvents.time;
     else
         grabinfo->grabTime = time;
-    if (grab->cursor)
-        grab->cursor->refcnt++;
-    BUG_WARN(grabinfo->grab != NULL);
     grabinfo->grab = AllocGrab(grab);
     grabinfo->fromPassiveGrab = isPassive;
     grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
@@ -1549,8 +1546,6 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
     if (grab->confineTo)
         ConfineCursorToWindow(mouse, GetCurrentRootWindow(mouse), FALSE, FALSE);
     PostNewCursor(mouse);
-    if (grab->cursor)
-        FreeCursor(grab->cursor, (Cursor) 0);
 
     if (!wasImplicit && grab->grabtype == XI2)
         ReattachToOldMaster(mouse);
@@ -4857,7 +4852,6 @@ ProcGrabPointer(ClientPtr client)
     GrabPtr grab;
     GrabMask mask;
     WindowPtr confineTo;
-    CursorPtr oldCursor;
     BYTE status;
 
     REQUEST(xGrabPointerReq);
@@ -4880,15 +4874,10 @@ ProcGrabPointer(ClientPtr client)
             return rc;
     }
 
-    oldCursor = NullCursor;
     grab = device->deviceGrab.grab;
 
-    if (grab) {
-        if (grab->confineTo && !confineTo)
-            ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE,
-                                  FALSE);
-        oldCursor = grab->cursor;
-    }
+    if (grab && grab->confineTo && !confineTo)
+        ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE, FALSE);
 
     mask.core = stuff->eventMask;
 
@@ -4898,9 +4887,6 @@ ProcGrabPointer(ClientPtr client)
     if (rc != Success)
         return rc;
 
-    if (oldCursor && status == GrabSuccess)
-        FreeCursor(oldCursor, (Cursor) 0);
-
     rep = (xGrabPointerReply) {
         .type = X_Reply,
         .status = status,
@@ -5104,6 +5090,8 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
             xi2mask_merge(tempGrab->xi2mask, mask->xi2mask);
         tempGrab->device = dev;
         tempGrab->cursor = cursor;
+        if (cursor)
+            tempGrab->cursor->refcnt++;
         tempGrab->confineTo = confineTo;
         tempGrab->grabtype = grabtype;
         (*grabInfo->ActivateGrab) (dev, tempGrab, time, FALSE);
commit 0ee9704f3c70fa7cf77edef55d158ad78df72a25
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 3 15:02:05 2013 +1000

    dix: free the old grab when activating a new grab
    
    A client may call XIGrabDevice twice, overwriting the existing grab. Thus,
    make sure we free the old copy after we copied it. Free it last, to make
    sure our refcounts don't run to 0 and inadvertantly free something on the
    way.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 3093f78d17e48a506aab170a9089cd10e21af299)

diff --git a/dix/events.c b/dix/events.c
index 8745c11..24fd6b9 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1465,6 +1465,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
                     TimeStamp time, Bool autoGrab)
 {
     GrabInfoPtr grabinfo = &mouse->deviceGrab;
+    GrabPtr oldgrab = grabinfo->grab;
     WindowPtr oldWin = (grabinfo->grab) ?
         grabinfo->grab->window : mouse->spriteInfo->sprite->win;
     Bool isPassive = autoGrab & ~ImplicitGrabMask;
@@ -1497,6 +1498,8 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
     UpdateTouchesForGrab(mouse);
     CheckGrabForSyncs(mouse, (Bool) grab->pointerMode,
                       (Bool) grab->keyboardMode);
+    if (oldgrab)
+        FreeGrab(oldgrab);
 }
 
 /**
@@ -1567,6 +1570,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
                      Bool passive)
 {
     GrabInfoPtr grabinfo = &keybd->deviceGrab;
+    GrabPtr oldgrab = grabinfo->grab;
     WindowPtr oldWin;
 
     /* slave devices need to float for the duration of the grab. */
@@ -1592,12 +1596,13 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
         grabinfo->grabTime = syncEvents.time;
     else
         grabinfo->grabTime = time;
-    BUG_WARN(grabinfo->grab != NULL);
     grabinfo->grab = AllocGrab(grab);
     grabinfo->fromPassiveGrab = passive;
     grabinfo->implicitGrab = passive & ImplicitGrabMask;
     CheckGrabForSyncs(keybd, (Bool) grab->keyboardMode,
                       (Bool) grab->pointerMode);
+    if (oldgrab)
+        FreeGrab(oldgrab);
 }
 
 /**
commit ef0fff102d1feb5bccffc918da5c0dc7c0d28f3b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 24 14:46:06 2013 +1000

    Xi: check for HAS_ACCEPTED only for grab listeners
    
    If we have one listener left but it's not a grab, it cannot be in
    LISTENER_HAS_ACCEPTED state.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 2566bdd8bc996cccde77b846819808c6239a89d2)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 90cbcc5..e1945b9 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1917,7 +1917,7 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
             rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
 
         if ((ti->num_listeners > 1 ||
-             listener->state != LISTENER_HAS_ACCEPTED) &&
+             (ti->num_grabs > 0 && listener->state != LISTENER_HAS_ACCEPTED)) &&
             (ev->device_event.flags & (TOUCH_ACCEPT | TOUCH_REJECT)) == 0) {
             ev->any.type = ET_TouchUpdate;
             ev->device_event.flags |= TOUCH_PENDING_END;
commit f3d63710d57aea0184ae07f0422a76b0fd6d415f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 24 14:40:31 2013 +1000

    Move TouchListenerGone call to CloseDownClient
    
    TouchListenerGone cleans up if a client disappears. Having this in
    FreeGrab() triggers cyclic removal of grabs, emitting wrong events. In
    particular, it would clean up a passive grab record while that grab is
    active.
    
    Move it to CloseDownClient() instead, cleaning up before we go.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 5b00fc52270e9cfdfe7ac1838a21defe50fc3d31)

diff --git a/dix/dispatch.c b/dix/dispatch.c
index 8d61735..20f2414 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3398,6 +3398,7 @@ CloseDownClient(ClientPtr client)
             clientinfo.setup = (xConnSetup *) NULL;
             CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
         }
+        TouchListenerGone(client->clientAsMask);
         FreeClientResources(client);
         /* Disable client ID tracking. This must be done after
          * ClientStateCallback. */
diff --git a/dix/grabs.c b/dix/grabs.c
index f46a6b2..b254ddc 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -257,9 +257,6 @@ FreeGrab(GrabPtr pGrab)
 {
     BUG_RETURN(!pGrab);
 
-    if (pGrab->grabtype == XI2 && pGrab->type == XI_TouchBegin)
-        TouchListenerGone(pGrab->resource);
-
     free(pGrab->modifiersDetail.pMask);
     free(pGrab->detail.pMask);
 
diff --git a/dix/touch.c b/dix/touch.c
index 0099914..110b1cc 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -989,11 +989,11 @@ TouchListenerGone(XID resource)
                 continue;
 
             for (j = 0; j < ti->num_listeners; j++) {
-                if (ti->listeners[j].listener != resource)
+                if (CLIENT_BITS(ti->listeners[j].listener) != resource)
                     continue;
 
                 nev = GetTouchOwnershipEvents(events, dev, ti, XIRejectTouch,
-                                              resource, 0);
+                                              ti->listeners[j].listener, 0);
                 for (k = 0; k < nev; k++)
                     mieqProcessDeviceEvent(dev, events + k, NULL);
 
commit 6c880c143f6a32d3bbc529e4a0ab1663ddecf0a0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 24 12:53:52 2013 +1000

    dix: remove all listeners when freeing a touch
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 34c9b39d9937c2e19c2dffc9748605f90d40f965)

diff --git a/dix/touch.c b/dix/touch.c
index fb218d4..0099914 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -263,6 +263,7 @@ void
 TouchFreeTouchPoint(DeviceIntPtr device, int index)
 {
     TouchPointInfoPtr ti;
+    int i;
 
     if (!device->touch || index >= device->touch->num_touches)
         return;
@@ -271,6 +272,9 @@ TouchFreeTouchPoint(DeviceIntPtr device, int index)
     if (ti->active)
         TouchEndTouch(device, ti);
 
+    for (i = 0; i < ti->num_listeners; i++)
+        TouchRemoveListener(ti, ti->listeners[0].listener);
+
     valuator_mask_free(&ti->valuators);
     free(ti->sprite.spriteTrace);
     ti->sprite.spriteTrace = NULL;
commit ab76a3a3fc56cf8f530e5ab9b6389b09da1cdc12
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 17 20:15:35 2013 +1000

    dix: always copy grabs, don't reference them
    
    Introduced in xorg-server-1.13.99.901-2-g9ad0fdb. Storing the grab pointer
    in the listener turns out to be a bad idea. If the grab is not an active
    grab or an implicit grab, the pointer stored is the one to the grab attached
    on the window. This grab may be removed if the client calls UngrabButton or
    similar while the touch is still active, leaving a dangling pointer.
    
    To avoid this, copy the grab wherever we need to reference it later. This
    is also what we do for pointer/keyboard grabs, where we copy the grab as
    soon as it becomes active.
    
    Reported-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 395124bd2782823de37e5c5b2f15dba49cff05f6)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index ff32e02..90cbcc5 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1429,8 +1429,11 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
          */
         if (!devgrab && dev->deviceGrab.grab && dev->deviceGrab.implicitGrab) {
             TouchListener *l;
+            GrabPtr g;
 
             devgrab = dev->deviceGrab.grab;
+            g = AllocGrab(devgrab);
+            BUG_WARN(!g);
 
             *dev->deviceGrab.sync.event = ev->device_event;
 
@@ -1439,8 +1442,8 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
              * event selection. Thus, we update the last listener in the array.
              */
             l = &ti->listeners[ti->num_listeners - 1];
-            l->listener = devgrab->resource;
-            l->grab = devgrab;
+            l->listener = g->resource;
+            l->grab = g;
             //l->resource_type = RT_NONE;
 
             if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
diff --git a/dix/events.c b/dix/events.c
index 6a8e7a6..8745c11 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1439,7 +1439,8 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
                 listener->type = LISTENER_POINTER_GRAB;
             else
                 listener->type = LISTENER_GRAB;
-            listener->grab = grab;
+            FreeGrab(listener->grab);
+            listener->grab = AllocGrab(grab);
         }
     }
 }
diff --git a/dix/touch.c b/dix/touch.c
index 01a554e..fb218d4 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -365,6 +365,8 @@ TouchBeginTouch(DeviceIntPtr dev, int sourceid, uint32_t touchid,
 void
 TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti)
 {
+    int i;
+
     if (ti->emulate_pointer) {
         GrabPtr grab;
 
@@ -376,6 +378,9 @@ TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti)
         }
     }
 
+    for (i = 0; i < ti->num_listeners; i++)
+        TouchRemoveListener(ti, ti->listeners[0].listener);
+
     ti->active = FALSE;
     ti->pending_finish = FALSE;
     ti->sprite.spriteTraceGood = 0;
@@ -692,15 +697,23 @@ void
 TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
                  enum InputLevel level, enum TouchListenerType type,
                  enum TouchListenerState state, WindowPtr window,
-                 GrabPtr grab)
+                 const GrabPtr grab)
 {
+    GrabPtr g = NULL;
+
+    /* We need a copy of the grab, not the grab itself since that may be
+     * deleted by a UngrabButton request and leaves us with a dangling
+     * pointer */
+    if (grab)
+        g = AllocGrab(grab);
+
     ti->listeners[ti->num_listeners].listener = resource;
     ti->listeners[ti->num_listeners].resource_type = resource_type;
     ti->listeners[ti->num_listeners].level = level;
     ti->listeners[ti->num_listeners].state = state;
     ti->listeners[ti->num_listeners].type = type;
     ti->listeners[ti->num_listeners].window = window;
-    ti->listeners[ti->num_listeners].grab = grab;
+    ti->listeners[ti->num_listeners].grab = g;
     if (grab)
         ti->num_grabs++;
     ti->num_listeners++;
@@ -725,6 +738,7 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
             continue;
 
         if (listener->grab) {
+            FreeGrab(listener->grab);
             listener->grab = NULL;
             ti->num_grabs--;
         }
@@ -734,6 +748,7 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
         ti->num_listeners--;
         ti->listeners[ti->num_listeners].listener = 0;
         ti->listeners[ti->num_listeners].state = LISTENER_AWAITING_BEGIN;
+
         return TRUE;
     }
     return FALSE;
commit 6bd9badc780ec9d1fb147dfa0c671979c75b722c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 23 15:52:18 2013 +1000

    dix: AllocGrab can copy if an argument is passed in
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 925e35122ebad877395bcf13676e9dbeb254bdfa)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index c33a922..ff32e02 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -2845,7 +2845,7 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
              (deliveryMask & DeviceButtonGrabMask)) {
         GrabPtr tempGrab;
 
-        tempGrab = AllocGrab();
+        tempGrab = AllocGrab(NULL);
         if (!tempGrab)
             return;
 
diff --git a/Xi/ungrdevb.c b/Xi/ungrdevb.c
index c4632fa..b02510e 100644
--- a/Xi/ungrdevb.c
+++ b/Xi/ungrdevb.c
@@ -127,7 +127,7 @@ ProcXUngrabDeviceButton(ClientPtr client)
         (stuff->modifiers & ~AllModifiersMask))
         return BadValue;
 
-    temporaryGrab = AllocGrab();
+    temporaryGrab = AllocGrab(NULL);
     if (!temporaryGrab)
         return BadAlloc;
 
diff --git a/Xi/ungrdevk.c b/Xi/ungrdevk.c
index 3273878..f981171 100644
--- a/Xi/ungrdevk.c
+++ b/Xi/ungrdevk.c
@@ -134,7 +134,7 @@ ProcXUngrabDeviceKey(ClientPtr client)
         (stuff->modifiers & ~AllModifiersMask))
         return BadValue;
 
-    temporaryGrab = AllocGrab();
+    temporaryGrab = AllocGrab(NULL);
     if (!temporaryGrab)
         return BadAlloc;
 
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 62a3a46..eccec0a 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -307,7 +307,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
 
     mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
 
-    tempGrab = AllocGrab();
+    tempGrab = AllocGrab(NULL);
     if (!tempGrab)
         return BadAlloc;
 
diff --git a/dix/events.c b/dix/events.c
index 0216502..6a8e7a6 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1489,8 +1489,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
     if (grab->cursor)
         grab->cursor->refcnt++;
     BUG_WARN(grabinfo->grab != NULL);
-    grabinfo->grab = AllocGrab();
-    CopyGrab(grabinfo->grab, grab);
+    grabinfo->grab = AllocGrab(grab);
     grabinfo->fromPassiveGrab = isPassive;
     grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
     PostNewCursor(mouse);
@@ -1593,8 +1592,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
     else
         grabinfo->grabTime = time;
     BUG_WARN(grabinfo->grab != NULL);
-    grabinfo->grab = AllocGrab();
-    CopyGrab(grabinfo->grab, grab);
+    grabinfo->grab = AllocGrab(grab);
     grabinfo->fromPassiveGrab = passive;
     grabinfo->implicitGrab = passive & ImplicitGrabMask;
     CheckGrabForSyncs(keybd, (Bool) grab->keyboardMode,
@@ -1988,7 +1986,7 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
     else
         return FALSE;
 
-    tempGrab = AllocGrab();
+    tempGrab = AllocGrab(NULL);
     if (!tempGrab)
         return FALSE;
     tempGrab->next = NULL;
@@ -3895,7 +3893,7 @@ CheckPassiveGrabsOnWindow(WindowPtr pWin,
     if (!grab)
         return NULL;
 
-    tempGrab = AllocGrab();
+    tempGrab = AllocGrab(NULL);
 
     /* Fill out the grab details, but leave the type for later before
      * comparing */
@@ -5084,7 +5082,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
     else {
         GrabPtr tempGrab;
 
-        tempGrab = AllocGrab();
+        tempGrab = AllocGrab(NULL);
 
         tempGrab->next = NULL;
         tempGrab->window = pWin;
@@ -5440,7 +5438,7 @@ ProcUngrabKey(ClientPtr client)
         client->errorValue = stuff->modifiers;
         return BadValue;
     }
-    tempGrab = AllocGrab();
+    tempGrab = AllocGrab(NULL);
     if (!tempGrab)
         return BadAlloc;
     tempGrab->resource = client->clientAsMask;
@@ -5634,7 +5632,7 @@ ProcUngrabButton(ClientPtr client)
 
     ptr = PickPointer(client);
 
-    tempGrab = AllocGrab();
+    tempGrab = AllocGrab(NULL);
     if (!tempGrab)
         return BadAlloc;
     tempGrab->resource = client->clientAsMask;
diff --git a/dix/grabs.c b/dix/grabs.c
index 0a2111d..f46a6b2 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -189,7 +189,7 @@ UngrabAllDevices(Bool kill_client)
 }
 
 GrabPtr
-AllocGrab(void)
+AllocGrab(const GrabPtr src)
 {
     GrabPtr grab = calloc(1, sizeof(GrabRec));
 
@@ -201,6 +201,12 @@ AllocGrab(void)
         }
     }
 
+    if (src && !CopyGrab(grab, src)) {
+        free(grab->xi2mask);
+        free(grab);
+        grab = NULL;
+    }
+
     return grab;
 }
 
@@ -213,7 +219,7 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
 {
     GrabPtr grab;
 
-    grab = AllocGrab();
+    grab = AllocGrab(NULL);
     if (!grab)
         return (GrabPtr) NULL;
     grab->resource = FakeClientID(client);
diff --git a/include/dixgrabs.h b/include/dixgrabs.h
index eccec77..ca3c95b 100644
--- a/include/dixgrabs.h
+++ b/include/dixgrabs.h
@@ -31,7 +31,7 @@ struct _GrabParameters;
 extern void PrintDeviceGrabInfo(DeviceIntPtr dev);
 extern void UngrabAllDevices(Bool kill_client);
 
-extern GrabPtr AllocGrab(void);
+extern GrabPtr AllocGrab(const GrabPtr src);
 extern void FreeGrab(GrabPtr grab);
 extern Bool CopyGrab(GrabPtr dst, const GrabPtr src);
 
commit 479f8bf236d17e2a2093d349d2ef6471ff089a53
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 23 15:46:04 2013 +1000

    dix: freeing a null grab is a bug, complain if doing so
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 4980bcef9973ba1f90f53028f061669ee5d2661b)

diff --git a/dix/grabs.c b/dix/grabs.c
index 3b02352..0a2111d 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -249,6 +249,8 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
 void
 FreeGrab(GrabPtr pGrab)
 {
+    BUG_RETURN(!pGrab);
+
     if (pGrab->grabtype == XI2 && pGrab->type == XI_TouchBegin)
         TouchListenerGone(pGrab->resource);
 
commit 27752301377698124634d48b62ba7fcf8310caab
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 23 15:39:32 2013 +1000

    dix: use a temporary variable for listeners[0]
    
    no functional changes
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit ccfa0f2d5de557546815a5e4f59552e2af46b578)

diff --git a/dix/events.c b/dix/events.c
index 9ac8792..0216502 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1424,21 +1424,22 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
 
     for (i = 0; i < mouse->touch->num_touches; i++) {
         TouchPointInfoPtr ti = mouse->touch->touches + i;
+        TouchListener *listener = &ti->listeners[0];
         GrabPtr grab = mouse->deviceGrab.grab;
 
         if (ti->active &&
-            CLIENT_BITS(ti->listeners[0].listener) == grab->resource) {
-            ti->listeners[0].listener = grab->resource;
-            ti->listeners[0].level = grab->grabtype;
-            ti->listeners[0].state = LISTENER_IS_OWNER;
-            ti->listeners[0].window = grab->window;
+            CLIENT_BITS(listener->listener) == grab->resource) {
+            listener->listener = grab->resource;
+            listener->level = grab->grabtype;
+            listener->state = LISTENER_IS_OWNER;
+            listener->window = grab->window;
 
             if (grab->grabtype == CORE || grab->grabtype == XI ||
                 !xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin))
-                ti->listeners[0].type = LISTENER_POINTER_GRAB;
+                listener->type = LISTENER_POINTER_GRAB;
             else
-                ti->listeners[0].type = LISTENER_GRAB;
-            ti->listeners[0].grab = grab;
+                listener->type = LISTENER_GRAB;
+            listener->grab = grab;
         }
     }
 }
commit d8c0cc9bab1fe159f58c2b5e8056c2d94a623789
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 18 10:32:11 2013 +1000

    dix: drop DeviceIntRec's activeGrab struct
    
    Obsolete since 4bc2761ad5ec2d0668aec639780ffb136605fbc8. This struct
    existed so copying a passive grab could be simply done by
      activeGrab = *grab
    
    and thus have a copy of the GrabPtr we'd get from various sources but still
    be able to check device->grab for NULL.
    
    Since 4bc2761 activeGrab is a pointer itself and points to the same memory
    as grabinfo->grab, leaving us with the potential of dangling pointers if
    either calls FreeGrab() and doesn't reset the other one.
    
    There is no reader of activeGrab anyway, so simply removing it is
    sufficient.
    
    Note: field is merely renamed to keep the ABI. Should be removed in the
    future.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 5363433a5cc64e2f83859aa1c32a89e5e1ddf9e4)

diff --git a/dix/devices.c b/dix/devices.c
index a0d545a..9ef32bb 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -281,7 +281,6 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
     dev->deviceGrab.grabTime = currentTime;
     dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
     dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
-    dev->deviceGrab.activeGrab = AllocGrab();
     dev->deviceGrab.sync.event = calloc(1, sizeof(DeviceEvent));
 
     XkbSetExtension(dev, ProcessKeyboardEvent);
@@ -977,7 +976,8 @@ CloseDevice(DeviceIntPtr dev)
         }
     }
 
-    FreeGrab(dev->deviceGrab.activeGrab);
+    if (dev->deviceGrab.grab)
+        FreeGrab(dev->deviceGrab.grab);
     free(dev->deviceGrab.sync.event);
     free(dev->config_info);     /* Allocated in xf86ActivateDevice. */
     free(dev->last.scroll);
diff --git a/dix/events.c b/dix/events.c
index 7772c0b..9ac8792 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1487,8 +1487,9 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
         grabinfo->grabTime = time;
     if (grab->cursor)
         grab->cursor->refcnt++;
-    CopyGrab(grabinfo->activeGrab, grab);
-    grabinfo->grab = grabinfo->activeGrab;
+    BUG_WARN(grabinfo->grab != NULL);
+    grabinfo->grab = AllocGrab();
+    CopyGrab(grabinfo->grab, grab);
     grabinfo->fromPassiveGrab = isPassive;
     grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
     PostNewCursor(mouse);
@@ -1551,6 +1552,8 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
         ReattachToOldMaster(mouse);
 
     ComputeFreezes();
+
+    FreeGrab(grab);
 }
 
 /**
@@ -1588,8 +1591,9 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
         grabinfo->grabTime = syncEvents.time;
     else
         grabinfo->grabTime = time;
-    CopyGrab(grabinfo->activeGrab, grab);
-    grabinfo->grab = grabinfo->activeGrab;
+    BUG_WARN(grabinfo->grab != NULL);
+    grabinfo->grab = AllocGrab();
+    CopyGrab(grabinfo->grab, grab);
     grabinfo->fromPassiveGrab = passive;
     grabinfo->implicitGrab = passive & ImplicitGrabMask;
     CheckGrabForSyncs(keybd, (Bool) grab->keyboardMode,
@@ -1635,6 +1639,8 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
         ReattachToOldMaster(keybd);
 
     ComputeFreezes();
+
+    FreeGrab(grab);
 }
 
 void
diff --git a/include/inputstr.h b/include/inputstr.h
index de96fae..85be885 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -485,7 +485,7 @@ typedef struct _GrabInfoRec {
     TimeStamp grabTime;
     Bool fromPassiveGrab;       /* true if from passive grab */
     Bool implicitGrab;          /* implicit from ButtonPress */
-    GrabPtr activeGrab;
+    GrabPtr unused;             /* Kept for ABI stability, remove soon */
     GrabPtr grab;
     CARD8 activatingKey;
     void (*ActivateGrab) (DeviceIntPtr /*device */ ,
commit 25b641bb324c33226313c15448592b785043eaba
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 17 20:14:56 2013 +1000

    dix: use a tmp variable for the to-be-removed touch listener
    
    No functional changes.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 7dbf61817d3bd4b1fc71710677e56c5d8cfcdb4e)

diff --git a/dix/touch.c b/dix/touch.c
index be4a7de..01a554e 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -719,12 +719,13 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
 
     for (i = 0; i < ti->num_listeners; i++) {
         int j;
+        TouchListener *listener = &ti->listeners[i];
 
-        if (ti->listeners[i].listener != resource)
+        if (listener->listener != resource)
             continue;
 
-        if (ti->listeners[i].grab) {
-            ti->listeners[i].grab = NULL;
+        if (listener->grab) {
+            listener->grab = NULL;
             ti->num_grabs--;
         }
 
commit 88273287e1d7b3c06313f77d450f87a31bf53780
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 17 20:13:34 2013 +1000

    dix: invert a loop condition
    
    Change the single if condition in the loop body to a
        if (!foo) continue;
    and re-indent the rest.
    
    No functional changes.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit a71a283934406d870bcd8dc376eb1c9ce1c8bbb4)

diff --git a/dix/touch.c b/dix/touch.c
index 0cbc2eb..be4a7de 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -718,21 +718,22 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
     int i;
 
     for (i = 0; i < ti->num_listeners; i++) {
-        if (ti->listeners[i].listener == resource) {
-            int j;
+        int j;
 
-            if (ti->listeners[i].grab) {
-                ti->listeners[i].grab = NULL;
-                ti->num_grabs--;
-            }
+        if (ti->listeners[i].listener != resource)
+            continue;
 
-            for (j = i; j < ti->num_listeners - 1; j++)
-                ti->listeners[j] = ti->listeners[j + 1];
-            ti->num_listeners--;
-            ti->listeners[ti->num_listeners].listener = 0;
-            ti->listeners[ti->num_listeners].state = LISTENER_AWAITING_BEGIN;
-            return TRUE;
+        if (ti->listeners[i].grab) {
+            ti->listeners[i].grab = NULL;
+            ti->num_grabs--;
         }
+
+        for (j = i; j < ti->num_listeners - 1; j++)
+            ti->listeners[j] = ti->listeners[j + 1];
+        ti->num_listeners--;
+        ti->listeners[ti->num_listeners].listener = 0;
+        ti->listeners[ti->num_listeners].state = LISTENER_AWAITING_BEGIN;
+        return TRUE;
     }
     return FALSE;
 }
commit 4081b00d36d074eedf5c8d04196998d23cff28cf
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 28 11:02:40 2013 +1000

    dix: XAllowEvents() on a touch event means accepting it
    
    A sync grab is the owner once it gets events. If it doesn't replay the
    event it will get all events from this touch, equivalent to accepting it.
    
    If the touch has ended before XAllowEvents() is called, we also now need to
    send the TouchEnd event and clean-up since we won't see anything more from
    this touch.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 5174b1f98204beee79eba74c4cda5f2be0a60a8f)

diff --git a/dix/events.c b/dix/events.c
index 2682ecd..7772c0b 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1739,6 +1739,16 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
         }
         break;
     }
+
+    /* We've unfrozen the grab. If the grab was a touch grab, we're now the
+     * owner and expected to accept/reject it. Reject == ReplayPointer which
+     * we've handled in ComputeFreezes() (during DeactivateGrab) above,
+     * anything else is accept.
+     */
+    if (newState != NOT_GRABBED /* Replay */ &&
+        IsTouchEvent((InternalEvent*)grabinfo->sync.event)) {
+        TouchAcceptAndEnd(thisDev, grabinfo->sync.event->touchid);
+    }
 }
 
 /**
diff --git a/dix/touch.c b/dix/touch.c
index f7112fc..0cbc2eb 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -1102,3 +1102,17 @@ TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resourc
     GetDixTouchEnd(&event, dev, ti, flags);
     DeliverTouchEvents(dev, ti, &event, resource);
 }
+
+void
+TouchAcceptAndEnd(DeviceIntPtr dev, int touchid)
+{
+    TouchPointInfoPtr ti = TouchFindByClientID(dev, touchid);
+    if (!ti)
+        return;
+
+    TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
+    if (ti->pending_finish)
+        TouchEmitTouchEnd(dev, ti, 0, 0);
+    if (ti->num_listeners <= 1)
+        TouchEndTouch(dev, ti);
+}
diff --git a/include/input.h b/include/input.h
index 866879b..7eed60b 100644
--- a/include/input.h
+++ b/include/input.h
@@ -591,6 +591,7 @@ extern void TouchEndPhysicallyActiveTouches(DeviceIntPtr dev);
 extern void TouchDeliverDeviceClassesChangedEvent(TouchPointInfoPtr ti,
                                                   Time time, XID resource);
 extern void TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource);
+extern void TouchAcceptAndEnd(DeviceIntPtr dev, int touchid);
 
 /* misc event helpers */
 extern Mask GetEventMask(DeviceIntPtr dev, xEvent *ev, InputClientsPtr clients);
commit 8666395484d0ff68526b1afd0044329ca3e9c907
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Mar 1 12:52:35 2013 +1000

    dix: move EmitTouchEnd to touch.c
    
    No functional changes, this just enables it to be re-used easier.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit e7f79c48b0faea910dc881034c00eb807fcd6210)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 10fb810..c33a922 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1053,33 +1053,6 @@ ActivateEarlyAccept(DeviceIntPtr dev, TouchPointInfoPtr ti)
 }
 
 /**
- * Generate and deliver a TouchEnd event.
- *
- * @param dev The device to deliver the event for.
- * @param ti The touch point record to deliver the event for.
- * @param flags Internal event flags. The called does not need to provide
- *        TOUCH_CLIENT_ID and TOUCH_POINTER_EMULATED, this function will ensure
- *        they are set appropriately.
- * @param resource The client resource to deliver to, or 0 for all clients.
- */
-static void
-EmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource)
-{
-    InternalEvent event;
-
-    /* We're not processing a touch end for a frozen device */
-    if (dev->deviceGrab.sync.frozen)
-        return;
-
-    flags |= TOUCH_CLIENT_ID;
-    if (ti->emulate_pointer)
-        flags |= TOUCH_POINTER_EMULATED;
-    TouchDeliverDeviceClassesChangedEvent(ti, GetTimeInMillis(), resource);
-    GetDixTouchEnd(&event, dev, ti, flags);
-    DeliverTouchEvents(dev, ti, &event, resource);
-}
-
-/**
  * Find the oldest touch that still has a pointer emulation client.
  *
  * Pointer emulation can only be performed for the oldest touch. Otherwise, the
@@ -1150,7 +1123,7 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
     /* New owner has Begin/Update but not end. If touch is pending_finish,
      * emulate the TouchEnd now */
     if (ti->pending_finish) {
-        EmitTouchEnd(dev, ti, 0, 0);
+        TouchEmitTouchEnd(dev, ti, 0, 0);
 
         /* If the last owner is not a touch grab, finalise the touch, we
            won't get more correspondence on this.
@@ -1208,7 +1181,7 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
     for (i = 0; i < ti->num_listeners; i++) {
         if (ti->listeners[i].listener == resource) {
             if (ti->listeners[i].state != LISTENER_HAS_END)
-                EmitTouchEnd(sourcedev, ti, TOUCH_REJECT, resource);
+                TouchEmitTouchEnd(sourcedev, ti, TOUCH_REJECT, resource);
             break;
         }
     }
@@ -1255,12 +1228,12 @@ ProcessTouchOwnershipEvent(TouchOwnershipEvent *ev,
          * already seen the end. This ensures that the touch record is ended in
          * the server. */
         if (ti->listeners[0].state == LISTENER_HAS_END)
-            EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
+            TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
 
         /* The touch owner has accepted the touch.  Send TouchEnd events to
          * everyone else, and truncate the list of listeners. */
         for (i = 1; i < ti->num_listeners; i++)
-            EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener);
+            TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener);
 
         while (ti->num_listeners > 1)
             TouchRemoveListener(ti, ti->listeners[1].listener);
diff --git a/dix/touch.c b/dix/touch.c
index 76592e7..f7112fc 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -1075,3 +1075,30 @@ TouchEndPhysicallyActiveTouches(DeviceIntPtr dev)
 
     FreeEventList(eventlist, GetMaximumEventsNum());
 }
+
+/**
+ * Generate and deliver a TouchEnd event.
+ *
+ * @param dev The device to deliver the event for.
+ * @param ti The touch point record to deliver the event for.
+ * @param flags Internal event flags. The called does not need to provide
+ *        TOUCH_CLIENT_ID and TOUCH_POINTER_EMULATED, this function will ensure
+ *        they are set appropriately.
+ * @param resource The client resource to deliver to, or 0 for all clients.
+ */
+void
+TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource)
+{
+    InternalEvent event;
+
+    /* We're not processing a touch end for a frozen device */
+    if (dev->deviceGrab.sync.frozen)
+        return;
+
+    flags |= TOUCH_CLIENT_ID;
+    if (ti->emulate_pointer)
+        flags |= TOUCH_POINTER_EMULATED;
+    TouchDeliverDeviceClassesChangedEvent(ti, GetTimeInMillis(), resource);
+    GetDixTouchEnd(&event, dev, ti, flags);
+    DeliverTouchEvents(dev, ti, &event, resource);
+}
diff --git a/include/input.h b/include/input.h
index 5c65597..866879b 100644
--- a/include/input.h
+++ b/include/input.h
@@ -590,6 +590,7 @@ extern int TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode,
 extern void TouchEndPhysicallyActiveTouches(DeviceIntPtr dev);
 extern void TouchDeliverDeviceClassesChangedEvent(TouchPointInfoPtr ti,
                                                   Time time, XID resource);
+extern void TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource);
 
 /* misc event helpers */
 extern Mask GetEventMask(DeviceIntPtr dev, xEvent *ev, InputClientsPtr clients);
commit 4dac09796ca7ec19c1a9b17f338babd51c999e2e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Mar 1 10:41:01 2013 +1000

    Xi: Don't emit a TouchEnd event to a frozen device
    
    EmitTouchEnd calls DeliverTouchEvents directly instead of through
    public.processInputProc. If a device is frozen, the TouchEnd is
    processed while the device is waiting for a XAllowEvents and thus ends the
    touch point (and the grab) before the client decided what to do with it. In
    the case of ReplayPointer, this loses the event.
    
    This is a hack, but making EmitTouchEnd use processInputProc breaks
    approximately everything, especially the touch point is cleaned up during
    ProcessTouchEvents. Working around that is a bigger hack than this.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 0eb9390f6048049136347d5a5834d88bfc67cc09)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 7975a40..10fb810 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1067,6 +1067,10 @@ EmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource)
 {
     InternalEvent event;
 
+    /* We're not processing a touch end for a frozen device */
+    if (dev->deviceGrab.sync.frozen)
+        return;
+
     flags |= TOUCH_CLIENT_ID;
     if (ti->emulate_pointer)
         flags |= TOUCH_POINTER_EMULATED;
commit c8a48358065ff94b8307d8aedfe58e54f34ba84f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 28 13:07:26 2013 +1000

    Xi: use public.processInputProc to replay the touch history
    
    If a device is frozen in results to a grab, we need to enqueue the events.
    
    This makes things complicated, and hard to follow since touch events are now
    replayed in the history, pushed into EnqueueEvent, then replayed later
    during PlayReleasedEvents in response to an XAllowEvents.
    
    While the device is frozen, no touch events are processed, so if there is a
    touch client with ownership mask _below_ the grab this will delay the
    delivery and potentially screw gesture recognition. However, this is the
    behaviour we have already anyway if the top-most client is a sync pgrab or
    there is a sync grab active on the device when the TouchBegin was generated.
    
    (also note, such a client would only reliably work in case of ReplayPointer
    anyway)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit a7d989d335f903ffd8b168cd2beeb82c78d30c21)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index a8b3ee6..7975a40 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1554,7 +1554,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
 
     touchid = ev->device_event.touchid;
 
-    if (type == ET_TouchBegin) {
+    if (type == ET_TouchBegin && !(ev->device_event.flags & TOUCH_REPLAYING)) {
         ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
                              emulate_pointer);
     }
@@ -1621,7 +1621,9 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
      * called after event type mutation. Touch end events are always processed
      * in order to end touch records. */
     /* FIXME: check this */
-    if ((type == ET_TouchBegin && !TouchBuildSprite(dev, ti, ev)) ||
+    if ((type == ET_TouchBegin &&
+         !(ev->device_event.flags & TOUCH_REPLAYING) &&
+         !TouchBuildSprite(dev, ti, ev)) ||
         (type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0))
         return;
 
@@ -1629,7 +1631,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
     /* WARNING: the event type may change to TouchUpdate in
      * DeliverTouchEvents if a TouchEnd was delivered to a grabbing
      * owner */
-    DeliverTouchEvents(dev, ti, (InternalEvent *) ev, 0);
+    DeliverTouchEvents(dev, ti, ev, ev->device_event.resource);
     if (ev->any.type == ET_TouchEnd)
         TouchEndTouch(dev, ti);
 
diff --git a/dix/touch.c b/dix/touch.c
index 5d6e2a7..76592e7 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -474,7 +474,21 @@ TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource)
         DeviceEvent *ev = &ti->history[i];
 
         ev->flags |= TOUCH_REPLAYING;
-        DeliverTouchEvents(dev, ti, (InternalEvent *) ev, resource);
+        ev->resource = resource;
+        /* FIXME:
+           We're replaying ti->history which contains the TouchBegin +
+           all TouchUpdates for ti. This needs to be passed on to the next
+           listener. If that is a touch listener, everything is dandy.
+           If the TouchBegin however triggers a sync passive grab, the
+           TouchUpdate events must be sent to EnqueueEvent so the events end
+           up in syncEvents.pending to be forwarded correctly in a
+           subsequent ComputeFreeze().
+
+           However, if we just send them to EnqueueEvent the sync'ing device
+           prevents handling of touch events for ownership listeners who
+           want the events right here, right now.
+         */
+        dev->public.processInputProc((InternalEvent*)ev, dev);
     }
 }
 
diff --git a/include/eventstr.h b/include/eventstr.h
index 5c1adc4..3950584 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -123,6 +123,7 @@ struct _DeviceEvent {
     int corestate;    /**< Core key/button state BEFORE the event */
     int key_repeat;   /**< Internally-generated key repeat event */
     uint32_t flags;   /**< Flags to be copied into the generated event */
+    uint32_t resource; /**< Touch event resource, only for TOUCH_REPLAYING */
 };
 
 /**
commit 2fcf86036f95128e9b90ddbd5ffc6edbacd3de9f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Feb 27 15:05:54 2013 +1000

    Xi: when punting to a new owner, always create TouchEnd events
    
    If a touch is pending_finish and we just punted it to the next owner, that
    client must receive a TouchEnd event.
    
    If we just punted to the last owner and that owner not a touch grab, we need
    to end the touch since this is the last event to be sent, and the client
    cannot accept/reject this.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 214d11d3fcdac51fc7afbf3770516ec14f9e13c1)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 14b0cec..a8b3ee6 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1143,12 +1143,21 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
         TouchEventHistoryReplay(ti, dev, listener->listener);
     }
 
-    /* If we've just removed the last grab and the touch has physically
-     * ended, send a TouchEnd event too and finalise the touch. */
-    if (ti->num_listeners == 1 && ti->num_grabs == 0 && ti->pending_finish) {
+    /* New owner has Begin/Update but not end. If touch is pending_finish,
+     * emulate the TouchEnd now */
+    if (ti->pending_finish) {
         EmitTouchEnd(dev, ti, 0, 0);
-        TouchEndTouch(dev, ti);
-        return;
+
+        /* If the last owner is not a touch grab, finalise the touch, we
+           won't get more correspondence on this.
+         */
+        if (ti->num_listeners == 1 &&
+            (ti->num_grabs == 0 ||
+             listener->grab->grabtype != XI2 ||
+             !xi2mask_isset(listener->grab->xi2mask, dev, XI_TouchBegin))) {
+            TouchEndTouch(dev, ti);
+            return;
+        }
     }
 
     if (accepted_early)
commit e1c908f3931aa82c7c5f14aa162e02f3abf98faf
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Mar 1 09:15:37 2013 +1000

    Xi: save state for early acceptance
    
    Delivering an event changes the state to LISTENER_IS_OWNER and we thus lose
    the information of early acceptance.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 026627fe19aad007544eccf209f0dea05e67a7a7)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index f1081cf..14b0cec 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1126,10 +1126,10 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
                      TouchOwnershipEvent *ev)
 {
     TouchListener *listener = &ti->listeners[0]; /* new owner */
+    int accepted_early = listener->state == LISTENER_EARLY_ACCEPT;
 
     /* Deliver the ownership */
-    if (listener->state == LISTENER_AWAITING_OWNER ||
-        listener->state == LISTENER_EARLY_ACCEPT)
+    if (listener->state == LISTENER_AWAITING_OWNER || accepted_early)
         DeliverTouchEvents(dev, ti, (InternalEvent *) ev,
                            listener->listener);
     else if (listener->state == LISTENER_AWAITING_BEGIN) {
@@ -1151,7 +1151,7 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
         return;
     }
 
-    if (listener->state == LISTENER_EARLY_ACCEPT)
+    if (accepted_early)
         ActivateEarlyAccept(dev, ti);
 }
 
commit 7343d05e3a502216532aa9901c3a8948ea118c78
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 28 15:28:46 2013 +1000

    Xi: if a passive async grab is activated from an emulated touch, accept
    
    Async grabs cannot replay events, they cannot reject, so we can do an early
    accept here.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit d905348134c80f19793eefb761731b00559ddf3a)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 180f4b5..f1081cf 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1848,8 +1848,14 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
         listener->type == LISTENER_POINTER_GRAB) {
         rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
                                        grab, xi2mask);
-        if (rc == Success)
+        if (rc == Success) {
             listener->state = LISTENER_IS_OWNER;
+            /* async grabs cannot replay, so automatically accept this touch */
+            if (dev->deviceGrab.grab &&
+                dev->deviceGrab.fromPassiveGrab &&
+                dev->deviceGrab.grab->pointerMode == GrabModeAsync)
+                ActivateEarlyAccept(dev, ti);
+        }
         goto out;
     }
 
commit 18346911ab0ce1ad66986b83f9afefadec25555e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 28 13:04:36 2013 +1000

    Xi: fix lookup in ActivateEarlyAccept
    
    ActivateEarlyAccept() can only be called from a grabbing client, so we can
    ignore the rest. And it's easy enough to get the client from that since
    9ad0fdb135a1c336771aee1f6eab75a6ad874aff.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 8b0d21044956f3810199d5e2f38ce33069e97be7)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index d075815..180f4b5 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1039,17 +1039,16 @@ ActivateEarlyAccept(DeviceIntPtr dev, TouchPointInfoPtr ti)
     int rc;
     ClientPtr client;
     XID error;
+    GrabPtr grab = ti->listeners[0].grab;
 
-    rc = dixLookupClient(&client, ti->listeners[0].listener, serverClient,
-                         DixSendAccess);
-    if (rc != Success) {
-        ErrorF("[Xi] Failed to lookup early accepting client.\n");
-        return;
-    }
+    BUG_RETURN(ti->listeners[0].type != LISTENER_GRAB &&
+               ti->listeners[0].type != LISTENER_POINTER_GRAB);
+    BUG_RETURN(!grab);
+
+    client = rClient(grab);
 
     if (TouchAcceptReject(client, dev, XIAcceptTouch, ti->client_id,
-                          ti->listeners[0].window->drawable.id, &error) !=
-        Success)
+                          ti->listeners[0].window->drawable.id, &error) != Success)
         ErrorF("[Xi] Failed to accept touch grab after early acceptance.\n");
 }
 
commit 000d469dd4d97424c72d82e4383ec295e31ffd34
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 28 13:08:27 2013 +1000

    Xi: update the core listener state if we delivered the touch event
    
    If a TouchBegin is sent to a core client, that client is now the owner.
    
    By the time the TouchEnd is being processed, the client cannot replay
    anymore, so we can assume that this is the final touch end and we can clean
    up the touch record.
    
    Note: DeliverTouchEmulatedEvent is called for all listeners and immediately
    bails out if the client is not the owner and thus shouldn't yet get the
    event. Thus, check the return code.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit d08bae297f9d7651edb1923d6b0d6b14b3d674fc)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 2fdeaf4..d075815 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1849,6 +1849,8 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
         listener->type == LISTENER_POINTER_GRAB) {
         rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
                                        grab, xi2mask);
+        if (rc == Success)
+            listener->state = LISTENER_IS_OWNER;
         goto out;
     }
 
@@ -1889,13 +1891,13 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
         rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
                                        grab, xi2mask);
 
-        if (ti->num_listeners > 1) {
-            ev->any.type = ET_TouchUpdate;
-            ev->device_event.flags |= TOUCH_PENDING_END;
-            if (!(ev->device_event.flags & TOUCH_CLIENT_ID))
-                ti->pending_finish = TRUE;
-        }
-
+         /* Once we send a TouchEnd to a legacy listener, we're already well
+          * past the accepting/rejecting stage (can only happen on
+          * GrabModeSync + replay. This listener now gets the end event,
+          * and we can continue.
+          */
+        if (rc == Success)
+            listener->state = LISTENER_HAS_END;
         goto out;
     }
 
commit a7ec834d5e8c351cfa5d87b7902fa061826e3097
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 25 11:21:07 2013 +1000

    Xi: if we delivered a TouchEnd to a passive grab, end it
    
    ef64b5ee97099618cf2e2cbbd3e471095695ae24 (which introduced the
    TOUCH_CLIENT_ID check) has a wrong assumption that generated touch events
    (TOUCH_CLIENT_ID) should not terminate passive grabs.
    This is untrue, a TouchEnd may be generated in response to a TouchReject
    higher up. If we _deliver_ an event to a client, terminate the passive grab.
    
    This requires us to count the actually delivered events too (first hunk).
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 81554d274f04951c55ea7f2e38d0455e2025e08d)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 9a7c1cb..2fdeaf4 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1417,7 +1417,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
             }
 
             if (!deliveries)
-                DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
+                deliveries = DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
 
             /* We must accept the touch sequence once a pointer listener has
              * received one event past ButtonPress. */
@@ -1425,8 +1425,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
                 !(ev->device_event.flags & TOUCH_CLIENT_ID))
                 TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
 
-            if (ev->any.type == ET_TouchEnd &&
-                !(ev->device_event.flags & TOUCH_CLIENT_ID) &&
+            if (deliveries && ev->any.type == ET_TouchEnd &&
                 !dev->button->buttonsDown &&
                 dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab)) {
                 (*dev->deviceGrab.DeactivateGrab) (dev);
commit 636647bc7f9ed10918cbb228f7d448c8cf733667
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Feb 13 11:26:11 2013 +1000

    dix: don't prepend an activated passive grab to the listeners
    
    If the device is currently grabbed as the result of a passive grab
    activating, do not prepend that grab to the listeners (unlike active grabs).
    Otherwise, a client with a passive pointer grab will prevent touch grabs
    from activating higher up in the window stack.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 363b6387da6e669099a2da3861c73a29808295a6)

diff --git a/dix/touch.c b/dix/touch.c
index 3027bbb..5d6e2a7 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -874,7 +874,7 @@ TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev)
     SpritePtr sprite = &ti->sprite;
     WindowPtr win;
 
-    if (dev->deviceGrab.grab)
+    if (dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab)
         TouchAddActiveGrabListener(dev, ti, ev, dev->deviceGrab.grab);
 
     /* We set up an active touch listener for existing touches, but not any
commit 87e027726f2d9223ce2fef2e4d26c18ae680a05e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Feb 13 10:49:23 2013 +1000

    Xi: not having an ownership mask does not mean automatic acceptance
    
    If we only have a single touch-grabbing client, setting the client as owner
    would clean up the touch once the TouchEnd was processed. If the client then
    calls XIAllowTouches() it will receive a BadValue for the touch ID (since
    the internal record is already cleaned up).
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 9cc45c18ad1511adf3fb163dd4cefbef106edb23)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 77c705f..9a7c1cb 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1867,7 +1867,7 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
         if (has_ownershipmask)
             TouchSendOwnershipEvent(dev, ti, 0, listener->listener);
 
-        if (!has_ownershipmask || listener->type == LISTENER_REGULAR)
+        if (listener->type == LISTENER_REGULAR)
             state = LISTENER_HAS_ACCEPTED;
         else
             state = LISTENER_IS_OWNER;
commit 34f5ca3a70e966d6fe232179a47c3dc660773ad5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Mar 1 08:26:06 2013 +1000

    Xi: use a temp variable for the new listener
    
    Instead of accessing ti->listener[0] all the time.
    
    No functional changes.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit fc504a44d12d537d4e07f659f1863f200a0272ad)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index d39cf89..77c705f 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1126,20 +1126,22 @@ static void
 TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
                      TouchOwnershipEvent *ev)
 {
+    TouchListener *listener = &ti->listeners[0]; /* new owner */
+
     /* Deliver the ownership */
-    if (ti->listeners[0].state == LISTENER_AWAITING_OWNER ||
-        ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
+    if (listener->state == LISTENER_AWAITING_OWNER ||
+        listener->state == LISTENER_EARLY_ACCEPT)
         DeliverTouchEvents(dev, ti, (InternalEvent *) ev,
-                           ti->listeners[0].listener);
-    else if (ti->listeners[0].state == LISTENER_AWAITING_BEGIN) {
+                           listener->listener);
+    else if (listener->state == LISTENER_AWAITING_BEGIN) {
         /* We can't punt to a pointer listener unless all older pointer
          * emulated touches have been seen already. */
-        if ((ti->listeners[0].type == LISTENER_POINTER_GRAB ||
-             ti->listeners[0].type == LISTENER_POINTER_REGULAR) &&
+        if ((listener->type == LISTENER_POINTER_GRAB ||
+             listener->type == LISTENER_POINTER_REGULAR) &&
             ti != FindOldestPointerEmulatedTouch(dev))
             return;
 
-        TouchEventHistoryReplay(ti, dev, ti->listeners[0].listener);
+        TouchEventHistoryReplay(ti, dev, listener->listener);
     }
 
     /* If we've just removed the last grab and the touch has physically
@@ -1150,7 +1152,7 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
         return;
     }
 
-    if (ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
+    if (listener->state == LISTENER_EARLY_ACCEPT)
         ActivateEarlyAccept(dev, ti);
 }
 
commit 54b125d1751385bcfc3c1b51d21ee6a7dc14143b
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Tue Apr 30 14:30:18 2013 -0700

    xfree86: don't enable anything in xf86InitialConfiguration for GPU screens
    
    There's no point in turning on outputs connected to GPU screens during initial
    configuration.  Not only does this cause them to just display black, it also
    confuses clients when these screens are attached to a master screen and RandR
    reports that the outputs are already on.
    
    Also, don't print the warning about no outputs being found on GPU screens,
    since that's expected.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Dave Airlie <airlied at gmail.com>
    (cherry picked from commit dbfeaf70623a83e1a3f3255c94d52e0e04702837)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 5a07793..989595f 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1908,6 +1908,14 @@ xf86CollectEnabledOutputs(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
     Bool any_enabled = FALSE;
     int o;
 
+    /*
+     * Don't bother enabling outputs on GPU screens: a client needs to attach
+     * it to a source provider before setting a mode that scans out a shared
+     * pixmap.
+     */
+    if (scrn->is_gpu)
+        return FALSE;
+
     for (o = 0; o < config->num_output; o++)
         any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], TRUE);
 
@@ -2377,9 +2385,11 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
 
     ret = xf86CollectEnabledOutputs(scrn, config, enabled);
     if (ret == FALSE && canGrow) {
-        xf86DrvMsg(i, X_WARNING,
-                   "Unable to find connected outputs - setting %dx%d initial framebuffer\n",
-                   NO_OUTPUT_DEFAULT_WIDTH, NO_OUTPUT_DEFAULT_HEIGHT);
+        if (!scrn->is_gpu)
+            xf86DrvMsg(i, X_WARNING,
+		       "Unable to find connected outputs - setting %dx%d "
+                       "initial framebuffer\n",
+                       NO_OUTPUT_DEFAULT_WIDTH, NO_OUTPUT_DEFAULT_HEIGHT);
         have_outputs = FALSE;
     }
     else {
commit 29545a422bbdd11fda5cb61f27720332d68d0c36
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jan 9 12:52:13 2013 +1000

    gpu: call CreateScreenResources for GPU screens
    
    I didn't think we needed this before, but after doing some more
    work with reverse optimus it seems like it should be called.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit f2fd8ec3725a61abbc831f0a9ec28fa2b7020c47)

diff --git a/dix/main.c b/dix/main.c
index fb935c9..e558d70 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -211,6 +211,9 @@ main(int argc, char *argv[], char *envp[])
             ScreenPtr pScreen = screenInfo.gpuscreens[i];
             if (!CreateScratchPixmapsForScreen(pScreen))
                 FatalError("failed to create scratch pixmaps");
+            if (pScreen->CreateScreenResources &&
+                !(*pScreen->CreateScreenResources) (pScreen))
+                FatalError("failed to create screen resources");
         }
 
         for (i = 0; i < screenInfo.numScreens; i++) {
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 9034dad..db831a8 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -454,6 +454,14 @@ xf86platformAddDevice(int index)
 
    CreateScratchPixmapsForScreen(xf86GPUScreens[i]->pScreen);
 
+   if (xf86GPUScreens[i]->pScreen->CreateScreenResources &&
+       !(*xf86GPUScreens[i]->pScreen->CreateScreenResources) (xf86GPUScreens[i]->pScreen)) {
+       RemoveGPUScreen(xf86GPUScreens[i]->pScreen);
+       xf86DeleteScreen(xf86GPUScreens[i]);
+       xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
+       xf86NumGPUScreens = old_screens;
+       return -1;
+   }
    /* attach unbound to 0 protocol screen */
    AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);
 
commit f21cc327a56e3b453cf0dba04457223d61c27ea6
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jan 9 12:52:08 2013 +1000

    dix: allow pixmap dirty helper to be used for non-shared pixmaps
    
    this allows the pixmap dirty helper to be used for reverse optimus,
    where the GPU wants to copy from the shared pixmap to its VRAM copy.
    
    [airlied: slave_dst is wrong name now but pointless ABI churn at this point]
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit 8fcb9d91b69abc72ddef31b9f2e8585580c6cad2)

diff --git a/dix/pixmap.c b/dix/pixmap.c
index 2418812..fe92147 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -243,6 +243,8 @@ Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty, RegionPtr dirty_region)
     }
 
     dst = dirty->slave_dst->master_pixmap;
+    if (!dst)
+        dst = dirty->slave_dst;
 
     RegionTranslate(dirty_region, -dirty->x, -dirty->y);
     n = RegionNumRects(dirty_region);
diff --git a/fb/fbpixmap.c b/fb/fbpixmap.c
index fbcdca9..0824b64 100644
--- a/fb/fbpixmap.c
+++ b/fb/fbpixmap.c
@@ -67,6 +67,7 @@ fbCreatePixmapBpp(ScreenPtr pScreen, int width, int height, int depth, int bpp,
     pPixmap->devKind = paddedWidth;
     pPixmap->refcnt = 1;
     pPixmap->devPrivate.ptr = (pointer) ((char *) pPixmap + base + adjust);
+    pPixmap->master_pixmap = NULL;
 
 #ifdef FB_DEBUG
     pPixmap->devPrivate.ptr =
commit d817284b01ad3bbe02c71d6b00af7526be77626b
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jan 9 12:52:03 2013 +1000

    xf86crtc: don't use scrn->display for gpu screens
    
    scrn->display is a property of the main screen really, and we don't
    want to have the GPU screens use it for anything when picking modes
    or a front buffer size.
    
    This fixes a bug where when you plugged a display link device, it
    would try and allocate a screen the same size as the current running
    one (3360x1050 in this case), which was too big for the device. Avoid
    doing this and just pick sizes based on whats plugged into this device.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit 16077b81c502e04d77f81f683e0c213b9fe75393)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 7d55f60..5a07793 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2360,11 +2360,11 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
     config->debug_modes = xf86ReturnOptValBool(config->options,
                                                OPTION_MODEDEBUG, FALSE);
 
-    if (scrn->display->virtualX)
+    if (scrn->display->virtualX && !scrn->is_gpu)
         width = scrn->display->virtualX;
     else
         width = config->maxWidth;
-    if (scrn->display->virtualY)
+    if (scrn->display->virtualY && !scrn->is_gpu)
         height = scrn->display->virtualY;
     else
         height = config->maxHeight;
@@ -2428,8 +2428,10 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
 
     /* XXX override xf86 common frame computation code */
 
-    scrn->display->frameX0 = 0;
-    scrn->display->frameY0 = 0;
+    if (!scrn->is_gpu) {
+        scrn->display->frameX0 = 0;
+        scrn->display->frameY0 = 0;
+    }
 
     for (c = 0; c < config->num_crtc; c++) {
         xf86CrtcPtr crtc = config->crtc[c];
@@ -2477,7 +2479,7 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
         }
     }
 
-    if (scrn->display->virtualX == 0) {
+    if (scrn->display->virtualX == 0 || scrn->is_gpu) {
         /*
          * Expand virtual size to cover the current config and potential mode
          * switches, if the driver can't enlarge the screen later.
@@ -2492,8 +2494,10 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
             }
         }
 
-        scrn->display->virtualX = width;
-        scrn->display->virtualY = height;
+	if (!scrn->is_gpu) {
+            scrn->display->virtualX = width;
+            scrn->display->virtualY = height;
+	}
     }
 
     if (width > scrn->virtualX)
commit 803d0ac49900903915f1dcd2496f085e5c1afa22
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jan 9 12:51:55 2013 +1000

    dix/gpu: remove asserts for output/offload from same slave
    
    We should have no problem allowing output/offload from the same slave,
    I asserted here, but in order to implement reverse optimus this makes
    perfect sense. (reverse optimus is intel outputting to nvidia).
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit f0d0d75bfe62553dde353f89e46ff13dd863fbe8)

diff --git a/dix/dispatch.c b/dix/dispatch.c
index 8d61735..90b6c7c 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3942,7 +3942,6 @@ void
 AttachOutputGPU(ScreenPtr pScreen, ScreenPtr new)
 {
     assert(new->isGPU);
-    assert(!new->current_master);
     xorg_list_add(&new->output_head, &pScreen->output_slave_list);
     new->current_master = pScreen;
 }
@@ -3959,7 +3958,6 @@ void
 AttachOffloadGPU(ScreenPtr pScreen, ScreenPtr new)
 {
     assert(new->isGPU);
-    assert(!new->current_master);
     xorg_list_add(&new->offload_head, &pScreen->offload_slave_list);
     new->current_master = pScreen;
 }
commit 3608d9f3dd6ae1d23e23294e9a56cb8158e65d19
Author: Piotr Dziwinski <piotrdz at gmail.com>
Date:   Sat Feb 23 13:14:45 2013 +0100

    glx: fix uninitialized var in __glXDRIscreenProbe
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=59825
    
    Signed-off-by: Piotr Dziwinski <piotrdz at gmail.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit cc3d1a5a6120e721a46c67446ba68f5596055633)

diff --git a/glx/glxdri.c b/glx/glxdri.c
index 5891a68..41424af 100644
--- a/glx/glxdri.c
+++ b/glx/glxdri.c
@@ -971,6 +971,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     size_t buffer_size;
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
 
+    framebuffer.base = NULL;
+
     if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
         !DRIQueryDirectRenderingCapable(pScreen, &isCapable) || !isCapable) {
         LogMessage(X_INFO,
commit 2767d9a17d62aede7cabac589c3388078bdb6022
Author: Matt Dew <marcoz at osource.org>
Date:   Tue Jun 25 09:49:08 2013 -0600

    Bump rev from  1.14.1.902  to 1.14.2

diff --git a/configure.ac b/configure.ac
index b977b54..99e3cd6 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.14.1.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-06-13"
-RELEASE_NAME="Act rc2-Normal"
+AC_INIT([xorg-server], 1.14.2, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-06-25"
+RELEASE_NAME="Act Abnormal"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
commit 7dec1d38799d82923e3241f73c83aa1ad357f72b
Author: Matt Dew <marcoz at osource.org>
Date:   Fri Jun 21 10:24:16 2013 -0600

    Revert "dix: pre-scale x by the screen:device:resolution ratio"
    
    This reverts commit 14d89b9a466b521b985bc95fc4994637367362a8.

diff --git a/dix/getevents.c b/dix/getevents.c
index 51d4fd4..dfe4652 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -770,29 +770,6 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
 }
 
 
-static void
-scale_for_device_resolution(DeviceIntPtr dev, ValuatorMask *mask)
-{
-    double x;
-    ValuatorClassPtr v = dev->valuator;
-    int xrange = v->axes[0].max_value - v->axes[0].min_value + 1;
-    int yrange = v->axes[1].max_value - v->axes[1].min_value + 1;
-
-    double screen_ratio = 1.0 * screenInfo.width/screenInfo.height;
-    double device_ratio = 1.0 * xrange/yrange;
-    double resolution_ratio = 1.0;
-    double ratio;
-
-    if (!valuator_mask_fetch_double(mask, 0, &x))
-        return;
-
-    if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0)
-        resolution_ratio = 1.0 * v->axes[0].resolution/v->axes[1].resolution;
-
-    ratio = device_ratio/resolution_ratio/screen_ratio;
-    valuator_mask_set_double(mask, 0, x * ratio);
-}
-
 /**
  * Move the device's pointer by the values given in @valuators.
  *
@@ -804,14 +781,27 @@ moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
 {
     int i;
     Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
-    ValuatorClassPtr v = dev->valuator;
 
     /* for abs devices in relative mode, we've just scaled wrong, since we
        mapped the device's shape into the screen shape. Undo this. */
-    if ((flags & POINTER_ABSOLUTE) == 0 && v && v->numAxes > 1 &&
-        v->axes[0].min_value < v->axes[0].max_value &&
-        v->axes[1].min_value < v->axes[1].max_value) {
-        scale_for_device_resolution(dev, mask);
+    if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator &&
+        dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) {
+
+        double ratio = 1.0 * screenInfo.width/screenInfo.height;
+
+        if (ratio > 1.0) {
+            double y;
+            if (valuator_mask_fetch_double(mask, 1, &y)) {
+                y *= ratio;
+                valuator_mask_set_double(mask, 1, y);
+            }
+        } else {
+            double x;
+            if (valuator_mask_fetch_double(mask, 0, &x)) {
+                x *= ratio;
+                valuator_mask_set_double(mask, 0, x);
+            }
+        }
     }
 
     /* calc other axes, clip, drop back into valuators */
commit 187cb5a037a03ab1e7702da5eebb2e7d884c6186
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Wed Apr 24 15:24:31 2013 -0700

    Only call xf86platformVTProbe() when it's defined
    
    Fixes build on non-udev systems, since XSERVER_PLATFORM_BUS is only
    defined in configure.ac if $CONFIG_UDEV_KMS is true.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 7a35250..2a05a0e 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -562,8 +562,10 @@ xf86VTSwitch(void)
         for (ih = InputHandlers; ih; ih = ih->next)
             xf86EnableInputHandler(ih);
 
+#ifdef XSERVER_PLATFORM_BUS
         /* check for any new output devices */
         xf86platformVTProbe();
+#endif
 
         OsReleaseSIGIO();
     }
commit 34259752340e287333fb03f3060c6db13d72f868
Author: Matt Dew <marcoz at osource.org>
Date:   Thu Jun 13 16:25:26 2013 -0600

    Bump rev from 1.14.1.901 to 1.14.1.902

diff --git a/configure.ac b/configure.ac
index b31559d..b977b54 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.14.1.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-05-30"
-RELEASE_NAME="Act rc1-Normal"
+AC_INIT([xorg-server], 1.14.1.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-06-13"
+RELEASE_NAME="Act rc2-Normal"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
commit 31e066546fd085725cc29e95867a04c70ce46ebc
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Apr 26 15:10:08 2013 +1000

    dix: fix device scaling to use a [min,max[ range.
    
    defmin/defmax are screen coords and thus use a min-inclusive, max-exclusive
    range. device axes ranges are inclusive, so bump the max up by one to get the
    scaling right.
    
    This fixes off-by-one coordinate errors if the coordinate matrix is used to
    bind the device to a fraction of the screen. It introduces an off-by-one
    scaling error in the device coordinate range, but since most devices have a
    higher resolution than the screen (e.g. a Wacom I4 has 5080 dpi) the effect
    of this should be limited.
    
    This error manifests when we have numScreens > 1, as the scaling from
    desktop size back to screen size drops one device unit.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 756ab88d93542f0589c9bf46f40ccc57df64f0fd)

diff --git a/dix/devices.c b/dix/devices.c
index b2db4aa..a0d545a 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -112,8 +112,8 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
      *  Transform is the user supplied (affine) transform
      *  InvScale scales coordinates back up into their native range
      */
-    sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value;
-    sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value;
+    sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value + 1;
+    sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value + 1;
 
     /* invscale */
     pixman_f_transform_init_scale(&scale, sx, sy);
diff --git a/dix/getevents.c b/dix/getevents.c
index ac0ccb2..51d4fd4 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -298,11 +298,11 @@ rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to,
 
     if (from && from->min_value < from->max_value) {
         fmin = from->min_value;
-        fmax = from->max_value;
+        fmax = from->max_value + 1;
     }
     if (to && to->min_value < to->max_value) {
         tmin = to->min_value;
-        tmax = to->max_value;
+        tmax = to->max_value + 1;
     }
 
     if (fmin == tmin && fmax == tmax)
@@ -924,9 +924,9 @@ scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask,
 
     /* scale x&y to desktop coordinates */
     *screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL,
-                                   screenInfo.x, screenInfo.width - 1);
+                                   screenInfo.x, screenInfo.width);
     *screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL,
-                                   screenInfo.y, screenInfo.height - 1);
+                                   screenInfo.y, screenInfo.height);
 
     *devx = x;
     *devy = y;
@@ -1366,6 +1366,12 @@ QueuePointerEvents(DeviceIntPtr device, int type,
  * is the last coordinate on the first screen and must be rescaled for the
  * event to be m. XI2 clients that do their own coordinate mapping would
  * otherwise interpret the position of the device elsewere to the cursor.
+ * However, this scaling leads to losses:
+ * if we have two ScreenRecs we scale from e.g. [0..44704]  (Wacom I4) to
+ * [0..2048[. that gives us 2047.954 as desktop coord, or the per-screen
+ * coordinate 1023.954. Scaling that back into the device coordinate range
+ * gives us 44703. So off by one device unit. It's a bug, but we'll have to
+ * live with it because with all this scaling, we just cannot win.
  *
  * @return the number of events written into events.
  */
commit 14d89b9a466b521b985bc95fc4994637367362a8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat Mar 9 20:43:51 2013 +1000

    dix: pre-scale x by the screen:device:resolution ratio
    
    commit 61a99aff9d33728a0b67920254d2d4d79f80cf39
        dix: pre-scale relative events from abs devices to desktop ratio (#31636)
    
    added pre-scaling of relative coordinates coming from absolute devices to
    undo uneven scaling based on the screen dimensions.
    
    Devices have their own device width/height ratio as well (in a specific
    resolution) and this must be applied for relative devices as well to avoid
    scaling of the relative events into the device's ratio.
    
    e.g. a Wacom Intuos4 6x9 is in 16:10 format with equal horiz/vert
    resolution (dpi). A movement by 1000/1000 coordinates is a perfect diagonal
    on the tablet and must be reflected as such on the screen.
    
    However, we map the relative device-coordinate events to absolute screen
    coordinates based on the axis ranges. This results in an effective scaling
    of 1000/(1000 * 1.6) and thus an uneven x/y axis movement - the y
    axis is always faster.
    
    So we need to pre-scale not only by the desktop dimenstions but also by the
    device width/height ratio _and_ the resolution ratio.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 5cc2c96f824dbb28b9f8da61efc41596f8bd0561)

diff --git a/dix/getevents.c b/dix/getevents.c
index 241c7ec..ac0ccb2 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -770,6 +770,29 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
 }
 
 
+static void
+scale_for_device_resolution(DeviceIntPtr dev, ValuatorMask *mask)
+{
+    double x;
+    ValuatorClassPtr v = dev->valuator;
+    int xrange = v->axes[0].max_value - v->axes[0].min_value + 1;
+    int yrange = v->axes[1].max_value - v->axes[1].min_value + 1;
+
+    double screen_ratio = 1.0 * screenInfo.width/screenInfo.height;
+    double device_ratio = 1.0 * xrange/yrange;
+    double resolution_ratio = 1.0;
+    double ratio;
+
+    if (!valuator_mask_fetch_double(mask, 0, &x))
+        return;
+
+    if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0)
+        resolution_ratio = 1.0 * v->axes[0].resolution/v->axes[1].resolution;
+
+    ratio = device_ratio/resolution_ratio/screen_ratio;
+    valuator_mask_set_double(mask, 0, x * ratio);
+}
+
 /**
  * Move the device's pointer by the values given in @valuators.
  *
@@ -781,27 +804,14 @@ moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
 {
     int i;
     Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
+    ValuatorClassPtr v = dev->valuator;
 
     /* for abs devices in relative mode, we've just scaled wrong, since we
        mapped the device's shape into the screen shape. Undo this. */
-    if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator &&
-        dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) {
-
-        double ratio = 1.0 * screenInfo.width/screenInfo.height;
-
-        if (ratio > 1.0) {
-            double y;
-            if (valuator_mask_fetch_double(mask, 1, &y)) {
-                y *= ratio;
-                valuator_mask_set_double(mask, 1, y);
-            }
-        } else {
-            double x;
-            if (valuator_mask_fetch_double(mask, 0, &x)) {
-                x *= ratio;
-                valuator_mask_set_double(mask, 0, x);
-            }
-        }
+    if ((flags & POINTER_ABSOLUTE) == 0 && v && v->numAxes > 1 &&
+        v->axes[0].min_value < v->axes[0].max_value &&
+        v->axes[1].min_value < v->axes[1].max_value) {
+        scale_for_device_resolution(dev, mask);
     }
 
     /* calc other axes, clip, drop back into valuators */
commit 57f6dbb3032b934a39c15cd1980b345f477ce1e6
Author: Robert Morell <rmorell at nvidia.com>
Date:   Thu May 9 13:09:02 2013 -0700

    os: Reset input buffer's 'ignoreBytes' field
    
    If a client sends a request larger than maxBigRequestSize, the server is
    supposed to ignore it.
    
    Before commit cf88363d, the server would simply disconnect the client.  After
    that commit, it attempts to gracefully ignore the request by remembering how
    long the client specified the request to be, and ignoring that many bytes.
    However, if a client sends a BigReq header with a large size and disconnects
    before actually sending the rest of the specified request, the server will
    reuse the ConnectionInput buffer without resetting the ignoreBytes field.  This
    makes the server ignore new X clients' requests.
    
    This fixes that behavior by resetting the ignoreBytes field when putting the
    ConnectionInput buffer back on the FreeInputs list.
    
    Signed-off-by: Robert Morell <rmorell at nvidia.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 67c66606c760c263d7a4c2d1bba43ed6225a4e7c)

diff --git a/os/io.c b/os/io.c
index 2f091c4..0d980ab 100644
--- a/os/io.c
+++ b/os/io.c
@@ -1063,6 +1063,7 @@ FreeOsBuffers(OsCommPtr oc)
             oci->bufptr = oci->buffer;
             oci->bufcnt = 0;
             oci->lenLastReq = 0;
+            oci->ignoreBytes = 0;
         }
     }
     if ((oco = oc->output)) {
commit 8cc686735296f1ff32089e64f78dfee46b8e7149
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 9 14:30:49 2013 +1000

    dix: don't overwrite proximity/focus classes
    
    InitPointerClassDeviceStruct/InitKeyboardDeviceStruct allocate a
    proximity/focus class, respectively. If a driver calls
    InitFocusClassDeviceStruct or InitProximityClassDeviceStruct beforehand,
    the previously allocated class is overwritten, leaking the memory.
    
    Neither takes a parameter other than the device, so we can simply skip
    initialising it if we already have one.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit 8a88b0ab52ba375ae84463a90503db88af10e368)

diff --git a/dix/devices.c b/dix/devices.c
index 85961a0..b2db4aa 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1366,7 +1366,7 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
     valc->numMotionEvents = numMotionEvents;
     valc->motionHintWindow = NullWindow;
 
-    if (mode & OutOfProximity)
+    if ((mode & OutOfProximity) && !dev->proximity)
         InitProximityClassDeviceStruct(dev);
 
     dev->valuator = valc;
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index 4e8e267..ed01114 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -574,7 +574,8 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
     XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes,
                      &check, &cause);
 
-    InitFocusClassDeviceStruct(dev);
+    if (!dev->focus)
+        InitFocusClassDeviceStruct(dev);
 
     xkbi->kbdProc = ctrl_func;
     dev->kbdfeed->BellProc = bell_func;
commit bf115aa906795df872104083c1187c126c3b1d76
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 17 19:47:42 2013 +1000

    dix: plug memory leak in freeing TouchClass
    
    ==15562== 1,800 bytes in 1 blocks are definitely lost in loss record 298 of 330
    ==15562==    at 0x4A06B6F: calloc (vg_replace_malloc.c:593)
    ==15562==    by 0x4312C7: InitTouchClassDeviceStruct (devices.c:1644)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit 7d722796c678532e8c5897c673c43184da353f44)

diff --git a/dix/devices.c b/dix/devices.c
index be236dd..85961a0 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -795,6 +795,7 @@ FreeDeviceClass(int type, pointer *class)
             free((*t)->touches[i].valuators);
         }
 
+        free((*t)->touches);
         free((*t));
         break;
     }
commit 6abc41689cfd274f5aa8bdfbfcd4e3dd7d0249fa
Author: Matt Dew <marcoz at osource.org>
Date:   Fri May 31 00:06:34 2013 -0600

    bah,  fixed release version: changed from rc1 to 1.901

diff --git a/configure.ac b/configure.ac
index 626aec4..b31559d 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.14.2-rc1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+AC_INIT([xorg-server], 1.14.1.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
 RELEASE_DATE="2013-05-30"
 RELEASE_NAME="Act rc1-Normal"
 AC_CONFIG_SRCDIR([Makefile.am])
commit 27c30396bf7ff16192fe5e17c6fe04ee58ee398b
Author: Matt Dew <marcoz at osource.org>
Date:   Thu May 30 22:34:17 2013 -0600

    bump release info to 1.14.2-rc1 (from 1.14.1)

diff --git a/configure.ac b/configure.ac
index bc53f16..626aec4 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.14.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-04-17"
-RELEASE_NAME="Act Normal"
+AC_INIT([xorg-server], 1.14.2-rc1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-05-30"
+RELEASE_NAME="Act rc1-Normal"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
commit bcc8eba00b57a63255e05bf80bad0cb95a5a5c3e
Author: Andreas Müller <schnitzeltony at googlemail.com>
Date:   Tue Apr 16 14:30:43 2013 +0200

    dixstruct.h: fix segfaults - char is unsigned for ARM and PowerPC architectures
    
    see ARM related bug reports [1-3]
    
    [1] https://github.com/archlinuxarm/PKGBUILDs/issues/446I
    [2] http://www.raspberrypi.org/phpBB3/viewtopic.php?t=38568&p=321673
    [3] http://lists.linuxtogo.org/pipermail/openembedded-core/2013-April/037805.html
    
    Signed-off-by: Andreas Müller <schnitzeltony at googlemail.com>
    Reviewed-by: Mark Kettenis <kettenis at openbsd.org>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/dixstruct.h b/include/dixstruct.h
index 6784819..aef822c 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -96,7 +96,7 @@ typedef struct _Client {
     unsigned int clientGone:1;
     unsigned int closeDownMode:2;
     unsigned int clientState:2;
-    char smart_priority;
+    signed char smart_priority;
     short noClientException;      /* this client died or needs to be killed */
     int priority;
     ReplySwapPtr pSwapReplyFunc;
commit a01839e8d3675abfef871a42415779961f1ee51c
Merge: 348de79 e90beb1
Author: Matt Dew <marcoz at osource.org>
Date:   Thu May 23 22:08:23 2013 -0600

    Merge branch 'server-1.14-branch' of git://people.freedesktop.org/~whot/xserver into server-1.14-branch

commit 348de79d8c3993577912c7aaf891b7ae702ad32d
Merge: a11cf8d c760fb0
Author: Matt Dew <marcoz at osource.org>
Date:   Thu May 23 14:49:33 2013 -0600

    Merge commit 'c760fb0154848d47438908ba8b3da2fffc68a460' into server-1.14-branch

diff --cc hw/xfree86/os-support/linux/lnx_platform.c
index 2bc8214,21768ee..d751f59
--- a/hw/xfree86/os-support/linux/lnx_platform.c
+++ b/hw/xfree86/os-support/linux/lnx_platform.c
@@@ -116,9 -137,18 +137,17 @@@ xf86PlatformDeviceProbe(struct OdevAttr
      if (i != xf86_num_platform_devices)
          goto out_free;
  
 -    LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n",
 -               path);
 +    LogMessage(X_INFO, "xfree86: Adding drm device (%s)\n", path);
  
-     ret = get_drm_info(attribs, path);
+     if (!xf86VTOwner()) {
+             /* if we don't currently own the VT then don't probe the device,
+                just mark it as unowned for later use */
+             attribs->unowned = TRUE;
+             xf86_add_platform_device(attribs);
+             return;
+     }
+ 
+     ret = get_drm_info(attribs, path, -1);
      if (ret == FALSE)
          goto out_free;
  
commit e90beb18000cf49b9108c4f977abfd111ed908ad
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 30 15:44:37 2013 +1000

    os: Use ErrorFSigSafe from FatalError and it's friends
    
    Backtrace logging etc. is already sigsafe, but the actual FatalError message
    in response is not yet, leading to amusing logs like this:
    
        (EE) Segmentation fault at address 0x0
        (EE) BUG: triggered 'if (inSignalContext)'
        (EE) BUG: log.c:499 in LogVMessageVerb()
        (EE) Warning: attempting to log data in a signal unsafe manner while in
        signal context.
        Please update to check inSignalContext and/or use LogMessageVerbSigSafe() or
        ErrorFSigSafe().
        The offending log format message is:
    
        Fatal server error:
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 042c6d861f7bb7038ddcdd6b59766fd9094d0e52)

diff --git a/glx/glxdri.c b/glx/glxdri.c
index da46468..5891a68 100644
--- a/glx/glxdri.c
+++ b/glx/glxdri.c
@@ -885,7 +885,7 @@ glxDRILeaveVT(ScrnInfoPtr scrn)
     __GLXDRIscreen *screen = (__GLXDRIscreen *)
         glxGetScreen(xf86ScrnToScreen(scrn));
 
-    LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
+    LogMessageVerbSigSafe(X_INFO, -1, "AIGLX: Suspending AIGLX clients for VT switch\n");
 
     glxSuspendClients();
 
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index b26e501..16e7e3d 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -835,7 +835,7 @@ glxDRILeaveVT(ScrnInfoPtr scrn)
     __GLXDRIscreen *screen = (__GLXDRIscreen *)
         glxGetScreen(xf86ScrnToScreen(scrn));
 
-    LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
+    LogMessageVerbSigSafe(X_INFO, -1, "AIGLX: Suspending AIGLX clients for VT switch\n");
 
     glxSuspendClients();
 
diff --git a/os/log.c b/os/log.c
index 3dc675f..f19faf5 100644
--- a/os/log.c
+++ b/os/log.c
@@ -250,7 +250,7 @@ void
 LogClose(enum ExitCode error)
 {
     if (logFile) {
-        ErrorF("Server terminated %s (%d). Closing log file.\n",
+        ErrorFSigSafe("Server terminated %s (%d). Closing log file.\n",
                (error == EXIT_NO_ERROR) ? "successfully" : "with error", error);
         fclose(logFile);
         logFile = NULL;
@@ -878,9 +878,9 @@ FatalError(const char *f, ...)
     static Bool beenhere = FALSE;
 
     if (beenhere)
-        ErrorF("\nFatalError re-entered, aborting\n");
+        ErrorFSigSafe("\nFatalError re-entered, aborting\n");
     else
-        ErrorF("\nFatal server error:\n");
+        ErrorFSigSafe("\nFatal server error:\n");
 
     va_start(args, f);
 
@@ -897,9 +897,9 @@ FatalError(const char *f, ...)
         va_end(apple_args);
     }
 #endif
-    VErrorF(f, args);
+    VErrorFSigSafe(f, args);
     va_end(args);
-    ErrorF("\n");
+    ErrorFSigSafe("\n");
     if (!beenhere)
         OsVendorFatalError(f, args2);
     va_end(args2);
commit d0725a0b8672465cc4d3b85fb705ddb64d020476
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 14 16:24:53 2013 +1000

    os: complain about unsupported pnprintf directives
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit d9848fb4b182ca21bacf28ed7410d1a502cb000e)

diff --git a/os/log.c b/os/log.c
index 9f95743..3dc675f 100644
--- a/os/log.c
+++ b/os/log.c
@@ -461,6 +461,7 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
             string[s_idx++] = '%';
             break;
         default:
+            BUG_WARN_MSG(f[f_idx], "Unsupported printf directive '%c'\n", f[f_idx]);
             va_arg(args, char*);
             string[s_idx++] = '%';
             if (s_idx < size - 1)
diff --git a/test/signal-logging.c b/test/signal-logging.c
index b45d8d4..f6bc85c 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -206,6 +206,13 @@ static void logging_format(void)
     read_log_msg(logmsg);
     assert(strcmp(logmsg, "(EE) test a\n") == 0);
 
+    /* something unsupported % */
+    LogMessageVerbSigSafe(X_ERROR, -1, "test %Q\n");
+    read_log_msg(logmsg);
+    assert(strstr(logmsg, "BUG") != NULL);
+    LogMessageVerbSigSafe(X_ERROR, -1, "\n");
+    fseek(f, 0, SEEK_END);
+
     /* string substitution */
     LogMessageVerbSigSafe(X_ERROR, -1, "%s\n", "substituted string");
     read_log_msg(logmsg);
commit 7eb73779a0c82386710c4b670a342c0340485d19
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 14 16:19:34 2013 +1000

    os: support %c in pnprintf
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit d903d17d7f006fa333265b8476063b189c20d082)

diff --git a/os/log.c b/os/log.c
index e4e9e8b..9f95743 100644
--- a/os/log.c
+++ b/os/log.c
@@ -450,6 +450,13 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
                     string[s_idx++] = number[i];
             }
             break;
+        case 'c':
+            {
+                char c = va_arg(args, int);
+                if (s_idx < size - 1)
+                    string[s_idx++] = c;
+            }
+            break;
         case '%':
             string[s_idx++] = '%';
             break;
diff --git a/test/signal-logging.c b/test/signal-logging.c
index 65baa45..b45d8d4 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -201,6 +201,11 @@ static void logging_format(void)
     read_log_msg(logmsg);
     assert(strcmp(logmsg, "(EE) test %\n") == 0);
 
+    /* character */
+    LogMessageVerbSigSafe(X_ERROR, -1, "test %c\n", 'a');
+    read_log_msg(logmsg);
+    assert(strcmp(logmsg, "(EE) test a\n") == 0);
+
     /* string substitution */
     LogMessageVerbSigSafe(X_ERROR, -1, "%s\n", "substituted string");
     read_log_msg(logmsg);
commit 6da756fb1d67d6de99077826a3d2434b0e3a1555
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 14 16:13:22 2013 +1000

    os: support %% in pnprintf
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 58ef34ee6d0f68aa28f6f1a26e56f49ec85ed9bf)

diff --git a/os/log.c b/os/log.c
index df025fb..e4e9e8b 100644
--- a/os/log.c
+++ b/os/log.c
@@ -450,6 +450,9 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
                     string[s_idx++] = number[i];
             }
             break;
+        case '%':
+            string[s_idx++] = '%';
+            break;
         default:
             va_arg(args, char*);
             string[s_idx++] = '%';
diff --git a/test/signal-logging.c b/test/signal-logging.c
index 9038cf8..65baa45 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -196,6 +196,11 @@ static void logging_format(void)
     read_log_msg(logmsg);
     assert(strcmp(logmsg, "(EE) %s %d %u %% %p %i\n") == 0);
 
+    /* literal % */
+    LogMessageVerbSigSafe(X_ERROR, -1, "test %%\n");
+    read_log_msg(logmsg);
+    assert(strcmp(logmsg, "(EE) test %\n") == 0);
+
     /* string substitution */
     LogMessageVerbSigSafe(X_ERROR, -1, "%s\n", "substituted string");
     read_log_msg(logmsg);
commit b606767f20c566e24704502eae682eacb41f450e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 14 15:34:32 2013 +1000

    os: support pnprintf length modifiers for integers
    
    Mainly for %ld, smaller than int is propagated anyway, and %lld isn't really
    used.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 5ea21560dd071ea4ab87430000d087fd5fe1f092)

diff --git a/os/log.c b/os/log.c
index dc6e288..df025fb 100644
--- a/os/log.c
+++ b/os/log.c
@@ -279,6 +279,55 @@ LogSetParameter(LogParameter param, int value)
     }
 }
 
+enum {
+    LMOD_LONG     = 0x1,
+    LMOD_LONGLONG = 0x2,
+    LMOD_SHORT    = 0x4,
+    LMOD_SIZET    = 0x8,
+};
+
+/**
+ * Parse non-digit length modifiers and set the corresponding flag in
+ * flags_return.
+ *
+ * @return the number of bytes parsed
+ */
+static int parse_length_modifier(const char *format, size_t len, int *flags_return)
+{
+    int idx = 0;
+    int length_modifier = 0;
+
+    while (idx < len) {
+        switch (format[idx]) {
+            case 'l':
+                BUG_RETURN_VAL(length_modifier & LMOD_SHORT, 0);
+
+                if (length_modifier & LMOD_LONG)
+                    length_modifier |= LMOD_LONGLONG;
+                else
+                    length_modifier |= LMOD_LONG;
+                break;
+            case 'h':
+                BUG_RETURN_VAL(length_modifier & (LMOD_LONG|LMOD_LONGLONG), 0);
+                length_modifier |= LMOD_SHORT;
+                /* gcc says 'short int' is promoted to 'int' when
+                 * passed through '...', so ignored during
+                 * processing */
+                break;
+            case 'z':
+                length_modifier |= LMOD_SIZET;
+                break;
+            default:
+                goto out;
+        }
+        idx++;
+    }
+
+out:
+    *flags_return = length_modifier;
+    return idx;
+}
+
 /**
  * Signal-safe snprintf, with some limitations over snprintf. Be careful
  * which directives you use.
@@ -297,6 +346,7 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
     int64_t si;
 
     for (; f_idx < f_len && s_idx < size - 1; f_idx++) {
+        int length_modifier = 0;
         if (f[f_idx] != '%') {
             string[s_idx++] = f[f_idx];
             continue;
@@ -304,10 +354,18 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
 
         f_idx++;
 
-        /* silently swallow length modifiers */
+        /* silently swallow digit length modifiers */
         while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.'))
             f_idx++;
 
+        /* non-digit length modifiers */
+        if (f_idx < f_len) {
+            int parsed_bytes = parse_length_modifier(&f[f_idx], f_len - f_idx, &length_modifier);
+            if (parsed_bytes < 0)
+                return 0;
+            f_idx += parsed_bytes;
+        }
+
         if (f_idx >= f_len)
             break;
 
@@ -321,7 +379,15 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
             break;
 
         case 'u':
-            ui = va_arg(args, unsigned);
+            if (length_modifier & LMOD_LONGLONG)
+                ui = va_arg(args, unsigned long long);
+            else if (length_modifier & LMOD_LONG)
+                ui = va_arg(args, unsigned long);
+            else if (length_modifier & LMOD_SIZET)
+                ui = va_arg(args, size_t);
+            else
+                ui = va_arg(args, unsigned);
+
             FormatUInt64(ui, number);
             p_len = strlen_sigsafe(number);
 
@@ -330,7 +396,15 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
             break;
         case 'i':
         case 'd':
-            si = va_arg(args, int);
+            if (length_modifier & LMOD_LONGLONG)
+                si = va_arg(args, long long);
+            else if (length_modifier & LMOD_LONG)
+                si = va_arg(args, long);
+            else if (length_modifier & LMOD_SIZET)
+                si = va_arg(args, ssize_t);
+            else
+                si = va_arg(args, int);
+
             FormatInt64(si, number);
             p_len = strlen_sigsafe(number);
 
@@ -351,7 +425,15 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
             break;
 
         case 'x':
-            ui = va_arg(args, unsigned);
+            if (length_modifier & LMOD_LONGLONG)
+                ui = va_arg(args, unsigned long long);
+            else if (length_modifier & LMOD_LONG)
+                ui = va_arg(args, unsigned long);
+            else if (length_modifier & LMOD_SIZET)
+                ui = va_arg(args, size_t);
+            else
+                ui = va_arg(args, unsigned);
+
             FormatUInt64Hex(ui, number);
             p_len = strlen_sigsafe(number);
 
diff --git a/test/signal-logging.c b/test/signal-logging.c
index e0eb810..9038cf8 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -158,6 +158,8 @@ static void logging_format(void)
     char buf[1024];
     int i;
     unsigned int ui;
+    long li;
+    unsigned long lui;
     FILE *f;
     char read_buf[2048];
     char *logmsg;
@@ -207,6 +209,14 @@ static void logging_format(void)
     LogMessageVerbSigSafe(X_ERROR, -1, "\n");
     fseek(f, 0, SEEK_END);
 
+#warning Ignore compiler warning below "unknown conversion type character".  This is intentional.
+    /* %hld is bogus */
+    LogMessageVerbSigSafe(X_ERROR, -1, "%hld\n", 4);
+    read_log_msg(logmsg);
+    assert(strstr(logmsg, "BUG") != NULL);
+    LogMessageVerbSigSafe(X_ERROR, -1, "\n");
+    fseek(f, 0, SEEK_END);
+
     /* number substitution */
     ui = 0;
     do {
@@ -215,12 +225,47 @@ static void logging_format(void)
         LogMessageVerbSigSafe(X_ERROR, -1, "%u\n", ui);
         read_log_msg(logmsg);
         assert(strcmp(logmsg, expected) == 0);
+
+        sprintf(expected, "(EE) %x\n", ui);
+        LogMessageVerbSigSafe(X_ERROR, -1, "%x\n", ui);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
         if (ui == 0)
             ui = 1;
         else
             ui <<= 1;
     } while(ui);
 
+    lui = 0;
+    do {
+        char expected[30];
+        sprintf(expected, "(EE) %lu\n", lui);
+        LogMessageVerbSigSafe(X_ERROR, -1, "%lu\n", lui);
+        read_log_msg(logmsg);
+
+        sprintf(expected, "(EE) %lld\n", (unsigned long long)ui);
+        LogMessageVerbSigSafe(X_ERROR, -1, "%lld\n", (unsigned long long)ui);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        sprintf(expected, "(EE) %lx\n", lui);
+        printf("%s\n", expected);
+        LogMessageVerbSigSafe(X_ERROR, -1, "%lx\n", lui);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        sprintf(expected, "(EE) %llx\n", (unsigned long long)ui);
+        LogMessageVerbSigSafe(X_ERROR, -1, "%llx\n", (unsigned long long)ui);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        if (lui == 0)
+            lui = 1;
+        else
+            lui <<= 1;
+    } while(lui);
+
     /* signed number substitution */
     i = 0;
     do {
@@ -230,7 +275,6 @@ static void logging_format(void)
         read_log_msg(logmsg);
         assert(strcmp(logmsg, expected) == 0);
 
-
         sprintf(expected, "(EE) %d\n", i | INT_MIN);
         LogMessageVerbSigSafe(X_ERROR, -1, "%d\n", i | INT_MIN);
         read_log_msg(logmsg);
@@ -242,19 +286,35 @@ static void logging_format(void)
             i <<= 1;
     } while(i > INT_MIN);
 
-    /* hex number substitution */
-    ui = 0;
+    li = 0;
     do {
         char expected[30];
-        sprintf(expected, "(EE) %x\n", ui);
-        LogMessageVerbSigSafe(X_ERROR, -1, "%x\n", ui);
+        sprintf(expected, "(EE) %ld\n", li);
+        LogMessageVerbSigSafe(X_ERROR, -1, "%ld\n", li);
         read_log_msg(logmsg);
         assert(strcmp(logmsg, expected) == 0);
-        if (ui == 0)
-            ui = 1;
+
+        sprintf(expected, "(EE) %ld\n", li | LONG_MIN);
+        LogMessageVerbSigSafe(X_ERROR, -1, "%ld\n", li | LONG_MIN);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        sprintf(expected, "(EE) %lld\n", (long long)li);
+        LogMessageVerbSigSafe(X_ERROR, -1, "%lld\n", (long long)li);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        sprintf(expected, "(EE) %lld\n", (long long)(li | LONG_MIN));
+        LogMessageVerbSigSafe(X_ERROR, -1, "%lld\n", (long long)(li | LONG_MIN));
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        if (li == 0)
+            li = 1;
         else
-            ui <<= 1;
-    } while(ui);
+            li <<= 1;
+    } while(li > LONG_MIN);
+
 
     /* pointer substitution */
     /* we print a null-pointer differently to printf */
commit 00b8d11dafdbd1214695e0b54c6c2184ece6aa4d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 18 14:57:58 2013 +1000

    os: document pnprintf as sigsafe snprintf
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 44fc062f85df7288c17d2d64b73aa4957b91fd6d)

diff --git a/os/log.c b/os/log.c
index 95bd8cc..dc6e288 100644
--- a/os/log.c
+++ b/os/log.c
@@ -279,6 +279,10 @@ LogSetParameter(LogParameter param, int value)
     }
 }
 
+/**
+ * Signal-safe snprintf, with some limitations over snprintf. Be careful
+ * which directives you use.
+ */
 static int
 pnprintf(char *string, size_t size, const char *f, va_list args)
 {
commit 8318d6a89cb3ffad5c90670027ef997fd19994a1
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 1 09:06:20 2013 +1000

    If neither HAL nor udev backends are enabled, warn the user
    
    If both are missing,  input device hotplugging will not work out of the box.
    While we still have a DBus-API or the user may want to set AAD off all the
    time, the most likely source of this is misconfiguration (i.e. lack of the
    udev/hal devel packages).
    
    Message printed last to make it more obvious to the user.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 623981ddaeb8836f3b0939e527c0e943f9c4e974)

diff --git a/configure.ac b/configure.ac
index 4289863..bc53f16 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2216,6 +2216,14 @@ AC_SUBST([prefix])
 
 AC_CONFIG_COMMANDS([sdksyms], [touch hw/xfree86/sdksyms.dep])
 
+if test "x$CONFIG_HAL" = xno && test "x$CONFIG_UDEV" = xno; then
+    AC_WARN([
+             ***********************************************
+             Neither HAL nor udev backend will be enabled.
+             Input device hotplugging will not be available!
+             ***********************************************])
+fi
+
 AC_OUTPUT([
 Makefile
 glx/Makefile
commit 1c215f5a9c7f8a75ad56f3b34b0b7de2ee9aa6ff
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 14 11:07:57 2013 +1000

    dix: send the current axis value in DeviceChangedEvents (#62321)
    
    X.Org Bug 62321 <http://bugs.freedesktop.org/show_bug.cgi?id=62321>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 23d1bc69f305edd5a6e2cfec3dfc84befda0881c)

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index ebc52c3..f7ecdba 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -501,9 +501,7 @@ appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo * info,
     info->min.frac = 0;
     info->max.integral = dce->valuators[axisnumber].max;
     info->max.frac = 0;
-    /* FIXME: value */
-    info->value.integral = 0;
-    info->value.frac = 0;
+    info->value = double_to_fp3232(dce->valuators[axisnumber].value);
     info->resolution = dce->valuators[axisnumber].resolution;
     info->number = axisnumber;
     info->mode = dce->valuators[axisnumber].mode;
diff --git a/dix/getevents.c b/dix/getevents.c
index a4f192c..241c7ec 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -277,6 +277,7 @@ CreateClassesChangedEvent(InternalEvent *event,
             dce->valuators[i].mode = slave->valuator->axes[i].mode;
             dce->valuators[i].name = slave->valuator->axes[i].label;
             dce->valuators[i].scroll = slave->valuator->axes[i].scroll;
+            dce->valuators[i].value = slave->valuator->axisVal[i];
         }
     }
     if (slave->key) {
diff --git a/include/eventstr.h b/include/eventstr.h
index 38fab4f..5c1adc4 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -175,6 +175,7 @@ struct _DeviceChangedEvent {
     struct {
         uint32_t min;           /**< Minimum value */
         uint32_t max;           /**< Maximum value */
+        double value;           /**< Current value */;
         /* FIXME: frac parts of min/max */
         uint32_t resolution;    /**< Resolution counts/m */
         uint8_t mode;           /**< Relative or Absolute */
commit 70236f770c7004016efe89dc5638ccbb9ef15bee
Author: Daniel Martin <consume.noise at gmail.com>
Date:   Thu Dec 20 13:50:17 2012 +0100

    ephyr: Fix crash on 24bpp host framebuffer
    
    Use bytes_per_line and bits_per_pixel from the created XImage to fix
        https://bugzilla.redhat.com/show_bug.cgi?id=518960
    
    Signed-off-by: Daniel Martin <consume.noise at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit bd58ebe4cf3b0ce60f87fb26a3715f774dabd349)

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index e6520d0..c9672c0 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -237,13 +237,11 @@ ephyrMapFramebuffer(KdScreenInfo * screen)
     KdComputePointerMatrix(&m, ephyrRandr, screen->width, screen->height);
     KdSetPointerMatrix(&m);
 
-    priv->bytes_per_line =
-        ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2;
-
     buffer_height = ephyrBufferHeight(screen);
 
     priv->base =
-        hostx_screen_init(screen, screen->width, screen->height, buffer_height);
+        hostx_screen_init(screen, screen->width, screen->height, buffer_height,
+                          &priv->bytes_per_line, &screen->fb.bitsPerPixel);
 
     if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All)) {
         scrpriv->shadow = FALSE;
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 157ac36..6bbccd3 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -617,7 +617,8 @@ hostx_set_cmap_entry(unsigned char idx,
  */
 void *
 hostx_screen_init(EphyrScreenInfo screen,
-                  int width, int height, int buffer_height)
+                  int width, int height, int buffer_height,
+                  int *bytes_per_line, int *bits_per_pixel)
 {
     int bitmap_pad;
     Bool shm_success = False;
@@ -694,6 +695,9 @@ hostx_screen_init(EphyrScreenInfo screen,
             malloc(host_screen->ximg->bytes_per_line * buffer_height);
     }
 
+    *bytes_per_line = host_screen->ximg->bytes_per_line;
+    *bits_per_pixel = host_screen->ximg->bits_per_pixel;
+
     XResizeWindow(HostX.dpy, host_screen->win, width, height);
 
     /* Ask the WM to keep our size static */
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 31c4053..38b7b37 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -193,7 +193,8 @@ hostx_set_cmap_entry(unsigned char idx,
                      unsigned char r, unsigned char g, unsigned char b);
 
 void *hostx_screen_init(EphyrScreenInfo screen,
-                        int width, int height, int buffer_height);
+                        int width, int height, int buffer_height,
+                        int *bytes_per_line, int *bits_per_pixel);
 
 void
 
commit a11cf8dd68275ba4676888e5957bff13efbfbb3d
Author: Maarten Lankhorst <maarten.lankhorst at canonical.com>
Date:   Mon Apr 15 16:53:48 2013 +0200

    dix: copy event in TouchConvertToPointerEvent correctly
    
    Fixes reading random memory read beyond the end of original event.
    
    sizeof device_event: 424
    sizeof internal_event: 2800
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 98b94c36d6b1d286bbd4cb414e54b4b95a1484b0)

diff --git a/dix/touch.c b/dix/touch.c
index 891cc78..3027bbb 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -620,14 +620,14 @@ TouchConvertToPointerEvent(const InternalEvent *event,
     BUG_WARN_MSG(!(event->device_event.flags & TOUCH_POINTER_EMULATED),
                  "Non-emulating touch event\n");
 
-    *motion_event = *event;
+    motion_event->device_event = event->device_event;
     motion_event->any.type = ET_Motion;
     motion_event->device_event.detail.button = 0;
     motion_event->device_event.flags = XIPointerEmulated;
 
     if (nevents > 1) {
         BUG_RETURN_VAL(!button_event, 0);
-        *button_event = *event;
+        button_event->device_event = event->device_event;
         button_event->any.type = ptrtype;
         button_event->device_event.flags = XIPointerEmulated;
         /* detail is already correct */
commit 05ca549d81f476561257076f354c781d590c9a4f
Author: Knut Petersen <Knut_Petersen at t-online.de>
Date:   Tue Feb 26 07:52:59 2013 +0100

    Never try to execute BellProcPtr NULL.
    
    This prevents xts XI/XDeviceBell-2 test
    from segfaulting the server.
    
    Signed-off-by: Knut Petersen <Knut_Petersen at t-online.de>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 4bff442ec5aa4b93a3f5c11782d4b7b9d1ae13ac)

diff --git a/Xi/devbell.c b/Xi/devbell.c
index c75b94d..202c8de 100644
--- a/Xi/devbell.c
+++ b/Xi/devbell.c
@@ -142,7 +142,8 @@ ProcXDeviceBell(ClientPtr client)
         newpercent = base + newpercent;
     else
         newpercent = base - newpercent + stuff->percent;
+    if (proc == NULL)
+        return BadValue;
     (*proc) (newpercent, dev, ctrl, class);
-
     return Success;
 }
commit 2cc81338d1804a6a6c92f48773d3e1b2543a262b
Author: Rui Matos <tiagomatos at gmail.com>
Date:   Sat Apr 13 04:22:54 2013 +0200

    Xi: fix swapped grab mode args for keyboard devices in XIGrabDevice
    
    The protocol says that the grab_mode argument applies to the device
    being grabbed and paired_device_mode to the paired master
    device. GrabDevice() however takes in a pointer mode and a keyboard
    mode and so we have to swap the values according the type of device
    being grabbed.
    
    Signed-off-by: Rui Matos <tiagomatos at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 9003399708936481083424b4ff8f18a16b88b7b3)

diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c
index 09186e8..63d95bc 100644
--- a/Xi/xigrabdev.c
+++ b/Xi/xigrabdev.c
@@ -67,6 +67,8 @@ ProcXIGrabDevice(ClientPtr client)
     uint8_t status;
     GrabMask mask = { 0 };
     int mask_len;
+    unsigned int keyboard_mode;
+    unsigned int pointer_mode;
 
     REQUEST(xXIGrabDeviceReq);
     REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
@@ -78,6 +80,15 @@ ProcXIGrabDevice(ClientPtr client)
     if (!IsMaster(dev))
         stuff->paired_device_mode = GrabModeAsync;
 
+    if (IsKeyboardDevice(dev)) {
+        keyboard_mode = stuff->grab_mode;
+        pointer_mode = stuff->paired_device_mode;
+    }
+    else {
+        keyboard_mode = stuff->paired_device_mode;
+        pointer_mode = stuff->grab_mode;
+    }
+
     if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
                                stuff->mask_len * 4) != Success)
         return BadValue;
@@ -91,8 +102,8 @@ ProcXIGrabDevice(ClientPtr client)
     xi2mask_set_one_mask(mask.xi2mask, dev->id, (unsigned char *) &stuff[1],
                          mask_len);
 
-    ret = GrabDevice(client, dev, stuff->grab_mode,
-                     stuff->paired_device_mode,
+    ret = GrabDevice(client, dev, pointer_mode,
+                     keyboard_mode,
                      stuff->grab_window,
                      stuff->owner_events,
                      stuff->time,
commit 08998230789ff15843f726d7231ec0de2f67be6b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Apr 12 09:14:53 2013 +1000

    xfree86: change a log message
    
    This path is technically executed through config/udev, but having two
    messages in the form "config/udev: Adding drm device" makes it appear as if
    the udev filters are wrong and it's trying to add the same device twice. In
    fact, it's only one device, only added once, but a duplicate log message.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit 131f883f85b9b734e5e5652f16ba1d3b5f4de12f)

diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c
index 76f5583..2bc8214 100644
--- a/hw/xfree86/os-support/linux/lnx_platform.c
+++ b/hw/xfree86/os-support/linux/lnx_platform.c
@@ -116,8 +116,7 @@ xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
     if (i != xf86_num_platform_devices)
         goto out_free;
 
-    LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n",
-               path);
+    LogMessage(X_INFO, "xfree86: Adding drm device (%s)\n", path);
 
     ret = get_drm_info(attribs, path);
     if (ret == FALSE)
commit 2c9ac2689fc75cfa3293316acd51b9a39f37edfd
Author: Maarten Lankhorst <maarten.lankhorst at canonical.com>
Date:   Tue Apr 9 11:19:07 2013 +0200

    Xi: Do not handle ET_TouchOwnership in ProcessTouchEvent
    
    The event struct is different, causing memory corruption on 1.13 and 1.14,
    
    as can be witnessed in https://bugs.freedesktop.org/show_bug.cgi?id=56578
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 7347f39f94d8cebbf73ce1a2f94d1abdaf7ff383)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index f05e03d..d39cf89 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1221,9 +1221,16 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
  * touchpoint if it is pending finish.
  */
 static void
-ProcessTouchOwnershipEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
-                           TouchOwnershipEvent *ev)
+ProcessTouchOwnershipEvent(TouchOwnershipEvent *ev,
+                           DeviceIntPtr dev)
 {
+    TouchPointInfoPtr ti = TouchFindByClientID(dev, ev->touchid);
+
+    if (!ti) {
+        DebugF("[Xi] %s: Failed to get event %d for touchpoint %d\n",
+               dev->name, ev->type, ev->touchid);
+        return;
+    }
 
     if (ev->reason == XIRejectTouch)
         TouchRejected(dev, ti, ev->resource, ev);
@@ -1536,10 +1543,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
     if (!t)
         return;
 
-    if (ev->any.type == ET_TouchOwnership)
-        touchid = ev->touch_ownership_event.touchid;
-    else
-        touchid = ev->device_event.touchid;
+    touchid = ev->device_event.touchid;
 
     if (type == ET_TouchBegin) {
         ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
@@ -1612,19 +1616,13 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
         (type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0))
         return;
 
-    /* TouchOwnership events are handled separately from the rest, as they
-     * have more complex semantics. */
-    if (ev->any.type == ET_TouchOwnership)
-        ProcessTouchOwnershipEvent(dev, ti, &ev->touch_ownership_event);
-    else {
-        TouchCopyValuatorData(&ev->device_event, ti);
-        /* WARNING: the event type may change to TouchUpdate in
-         * DeliverTouchEvents if a TouchEnd was delivered to a grabbing
-         * owner */
-        DeliverTouchEvents(dev, ti, (InternalEvent *) ev, 0);
-        if (ev->any.type == ET_TouchEnd)
-            TouchEndTouch(dev, ti);
-    }
+    TouchCopyValuatorData(&ev->device_event, ti);
+    /* WARNING: the event type may change to TouchUpdate in
+     * DeliverTouchEvents if a TouchEnd was delivered to a grabbing
+     * owner */
+    DeliverTouchEvents(dev, ti, (InternalEvent *) ev, 0);
+    if (ev->any.type == ET_TouchEnd)
+        TouchEndTouch(dev, ti);
 
     if (emulate_pointer)
         UpdateDeviceState(dev, &ev->device_event);
@@ -1818,10 +1816,14 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
         break;
     case ET_TouchBegin:
     case ET_TouchUpdate:
-    case ET_TouchOwnership:
     case ET_TouchEnd:
         ProcessTouchEvent(ev, device);
         break;
+    case ET_TouchOwnership:
+        /* TouchOwnership events are handled separately from the rest, as they
+         * have more complex semantics. */
+        ProcessTouchOwnershipEvent(&ev->touch_ownership_event, device);
+        break;
     case ET_BarrierHit:
     case ET_BarrierLeave:
         ProcessBarrierEvent(ev, device);
commit 0a3630708b729a02cefc342456b243254f5b699d
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Apr 9 16:23:19 2013 -0700

    Xi: Use correct destination when swapping barrier events
    
    Write the swapped values to the destination rather than the source.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit dbba50a1280cbda9ecff6f37884b4c5756c30bab)

diff --git a/Xi/extinit.c b/Xi/extinit.c
index 619d0e4..02fffe5 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -848,24 +848,24 @@ SBarrierEvent(xXIBarrierEvent * from,
 
     *to = *from;
 
-    swaps(&from->sequenceNumber);
-    swapl(&from->length);
-    swaps(&from->evtype);
-    swapl(&from->time);
-    swaps(&from->deviceid);
-    swaps(&from->sourceid);
-    swapl(&from->event);
-    swapl(&from->root);
-    swapl(&from->root_x);
-    swapl(&from->root_y);
-
-    swapl(&from->dx.integral);
-    swapl(&from->dx.frac);
-    swapl(&from->dy.integral);
-    swapl(&from->dy.frac);
-    swapl(&from->dtime);
-    swapl(&from->barrier);
-    swapl(&from->eventid);
+    swaps(&to->sequenceNumber);
+    swapl(&to->length);
+    swaps(&to->evtype);
+    swapl(&to->time);
+    swaps(&to->deviceid);
+    swaps(&to->sourceid);
+    swapl(&to->event);
+    swapl(&to->root);
+    swapl(&to->root_x);
+    swapl(&to->root_y);
+
+    swapl(&to->dx.integral);
+    swapl(&to->dx.frac);
+    swapl(&to->dy.integral);
+    swapl(&to->dy.frac);
+    swapl(&to->dtime);
+    swapl(&to->barrier);
+    swapl(&to->eventid);
 }
 
 /** Event swapping function for XI2 events. */
commit 9ad9c1358567998564d177f06d98fc46dcb41009
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Mar 4 07:58:41 2013 +1000

    dix: don't set non-exisiting flags on touch events
    
    Unlike pointer/keyboard events, the flags field for ET_Touch* is a set of
    server-internal defines that we need to convert to XI protocol defines.
    Currently only two of those defines actually translate to the protocol, so
    make sure we don't send internal garbage down the wire.
    
    No effect to current clients since they shouldn't look at undefined bits
    anyway.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit b86b3d10bb2fee1a922b8831e8bb415c339f3d99)

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 2c411cf..ebc52c3 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -684,17 +684,18 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
     xde->root_x = double_to_fp1616(ev->root_x + ev->root_x_frac);
     xde->root_y = double_to_fp1616(ev->root_y + ev->root_y_frac);
 
-    if (ev->type == ET_TouchUpdate)
-        xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0;
-    else
-        xde->flags = ev->flags;
+    if (IsTouchEvent((InternalEvent *)ev)) {
+        if (ev->type == ET_TouchUpdate)
+            xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0;
 
-    if (IsTouchEvent((InternalEvent *) ev) &&
-        ev->flags & TOUCH_POINTER_EMULATED)
-        xde->flags |= XITouchEmulatingPointer;
+        if (ev->flags & TOUCH_POINTER_EMULATED)
+            xde->flags |= XITouchEmulatingPointer;
+    } else {
+        xde->flags = ev->flags;
 
-    if (ev->key_repeat)
-        xde->flags |= XIKeyRepeat;
+        if (ev->key_repeat)
+            xde->flags |= XIKeyRepeat;
+    }
 
     xde->mods.base_mods = ev->mods.base;
     xde->mods.latched_mods = ev->mods.latched;
commit c760fb0154848d47438908ba8b3da2fffc68a460
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jan 10 03:26:33 2013 +0000

    hw/xfree86: Only report SetDesiredModes() failed if at least one modeset fails
    
    commit 6703a7c7cf1a349c137e247a0c8eb462ff7b07be
    Author: Keith Packard <keithp at keithp.com>
    Date:   Tue Jan 8 20:24:32 2013 -0800
    
        hw/xfree86: Require only one working CRTC to start the server.
    
    changed the logic to try to set the mode on all connected outputs rather
    than abort upon the first failure. The return error code was then
    tweaked such that it reported success if it set a mode on any crtc.
    However, this confuses the headless case where we never enable any crtcs
    and also, importantly, never fail to set a crtc.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=59190
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Also-written-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 451ba4bd41b82acd4aec6236ba121e00cfeb311b)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index f9ae465..7d55f60 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2598,8 +2598,8 @@ xf86SetDesiredModes(ScrnInfoPtr scrn)
 {
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
     xf86CrtcPtr crtc = config->crtc[0];
+    int enabled = 0, failed = 0;
     int c;
-    int enabled = 0;
 
     /* A driver with this hook will take care of this */
     if (!crtc->funcs->set_mode_major) {
@@ -2659,11 +2659,12 @@ xf86SetDesiredModes(ScrnInfoPtr scrn)
                 if (config->output[o]->crtc == crtc)
                     config->output[o]->crtc = NULL;
             crtc->enabled = FALSE;
+            ++failed;
 	}
     }
 
     xf86DisableUnusedFunctions(scrn);
-    return enabled != 0;
+    return enabled != 0 || failed == 0;
 }
 
 /**
commit 5c296c32d9486201c0fbb51e905dd3f8542c4d88
Author: Dave Airlie <airlied at gmail.com>
Date:   Wed Apr 10 16:32:15 2013 +1000

    xf86: don't hotplug output devices while VT switched.
    
    We don't want to hotplug output devices while we are VT switched,
    as we get races between multiple X servers on the device open, and
    drm device master status. This just queues device opens until we return
    from VT switch.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit 22cab8a28a433d03a4e6ba97f9a160271d73cb52)

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 44c4d4a..7a35250 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -84,6 +84,7 @@
 #include "dpmsproc.h"
 #endif
 
+#include "xf86platformBus.h"
 /*
  * This is a toggling variable:
  *  FALSE = No VT switching keys have been pressed last time around
@@ -561,6 +562,9 @@ xf86VTSwitch(void)
         for (ih = InputHandlers; ih; ih = ih->next)
             xf86EnableInputHandler(ih);
 
+        /* check for any new output devices */
+        xf86platformVTProbe();
+
         OsReleaseSIGIO();
     }
 }
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 5866333..9034dad 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -113,6 +113,11 @@ xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_
     return NULL;
 }
 
+Bool
+xf86_get_platform_device_unowned(int index)
+{
+    return xf86_platform_devices[index].attribs->unowned;
+}
 
 /*
  * xf86IsPrimaryPlatform() -- return TRUE if primary device
@@ -498,4 +503,18 @@ xf86platformRemoveDevice(int index)
  out:
     return;
 }
+
+/* called on return from VT switch to find any new devices */
+void xf86platformVTProbe(void)
+{
+    int i;
+
+    for (i = 0; i < xf86_num_platform_devices; i++) {
+        if (xf86_platform_devices[i].attribs->unowned == FALSE)
+            continue;
+
+        xf86_platform_devices[i].attribs->unowned = FALSE;
+        xf86PlatformReprobeDevice(i, xf86_platform_devices[i].attribs);
+    }
+}
 #endif
diff --git a/hw/xfree86/common/xf86platformBus.h b/hw/xfree86/common/xf86platformBus.h
index 49afc24..4e17578 100644
--- a/hw/xfree86/common/xf86platformBus.h
+++ b/hw/xfree86/common/xf86platformBus.h
@@ -46,6 +46,8 @@ extern int
 xf86_remove_platform_device(int dev_index);
 extern Bool
 xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str);
+extern Bool
+xf86_get_platform_device_unowned(int index);
 
 extern int
 xf86platformAddDevice(int index);
@@ -59,6 +61,8 @@ xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *bu
 
 extern _X_EXPORT int
 xf86PlatformMatchDriver(char *matches[], int nmatches);
+
+extern void xf86platformVTProbe(void);
 #endif
 
 #endif
diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c
index 76f5583..21768ee 100644
--- a/hw/xfree86/os-support/linux/lnx_platform.c
+++ b/hw/xfree86/os-support/linux/lnx_platform.c
@@ -18,7 +18,7 @@
 #include "hotplug.h"
 
 static Bool
-get_drm_info(struct OdevAttributes *attribs, char *path)
+get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
 {
     drmSetVersion sv;
     char *buf;
@@ -37,10 +37,14 @@ get_drm_info(struct OdevAttributes *attribs, char *path)
         return FALSE;
     }
 
-    xf86_add_platform_device(attribs);
+    /* for a delayed probe we've already added the device */
+    if (delayed_index == -1) {
+            xf86_add_platform_device(attribs);
+            delayed_index = xf86_num_platform_devices - 1;
+    }
 
     buf = drmGetBusid(fd);
-    xf86_add_platform_device_attrib(xf86_num_platform_devices - 1,
+    xf86_add_platform_device_attrib(delayed_index,
                                     ODEV_ATTRIB_BUSID, buf);
     drmFreeBusid(buf);
     close(fd);
@@ -89,6 +93,23 @@ xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *bu
 }
 
 void
+xf86PlatformReprobeDevice(int index, struct OdevAttributes *attribs)
+{
+    Bool ret;
+    char *dpath;
+    dpath = xf86_get_platform_attrib(index, ODEV_ATTRIB_PATH);
+
+    ret = get_drm_info(attribs, dpath, index);
+    if (ret == FALSE) {
+        xf86_remove_platform_device(index);
+        return;
+    }
+    ret = xf86platformAddDevice(index);
+    if (ret == -1)
+        xf86_remove_platform_device(index);
+}
+
+void
 xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
 {
     struct OdevAttribute *attrib;
@@ -119,7 +140,15 @@ xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
     LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n",
                path);
 
-    ret = get_drm_info(attribs, path);
+    if (!xf86VTOwner()) {
+            /* if we don't currently own the VT then don't probe the device,
+               just mark it as unowned for later use */
+            attribs->unowned = TRUE;
+            xf86_add_platform_device(attribs);
+            return;
+    }
+
+    ret = get_drm_info(attribs, path, -1);
     if (ret == FALSE)
         goto out_free;
 
@@ -138,6 +167,9 @@ void NewGPUDeviceRequest(struct OdevAttributes *attribs)
     if (old_num == xf86_num_platform_devices)
         return;
 
+    if (xf86_get_platform_device_unowned(xf86_num_platform_devices - 1) == TRUE)
+        return;
+
     ret = xf86platformAddDevice(xf86_num_platform_devices-1);
     if (ret == -1)
         xf86_remove_platform_device(xf86_num_platform_devices-1);
@@ -171,7 +203,10 @@ void DeleteGPUDeviceRequest(struct OdevAttributes *attribs)
 
     ErrorF("xf86: remove device %d %s\n", index, syspath);
 
-    xf86platformRemoveDevice(index);
+    if (xf86_get_platform_device_unowned(index) == TRUE)
+            xf86_remove_platform_device(index);
+    else
+            xf86platformRemoveDevice(index);
 out:
     config_odev_free_attribute_list(attribs);
 }
diff --git a/hw/xfree86/os-support/xf86_OSproc.h b/hw/xfree86/os-support/xf86_OSproc.h
index ea2b16e..6be5946 100644
--- a/hw/xfree86/os-support/xf86_OSproc.h
+++ b/hw/xfree86/os-support/xf86_OSproc.h
@@ -223,6 +223,9 @@ extern _X_EXPORT void xf86InitVidMem(void);
 #include "hotplug.h"
 void
 xf86PlatformDeviceProbe(struct OdevAttributes *attribs);
+
+void
+xf86PlatformReprobeDevice(int index, struct OdevAttributes *attribs);
 #endif
 
 _XFUNCPROTOEND
diff --git a/include/hotplug.h b/include/hotplug.h
index 2a95b45..29a22c4 100644
--- a/include/hotplug.h
+++ b/include/hotplug.h
@@ -40,6 +40,7 @@ struct OdevAttribute {
 
 struct OdevAttributes {
     struct xorg_list list;
+    Bool unowned;
 };
 
 struct OdevAttributes *
commit 39ce034505b6526b5c945a6f44a34e020a22d187
Author: Dave Airlie <airlied at gmail.com>
Date:   Wed Apr 10 16:32:11 2013 +1000

    xf86: use new xf86VTOwner interface in a few places
    
    This replaces some previous uses of direct xf86Screens[0] accesses.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Dave Airlie <airlied at gmail.com>
    (cherry picked from commit 5b359cf6135ca173d8f65cb92926332f07f91efe)

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 052f9d6..44c4d4a 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -428,7 +428,7 @@ xf86VTSwitch(void)
      * Since all screens are currently all in the same state it is sufficient
      * check the first.  This might change in future.
      */
-    if (xf86Screens[0]->vtSema) {
+    if (xf86VTOwner()) {
 
         DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
                BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 1695dbf..91ec4c8 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -819,7 +819,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
     if (serverGeneration != 1) {
         xf86Resetting = TRUE;
         /* All screens are in the same state, so just check the first */
-        if (!xf86Screens[0]->vtSema) {
+        if (!xf86VTOwner()) {
 #ifdef HAS_USL_VTS
             ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
 #endif
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index bee407b..26c03c6 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -870,7 +870,7 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
     }
 
     /* Enable it if it's properly initialised and we're currently in the VT */
-    if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema) {
+    if (enable && dev->inited && dev->startup && xf86VTOwner()) {
         OsBlockSignals();
         EnableDevice(dev, TRUE);
         if (!dev->enabled) {
diff --git a/hw/xfree86/os-support/solaris/sun_init.c b/hw/xfree86/os-support/solaris/sun_init.c
index 4b75a98..68527a5 100644
--- a/hw/xfree86/os-support/solaris/sun_init.c
+++ b/hw/xfree86/os-support/solaris/sun_init.c
@@ -274,7 +274,7 @@ xf86OpenConsole(void)
              * this is to make sure we don't continue until the activate
              * signal is received.
              */
-            if (!xf86Screens[0]->vtSema)
+            if (!xf86VTOwner())
                 sleep(5);
         }
 #endif                          /* HAS_USL_VTS */
commit 92135056375fe9a2b637487dd4a9274ab6dd338d
Author: Dave Airlie <airlied at gmail.com>
Date:   Wed Apr 10 16:32:02 2013 +1000

    xfree86: add VT owner interface
    
    This is just a simple interface to avoid accessing x86Screens[0]
    directly.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Dave Airlie <airlied at gmail.com>
    (cherry picked from commit d61ea1f64db45201c1a2b39c39293c5768d98092)

diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index 1514c26..828d958 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -243,6 +243,7 @@ extern _X_EXPORT void xf86InterceptSigIll(void (*sigillhandler) (void));
 extern _X_EXPORT Bool xf86EnableVTSwitch(Bool new);
 extern _X_EXPORT void xf86ProcessActionEvent(ActionEvent action, void *arg);
 extern _X_EXPORT void xf86PrintBacktrace(void);
+extern _X_EXPORT Bool xf86VTOwner(void);
 
 /* xf86Helper.c */
 
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index d92174e..052f9d6 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -769,3 +769,12 @@ DDXRingBell(int volume, int pitch, int duration)
 {
     xf86OSRingBell(volume, pitch, duration);
 }
+
+Bool
+xf86VTOwner(void)
+{
+    /* at system startup xf86Screens[0] won't be set - but we will own the VT */
+    if (xf86NumScreens == 0)
+	return TRUE;
+    return xf86Screens[0]->vtSema;
+}
commit f5796f98dadccf67c04f601178966614dd51a1b4
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 17 16:12:00 2013 +1000

    xserver 1.14.1
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/configure.ac b/configure.ac
index 44982b3..4289863 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.14.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-03-05"
-RELEASE_NAME="Keemun Mao Feng"
+AC_INIT([xorg-server], 1.14.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-04-17"
+RELEASE_NAME="Act Normal"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
commit aac2d9d09c73fa2b9d02d8446718aa6ccd7e894a
Author: Dave Airlie <airlied at gmail.com>
Date:   Wed Apr 10 16:09:01 2013 +1000

    xf86: fix flush input to work with Linux evdev devices.
    
    So when we VT switch back and attempt to flush the input devices,
    we don't succeed because evdev won't return part of an event,
    since we were only asking for 4 bytes, we'd only get -EINVAL back.
    
    This could later cause events to be flushed that we shouldn't have
    gotten.
    
    This is a fix for CVE-2013-1940.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 6ca03b9161d33b1d2b55a3a1a913cf88deb2343f)

diff --git a/hw/xfree86/os-support/shared/posix_tty.c b/hw/xfree86/os-support/shared/posix_tty.c
index ab3757a..4d08c1e 100644
--- a/hw/xfree86/os-support/shared/posix_tty.c
+++ b/hw/xfree86/os-support/shared/posix_tty.c
@@ -421,7 +421,8 @@ xf86FlushInput(int fd)
 {
     fd_set fds;
     struct timeval timeout;
-    char c[4];
+    /* this needs to be big enough to flush an evdev event. */
+    char c[256];
 
     DebugF("FlushingSerial\n");
     if (tcflush(fd, TCIFLUSH) == 0)
commit 2eec013569f6daa952482ac5d9db8acc71fe01aa
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 25 11:13:52 2013 +1000

    dix: fix a comment
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 11bead1fa205a1353e6a33c6024c7e8ace80be7c)

diff --git a/dix/touch.c b/dix/touch.c
index 0db842c..891cc78 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -902,7 +902,8 @@ TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev)
 }
 
 /**
- * Remove the touch pointer grab from the device. Called from AllowSome()
+ * Remove the touch pointer grab from the device. Called from
+ * DeactivatePointerGrab()
  */
 void
 TouchRemovePointerGrab(DeviceIntPtr dev)
commit bce06afc99ce1d948f9002e0c5c7bc29d66425da
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 28 10:43:05 2013 +1000

    Xi: add a comment to make a condition a bit clearer
    
    The commit message to 676447190190d8546165e21be242cf16dd69f5ae explains it,
    but that doesn't stop the WTF moment when reading the code.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 2967391c6d35f03121afa8003e0fb94b62495129)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 609b126..f05e03d 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1896,6 +1896,7 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
         goto out;
     }
 
+    /* A client is waiting for the begin, don't give it a TouchEnd */
     if (listener->state == LISTENER_AWAITING_BEGIN) {
         listener->state = LISTENER_HAS_END;
         goto out;
commit 8e16c2e3038c1c17cae73d8d9681dccce0fd402a
Author: Robert Morell <rmorell at nvidia.com>
Date:   Tue Mar 12 09:40:16 2013 -0700

    list.h: Make xorg_list_init inline
    
    Otherwise this file is emitted in every unit that includes it.
    
    Signed-off-by: Robert Morell <rmorell at nvidia.com>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 7050aae69c2a55dfdbb5c6af7882307e90ba4275)

diff --git a/include/list.h b/include/list.h
index 067c679..11de7c5 100644
--- a/include/list.h
+++ b/include/list.h
@@ -119,7 +119,7 @@ struct xorg_list {
  *
  * @param The list to initialized.
  */
-static void
+static inline void
 xorg_list_init(struct xorg_list *list)
 {
     list->next = list->prev = list;
commit 44def3caf002f9fc53b971014e4e2d62afe39435
Author: Robert Morell <rmorell at nvidia.com>
Date:   Tue Mar 12 09:37:43 2013 -0700

    configure.ac: Require inputproto 2.3
    
    This picks up support for Xi pointer barriers in the protocol.
    
    Signed-off-by: Robert Morell <rmorell at nvidia.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 31595b528645a7e4903eb81da0fc332d78407f25)

diff --git a/configure.ac b/configure.ac
index 6e1ff65..44982b3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -788,7 +788,7 @@ XPROTO="xproto >= 7.0.22"
 RANDRPROTO="randrproto >= 1.4.0"
 RENDERPROTO="renderproto >= 0.11"
 XEXTPROTO="xextproto >= 7.1.99"
-INPUTPROTO="inputproto >= 2.2.99.1"
+INPUTPROTO="inputproto >= 2.3"
 KBPROTO="kbproto >= 1.0.3"
 FONTSPROTO="fontsproto"
 FIXESPROTO="fixesproto >= 5.0"
commit 27a49db31a146b8e2f1133c23262ecadc5ff4157
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat Mar 9 17:12:53 2013 +1000

    xfixes: ifdef PanoramiXFixes* (#62015)
    
    Fixes build failure with --disable-xinerama introduced by
    482e0cb cursor: Move pointer barrier code over to XI
    
    Reason is new include order: sdksyms.sh includes xfixes.h, which previously
    did not include xfixesint.h.
    
    As of 482e0cb xfixes.h includes xibarriers.h which includes xfixesint.h
    
    X.Org Bug 62015 <http://bugs.freedesktop.org/show_bug.cgi?id=62015>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Tested-by: Daniel Martin <consume.noise at gmail.com>
    (cherry picked from commit 3ac2e61705432951f9e1b96b42b4214e7f748f94)

diff --git a/xfixes/xfixesint.h b/xfixes/xfixesint.h
index 334c71f..44e8890 100644
--- a/xfixes/xfixesint.h
+++ b/xfixes/xfixesint.h
@@ -291,8 +291,10 @@ int
  SProcXFixesDestroyPointerBarrier(ClientPtr client);
 
 /* Xinerama */
+#ifdef PANORAMIX
 extern int (*PanoramiXSaveXFixesVector[XFixesNumberRequests]) (ClientPtr);
 void PanoramiXFixesInit(void);
 void PanoramiXFixesReset(void);
+#endif
 
 #endif                          /* _XFIXESINT_H_ */
commit 103b77c59e3638a45179bf6d7908f5c738d2d872
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Mar 5 22:31:17 2013 -0800

    Version bumped to 1.14
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 53335b1..6e1ff65 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.13.99.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-02-12"
-RELEASE_NAME="Ginger Beer"
+AC_INIT([xorg-server], 1.14.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-03-05"
+RELEASE_NAME="Keemun Mao Feng"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
commit 6238bd68bd71323f8b4f1808f34dabe2ae447fe3
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Tue Mar 5 13:04:46 2013 -0800

    DPMS: include GPU screens in DPMS code
    
    Otherwise, displays driven by GPU screens remain on all the time.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86DPMS.c b/hw/xfree86/common/xf86DPMS.c
index ef4a2c1..3f1e142 100644
--- a/hw/xfree86/common/xf86DPMS.c
+++ b/hw/xfree86/common/xf86DPMS.c
@@ -130,6 +130,19 @@ DPMSClose(ScreenPtr pScreen)
     return pScreen->CloseScreen(pScreen);
 }
 
+static void
+DPMSSetScreen(ScrnInfoPtr pScrn, int level)
+{
+    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
+    DPMSPtr pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
+
+    if (pDPMS && pScrn->DPMSSet && pDPMS->Enabled && pScrn->vtSema) {
+        xf86VGAarbiterLock(pScrn);
+        pScrn->DPMSSet(pScrn, level, 0);
+        xf86VGAarbiterUnlock(pScrn);
+    }
+}
+
 /*
  * DPMSSet --
  *	Device dependent DPMS mode setting hook.  This is called whenever
@@ -139,8 +152,6 @@ int
 DPMSSet(ClientPtr client, int level)
 {
     int rc, i;
-    DPMSPtr pDPMS;
-    ScrnInfoPtr pScrn;
 
     DPMSPowerLevel = level;
 
@@ -155,17 +166,23 @@ DPMSSet(ClientPtr client, int level)
 
     /* For each screen, set the DPMS level */
     for (i = 0; i < xf86NumScreens; i++) {
-        pScrn = xf86Screens[i];
-        pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
-        if (pDPMS && pScrn->DPMSSet && pDPMS->Enabled && pScrn->vtSema) {
-            xf86VGAarbiterLock(pScrn);
-            pScrn->DPMSSet(pScrn, level, 0);
-            xf86VGAarbiterUnlock(pScrn);
-        }
+        DPMSSetScreen(xf86Screens[i], level);
+    }
+    for (i = 0; i < xf86NumGPUScreens; i++) {
+        DPMSSetScreen(xf86GPUScreens[i], level);
     }
     return Success;
 }
 
+static Bool
+DPMSSupportedOnScreen(ScrnInfoPtr pScrn)
+{
+    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
+    DPMSPtr pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
+
+    return pDPMS && pScrn->DPMSSet;
+}
+
 /*
  * DPMSSupported --
  *	Return TRUE if any screen supports DPMS.
@@ -174,8 +191,6 @@ Bool
 DPMSSupported(void)
 {
     int i;
-    DPMSPtr pDPMS;
-    ScrnInfoPtr pScrn;
 
     if (DPMSKey == NULL) {
         return FALSE;
@@ -183,9 +198,11 @@ DPMSSupported(void)
 
     /* For each screen, check if DPMS is supported */
     for (i = 0; i < xf86NumScreens; i++) {
-        pScrn = xf86Screens[i];
-        pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
-        if (pDPMS && pScrn->DPMSSet)
+        if (DPMSSupportedOnScreen(xf86Screens[i]))
+            return TRUE;
+    }
+    for (i = 0; i < xf86NumGPUScreens; i++) {
+        if (DPMSSupportedOnScreen(xf86GPUScreens[i]))
             return TRUE;
     }
     return FALSE;
commit dd4ab8b572956f9457616869d6e383c8ed964c73
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Mar 5 10:14:29 2013 +1000

    Xi: force dtime to 0 on the first BarrierHit
    
    dtime to the previous event is 0 on the first BarrierHit event.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index a225cbc..fccab86 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -435,6 +435,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
     dir = barrier_get_direction(current_x, current_y, x, y);
 
     while (dir != 0) {
+        int new_sequence;
         struct PointerBarrierDevice *pbd;
 
         c = barrier_find_nearest(cs, master, dir, current_x, current_y, x, y);
@@ -444,6 +445,8 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         nearest = &c->barrier;
 
         pbd = GetBarrierDevice(c, master->id);
+        new_sequence = !pbd->hit;
+
         pbd->seen = TRUE;
         pbd->hit = TRUE;
 
@@ -466,7 +469,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         ev.event_id = pbd->barrier_event_id;
         ev.barrierid = c->id;
 
-        ev.dt = ms - pbd->last_timestamp;
+        ev.dt = new_sequence ? 0 : ms - pbd->last_timestamp;
         ev.window = c->window;
         pbd->last_timestamp = ms;
 
commit 604169af8b67afc74a292cdb9070a3a1f2d7c536
Merge: 8f4640b 6ea59dc
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Mar 4 21:09:59 2013 -0800

    Merge commit '6ea59dc2d8887102bfd8d7c838d2e7ab17645aec'

commit 6ea59dc2d8887102bfd8d7c838d2e7ab17645aec
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sun Mar 3 04:50:55 2013 -0500

    xibarriers: Remove accidental use of the comma operator
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 7b7b83f..a225cbc 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -676,8 +676,8 @@ BarrierFreeBarrier(void *data, XID id)
             continue;
 
         ev.deviceid = dev->id;
-        ev.event_id = pbd->barrier_event_id,
-        ev.dt = ms - pbd->last_timestamp,
+        ev.event_id = pbd->barrier_event_id;
+        ev.dt = ms - pbd->last_timestamp;
 
         GetSpritePosition(dev, &root_x, &root_y);
         ev.root_x = root_x;
commit 8f4640bdb9d3988148e09a08d2c7e3bab1d538d6
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jan 9 12:58:28 2013 +1000

    randr: cleanup provider properly
    
    So in the cold plug server shutdown case, we reap the resources
    before we call CloseScreen handlers, so the config->randr_provider
    is a dangling pointer when the xf86CrtcCloseScreen handler is called,
    
    however in the hot screen unplug case, we can't rely on automatically
    reaped resources, so we need to clean up the provider in the xf86CrtcCloseScreen
    case.
    
    This patch provides a cleanup callback from the randr provider removal
    into the DDX so it can cleanup properly, this then gets called by the automatic
    code for cold plug, or if hot unplug it gets called explicitly.
    
    Fixes a number of random server crashes on shutdown
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=58174
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=891140
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index b52b6ef..f9ae465 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -743,16 +743,8 @@ xf86CrtcCloseScreen(ScreenPtr screen)
     }
     /* detach any providers */
     if (config->randr_provider) {
-        if (config->randr_provider->offload_sink) {
-            DetachOffloadGPU(screen);
-            config->randr_provider->offload_sink = NULL;
-        }
-        else if (config->randr_provider->output_source) {
-            DetachOutputGPU(screen);
-            config->randr_provider->output_source = NULL;
-        }
-        else if (screen->current_master)
-            DetachUnboundGPU(screen);
+        RRProviderDestroy(config->randr_provider);
+        config->randr_provider = NULL;
     }
     return TRUE;
 }
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 3530abf..01fc9c5 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1885,6 +1885,27 @@ xf86RandR13ConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode, i
     }
 }
 
+static void
+xf86RandR14ProviderDestroy(ScreenPtr screen, RRProviderPtr provider)
+{
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+    
+    if (config->randr_provider == provider) {
+        if (config->randr_provider->offload_sink) {
+            DetachOffloadGPU(screen);
+            config->randr_provider->offload_sink = NULL;
+        }
+        else if (config->randr_provider->output_source) {
+            DetachOutputGPU(screen);
+            config->randr_provider->output_source = NULL;
+        }
+        else if (screen->current_master)
+            DetachUnboundGPU(screen);
+    }
+    config->randr_provider = NULL;
+}
+
 static Bool
 xf86RandR12Init12(ScreenPtr pScreen)
 {
@@ -1914,6 +1935,7 @@ xf86RandR12Init12(ScreenPtr pScreen)
     rp->rrProviderSetProperty = xf86RandR14ProviderSetProperty;
     rp->rrProviderGetProperty = xf86RandR14ProviderGetProperty;
     rp->rrCrtcSetScanoutPixmap = xf86CrtcSetScanoutPixmap;
+    rp->rrProviderDestroy = xf86RandR14ProviderDestroy;
 
     pScrn->PointerMoved = xf86RandR12PointerMoved;
     pScrn->ChangeGamma = xf86RandR12ChangeGamma;
diff --git a/randr/randrstr.h b/randr/randrstr.h
index f52d0f2..2517479 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -232,6 +232,9 @@ typedef Bool (*RRProviderSetOffloadSinkProcPtr)(ScreenPtr pScreen,
                                          RRProviderPtr offload_sink);
 
 
+typedef void (*RRProviderDestroyProcPtr)(ScreenPtr pScreen,
+                                         RRProviderPtr provider);
+
 /* These are for 1.0 compatibility */
 
 typedef struct _rrRefresh {
@@ -330,6 +333,9 @@ typedef struct _rrScrPriv {
     Bool discontiguous;
 
     RRProviderPtr provider;
+
+    RRProviderDestroyProcPtr rrProviderDestroy;
+
 } rrScrPrivRec, *rrScrPrivPtr;
 
 extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
diff --git a/randr/rrprovider.c b/randr/rrprovider.c
index c4ed515..b321e62 100644
--- a/randr/rrprovider.c
+++ b/randr/rrprovider.c
@@ -389,6 +389,8 @@ RRProviderDestroyResource (pointer value, XID pid)
     {
         rrScrPriv(pScreen);
 
+        if (pScrPriv->rrProviderDestroy)
+            (*pScrPriv->rrProviderDestroy)(pScreen, provider);
         pScrPriv->provider = NULL;
     }
     free(provider);
commit 3ec35c45ca17f5ed6fd02c50fc49ae7b8d128dcb
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jan 9 12:53:14 2013 +1000

    xf86: actually set the compat output in the failure case
    
    The previous fix for the previous fix, didn't fully work,
    
    If we don't set compat_output we end up doing derferences
    of arrays with -1, leading to valgrind warnings.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index b3ded5a..b52b6ef 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1848,8 +1848,10 @@ SetCompatOutput(xf86CrtcConfigPtr config)
     }
 
     /* All outputs are disconnected, select one to fake */
-    if (!output && config->num_output)
-        output = config->output[0];
+    if (!output && config->num_output) {
+        config->compat_output = 0;
+        output = config->output[config->compat_output];
+    }
 
     return output;
 }
commit da8ee26023fc2868fe970471195a5f3c86fb574b
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jan 9 12:51:45 2013 +1000

    xfree86/hotplug: cleanup properly if the screen fails to initialise
    
    Due to another bug, the modesetting/udl driver would fail to init properly
    on hotplug, when it did the code didn't clean up properly, and on removing
    the device the server could crash.
    
    Found in F18 testing.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>

diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 0525e39..5866333 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -438,7 +438,12 @@ xf86platformAddDevice(int index)
     }
 
    scr_index = AddGPUScreen(xf86GPUScreens[i]->ScreenInit, 0, NULL);
-
+   if (scr_index == -1) {
+       xf86DeleteScreen(xf86GPUScreens[i]);
+       xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
+       xf86NumGPUScreens = old_screens;
+       return -1;
+   }
    dixSetPrivate(&xf86GPUScreens[i]->pScreen->devPrivates,
                  xf86ScreenKey, xf86GPUScreens[i]);
 
commit 90642948cc78834d95f7a3bddaac7ff77b68ed7e
Merge: 9a35d42 eda7dbf
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Feb 14 11:05:48 2013 -0800

    Merge remote-tracking branch 'jeremyhu/master'

commit 9a35d4240e2aa91ac104f0f9f86f83ff9a2d3d04
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 14 16:31:13 2013 +1000

    os: fix pnprintf OOB buffer read for unterminated length modifiers
    
    Format strings with length modifiers but missing format specifier like "%0"
    will read one byte past the array size.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/log.c b/os/log.c
index 2697ace..95bd8cc 100644
--- a/os/log.c
+++ b/os/log.c
@@ -304,6 +304,9 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
         while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.'))
             f_idx++;
 
+        if (f_idx >= f_len)
+            break;
+
         switch (f[f_idx]) {
         case 's':
             string_arg = va_arg(args, char*);
diff --git a/test/signal-logging.c b/test/signal-logging.c
index 1ef17af..e0eb810 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -199,6 +199,14 @@ static void logging_format(void)
     read_log_msg(logmsg);
     assert(strcmp(logmsg, "(EE) substituted string\n") == 0);
 
+    /* Invalid format */
+#warning Ignore compiler warning below "lacks type at end of format".  This is intentional.
+    LogMessageVerbSigSafe(X_ERROR, -1, "%4", 4);
+    read_log_msg(logmsg);
+    assert(strcmp(logmsg, "(EE) ") == 0);
+    LogMessageVerbSigSafe(X_ERROR, -1, "\n");
+    fseek(f, 0, SEEK_END);
+
     /* number substitution */
     ui = 0;
     do {
commit eda7dbff5a9f35fefe1e3dedacb82daadbf5945e
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sat Feb 9 20:53:02 2013 -0800

    XORG_TLS: Pick the first option that works (ie: prefer __thread)
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/m4/xorg-tls.m4 b/m4/xorg-tls.m4
index 237fdcd..e04f1ff 100644
--- a/m4/xorg-tls.m4
+++ b/m4/xorg-tls.m4
@@ -28,7 +28,7 @@ AC_DEFUN([XORG_TLS], [
         ac_cv_tls=none
         keywords="__thread __declspec(thread)"
         for kw in $keywords ; do
-            AC_TRY_COMPILE([int $kw test;], [], ac_cv_tls=$kw)
+            AC_TRY_COMPILE([int $kw test;], [], ac_cv_tls=$kw ; break ;)
         done
     ])
     AC_MSG_RESULT($ac_cv_tls)
commit 5da82f872daf25939a8fa04f1561b01f0315a623
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sat Feb 9 20:40:10 2013 -0800

    os: Ensure <dix-config.h> is included in strndup.c
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/os/strndup.c b/os/strndup.c
index b604b9b..e0eddf1 100644
--- a/os/strndup.c
+++ b/os/strndup.c
@@ -27,6 +27,10 @@
  * SUCH DAMAGE.
  */
 
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
commit 67eaf4b46f678bc904f47dfcab6655e170d843e0
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sat Feb 9 20:34:33 2013 -0800

    XQuartz: Ensure <dix-config.h> is included in capabilities.c
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/hw/xquartz/GL/capabilities.c b/hw/xquartz/GL/capabilities.c
index 4702595..5573629 100644
--- a/hw/xquartz/GL/capabilities.c
+++ b/hw/xquartz/GL/capabilities.c
@@ -20,6 +20,10 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
commit 955d434f4d755d00a24ae4068b9957765989d672
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Feb 13 21:39:37 2013 -0800

    Update to version 1.3.99.902 (1.14 RC2)
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 435a38f..53335b1 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.13.99.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2012-12-19"
-RELEASE_NAME="Egg Nog"
+AC_INIT([xorg-server], 1.13.99.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-02-12"
+RELEASE_NAME="Ginger Beer"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
commit 7115f6c709898a5124b67e19c61dc01334471358
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Wed Jan 23 16:58:47 2013 -0800

    randr: unref the provider shared pixmap the appropriate number of times
    
    When an RandR shared pixmap is created in rrCreateSharedPixmap, it has a refcnt
    of 1.  Then, PixmapShareToSlave bumps the refcnt to 2.  However, there's no
    corresponding PixmapUnshareFromSlave where the refcnt can be decreased again,
    and there's no convenient common place where the refcnt can be decremented when
    the slave pixmap is destroyed.
    
    Fix this by just unreffing the pixmap twice in RRCrtcDetachScanoutPixmap.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index e82d050..6e2eca5 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -372,6 +372,11 @@ RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
     ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL);
     if (crtc->scanout_pixmap) {
         master->StopPixmapTracking(mscreenpix, crtc->scanout_pixmap);
+        /*
+         * Unref the pixmap twice: once for the original reference, and once
+         * for the reference implicitly added by PixmapShareToSlave.
+         */
+        master->DestroyPixmap(crtc->scanout_pixmap->master_pixmap);
         master->DestroyPixmap(crtc->scanout_pixmap->master_pixmap);
         crtc->pScreen->DestroyPixmap(crtc->scanout_pixmap);
     }
commit da92690107d90061205340d4cdc98b73b59db9b2
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Mon Feb 11 14:31:56 2013 -0800

    xf86: use nt_list_for_each_entry_safe to walk InputHandlers in xf86Wakeup
    
    This is necessary when the input handler deletes itself from the
    list. Bug found by Maarten Lankhorst, this patch uses the list macros
    instead of open-coding the fix.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 377e936..d92174e 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -272,9 +272,9 @@ xf86Wakeup(pointer blockData, int err, pointer pReadmask)
     }
 
     if (err >= 0) {             /* we don't want the handlers called if select() */
-        IHPtr ih;               /* returned with an error condition, do we?      */
+        IHPtr ih, ih_tmp;       /* returned with an error condition, do we?      */
 
-        for (ih = InputHandlers; ih; ih = ih->next) {
+        nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next) {
             if (ih->enabled && ih->fd >= 0 && ih->ihproc &&
                 (FD_ISSET(ih->fd, ((fd_set *) pReadmask)) != 0)) {
                 ih->ihproc(ih->fd, ih->data);
commit d0a14877872b6a33172fb8c8f335792a28b9499b
Author: Bryce Harrington <bryce at canonical.com>
Date:   Fri Feb 8 15:56:02 2013 -0800

    xfree86: Man page shouldn't say Device is mandatory anymore
    
    man xorg.conf states that the 'Device' identifier is required in the
    'Screen' section, yet current xserver defaults properly and boots up
    fine without it.
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=20742
    Signed-off-by: Bryce Harrington <bryce at canonical.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
index 5d92bbe..9361ce9 100644
--- a/hw/xfree86/man/xorg.conf.man
+++ b/hw/xfree86/man/xorg.conf.man
@@ -1821,9 +1821,7 @@ sections have the following format:
 .PP
 The
 .B Identifier
-and
-.B Device
-entries are mandatory.
+entry is mandatory.
 All others are optional.
 .PP
 The
@@ -1841,11 +1839,10 @@ The entries available
 for this section are:
 .TP 7
 .BI "Device  \*q" device\-id \*q
-This mandatory entry specifies the
+This entry specifies the
 .B Device
-section to be used for this screen.
-This is what ties a specific graphics card to a screen.
-The
+section to be used for this screen.  When multiple graphics cards are
+present, this is what ties a specific card to a screen.  The
 .I device\-id
 must match the
 .B Identifier
commit 5e91054aa070ea09b61325b7ec479d767b02730e
Author: Bryce Harrington <bryce at canonical.com>
Date:   Fri Feb 8 15:56:01 2013 -0800

    xfree86: Use fbdev/vesa driver on Oaktrail, Medfield, CDV rather than -intel
    
    Instead of defaulting to -intel for Oaktrail, Medfield, and CDV chips,
    default to -fbdev.  For Poulsbo (only), attempt to use -psb if it's
    installed, and fallback to fbdev otherwise.  All other Intel chips
    should use -intel.
    
    This fixed an issue where -intel would load on these chips and cause a
    boot failure.  Newer -intel drivers avoid the boot hang, but it's still
    the wrong driver to load, so why take chances.
    
    The patch was originally created by Stefan Dirsch for OpenSUSE.  We have
    included it in our stable release (Ubuntu "quantal" 12.10) since
    December.
    
    ref:  https://bugzilla.novell.com/show_bug.cgi?id=772279
    ref:  https://bugs.launchpad.net/ubuntu/+bug/1069031
    Fixes:  https://bugs.freedesktop.org/show_bug.cgi?id=60514
    Signed-off-by: Bryce Harrington <bryce at canonical.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index a2c18eb..258988a 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -1147,14 +1147,62 @@ xf86VideoPtrToDriverList(struct pci_device *dev,
         driverList[0] = "i128";
         break;
     case 0x8086:
-        if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800)) {
-            driverList[0] = "i740";
-        }
-        else if (dev->device_id == 0x8108) {
-            break;              /* "hooray" for poulsbo */
-        }
-        else {
-            driverList[0] = "intel";
+	switch (dev->device_id)
+	{
+		/* Intel i740 */
+		case 0x00d1:
+		case 0x7800:
+			driverList[0] = "i740";
+			break;
+		/* GMA500/Poulsbo */
+		case 0x8108:
+		case 0x8109:
+			/* Try psb driver on Poulsbo - if available */
+			driverList[0] = "psb";
+			driverList[1] = "psb_drv";
+			break;
+		/* GMA600/Oaktrail */
+		case 0x4100:
+		case 0x4101:
+		case 0x4102:
+		case 0x4103:
+		case 0x4104:
+		case 0x4105:
+		case 0x4106:
+		case 0x4107:
+		/* Atom E620/Oaktrail */
+		case 0x4108:
+		/* Medfield */
+		case 0x0130:
+		case 0x0131:
+		case 0x0132:
+		case 0x0133:
+		case 0x0134:
+		case 0x0135:
+		case 0x0136:
+		case 0x0137:
+		/* GMA 3600/CDV */
+		case 0x0be0:
+		case 0x0be1:
+		case 0x0be2:
+		case 0x0be3:
+		case 0x0be4:
+		case 0x0be5:
+		case 0x0be6:
+		case 0x0be7:
+		case 0x0be8:
+		case 0x0be9:
+		case 0x0bea:
+		case 0x0beb:
+		case 0x0bec:
+		case 0x0bed:
+		case 0x0bee:
+		case 0x0bef:
+			/* Use fbdev/vesa driver on Oaktrail, Medfield, CDV */
+			break;
+		default:
+			driverList[0] = "intel";
+			break;
         }
         break;
     case 0x102b:
commit c1602d1c17967bdd4db9db19b3a9c0dfca6a58aa
Author: Dave Airlie <airlied at gmail.com>
Date:   Tue Feb 5 07:46:06 2013 -0800

    randr: bump advertised RandR version to 1.4
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
    Tested-by: Aaron Plattner <aplattner at nvidia.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index 10f5117..5ceaeb0 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -65,7 +65,7 @@
 
 /* RandR */
 #define SERVER_RANDR_MAJOR_VERSION		1
-#define SERVER_RANDR_MINOR_VERSION		3
+#define SERVER_RANDR_MINOR_VERSION		4
 
 /* Record */
 #define SERVER_RECORD_MAJOR_VERSION		1
diff --git a/randr/randrstr.h b/randr/randrstr.h
index a16302f..f52d0f2 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -57,7 +57,7 @@
 #define RANDR_13_INTERFACE 1    /* requires RANDR_12_INTERFACE */
 #define RANDR_GET_CRTC_INTERFACE 1
 
-#define RANDR_INTERFACE_VERSION 0x0103
+#define RANDR_INTERFACE_VERSION 0x0104
 
 typedef XID RRMode;
 typedef XID RROutput;
commit 9f79e93b6b3416055d08a0e8f9f16d5fd0649e36
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jan 30 03:20:07 2013 +0000

    Short-cut the input device cleanup process during AbortServer()
    
    If we're about to abort, we're already in the signal handler and cannot call
    down to the default device cleanup routines (which reset, free, alloc, and
    do a bunch of other things).
    
    Add a new DEVICE_ABORT mode to signal a driver's DeviceProc that it must
    reset the hardware if needed but do nothing else. An actual HW reset is only
    required for some drivers dealing with the HW directly.
    
    This is largely backwards-compatible, hence the input ABI minor bump only.
    
    Drivers we care about either return BadValue on a mode that's not
    DEVICE_{INIT|ON|OFF|CLOSE} or print an error and return BadValue. Exception
    here is vmmouse, which currently ignores it and would not reset anything.
    This should be fixed if the reset is required.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/devices.c b/dix/devices.c
index 530f15d..be236dd 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1056,6 +1056,25 @@ CloseDownDevices(void)
 }
 
 /**
+ * Signal all devices that we're in the process of aborting.
+ * This function is called from a signal handler.
+ */
+void
+AbortDevices(void)
+{
+    DeviceIntPtr dev;
+    nt_list_for_each_entry(dev, inputInfo.devices, next) {
+        if (!IsMaster(dev))
+            (*dev->deviceProc) (dev, DEVICE_ABORT);
+    }
+
+    nt_list_for_each_entry(dev, inputInfo.off_devices, next) {
+        if (!IsMaster(dev))
+            (*dev->deviceProc) (dev, DEVICE_ABORT);
+    }
+}
+
+/**
  * Remove the cursor sprite for all devices. This needs to be done before any
  * resources are freed or any device is deleted.
  */
diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index e545c14..1393427 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -81,7 +81,7 @@ typedef enum {
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
 #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(14, 1)
-#define ABI_XINPUT_VERSION	SET_ABI_VERSION(19, 0)
+#define ABI_XINPUT_VERSION	SET_ABI_VERSION(19, 1)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(7, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
diff --git a/include/input.h b/include/input.h
index 7b5ab94..5c65597 100644
--- a/include/input.h
+++ b/include/input.h
@@ -62,6 +62,7 @@ SOFTWARE.
 #define DEVICE_ON	1
 #define DEVICE_OFF	2
 #define DEVICE_CLOSE	3
+#define DEVICE_ABORT	4
 
 #define POINTER_RELATIVE	(1 << 1)
 #define POINTER_ABSOLUTE	(1 << 2)
@@ -269,6 +270,7 @@ extern void DisableAllDevices(void);
 extern int InitAndStartDevices(void);
 
 extern void CloseDownDevices(void);
+extern void AbortDevices(void);
 
 extern void UndisplayDevices(void);
 
diff --git a/os/log.c b/os/log.c
index 7b5c9ee..2697ace 100644
--- a/os/log.c
+++ b/os/log.c
@@ -663,7 +663,7 @@ AbortServer(void)
 #endif
     CloseWellKnownConnections();
     OsCleanup(TRUE);
-    CloseDownDevices();
+    AbortDevices();
     AbortDDX(EXIT_ERR_ABORT);
     fflush(stderr);
     if (CoreDump)
commit b58221f9da8c549d979215271359c6cd88b5568a
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 8 14:52:02 2013 +1000

    dix: support the transformation matrix for relative devices.
    
    The transformation matrix we previously stored was a scaled matrix based on
    the axis ranges of the device. For relative movements, the scaling is not
    required (or desired).
    
    Store two separate matrices, one as requested by the client, one as the
    product of [scale . matrix . inv_scale]. Depending on the type of movement,
    apply the respective matrix.
    
    For relative movements, also drop the translation component since it doesn't
    really make sense to use that bit.
    
    Input ABI 19
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/devices.c b/dix/devices.c
index 172fc04..530f15d 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -93,9 +93,10 @@ SOFTWARE.
 static void RecalculateMasterButtons(DeviceIntPtr slave);
 
 static void
-DeviceSetTransform(DeviceIntPtr dev, float *transform)
+DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
 {
     struct pixman_f_transform scale;
+    struct pixman_f_transform transform;
     double sx, sy;
     int x, y;
 
@@ -122,16 +123,21 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform)
     /* transform */
     for (y = 0; y < 3; y++)
         for (x = 0; x < 3; x++)
-            dev->transform.m[y][x] = *transform++;
+            transform.m[y][x] = *transform_data++;
 
-    pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
+    pixman_f_transform_multiply(&dev->scale_and_transform, &scale, &transform);
 
     /* scale */
     pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
     scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
     scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
 
-    pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale);
+    pixman_f_transform_multiply(&dev->scale_and_transform, &dev->scale_and_transform, &scale);
+
+    /* remove translation component for relative movements */
+    dev->relative_transform = transform;
+    dev->relative_transform.m[0][2] = 0;
+    dev->relative_transform.m[1][2] = 0;
 }
 
 /**
@@ -308,9 +314,10 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
     /* unity matrix */
     memset(transform, 0, sizeof(transform));
     transform[0] = transform[4] = transform[8] = 1.0f;
-    dev->transform.m[0][0] = 1.0;
-    dev->transform.m[1][1] = 1.0;
-    dev->transform.m[2][2] = 1.0;
+    dev->relative_transform.m[0][0] = 1.0;
+    dev->relative_transform.m[1][1] = 1.0;
+    dev->relative_transform.m[2][2] = 1.0;
+    dev->scale_and_transform = dev->relative_transform;
 
     XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
                            XIGetKnownProperty(XATOM_FLOAT), 32,
diff --git a/dix/getevents.c b/dix/getevents.c
index 7cc8d8c..a4f192c 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1202,6 +1202,27 @@ transform(struct pixman_f_transform *m, double *x, double *y)
     *y = p.v[1];
 }
 
+static void
+transformRelative(DeviceIntPtr dev, ValuatorMask *mask)
+{
+    double x = 0, y = 0;
+
+    valuator_mask_fetch_double(mask, 0, &x);
+    valuator_mask_fetch_double(mask, 1, &y);
+
+    transform(&dev->relative_transform, &x, &y);
+
+    if (x)
+        valuator_mask_set_double(mask, 0, x);
+    else
+        valuator_mask_unset(mask, 0);
+
+    if (y)
+        valuator_mask_set_double(mask, 1, y);
+    else
+        valuator_mask_unset(mask, 1);
+}
+
 /**
  * Apply the device's transformation matrix to the valuator mask and replace
  * the scaled values in mask. This transformation only applies to valuators
@@ -1229,7 +1250,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
         ox = dev->last.valuators[0];
         oy = dev->last.valuators[1];
 
-        pixman_f_transform_invert(&invert, &dev->transform);
+        pixman_f_transform_invert(&invert, &dev->scale_and_transform);
         transform(&invert, &ox, &oy);
 
         x = ox;
@@ -1242,7 +1263,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
     if (valuator_mask_isset(mask, 1))
         oy = y = valuator_mask_get_double(mask, 1);
 
-    transform(&dev->transform, &x, &y);
+    transform(&dev->scale_and_transform, &x, &y);
 
     if (valuator_mask_isset(mask, 0) || ox != x)
         valuator_mask_set_double(mask, 0, x);
@@ -1403,6 +1424,8 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
             set_raw_valuators(raw, &mask, raw->valuators.data);
     }
     else {
+        transformRelative(pDev, &mask);
+
         if (flags & POINTER_ACCELERATE)
             accelPointer(pDev, &mask, ms);
         if ((flags & POINTER_NORAW) == 0)
diff --git a/include/inputstr.h b/include/inputstr.h
index 48a29be..de96fae 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -588,8 +588,12 @@ typedef struct _DeviceIntRec {
         XIPropertyHandlerPtr handlers;  /* NULL-terminated */
     } properties;
 
-    /* coordinate transformation matrix for absolute input devices */
-    struct pixman_f_transform transform;
+    /* coordinate transformation matrix for relative movement. Matrix with
+     * the translation component dropped */
+    struct pixman_f_transform relative_transform;
+    /* scale matrix for absolute devices, this is the combined matrix of
+       [1/scale] . [transform] . [scale]. See DeviceSetTransform */
+    struct pixman_f_transform scale_and_transform;
 
     /* XTest related master device id */
     int xtest_master_id;
commit b173eb2ae3349c557db1ff9e424fa540b8289bb2
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Feb 8 08:57:43 2013 -0800

    os: Round fraction in pnprintf %f format
    
    Truncating the fraction part leads to a test failure where -1203.30 is
    printed as -1203.29. Round this to the nearest value instead by adding
    0.5 before converting to an integer
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/utils.c b/os/utils.c
index 3ba6499..60e828e 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1999,7 +1999,7 @@ FormatDouble(double dbl, char *string)
     int slen = 0;
     uint64_t frac;
 
-    frac = (dbl > 0 ? dbl : -dbl) * 100.0;
+    frac = (dbl > 0 ? dbl : -dbl) * 100.0 + 0.5;
     frac %= 100;
 
     /* write decimal part to string */
commit 509b3c3dc82e7abce1900d5e1cddd90f23be5a87
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Wed Feb 6 14:07:22 2013 +0100

    dix: Set focus field on XI2 crossing events
    
    Set on DeviceEnterLeaveEvent() the xXIEnterEvent->focus field
    similarly to how the CoreEnterLeaveEvent() function above does
    for core events.
    
    This fixes bug https://bugzilla.gnome.org/show_bug.cgi?id=677329
    reported to GTK+, where focus handling on window managers with
    sloppy focus or no window manager present was broken due to this
    field being always set to FALSE.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    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/events.c b/dix/events.c
index f72cdc7..2682ecd 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4569,6 +4569,7 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
 {
     GrabPtr grab = mouse->deviceGrab.grab;
     xXIEnterEvent *event;
+    WindowPtr focus;
     int filter;
     int btlen, len, i;
     DeviceIntPtr kbd;
@@ -4610,6 +4611,11 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
         event->group.locked_group = kbd->key->xkbInfo->state.locked_group;
     }
 
+    focus = (kbd) ? kbd->focus->win : None;
+    if ((focus != NoneWin) &&
+        ((pWin == focus) || (focus == PointerRootWin) || IsParent(focus, pWin)))
+        event->focus = TRUE;
+
     FixUpEventFromWindow(mouse->spriteInfo->sprite, (xEvent *) event, pWin,
                          None, FALSE);
 
commit 3e4be4033aed78b2bb3a18d51f0963989efd1af3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 25 11:47:32 2013 +1000

    dix: when shutting down slave devices, shut down xtest devices last
    
    XTest devices are the first ones in the list, being initialised together
    with the master devices. If we disable the devices in-order and a device has
    a button down when being disabled, the XTest device is checked for a
    required button release (xkbAccessX.c's ProcessPointerEvent). This fails if
    the device is already NULL.
    
    Instead of putting the check there, disable the devices in the reverse order
    they are initialised. Disable physical slaves first, then xtest devices,
    then the master devices.
    
    Testcase: shut down server with a button still held down on a physical
    device
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/devices.c b/dix/devices.c
index 3c7d480..172fc04 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -516,6 +516,12 @@ DisableAllDevices(void)
 {
     DeviceIntPtr dev, tmp;
 
+    /* Disable slave devices first, excluding XTest devices */
+    nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
+        if (!IsXTestDevice(dev, NULL) && !IsMaster(dev))
+            DisableDevice(dev, FALSE);
+    }
+    /* Disable XTest devices */
     nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
         if (!IsMaster(dev))
             DisableDevice(dev, FALSE);
commit 0d5bb882600ee7734af034fbea935a79d21d1e70
Merge: b33fcb1 61a99af
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 8 14:10:52 2013 +1000

    Merge branch 'ptraccel-fixes' into for-keith

commit 61a99aff9d33728a0b67920254d2d4d79f80cf39
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 11 14:22:07 2013 +1000

    dix: pre-scale relative events from abs devices to desktop ratio (#31636)
    
    Absolute devices may send relative events depending on the mode (synaptics
    by default, wacom per option). The relative events are added to the previous
    position, converted into device coordinates and then scaled into desktop
    coordinates for pointer movement.
    
    Because the device range must be mapped into the desktop coordinate range,
    this results in uneven scaling depending dimensions, e.g. on a setup with
    width == 2 * height, a relative movement of 10/10 in device coordinates
    results in a cursor movement of 20/10 (+ acceleration)
    
    Other commonly user-visible results:
    * the touchpad changing acceleration once an external monitor as added.
    * drawing a circle on a wacom tablet in relative mode gives an ellipsis in
      the same ratio as the desktop dimensions.
    
    Solution: pre-scale the incoming relative x/y coordinates by width/height
    ratio of the total desktop size. Then add them to the previous
    coordinates and scale back with the previous mapping, which will undo the
    pre-scaling and give us the right movement.
    
    X.Org Bug 31636 <http://bugs.freedesktop.org/show_bug.cgi?id=31636>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index a1e1938..5100607 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -776,11 +776,33 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
  * @param[in,out] mask Valuator data for this event, modified in-place.
  */
 static void
-moveRelative(DeviceIntPtr dev, ValuatorMask *mask)
+moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
 {
     int i;
     Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
 
+    /* for abs devices in relative mode, we've just scaled wrong, since we
+       mapped the device's shape into the screen shape. Undo this. */
+    if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator &&
+        dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) {
+
+        double ratio = 1.0 * screenInfo.width/screenInfo.height;
+
+        if (ratio > 1.0) {
+            double y;
+            if (valuator_mask_fetch_double(mask, 1, &y)) {
+                y *= ratio;
+                valuator_mask_set_double(mask, 1, y);
+            }
+        } else {
+            double x;
+            if (valuator_mask_fetch_double(mask, 0, &x)) {
+                x *= ratio;
+                valuator_mask_set_double(mask, 0, x);
+            }
+        }
+    }
+
     /* calc other axes, clip, drop back into valuators */
     for (i = 0; i < valuator_mask_size(mask); i++) {
         double val = dev->last.valuators[i];
@@ -1380,7 +1402,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
         if ((flags & POINTER_NORAW) == 0)
             set_raw_valuators(raw, &mask, raw->valuators.data);
 
-        moveRelative(pDev, &mask);
+        moveRelative(pDev, flags, &mask);
     }
 
     /* valuators are in device coordinate system in absolute coordinates */
commit a6ba2b79ae8ad0fdee3f208d5e030b012df48785
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 11 08:53:24 2013 +1000

    dix: unify prefix for ptraccel debugging in DebugAccelF macro
    
    If we're already using our own custom macro, might as well use it properly.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index b6d2dae..d6fef9c 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -77,7 +77,7 @@ DeletePredictableAccelerationProperties(DeviceIntPtr,
 /*#define PTRACCEL_DEBUGGING*/
 
 #ifdef PTRACCEL_DEBUGGING
-#define DebugAccelF ErrorFSigSafe
+#define DebugAccelF(...) ErrorFSigSafe("dix/ptraccel: " __VA_ARGS__)
 #else
 #define DebugAccelF(...)        /* */
 #endif
@@ -421,7 +421,7 @@ void
 InitTrackers(DeviceVelocityPtr vel, int ntracker)
 {
     if (ntracker < 1) {
-        ErrorF("(dix ptracc) invalid number of trackers\n");
+        ErrorF("invalid number of trackers\n");
         return;
     }
     free(vel->tracker);
@@ -566,7 +566,7 @@ FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t)
     vel->tracker[n].dy = 0.0;
     vel->tracker[n].time = cur_t;
     vel->tracker[n].dir = GetDirection(dx, dy);
-    DebugAccelF("(dix prtacc) motion [dx: %f dy: %f dir:%d diff: %d]\n",
+    DebugAccelF("motion [dx: %f dy: %f dir:%d diff: %d]\n",
                 dx, dy, vel->tracker[n].dir,
                 cur_t - vel->tracker[vel->cur_tracker].time);
     vel->cur_tracker = n;
@@ -614,7 +614,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
 
         /* bail out if data is too old and protect from overrun */
         if (age_ms >= vel->reset_time || age_ms < 0) {
-            DebugAccelF("(dix prtacc) query: tracker too old (reset after %d, age is %d)\n",
+            DebugAccelF("query: tracker too old (reset after %d, age is %d)\n",
                         vel->reset_time, age_ms);
             break;
         }
@@ -627,7 +627,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
          */
         dir &= tracker->dir;
         if (dir == 0) {         /* we've changed octant of movement (e.g. NE → NW) */
-            DebugAccelF("(dix prtacc) query: no longer linear\n");
+            DebugAccelF("query: no longer linear\n");
             /* instead of breaking it we might also inspect the partition after,
              * but actual improvement with this is probably rare. */
             break;
@@ -648,7 +648,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
                 velocity_diff / (initial_velocity + tracker_velocity) >=
                 vel->max_rel_diff) {
                 /* we're not in range, quit - it won't get better. */
-                DebugAccelF("(dix prtacc) query: tracker too different:"
+                DebugAccelF("query: tracker too different:"
                             " old %2.2f initial %2.2f diff: %2.2f\n",
                             tracker_velocity, initial_velocity, velocity_diff);
                 break;
@@ -661,14 +661,14 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
         }
     }
     if (offset == vel->num_tracker) {
-        DebugAccelF("(dix prtacc) query: last tracker in effect\n");
+        DebugAccelF("query: last tracker in effect\n");
         used_offset = vel->num_tracker - 1;
     }
     if (used_offset >= 0) {
 #ifdef PTRACCEL_DEBUGGING
         MotionTracker *tracker = TRACKER(vel, used_offset);
 
-        DebugAccelF("(dix prtacc) result: offset %i [dx: %f dy: %f diff: %i]\n",
+        DebugAccelF("result: offset %i [dx: %f dy: %f diff: %i]\n",
                     used_offset, tracker->dx, tracker->dy,
                     cur_t - tracker->time);
 #endif
@@ -694,6 +694,8 @@ ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time)
 
     velocity = QueryTrackers(vel, time);
 
+    DebugAccelF("velocity is %f\n", velocity);
+
     vel->velocity = velocity;
     return velocity == 0;
 }
@@ -769,7 +771,7 @@ ComputeAcceleration(DeviceIntPtr dev,
     double result;
 
     if (vel->velocity <= 0) {
-        DebugAccelF("(dix ptracc) profile skipped\n");
+        DebugAccelF("profile skipped\n");
         /*
          * If we have no idea about device velocity, don't pretend it.
          */
@@ -793,13 +795,13 @@ ComputeAcceleration(DeviceIntPtr dev,
                                             threshold,
                                             acc);
         result /= 6.0f;
-        DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
+        DebugAccelF("profile average [%.2f ... %.2f] is %.3f\n",
                     vel->velocity, vel->last_velocity, result);
     }
     else {
         result = BasicComputeAcceleration(dev, vel,
                                           vel->velocity, threshold, acc);
-        DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
+        DebugAccelF("profile sample [%.2f] is %.3f\n",
                     vel->velocity, result);
     }
 
@@ -1111,6 +1113,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
                                        (double) dev->ptrfeed->ctrl.num /
                                        (double) dev->ptrfeed->ctrl.den);
 
+            DebugAccelF("mult is %f\n", mult);
             if (mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
                 if (mult > 1.0f && soften)
                     ApplySoftening(velocitydata, &dx, &dy);
commit 0d7d79406011169ad95e23c6e937f6d15a5ec3cc
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 11 08:52:08 2013 +1000

    dix: use BUG_RETURN_VAL for an error message
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 6994bd5..b6d2dae 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -1051,11 +1051,8 @@ SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel,
 DeviceVelocityPtr
 GetDevicePredictableAccelData(DeviceIntPtr dev)
 {
-    /*sanity check */
-    if (!dev) {
-        ErrorF("[dix] accel: DeviceIntPtr was NULL");
-        return NULL;
-    }
+    BUG_RETURN_VAL(!dev, NULL);
+
     if (dev->valuator &&
         dev->valuator->accelScheme.AccelSchemeProc ==
         acceleratePointerPredictable &&
commit a0c38ea6cbad61edcfefff0e5dd6330edb706f13
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 11 08:49:15 2013 +1000

    dix: add some more info to a ptraccel debug msg
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index b95f194..6994bd5 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -614,7 +614,8 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
 
         /* bail out if data is too old and protect from overrun */
         if (age_ms >= vel->reset_time || age_ms < 0) {
-            DebugAccelF("(dix prtacc) query: tracker too old\n");
+            DebugAccelF("(dix prtacc) query: tracker too old (reset after %d, age is %d)\n",
+                        vel->reset_time, age_ms);
             break;
         }
 
commit 95125a7c0cbbbae40216a0497acdd863ddc645ed
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 10 13:19:27 2013 +1000

    dix: fix ptraccel debugging printfs
    
    This is mostly sigsafe code, so use sigsave printf. And update some fields
    to double that used to be int.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index c7994b0..b95f194 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -77,7 +77,7 @@ DeletePredictableAccelerationProperties(DeviceIntPtr,
 /*#define PTRACCEL_DEBUGGING*/
 
 #ifdef PTRACCEL_DEBUGGING
-#define DebugAccelF ErrorF
+#define DebugAccelF ErrorFSigSafe
 #else
 #define DebugAccelF(...)        /* */
 #endif
@@ -566,7 +566,7 @@ FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t)
     vel->tracker[n].dy = 0.0;
     vel->tracker[n].time = cur_t;
     vel->tracker[n].dir = GetDirection(dx, dy);
-    DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n",
+    DebugAccelF("(dix prtacc) motion [dx: %f dy: %f dir:%d diff: %d]\n",
                 dx, dy, vel->tracker[n].dir,
                 cur_t - vel->tracker[vel->cur_tracker].time);
     vel->cur_tracker = n;
@@ -667,7 +667,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
 #ifdef PTRACCEL_DEBUGGING
         MotionTracker *tracker = TRACKER(vel, used_offset);
 
-        DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n",
+        DebugAccelF("(dix prtacc) result: offset %i [dx: %f dy: %f diff: %i]\n",
                     used_offset, tracker->dx, tracker->dy,
                     cur_t - tracker->time);
 #endif
@@ -799,7 +799,7 @@ ComputeAcceleration(DeviceIntPtr dev,
         result = BasicComputeAcceleration(dev, vel,
                                           vel->velocity, threshold, acc);
         DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
-                    vel->velocity, res);
+                    vel->velocity, result);
     }
 
     return result;
@@ -1122,8 +1122,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
                     valuator_mask_set_double(val, 0, mult * dx);
                 if (dy != 0.0)
                     valuator_mask_set_double(val, 1, mult * dy);
-                DebugAccelF("pos (%i | %i) delta x:%.3f y:%.3f\n", mult * dx,
-                            mult * dy);
+                DebugAccelF("delta x:%.3f y:%.3f\n", mult * dx, mult * dy);
             }
         }
     }
commit b33fcb149710a28fd8767b2307a97bf367de695e
Author: Andreas Wettstein <wettstein509 at solnet.ch>
Date:   Tue Jan 29 21:49:20 2013 +0100

    xkb: Fix repeat behaviour of redirect and message actions
    
    The redirect and the message action filter functions implicitly assumed that
    when they receive an event for the same keycode they were activated for, that
    this is the a release of the key that activated the filter.  This is not true
    if the key autorepeats.  Due to the incorrect assumption, the effective key
    repeat rate was effectively halved.
    
    Signed-off-by: Andreas Wettstein <wettstein509 at solnet.ch>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 1adb389..416de92 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -747,6 +747,15 @@ _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
     XkbMessageAction *pMsg;
     DeviceIntPtr kbd;
 
+    if ((filter->keycode != 0) && (filter->keycode != keycode))
+	return 1;
+
+    /* This can happen if the key repeats, and the state (modifiers or group)
+       changes meanwhile. */
+    if ((filter->keycode == keycode) && pAction &&
+	(pAction->type != XkbSA_ActionMessage))
+	return 1;
+
     kbd = xkbi->device;
     if (filter->keycode == 0) { /* initial press */
         pMsg = &pAction->msg;
@@ -774,20 +783,27 @@ _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
     }
     else if (filter->keycode == keycode) {
         pMsg = &filter->upAction.msg;
-        if (pMsg->flags & XkbSA_MessageOnRelease) {
-            xkbActionMessage msg;
-
-            msg.keycode = keycode;
-            msg.press = 0;
-            msg.keyEventFollows =
-                ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
-            memcpy((char *) msg.message, (char *) pMsg->message,
-                   XkbActionMessageLength);
-            XkbSendActionMessage(kbd, &msg);
+	if (pAction == NULL) {
+	    if (pMsg->flags & XkbSA_MessageOnRelease) {
+		xkbActionMessage msg;
+
+		msg.keycode = keycode;
+		msg.press = 0;
+		msg.keyEventFollows =
+		    ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
+		memcpy((char *) msg.message, (char *) pMsg->message,
+		       XkbActionMessageLength);
+		XkbSendActionMessage(kbd, &msg);
+	    }
+	    filter->keycode = 0;
+	    filter->active = 0;
+	    return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
+	} else if (memcmp(pMsg, pAction, 8) == 0) {
+	    /* Repeat: If we send the same message, avoid multiple messages
+	       on release from piling up. */
+	    filter->keycode = 0;
+	    filter->active = 0;
         }
-        filter->keycode = 0;
-        filter->active = 0;
-        return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
     }
     return 1;
 }
@@ -803,15 +819,21 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
     ProcessInputProc backupproc;
 
+    if ((filter->keycode != 0) && (filter->keycode != keycode))
+        return 1;
+
+    /* This can happen if the key repeats, and the state (modifiers or group)
+       changes meanwhile. */
+    if ((filter->keycode == keycode) && pAction &&
+	(pAction->type != XkbSA_RedirectKey))
+	return 1;
+
     /* never actually used uninitialised, but gcc isn't smart enough
      * to work that out. */
     memset(&old, 0, sizeof(old));
     memset(&old_prev, 0, sizeof(old_prev));
     memset(&ev, 0, sizeof(ev));
 
-    if ((filter->keycode != 0) && (filter->keycode != keycode))
-        return 1;
-
     GetSpritePosition(xkbi->device, &x, &y);
     ev.header = ET_Internal;
     ev.length = sizeof(DeviceEvent);
@@ -870,49 +892,60 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
             xkbi->state = old;
             xkbi->prev_state = old_prev;
         }
+	return 0;
     }
-    else if (filter->keycode == keycode) {
-
-        ev.type = ET_KeyRelease;
-        ev.detail.key = filter->upAction.redirect.new_key;
-
-        mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
-        mods = XkbSARedirectVMods(&filter->upAction.redirect);
-        if (mask)
-            XkbVirtualModsToReal(xkbi->desc, mask, &mask);
-        if (mods)
-            XkbVirtualModsToReal(xkbi->desc, mods, &mods);
-        mask |= filter->upAction.redirect.mods_mask;
-        mods |= filter->upAction.redirect.mods;
-
-        if (mask || mods) {
-            old = xkbi->state;
-            old_prev = xkbi->prev_state;
-            xkbi->state.base_mods &= ~mask;
-            xkbi->state.base_mods |= (mods & mask);
-            xkbi->state.latched_mods &= ~mask;
-            xkbi->state.latched_mods |= (mods & mask);
-            xkbi->state.locked_mods &= ~mask;
-            xkbi->state.locked_mods |= (mods & mask);
-            XkbComputeDerivedState(xkbi);
-            xkbi->prev_state = xkbi->state;
-        }
-
-        UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
-        xkbi->device->public.processInputProc((InternalEvent *) &ev,
-                                              xkbi->device);
-        COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
-                                     xkbUnwrapProc);
-
-        if (mask || mods) {
-            xkbi->state = old;
-            xkbi->prev_state = old_prev;
-        }
-
-        filter->keycode = 0;
-        filter->active = 0;
+    else {
+	/* If it is a key release, or we redirect to another key, release the
+	   previous new_key.  Otherwise, repeat. */
+	ev.detail.key = filter->upAction.redirect.new_key;
+	if (pAction == NULL ||  ev.detail.key != pAction->redirect.new_key) {
+	    ev.type = ET_KeyRelease;
+	    filter->active = 0;
+	}
+	else {
+	    ev.type = ET_KeyPress;
+	    ev.key_repeat = TRUE;
+	}
+
+	mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
+	mods = XkbSARedirectVMods(&filter->upAction.redirect);
+	if (mask)
+	    XkbVirtualModsToReal(xkbi->desc, mask, &mask);
+	if (mods)
+	    XkbVirtualModsToReal(xkbi->desc, mods, &mods);
+	mask |= filter->upAction.redirect.mods_mask;
+	mods |= filter->upAction.redirect.mods;
+
+	if (mask || mods) {
+	    old = xkbi->state;
+	    old_prev = xkbi->prev_state;
+	    xkbi->state.base_mods &= ~mask;
+	    xkbi->state.base_mods |= (mods & mask);
+	    xkbi->state.latched_mods &= ~mask;
+	    xkbi->state.latched_mods |= (mods & mask);
+	    xkbi->state.locked_mods &= ~mask;
+	    xkbi->state.locked_mods |= (mods & mask);
+	    XkbComputeDerivedState(xkbi);
+	    xkbi->prev_state = xkbi->state;
+	}
+
+	UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
+	xkbi->device->public.processInputProc((InternalEvent *) &ev,
+					      xkbi->device);
+	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
+				     xkbUnwrapProc);
+
+	if (mask || mods) {
+	    xkbi->state = old;
+	    xkbi->prev_state = old_prev;
+	}
+
+	/* We return 1 in case we have sent a release event because the new_key
+	   has changed.  Then, subsequently, we will call this function again
+	   with the same pAction, which will create the press for the new
+	   new_key. */
+	return (pAction && ev.detail.key != pAction->redirect.new_key);
     }
-    return 0;
 }
 
 static int
commit 8571c648a79444bcee9a0fe6e395129116372f49
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat Jan 26 15:53:08 2013 +1000

    Xext: if a root window is given in XTestFakeInput, move to that
    
    For absolute events, if the client specifies a screen number offset the
    coordinates by that. And add a new flag so we know when _not_ to add the
    screen offset in GPE.
    
    Without this offset and the flag, GPE would simply add the offset of the
    current screen if POINTER_SCREEN is set.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 209bbdd..0a854f3 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -305,7 +305,7 @@ ProcXTestFakeInput(ClientPtr client)
             numValuators = 2;
             firstValuator = 0;
             if (ev->u.u.detail == xFalse)
-                flags = POINTER_ABSOLUTE | POINTER_SCREEN;
+                flags = POINTER_ABSOLUTE | POINTER_DESKTOP;
             break;
         default:
             client->errorValue = ev->u.u.type;
@@ -376,6 +376,14 @@ ProcXTestFakeInput(ClientPtr client)
                 client->errorValue = ev->u.keyButtonPointer.root;
                 return BadValue;
             }
+
+            /* Add the root window's offset to the valuators */
+            if ((flags & POINTER_ABSOLUTE) && firstValuator <= 1 && numValuators > 0) {
+                if (firstValuator == 0)
+                    valuators[0] += root->drawable.pScreen->x;
+                if (firstValuator < 2 && firstValuator + numValuators > 1)
+                    valuators[1 - firstValuator] += root->drawable.pScreen->y;
+            }
         }
         if (ev->u.u.detail != xTrue && ev->u.u.detail != xFalse) {
             client->errorValue = ev->u.u.detail;
diff --git a/dix/getevents.c b/dix/getevents.c
index 8fe54d7..02f5366 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -820,24 +820,30 @@ accelPointer(DeviceIntPtr dev, ValuatorMask *valuators, CARD32 ms)
  * device's coordinate range.
  *
  * @param dev The device to scale for.
- * @param[in, out] mask The mask in desktop coordinates, modified in place
+ * @param[in, out] mask The mask in desktop/screen coordinates, modified in place
  * to contain device coordinate range.
+ * @param flags If POINTER_SCREEN is set, mask is in per-screen coordinates.
+ *              Otherwise, mask is in desktop coords.
  */
 static void
-scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask)
+scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask, int flags)
 {
     double scaled;
     ScreenPtr scr = miPointerGetScreen(dev);
 
     if (valuator_mask_isset(mask, 0)) {
-        scaled = valuator_mask_get_double(mask, 0) + scr->x;
+        scaled = valuator_mask_get_double(mask, 0);
+        if (flags & POINTER_SCREEN)
+            scaled += scr->x;
         scaled = rescaleValuatorAxis(scaled,
                                      NULL, dev->valuator->axes + 0,
                                      screenInfo.x, screenInfo.width);
         valuator_mask_set_double(mask, 0, scaled);
     }
     if (valuator_mask_isset(mask, 1)) {
-        scaled = valuator_mask_get_double(mask, 1) + scr->y;
+        scaled = valuator_mask_get_double(mask, 1);
+        if (flags & POINTER_SCREEN)
+            scaled += scr->y;
         scaled = rescaleValuatorAxis(scaled,
                                      NULL, dev->valuator->axes + 1,
                                      screenInfo.y, screenInfo.height);
@@ -1363,10 +1369,10 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
     /* valuators are in driver-native format (rel or abs) */
 
     if (flags & POINTER_ABSOLUTE) {
-        if (flags & POINTER_SCREEN) {    /* valuators are in screen coords */
+        if (flags & (POINTER_SCREEN | POINTER_DESKTOP)) {    /* valuators are in screen/desktop coords */
             sx = valuator_mask_get(&mask, 0);
             sy = valuator_mask_get(&mask, 1);
-            scale_from_screen(pDev, &mask);
+            scale_from_screen(pDev, &mask, flags);
         }
 
         transformAbsolute(pDev, &mask);
diff --git a/include/input.h b/include/input.h
index f53ed99..7b5ab94 100644
--- a/include/input.h
+++ b/include/input.h
@@ -69,6 +69,7 @@ SOFTWARE.
 #define POINTER_SCREEN		(1 << 4)        /* Data in screen coordinates */
 #define POINTER_NORAW		(1 << 5)        /* Don't generate RawEvents */
 #define POINTER_EMULATED	(1 << 6)        /* Event was emulated from another event */
+#define POINTER_DESKTOP		(1 << 7)        /* Data in desktop coordinates */
 
 /* GetTouchEvent flags */
 #define TOUCH_ACCEPT            (1 << 0)
commit 9fd6cb89539fde44a41ae5183c89ef9c8831c8dd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 29 15:13:44 2013 +1000

    Xext: pass the current screen to miProcessDeviceEvent() from xtest calls
    
    Not passing in a screen means we skip the screen crossing updates, so a
    xtest event that changes between ScreenRecs won't do so until the next
    physical event comes in or never, whichever comes earlier.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 6519b9c..209bbdd 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -418,7 +418,7 @@ ProcXTestFakeInput(ClientPtr client)
     }
 
     for (i = 0; i < nevents; i++)
-        mieqProcessDeviceEvent(dev, &xtest_evlist[i], NULL);
+        mieqProcessDeviceEvent(dev, &xtest_evlist[i], miPointerGetScreen(inputInfo.pointer));
 
     if (need_ptr_update)
         miPointerUpdateSprite(dev);
commit a191dbfe850ed9c6440346f59cb0078e0e844edc
Author: Sybren van Elderen <sowmestno at msn.com>
Date:   Tue Jan 29 15:43:57 2013 +1000

    dix: when scaling from desktop coord, take the total desktop size (#51904)
    
    Scaled is already in desktop coordinates, take the total width into account,
    not just the current screen's width.
    
    Fixes Xdmx pointer position calculation.
    
    X.Org Bug 51904 <http://bugs.freedesktop.org/show_bug.cgi?id=51904>
    
    Signed-off-by: Sybren van Elderen <sowmestno at msn.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index a1e1938..8fe54d7 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -833,14 +833,14 @@ scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask)
         scaled = valuator_mask_get_double(mask, 0) + scr->x;
         scaled = rescaleValuatorAxis(scaled,
                                      NULL, dev->valuator->axes + 0,
-                                     0, scr->width);
+                                     screenInfo.x, screenInfo.width);
         valuator_mask_set_double(mask, 0, scaled);
     }
     if (valuator_mask_isset(mask, 1)) {
         scaled = valuator_mask_get_double(mask, 1) + scr->y;
         scaled = rescaleValuatorAxis(scaled,
                                      NULL, dev->valuator->axes + 1,
-                                     0, scr->height);
+                                     screenInfo.y, screenInfo.height);
         valuator_mask_set_double(mask, 1, scaled);
     }
 }
commit 1cb19803f0f8dfd1e0fb9d189afe2262e24a0be5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 29 12:51:15 2013 +1000

    include: fix typo in list description
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/list.h b/include/list.h
index 2d48a86..067c679 100644
--- a/include/list.h
+++ b/include/list.h
@@ -358,7 +358,7 @@ xorg_list_is_empty(struct xorg_list *head)
  * struct foo *element = list;
  * while ((element = nt_list_next(element, next)) { }
  *
- * This macro is not safe for node deletion. Use xorg_list_for_each_entry_safe
+ * This macro is not safe for node deletion. Use nt_list_for_each_entry_safe
  * instead.
  *
  * @param list The list or current element.
commit 3d35dfcf5bad1b0a028fbecd65cb6cf6ebf12503
Author: Ted Felix <ted at tedfelix.com>
Date:   Tue Jan 29 16:36:48 2013 +1000

    xfree86: bail on misformed acpi strings (#73227)
    
    If acpid sends a string in a format that we can't parse, bail out instead of
    potentially dereferencing a NULL-pointer.
    
    X.Org Bug 73227 <http://bugs.freedesktop.org/show_bug.cgi?id=73227>
    
    Signed-off-by: Ted Felix <ted at tedfelix.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/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c
index d98efa2..dcaa19e 100644
--- a/hw/xfree86/os-support/linux/lnx_acpi.c
+++ b/hw/xfree86/os-support/linux/lnx_acpi.c
@@ -82,18 +82,21 @@ lnxACPIGetEventFromOs(int fd, pmEvent * events, int num)
 
         video = strtok(ev, " ");
 
-        GFX = strtok(NULL, " ");
+        if (!(GFX = strtok(NULL, " ")))
+            return 0;
 #if 0
         ErrorF("GFX: %s\n", GFX);
 #endif
 
-        notify = strtok(NULL, " ");
+        if (!(notify = strtok(NULL, " ")))
+            return 0;
         notify_l = strtoul(notify, NULL, 16);
 #if 0
         ErrorF("notify: 0x%lx\n", notify_l);
 #endif
 
-        data = strtok(NULL, " ");
+        if (!(data = strtok(NULL, " ")))
+            return 0;
         data_l = strtoul(data, NULL, 16);
 #if 0
         ErrorF("data: 0x%lx\n", data_l);
commit fdc451588816c4bc798d54e56316530e9066be80
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 29 11:01:29 2013 +1000

    Xi: limit valuator copy to valuator array size (#59939)
    
    mask[(MAX_VALUATORS + 7)/8] is larger than data[MAX_VALUATORS], so static
    code checkers think we may be running OOB on the data array. Mask is
    initialized to 0, so this should not happen, but change it anyway to shut up
    code analyzer noise.
    
    X.Org Bug 59939 <http://bugs.freedesktop.org/show_bug.cgi?id=59939>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 74f3610..609b126 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1263,7 +1263,7 @@ TouchCopyValuatorData(DeviceEvent *ev, TouchPointInfoPtr ti)
 {
     int i;
 
-    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+    for (i = 0; i < ARRAY_SIZE(ev->valuators.data); i++)
         if (BitIsOn(ev->valuators.mask, i))
             valuator_mask_set_double(ti->valuators, i, ev->valuators.data[i]);
 }
commit 48bc30c5413a1be0039fa77affcbbb4fe677479f
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Jan 29 10:24:32 2013 +1000

    Xext: avoid null-pointer dereference in XTestFakeInput (#59937)
    
    dv is still NULL at this point, so return firstValuator instead (which is
    the same value dv->firstValuator would be once initialized)
    
    X.Org Bug 59937 <http://bugs.freedesktop.org/show_bug.cgi?id=59937>
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.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/Xext/xtest.c b/Xext/xtest.c
index 2abdc7f..6519b9c 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -156,7 +156,6 @@ ProcXTestFakeInput(ClientPtr client)
     DeviceIntPtr dev = NULL;
     WindowPtr root;
     Bool extension = FALSE;
-    deviceValuator *dv = NULL;
     ValuatorMask mask;
     int valuators[MAX_VALUATORS] = { 0 };
     int numValuators = 0;
@@ -241,14 +240,14 @@ ProcXTestFakeInput(ClientPtr client)
         }
 
         if (nev > 1 && !dev->valuator) {
-            client->errorValue = dv->first_valuator;
+            client->errorValue = firstValuator;
             return BadValue;
         }
 
         /* check validity of valuator events */
         base = firstValuator;
         for (n = 1; n < nev; n++) {
-            dv = (deviceValuator *) (ev + n);
+            deviceValuator *dv = (deviceValuator *) (ev + n);
             if (dv->type != DeviceValuator) {
                 client->errorValue = dv->type;
                 return BadValue;
commit 1058fcf57fdcb94d92e7b5f4483b347853d5f8e6
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat Jan 26 14:13:33 2013 +1000

    dmx: don't include dmx-config.h from xdmxconfig (#37502)
    
    dmx-config.h is a server header which includes dix-config.h. That again
    defines a bunch of server-specifics, including setting the size of XID to
    32 bit.
    
    libX11 uses unsigned long (8 bits on x86_64). XGCValues thus ends up being
    16 bytes smaller in xdmxconfig than in the library, causing garbage to be
    sent to the server.
    
    X.Org Bug 37502 <http://bugs.freedesktop.org/show_bug.cgi?id=37502>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/config/xdmxconfig.c b/hw/dmx/config/xdmxconfig.c
index f308412..2121dd7 100644
--- a/hw/dmx/config/xdmxconfig.c
+++ b/hw/dmx/config/xdmxconfig.c
@@ -31,9 +31,6 @@
  *
  */
 
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
 
 #include <stdio.h>
 #include <stdlib.h>
commit 7fe5e6dfa5c1e71d8b7540b28c1d508687a2fbee
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Wed Jan 23 13:11:55 2013 -0500

    protocol-versions: Bump minor version of XI
    
    This was accidentally excluded when we added barriers.
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index cb8e213..10f5117 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -127,7 +127,7 @@
 
 /* X Input */
 #define SERVER_XI_MAJOR_VERSION			2
-#define SERVER_XI_MINOR_VERSION			2
+#define SERVER_XI_MINOR_VERSION			3
 
 /* XKB */
 #define SERVER_XKB_MAJOR_VERSION		1
commit 70b127c9f1c53bdb42f078265e67f76b464deae2
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Thu Jan 10 17:01:17 2013 -0800

    config/udev: fix "removing GPU device" format string mistake
    
     udev.c: In function 'device_removed':
     udev.c:270:9: warning: format '%d' expects argument of type 'int', but argument 3 has type 'const char *' [-Wformat]
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/config/udev.c b/config/udev.c
index 454838f..de89241 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -267,7 +267,7 @@ device_removed(struct udev_device *device)
 
         if (strncmp(sysname,"card", 4) != 0)
             return;
-        ErrorF("removing GPU device %s %d\n", syspath, path);
+        ErrorF("removing GPU device %s %s\n", syspath, path);
         if (!path)
             return;
 
commit 605dfc6804a05ff2bda5692fec26c37344fd95cb
Author: Dave Airlie <airlied at gmail.com>
Date:   Tue Jan 22 07:39:53 2013 +1000

    xserver: fix build regression since 91ab237358c6e33da854914d3de493a9cbea7637
    
    inputstr, double defines TouchListener typedef, maybe some gcc handles it,
    but not all.
    
    fixes tinderbox
    
    Reported-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Signed-off-by: Dave Airlie <airlied 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/include/inputstr.h b/include/inputstr.h
index fc21913..48a29be 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -327,8 +327,6 @@ typedef struct _TouchPointInfo {
     size_t history_size;        /* Size of history in elements */
 } TouchPointInfoRec;
 
-typedef struct _TouchListener TouchListener;
-
 typedef struct _DDXTouchPointInfo {
     uint32_t client_id;         /* touch ID as seen in client events */
     Bool active;                /* whether or not the touch is active */
commit 069d8ed3eb659c48dd2b0f8b7b8c11f092fdb362
Merge: 591c062 d6dcde7
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Jan 20 15:58:38 2013 -0800

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

commit 591c06277bb120ab9615633f2d28addbd3a2aa5f
Merge: 6703a7c fa6ab7d
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Jan 20 15:52:26 2013 -0800

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

commit cde7cbe9674e8a771f9a4e646c1772a46a8230fb
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 10 13:20:12 2013 +1000

    os: add support for %f to pnprintf
    
    This is the lazy man's %f support. Print the decimal part of the number,
    then append a decimal point, then print the first two digits of the
    fractional part. So %f in sigsafe printing is really %.2f.
    
    No boundary checks in place here.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/include/misc.h b/include/misc.h
index 3487176..0c67f11 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -250,6 +250,7 @@ extern char **xstrtokenize(const char *str, const char *separators);
 extern void FormatInt64(int64_t num, char *string);
 extern void FormatUInt64(uint64_t num, char *string);
 extern void FormatUInt64Hex(uint64_t num, char *string);
+extern void FormatDouble(double dbl, char *string);
 
 /**
  * Compare the two version numbers comprising of major.minor.
diff --git a/os/log.c b/os/log.c
index 2139064..7b5c9ee 100644
--- a/os/log.c
+++ b/os/log.c
@@ -351,7 +351,16 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
             for (i = 0; i < p_len && s_idx < size - 1; i++)
                 string[s_idx++] = number[i];
             break;
-
+        case 'f':
+            {
+                double d = va_arg(args, double);
+                FormatDouble(d, number);
+                p_len = strlen_sigsafe(number);
+
+                for (i = 0; i < p_len && s_idx < size - 1; i++)
+                    string[s_idx++] = number[i];
+            }
+            break;
         default:
             va_arg(args, char*);
             string[s_idx++] = '%';
diff --git a/os/utils.c b/os/utils.c
index e396ba4..3ba6499 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1990,6 +1990,38 @@ FormatUInt64(uint64_t num, char *string)
     string[len] = '\0';
 }
 
+/**
+ * Format a double number as %.2f.
+ */
+void
+FormatDouble(double dbl, char *string)
+{
+    int slen = 0;
+    uint64_t frac;
+
+    frac = (dbl > 0 ? dbl : -dbl) * 100.0;
+    frac %= 100;
+
+    /* write decimal part to string */
+    if (dbl < 0 && dbl > -1)
+        string[slen++] = '-';
+    FormatInt64((int64_t)dbl, &string[slen]);
+
+    while(string[slen] != '\0')
+        slen++;
+
+    /* append fractional part, but only if we have enough characters. We
+     * expect string to be 21 chars (incl trailing \0) */
+    if (slen <= 17) {
+        string[slen++] = '.';
+        if (frac < 10)
+            string[slen++] = '0';
+
+        FormatUInt64(frac, &string[slen]);
+    }
+}
+
+
 /* Format a number into a hexadecimal string in a signal safe manner. The string
  * should be at least 17 characters in order to handle all uint64_t values. */
 void
diff --git a/test/signal-logging.c b/test/signal-logging.c
index 127a28f..1ef17af 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -41,6 +41,11 @@ struct signed_number_format_test {
     char string[21];
 };
 
+struct float_number_format_test {
+    double number;
+    char string[21];
+};
+
 static Bool
 check_signed_number_format_test(long int number)
 {
@@ -59,6 +64,25 @@ check_signed_number_format_test(long int number)
 }
 
 static Bool
+check_float_format_test(double number)
+{
+    char string[21];
+    char expected[21];
+
+    /* we currently always print float as .2f */
+    sprintf(expected, "%.2f", number);
+
+    FormatDouble(number, string);
+    if(strncmp(string, expected, 21) != 0) {
+        fprintf(stderr, "Failed to convert %f to string (%s vs %s)\n",
+                number, expected, string);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static Bool
 check_number_format_test(long unsigned int number)
 {
     char string[21];
@@ -84,6 +108,11 @@ check_number_format_test(long unsigned int number)
     return TRUE;
 }
 
+/* FIXME: max range stuff */
+double float_tests[] = { 0, 5, 0.1, 0.01, 5.2342, 10.2301,
+                         -1, -2.00, -0.6023, -1203.30
+                        };
+
 static void
 number_formatting(void)
 {
@@ -116,6 +145,9 @@ number_formatting(void)
 
     for (i = 0; i < sizeof(unsigned_tests) / sizeof(signed_tests[0]); i++)
         assert(check_signed_number_format_test(signed_tests[i]));
+
+    for (i = 0; i < sizeof(float_tests) / sizeof(float_tests[0]); i++)
+        assert(check_float_format_test(float_tests[i]));
 }
 
 #pragma GCC diagnostic ignored "-Wformat-security"
@@ -232,6 +264,30 @@ static void logging_format(void)
         ptr <<= 1;
     } while(ptr);
 
+
+    for (i = 0; i < sizeof(float_tests)/sizeof(float_tests[0]); i++) {
+        double d = float_tests[i];
+        char expected[30];
+        sprintf(expected, "(EE) %.2f\n", d);
+        LogMessageVerbSigSafe(X_ERROR, -1, "%f\n", d);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        /* test for length modifiers, we just ignore them atm */
+        LogMessageVerbSigSafe(X_ERROR, -1, "%.3f\n", d);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        LogMessageVerbSigSafe(X_ERROR, -1, "%3f\n", d);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        LogMessageVerbSigSafe(X_ERROR, -1, "%.0f\n", d);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+    }
+
+
     LogClose(EXIT_NO_ERROR);
     unlink(log_file_path);
 
commit 20def57632583aef095ca18792c7fce16d2d9004
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 10 13:24:05 2013 +1000

    os: silently ignore length modifiers in pnprintf
    
    Until we have support for them, ignore any length modifiers so we don't need
    to update all callers.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/os/log.c b/os/log.c
index 4820e9a..2139064 100644
--- a/os/log.c
+++ b/os/log.c
@@ -298,7 +298,13 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
             continue;
         }
 
-        switch (f[++f_idx]) {
+        f_idx++;
+
+        /* silently swallow length modifiers */
+        while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.'))
+            f_idx++;
+
+        switch (f[f_idx]) {
         case 's':
             string_arg = va_arg(args, char*);
             p_len = strlen_sigsafe(string_arg);
commit f53b2012f39085d866f267dda1442a48ace3c5a5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 17 16:19:51 2013 +1000

    test/signal-logging: simplify tests using sprintf
    
    Ever looked at your own code and thought 'WTF was I thinking?'. yeah, that.
    
    Instead of passing in the expected string just use sprintf to print the
    number for us and compare. In the end we're just trying to emulate printf
    behaviour anyway.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/test/signal-logging.c b/test/signal-logging.c
index 810bd20..127a28f 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -42,14 +42,16 @@ struct signed_number_format_test {
 };
 
 static Bool
-check_signed_number_format_test(const struct signed_number_format_test *test)
+check_signed_number_format_test(long int number)
 {
     char string[21];
+    char expected[21];
 
-    FormatInt64(test->number, string);
-    if(strncmp(string, test->string, 21) != 0) {
-        fprintf(stderr, "Failed to convert %jd to decimal string (%s vs %s)\n",
-                test->number, test->string, string);
+    sprintf(expected, "%ld", number);
+    FormatInt64(number, string);
+    if(strncmp(string, expected, 21) != 0) {
+        fprintf(stderr, "Failed to convert %jd to decimal string (expected %s but got %s)\n",
+                number, expected, string);
         return FALSE;
     }
 
@@ -57,21 +59,25 @@ check_signed_number_format_test(const struct signed_number_format_test *test)
 }
 
 static Bool
-check_number_format_test(const struct number_format_test *test)
+check_number_format_test(long unsigned int number)
 {
     char string[21];
+    char expected[21];
 
-    FormatUInt64(test->number, string);
-    if(strncmp(string, test->string, 21) != 0) {
+    sprintf(expected, "%lu", number);
+
+    FormatUInt64(number, string);
+    if(strncmp(string, expected, 21) != 0) {
         fprintf(stderr, "Failed to convert %ju to decimal string (%s vs %s)\n",
-                test->number, test->string, string);
+                number, expected, string);
         return FALSE;
     }
-    FormatUInt64Hex(test->number, string);
-    if(strncmp(string, test->hex_string, 17) != 0) {
-        fprintf(stderr,
-                "Failed to convert %ju to hexadecimal string (%s vs %s)\n",
-                test->number, test->hex_string, string);
+
+    sprintf(expected, "%lx", number);
+    FormatUInt64Hex(number, string);
+    if(strncmp(string, expected, 17) != 0) {
+        fprintf(stderr, "Failed to convert %ju to hexadecimal string (%s vs %s)\n",
+                number, expected, string);
         return FALSE;
     }
 
@@ -82,100 +88,34 @@ static void
 number_formatting(void)
 {
     int i;
-    struct number_format_test unsigned_tests[] = {
-        { /* Zero */
-            0,
-            "0",
-            "0",
-        },
-        { /* Single digit number */
-            5,
-            "5",
-            "5",
-        },
-        { /* Two digit decimal number */
-            12,
-            "12",
-            "c",
-        },
-        { /* Two digit hex number */
-            37,
-            "37",
-            "25",
-        },
-        { /* Large < 32 bit number */
-            0xC90B2,
-            "823474",
-            "c90b2",
-        },
-        { /* Large > 32 bit number */
-            0x15D027BF211B37A,
-            "98237498237498234",
-            "15d027bf211b37a",
-        },
-        { /* Maximum 64-bit number */
-            0xFFFFFFFFFFFFFFFF,
-            "18446744073709551615",
-            "ffffffffffffffff",
-        },
+    long unsigned int unsigned_tests[] = { 0,/* Zero */
+                                           5, /* Single digit number */
+                                           12, /* Two digit decimal number */
+                                           37, /* Two digit hex number */
+                                           0xC90B2, /* Large < 32 bit number */
+                                           0x15D027BF211B37A, /* Large > 32 bit number */
+                                           0xFFFFFFFFFFFFFFFF, /* Maximum 64-bit number */
     };
 
-    struct signed_number_format_test signed_tests[] = {
-        { /* Zero */
-            0,
-            "0",
-        },
-        { /* Single digit number */
-            5,
-            "5",
-        },
-        { /* Two digit decimal number */
-            12,
-            "12",
-        },
-        { /* Two digit hex number */
-            37,
-            "37",
-        },
-        { /* Large < 32 bit number */
-            0xC90B2,
-            "823474",
-        },
-        { /* Large > 32 bit number */
-            0x15D027BF211B37A,
-            "98237498237498234",
-        },
-        { /* Maximum 64-bit signed number */
-            0x7FFFFFFFFFFFFFFF,
-            "9223372036854775807",
-        },
-        { /* Single digit number */
-            -1,
-            "-1",
-        },
-        { /* Two digit decimal number */
-            -12,
-            "-12",
-        },
-        { /* Large < 32 bit number */
-            -0xC90B2,
-            "-823474",
-        },
-        { /* Large > 32 bit number */
-            -0x15D027BF211B37A,
-            "-98237498237498234",
-        },
-        { /* Maximum 64-bit number */
-            -0x7FFFFFFFFFFFFFFF,
-            "-9223372036854775807",
-        },
-    };
+    long int signed_tests[] = { 0,/* Zero */
+                                5, /* Single digit number */
+                                12, /* Two digit decimal number */
+                                37, /* Two digit hex number */
+                                0xC90B2, /* Large < 32 bit number */
+                                0x15D027BF211B37A, /* Large > 32 bit number */
+                                0x7FFFFFFFFFFFFFFF, /* Maximum 64-bit signed number */
+                                -1, /* Single digit number */
+                                -12, /* Two digit decimal number */
+                                -0xC90B2, /* Large < 32 bit number */
+                                -0x15D027BF211B37A, /* Large > 32 bit number */
+                                -0x7FFFFFFFFFFFFFFF, /* Maximum 64-bit signed number */
+    } ;
 
     for (i = 0; i < sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); i++)
-        assert(check_number_format_test(unsigned_tests + i));
+        assert(check_number_format_test(unsigned_tests[i]));
 
     for (i = 0; i < sizeof(unsigned_tests) / sizeof(signed_tests[0]); i++)
-        assert(check_signed_number_format_test(signed_tests + i));
+        assert(check_signed_number_format_test(signed_tests[i]));
 }
 
 #pragma GCC diagnostic ignored "-Wformat-security"
commit d6dcde7a03bb38c17ffc4ec5f0ca1c161e54569f
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sat Feb 11 12:22:17 2012 +0000

    hw/xwin: Stop assuming WS_EX_APPWINDOW style in WM_SHOWWINDOW
    
    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/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index f7c6f2b..0e46ea7 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -870,41 +870,36 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         /* */
         if (!pWin->overrideRedirect) {
+            HWND zstyle = HWND_NOTOPMOST;
+
             /* Flag that this window needs to be made active when clicked */
             SetProp(hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1);
 
-            if (!(GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_APPWINDOW)) {
-                HWND zstyle = HWND_NOTOPMOST;
-
-                /* Set the window extended style flags */
-                SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
-
-                /* Set the transient style flags */
-                if (GetParent(hwnd))
-                    SetWindowLongPtr(hwnd, GWL_STYLE,
-                                     WS_POPUP | WS_OVERLAPPED | WS_SYSMENU |
-                                     WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
-                /* Set the window standard style flags */
-                else
-                    SetWindowLongPtr(hwnd, GWL_STYLE,
-                                     (WS_POPUP | WS_OVERLAPPEDWINDOW |
-                                      WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
-                                     & ~WS_CAPTION & ~WS_SIZEBOX);
-
-                winUpdateWindowPosition(hwnd, &zstyle);
-
-                {
-                    WinXWMHints hints;
-
-                    if (winMultiWindowGetWMHints(pWin, &hints)) {
-                        /*
-                           Give the window focus, unless it has an InputHint
-                           which is FALSE (this is used by e.g. glean to
-                           avoid every test window grabbing the focus)
-                         */
-                        if (!((hints.flags & InputHint) && (!hints.input))) {
-                            SetForegroundWindow(hwnd);
-                        }
+            /* Set the transient style flags */
+            if (GetParent(hwnd))
+                SetWindowLongPtr(hwnd, GWL_STYLE,
+                                 WS_POPUP | WS_OVERLAPPED | WS_SYSMENU |
+                                 WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+            /* Set the window standard style flags */
+            else
+                SetWindowLongPtr(hwnd, GWL_STYLE,
+                                 (WS_POPUP | WS_OVERLAPPEDWINDOW |
+                                  WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
+                                 & ~WS_CAPTION & ~WS_SIZEBOX);
+
+            winUpdateWindowPosition(hwnd, &zstyle);
+
+            {
+                WinXWMHints hints;
+
+                if (winMultiWindowGetWMHints(pWin, &hints)) {
+                    /*
+                       Give the window focus, unless it has an InputHint
+                       which is FALSE (this is used by e.g. glean to
+                       avoid every test window grabbing the focus)
+                     */
+                    if (!((hints.flags & InputHint) && (!hints.input))) {
+                        SetForegroundWindow(hwnd);
                     }
                 }
             }
commit 56e94403f8f9182e05428d895a983371c7737d2a
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Jan 9 20:15:01 2013 +0000

    hw/xwin: Use ITaskBarList interface to ensure show-on-taskbar state is updated correctly
    
    Use ITaskBarList interface to ensure that the taskbar notices if the window has
    changed it's style in a way which affects if the taskbar shows it or not.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 0c6b09a..4f6dec7 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -614,6 +614,19 @@ UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
     if (zstyle == HWND_NOTOPMOST)
         flags |= SWP_NOZORDER | SWP_NOOWNERZORDER;
     SetWindowPos(hWnd, NULL, 0, 0, 0, 0, flags);
+
+    /*
+       Use the WS_EX_TOOLWINDOW style to remove window from Alt-Tab window switcher
+
+       According to MSDN, this is supposed to remove the window from the taskbar as well,
+       if we SW_HIDE before changing the style followed by SW_SHOW afterwards.
+
+       But that doesn't seem to work reliably, and causes the window to flicker, so use
+       the iTaskbarList interface to tell the taskbar to show or hide this window.
+     */
+    winShowWindowOnTaskbar(hWnd,
+                           (GetWindowLongPtr(hWnd, GWL_EXSTYLE) &
+                            WS_EX_APPWINDOW) ? TRUE : FALSE);
 }
 
 #if 0
commit c94d1cb0a49106f44714f4511720a197cc549164
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Jan 10 14:35:56 2013 +0000

    hw/xwin: Ensure full styling is applied when the window is mapped
    
    Move styling update code from WM_WM_HINTS_EVENT to a function UpdateStyle(),
    which is also invoked from WM_WM_MAP3, so everything which needs to be done
    to style the window happens when it is mapped
    
    (Otherwise, the appearance of the window is sensitive to the timing of the
    notification of the windows appearance hint properties being set relative to
    window creation. e.g. see [1])
    
    [1] http://sourceware.org/ml/cygwin-xfree/2012-06/msg00004.html
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 1dc31fd..0c6b09a 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -590,6 +590,32 @@ UpdateIcon(WMInfoPtr pWMInfo, Window iWindow)
     winUpdateIcon(hWnd, pWMInfo->pDisplay, iWindow, hIconNew);
 }
 
+/*
+ * Updates the style of a HWND according to its X style properties
+ */
+
+static void
+UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
+{
+    HWND hWnd;
+    HWND zstyle = HWND_NOTOPMOST;
+    UINT flags;
+
+    hWnd = getHwnd(pWMInfo, iWindow);
+    if (!hWnd)
+        return;
+
+    /* Determine the Window style, which determines borders and clipping region... */
+    winApplyHints(pWMInfo->pDisplay, iWindow, hWnd, &zstyle);
+    winUpdateWindowPosition(hWnd, &zstyle);
+
+    /* Apply the updated window style, without changing it's show or activation state */
+    flags = SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
+    if (zstyle == HWND_NOTOPMOST)
+        flags |= SWP_NOZORDER | SWP_NOOWNERZORDER;
+    SetWindowPos(hWnd, NULL, 0, 0, 0, 0, flags);
+}
+
 #if 0
 /*
  * Fix up any differences between the X11 and Win32 window stacks
@@ -737,13 +763,8 @@ winMultiWindowWMProc(void *pArg)
                             (unsigned char *) &(pNode->msg.hwndWindow), 1);
             UpdateName(pWMInfo, pNode->msg.iWindow);
             UpdateIcon(pWMInfo, pNode->msg.iWindow);
-            {
-                HWND zstyle = HWND_NOTOPMOST;
+            UpdateStyle(pWMInfo, pNode->msg.iWindow);
 
-                winApplyHints(pWMInfo->pDisplay, pNode->msg.iWindow,
-                              pNode->msg.hwndWindow, &zstyle);
-                winUpdateWindowPosition(pNode->msg.hwndWindow, &zstyle);
-            }
 
             /* Reshape */
             {
@@ -815,8 +836,6 @@ winMultiWindowWMProc(void *pArg)
 
         case WM_WM_HINTS_EVENT:
             {
-            HWND zstyle = HWND_NOTOPMOST;
-            UINT flags;
             XWindowAttributes attr;
 
             /* Don't do anything if this is an override-redirect window */
@@ -824,18 +843,7 @@ winMultiWindowWMProc(void *pArg)
             if (attr.override_redirect)
               break;
 
-            pNode->msg.hwndWindow = getHwnd(pWMInfo, pNode->msg.iWindow);
-
-            /* Determine the Window style, which determines borders and clipping region... */
-            winApplyHints(pWMInfo->pDisplay, pNode->msg.iWindow,
-                          pNode->msg.hwndWindow, &zstyle);
-            winUpdateWindowPosition(pNode->msg.hwndWindow, &zstyle);
-
-            /* Apply the updated window style, without changing it's show or activation state */
-            flags = SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
-            if (zstyle == HWND_NOTOPMOST)
-                flags |= SWP_NOZORDER | SWP_NOOWNERZORDER;
-            SetWindowPos(pNode->msg.hwndWindow, NULL, 0, 0, 0, 0, flags);
+            UpdateStyle(pWMInfo, pNode->msg.iWindow);
             }
             break;
 
commit ef61f8cacc84080c9156675f9ce26a27e8a90ac1
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sat Mar 31 18:45:28 2012 +0100

    hw/xwin: Make sure that WM_WM_HINTS_EVENT does nothing for override-redirect windows
    
    Future work: It looks like this code could be rationalized quite a lot: It might
    make sense to pull the checking for override-redirect up out of UpdateIcon() and
    UpdateName() and consolidate WM_WM_MAP2 and WM_WM_MAP3
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 1200243..1dc31fd 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -817,6 +817,12 @@ winMultiWindowWMProc(void *pArg)
             {
             HWND zstyle = HWND_NOTOPMOST;
             UINT flags;
+            XWindowAttributes attr;
+
+            /* Don't do anything if this is an override-redirect window */
+            XGetWindowAttributes (pWMInfo->pDisplay, pNode->msg.iWindow, &attr);
+            if (attr.override_redirect)
+              break;
 
             pNode->msg.hwndWindow = getHwnd(pWMInfo, pNode->msg.iWindow);
 
commit 3628559e594fcbdfcc14b1e8fa60aa841f184e19
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sun Feb 5 11:25:39 2012 +0000

    hw/xwin: Add a new WM_WM_HINTS_EVENT event to update window style
    
    Add a new WM_WM_HINTS_EVENT event to update window style if any of the
    properties which affect window style change
    
    Check PropertyNotify events for any of the window properties which we consider
    to decide on the window style, and update the window style by sending a
    WM_WM_HINTS_EVENT message to the WM.
    
    This allows the styling of the window to change during it's lifetime.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index feefcf4..1200243 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -813,6 +813,26 @@ winMultiWindowWMProc(void *pArg)
             UpdateIcon(pWMInfo, pNode->msg.iWindow);
             break;
 
+        case WM_WM_HINTS_EVENT:
+            {
+            HWND zstyle = HWND_NOTOPMOST;
+            UINT flags;
+
+            pNode->msg.hwndWindow = getHwnd(pWMInfo, pNode->msg.iWindow);
+
+            /* Determine the Window style, which determines borders and clipping region... */
+            winApplyHints(pWMInfo->pDisplay, pNode->msg.iWindow,
+                          pNode->msg.hwndWindow, &zstyle);
+            winUpdateWindowPosition(pNode->msg.hwndWindow, &zstyle);
+
+            /* Apply the updated window style, without changing it's show or activation state */
+            flags = SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
+            if (zstyle == HWND_NOTOPMOST)
+                flags |= SWP_NOZORDER | SWP_NOOWNERZORDER;
+            SetWindowPos(pNode->msg.hwndWindow, NULL, 0, 0, 0, 0, flags);
+            }
+            break;
+
         case WM_WM_CHANGE_STATE:
             /* Minimize the window in Windows */
             winMinimizeWindow(pNode->msg.iWindow);
@@ -862,6 +882,7 @@ winMultiWindowXMsgProc(void *pArg)
     Atom atmWmHints;
     Atom atmWmChange;
     Atom atmNetWmIcon;
+    Atom atmWindowState, atmMotifWmHints, atmWindowType, atmNormalHints;
     int iReturn;
     XIconSize *xis;
 
@@ -988,6 +1009,10 @@ winMultiWindowXMsgProc(void *pArg)
     atmWmHints = XInternAtom(pProcArg->pDisplay, "WM_HINTS", False);
     atmWmChange = XInternAtom(pProcArg->pDisplay, "WM_CHANGE_STATE", False);
     atmNetWmIcon = XInternAtom(pProcArg->pDisplay, "_NET_WM_ICON", False);
+    atmWindowState = XInternAtom(pProcArg->pDisplay, "_NET_WM_STATE", False);
+    atmMotifWmHints = XInternAtom(pProcArg->pDisplay, "_MOTIF_WM_HINTS", False);
+    atmWindowType = XInternAtom(pProcArg->pDisplay, "_NET_WM_WINDOW_TYPE", False);
+    atmNormalHints = XInternAtom(pProcArg->pDisplay, "WM_NORMAL_HINTS", False);
 
     /*
        iiimxcf had a bug until 2009-04-27, assuming that the
@@ -1125,14 +1150,34 @@ winMultiWindowXMsgProc(void *pArg)
                 /* Other fields ignored */
                 winSendMessageToWM(pProcArg->pWMInfo, &msg);
             }
-            else if ((event.xproperty.atom == atmWmHints) ||
-                     (event.xproperty.atom == atmNetWmIcon)) {
-                memset(&msg, 0, sizeof(msg));
-                msg.msg = WM_WM_ICON_EVENT;
-                msg.iWindow = event.xproperty.window;
+            else {
+                /*
+                   Several properties are considered for WM hints, check if this property change affects any of them...
+                   (this list needs to be kept in sync with winApplyHints())
+                 */
+                if ((event.xproperty.atom == atmWmHints) ||
+                    (event.xproperty.atom == atmWindowState) ||
+                    (event.xproperty.atom == atmMotifWmHints) ||
+                    (event.xproperty.atom == atmWindowType) ||
+                    (event.xproperty.atom == atmNormalHints)) {
+                    memset(&msg, 0, sizeof(msg));
+                    msg.msg = WM_WM_HINTS_EVENT;
+                    msg.iWindow = event.xproperty.window;
+
+                    /* Other fields ignored */
+                    winSendMessageToWM(pProcArg->pWMInfo, &msg);
+                }
 
-                /* Other fields ignored */
-                winSendMessageToWM(pProcArg->pWMInfo, &msg);
+                /* Not an else as WM_HINTS affects both style and icon */
+                if ((event.xproperty.atom == atmWmHints) ||
+                    (event.xproperty.atom == atmNetWmIcon)) {
+                    memset(&msg, 0, sizeof(msg));
+                    msg.msg = WM_WM_ICON_EVENT;
+                    msg.iWindow = event.xproperty.window;
+
+                    /* Other fields ignored */
+                    winSendMessageToWM(pProcArg->pWMInfo, &msg);
+                }
             }
         }
         else if (event.type == ClientMessage
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 37b9752..25826ec 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -110,6 +110,7 @@ typedef struct _winWMMessageRec {
 #define		WM_WM_CHANGE_STATE	(WM_USER + 11)
 #define		WM_WM_MAP2		(WM_USER + 12)
 #define		WM_WM_MAP3		(WM_USER + 13)
+#define		WM_WM_HINTS_EVENT	(WM_USER + 14)
 #define		WM_MANAGE		(WM_USER + 100)
 #define		WM_UNMANAGE		(WM_USER + 102)
 
commit 066ecbd11d516ea68d7ebc7470232d01c5717546
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Jan 10 14:37:45 2013 +0000

    hw/xwin: Move reshape code from winUpdateWindowPosition() to the map event handler
    
    Move reshape code, which was only used when handling a map event, from
    winUpdateWindowPosition(), to put it explicitly in the map event handler.
    
    Remove 'reshape' parameter from winUpdatePosition().
    
    (Note that there's no handling of the ShapeNotify event to notice when the
    window shape changes, instead we hook the screen SetShape procedure and reshape
    the native window then)
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 773fc97..feefcf4 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -186,7 +186,7 @@ static void
  winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle);
 
 void
- winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle);
+ winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
 
 /*
  * Local globals
@@ -742,8 +742,19 @@ winMultiWindowWMProc(void *pArg)
 
                 winApplyHints(pWMInfo->pDisplay, pNode->msg.iWindow,
                               pNode->msg.hwndWindow, &zstyle);
-                winUpdateWindowPosition(pNode->msg.hwndWindow, TRUE, &zstyle);
+                winUpdateWindowPosition(pNode->msg.hwndWindow, &zstyle);
             }
+
+            /* Reshape */
+            {
+                WindowPtr pWin =
+                    GetProp(pNode->msg.hwndWindow, WIN_WINDOW_PROP);
+                if (pWin) {
+                    winReshapeMultiWindow(pWin);
+                    winUpdateRgnMultiWindow(pWin);
+                }
+            }
+
             break;
 
         case WM_WM_UNMAP:
@@ -1749,7 +1760,7 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
 }
 
 void
-winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle)
+winUpdateWindowPosition(HWND hWnd, HWND * zstyle)
 {
     int iX, iY, iWidth, iHeight;
     int iDx, iDy;
@@ -1800,8 +1811,4 @@ winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle)
     SetWindowPos(hWnd, *zstyle, rcNew.left, rcNew.top,
                  rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, 0);
 
-    if (reshape) {
-        winReshapeMultiWindow(pWin);
-        winUpdateRgnMultiWindow(pWin);
-    }
 }
diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index c2292c6..f7c6f2b 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -42,7 +42,7 @@
 #include "winmsg.h"
 #include "inputstr.h"
 
-extern void winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle);
+extern void winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
 
 /*
  * Local globals
@@ -891,7 +891,7 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                                       WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
                                      & ~WS_CAPTION & ~WS_SIZEBOX);
 
-                winUpdateWindowPosition(hwnd, FALSE, &zstyle);
+                winUpdateWindowPosition(hwnd, &zstyle);
 
                 {
                     WinXWMHints hints;
commit 852d1fb042f4160fe023a015f1c9a34126bf911a
Author: Ryan Pavlik <rpavlik at iastate.edu>
Date:   Sat Dec 1 16:58:40 2012 +0000

    hw/xwin: Add missing include xwin-config.h to winglobals.h
    
    winglobals.h checks if RELOCATE_PROJECTROOT is defined to see if a declaration
    of g_fLogFileChanged is needed, so must include xwin-config.h
    
    Signed-off-by: Ryan Pavlik <rpavlik at iastate.edu>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winglobals.h b/hw/xwin/winglobals.h
index 2edf957..d2e2ba2 100644
--- a/hw/xwin/winglobals.h
+++ b/hw/xwin/winglobals.h
@@ -26,6 +26,10 @@
 #ifndef WINGLOBALS_H
 #define WINGLOBALS_H
 
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+
 /*
  * References to external symbols
  */
commit ab686ce029208abf970a4bcd1435bf8411a44de9
Author: Ryan Pavlik <rpavlik at iastate.edu>
Date:   Wed Oct 26 17:03:25 2011 -0500

    include: Add RELOCATE_PROJECTROOT to xwin-config.h header
    
    RELOCATE_PROJECTROOT is AC_DEFINED in configure.ac, but currently has no effect
    as it doesn't appear in any AC_CONFIG_HEADER header.
    
    When packaged for Windows, we do not have a unix-style filesystem tree, where
    file needed by the X server can be found in fixed, absolute paths under the
    prefix (PROJECTROOT).
    
    Instead, the filesystem tree containing files needed by the X server and clients
    will be installed with the directory containing the X server executable as the
    root directory of that tree.
    
    (Typically, this will be in the Program Files directory, which does not have a
    fixed name, as it can be moved, localized, or added to to indicate x86 or x64
    binaries)
    
    So, RELOCATE_PROJECTROOT is used to make a native Windows build of the X server
    look for various files (fonts, xkb data) in locations relative to the X server
    rather than at absolute paths, by translating those paths at run-time.
    
    Additionally the XKEYSYMDB, XERRORDB, XLOCALEDIR env vars checked by libX11 are
    set appropriately for clients started by the X server.
    
    Signed-off-by: Ryan Pavlik <rpavlik at iastate.edu>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/include/xwin-config.h.in b/include/xwin-config.h.in
index 8122f55..c5119f2 100644
--- a/include/xwin-config.h.in
+++ b/include/xwin-config.h.in
@@ -31,3 +31,6 @@
 
 /* Default log location */
 #undef DEFAULT_LOGDIR
+
+/* Whether we should re-locate the root to where the executable lives */
+#undef RELOCATE_PROJECTROOT
commit fa6ab7d9b2d7fd8184f1e068360607845f5c33ab
Merge: adde4e6 0e1ab43
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 11 14:58:17 2013 +1000

    Merge branch 'pointer-emulation-fixes-56558-v2' into for-keith

commit adde4e64480315dc5b47a727ee37d86f5cd8584f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 10 10:33:05 2013 +1000

    dix: typo fix in comment
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 338f415..c7994b0 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -738,7 +738,7 @@ ApplyConstantDeceleration(DeviceVelocityPtr vel, double *fdx, double *fdy)
 }
 
 /*
- * compute the acceleration for given velocity and enforce min_acceleartion
+ * compute the acceleration for given velocity and enforce min_acceleration
  */
 double
 BasicComputeAcceleration(DeviceIntPtr dev,
commit 05ed095dd8d6cf939b4ebd9a59d70ce32705df7c
Author: Benjamin Tissoires <benjamin.tissoires at gmail.com>
Date:   Wed Jan 9 19:32:19 2013 +0100

    dix: fix error logging occuring in signal context of GetTouchEvents
    
    GetTouchEvents is usually called in a signal context.
    Calling ErrorF for the error messages leads to X complaining about log:
    
    (EE) BUG: triggered 'if (inSignalContext)'
    (EE) BUG: log.c:484 in LogVMessageVerb()
    (EE) Warning: attempting to log data in a signal unsafe manner while in signal context.
    Please update to check inSignalContext and/or use LogMessageVerbSigSafe() or ErrorFSigSafe().
    The offending log format message is:
    %s: Attempted to start touch without x/y (driver bug)
    
    Signed-off-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index 3d41e1e..a1e1938 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1895,16 +1895,16 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
         if (!mask_in ||
             !valuator_mask_isset(mask_in, 0) ||
             !valuator_mask_isset(mask_in, 1)) {
-            ErrorF("%s: Attempted to start touch without x/y (driver bug)\n",
-                   dev->name);
+            ErrorFSigSafe("%s: Attempted to start touch without x/y "
+                          "(driver bug)\n", dev->name);
             return 0;
         }
         break;
     case XI_TouchUpdate:
         event->type = ET_TouchUpdate;
         if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0) {
-            ErrorF("%s: TouchUpdate with no valuators? Driver bug\n",
-                   dev->name);
+            ErrorFSigSafe("%s: TouchUpdate with no valuators? Driver bug\n",
+                          dev->name);
         }
         break;
     case XI_TouchEnd:
commit f4a58469a298c226668fd8dce375bf22331c902d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jan 9 13:58:56 2013 +1000

    xfree86: don't access the old input handler after freeing it
    
    Introduced in 323869f3298cbbfe864af9404a8aed1bf7995d79
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index d8d4fad..377e936 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -619,14 +619,16 @@ InputHandlerProc
 xf86SetConsoleHandler(InputHandlerProc proc, pointer data)
 {
     static IHPtr handler = NULL;
-    IHPtr old_handler = handler;
+    InputHandlerProc old_proc = NULL;
 
-    if (old_handler)
-        xf86RemoveGeneralHandler(old_handler);
+    if (handler) {
+        old_proc = handler->ihproc;
+        xf86RemoveGeneralHandler(handler);
+    }
 
     handler = xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
 
-    return (old_handler) ? old_handler->ihproc : NULL;
+    return old_proc;
 }
 
 static void
commit 205cfbd6d9824fb9a67c21b19bc8f1e66c9df4d2
Author: Dave Airlie <airlied at gmail.com>
Date:   Sat Jan 5 18:35:42 2013 +1000

    xf86: bump input ABI version to 19
    
    The changes to miPointerSetPosition interface from int->double breaks
    the SIS driver build, so time to bump this.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index 1be7ba5..e545c14 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -81,7 +81,7 @@ typedef enum {
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
 #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(14, 1)
-#define ABI_XINPUT_VERSION	SET_ABI_VERSION(18, 0)
+#define ABI_XINPUT_VERSION	SET_ABI_VERSION(19, 0)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(7, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
commit ad3bc571348a7007a2960bf87ae739397c5511ee
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 8 11:19:09 2013 +1000

    xfree86: update the device state for all DGA events (#59100)
    
    DGA only handles master devices but it does intercept slave device events as
    well (since the event handlers are per event type, not per device).
    
    The DGA code must thus call into UpdateDeviceState to reset the button/key
    state on the slave device before it discards the remainder of the event.
    
    Test case:
    - Passive GrabModeSync on VCP
    - Press button
    - Enable DGA after ButtonPress
    - AllowEvents(SyncPointer)
    - Release button
    
    The button release is handled by DGAProcessPointerEvent but the device state
    is never updated, so the slave ends up with the button permanently down.
    And since the master's button state is the union of the slave states, the
    master has the button permanently down.
    
    X.Org Bug 59100 <http://bugs.freedesktop.org/show_bug.cgi?id=59100>
    
    Reported-by: Steven Elliott <selliott4 at austin.rr.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index c10dd32..6a05ce5 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -1033,6 +1033,9 @@ DGAProcessKeyboardEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr keybd)
 
     UpdateDeviceState(keybd, &ev);
 
+    if (!IsMaster(keybd))
+        return;
+
     /*
      * Deliver the DGA event
      */
@@ -1084,6 +1087,9 @@ DGAProcessPointerEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr mouse)
 
     UpdateDeviceState(mouse, &ev);
 
+    if (!IsMaster(mouse))
+        return;
+
     /*
      * Deliver the DGA event
      */
@@ -1191,9 +1197,6 @@ DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
     if (!pScreenPriv)
         return;
 
-    if (!IsMaster(device))
-        return;
-
     switch (event->subtype) {
     case KeyPress:
     case KeyRelease:
commit c5f2818edbec2f87383baa6c6be5c389b73ca6f9
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 8 10:13:53 2013 +1000

    xfree86: set event->detail for DGA pointer events
    
    Reported-by: Steven Elliott <selliott4 at austin.rr.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index c25a274..c10dd32 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -1074,6 +1074,7 @@ DGAProcessPointerEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr mouse)
     DeviceEvent ev = {
         .header = ET_Internal,
         .length = sizeof(ev),
+        .detail.key = event->detail,
         .type = event->subtype,
         .corestate = butc ? butc->state : 0
     };
commit 519d183d78e0b0eaf47a473e94f5d8611baf8463
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jan 7 10:44:33 2013 +1000

    Fix two typos "requires an string value"
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c
index c2ec79a..40c9d15 100644
--- a/hw/xfree86/common/xf86Option.c
+++ b/hw/xfree86/common/xf86Option.c
@@ -515,7 +515,7 @@ ParseOptionValue(int scrnIndex, XF86OptionPtr options, OptionInfoPtr p,
             if (*s == '\0') {
                 if (markUsed) {
                     xf86DrvMsg(scrnIndex, X_WARNING,
-                               "Option \"%s\" requires an string value\n",
+                               "Option \"%s\" requires a string value\n",
                                p->name);
                 }
                 p->found = FALSE;
diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c
index 313320f..9e38113 100644
--- a/hw/xwin/winconfig.c
+++ b/hw/xwin/winconfig.c
@@ -762,7 +762,7 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p)
         case OPTV_STRING:
             if (*s == '\0') {
                 winDrvMsg(scrnIndex, X_WARNING,
-                          "Option \"%s\" requires an string value\n", p->name);
+                          "Option \"%s\" requires a string value\n", p->name);
                 p->found = FALSE;
             }
             else {
commit 4e13dd90144dde47550aceea4db4b4329e531279
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Aug 22 10:34:07 2012 +1000

    dix: don't filter RawEvents if the grab window is not the root window (#53897)
    
    If a XI2.1+ client has a grab on a non-root window, it  must still receive
    raw events on the root window.
    
    Test case: register for XI_ButtonPress on window and XI_RawMotion on root.
    No raw events are received once the press activates an implicit grab on the
    window.
    
    X.Org Bug 53897 <http://bugs.freedesktop.org/show_bug.cgi?id=53897>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/events.c b/dix/events.c
index 7359362..adbb762 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2246,7 +2246,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
  * @return TRUE if the event should be discarded, FALSE otherwise.
  */
 static BOOL
-FilterRawEvents(const ClientPtr client, const GrabPtr grab)
+FilterRawEvents(const ClientPtr client, const GrabPtr grab, WindowPtr root)
 {
     XIClientPtr client_xi_version;
     int cmp;
@@ -2262,7 +2262,10 @@ FilterRawEvents(const ClientPtr client, const GrabPtr grab)
                           client_xi_version->minor_version, 2, 0);
     /* XI 2.0: if device is grabbed, skip
        XI 2.1: if device is grabbed by us, skip, we've already delivered */
-    return (cmp == 0) ? TRUE : SameClient(grab, client);
+    if (cmp == 0)
+        return TRUE;
+
+    return (grab->window != root) ? FALSE : SameClient(grab, client);
 }
 
 /**
@@ -2315,7 +2318,7 @@ DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
              */
             ic.next = NULL;
 
-            if (!FilterRawEvents(rClient(&ic), grab))
+            if (!FilterRawEvents(rClient(&ic), grab, root))
                 DeliverEventToInputClients(device, &ic, root, xi, 1,
                                            filter, NULL, &c, &m);
         }
commit a2037d7080ae64ea55f7d76971716346aa3ec6d3
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Nov 28 22:25:35 2012 +0000

    hw/xwin: Fix MinGW build of winSetAppModelID.c
    
    Add missing #include <pthread.h>
    
    In file included from /jhbuild/checkout/xorg/xserver/hw/xwin/winSetAppUserModelID.c:31:0:
    /jhbuild/checkout/xorg/xserver/hw/xwin/winwindow.h:140:11: error: expected declaration specifiers or ‘...’ before ‘pthread_t’
    /jhbuild/checkout/xorg/xserver/hw/xwin/winwindow.h:141:11: error: expected declaration specifiers or ‘...’ before ‘pthread_t’
    /jhbuild/checkout/xorg/xserver/hw/xwin/winwindow.h:142:11: error: expected declaration specifiers or ‘...’ before ‘pthread_mutex_t’
    
    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/winSetAppUserModelID.c b/hw/xwin/winSetAppUserModelID.c
index ce9da5e..41615e1 100644
--- a/hw/xwin/winSetAppUserModelID.c
+++ b/hw/xwin/winSetAppUserModelID.c
@@ -28,6 +28,7 @@
 #include <X11/Xlib.h>
 #include <X11/Xproto.h>
 #include <X11/Xwindows.h>
+#include <pthread.h>
 #include "winwindow.h"
 #include "os.h"
 #include "winmsg.h"
commit f57100bb36eae3b4d75f3c315973405f705b8de6
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Feb 23 13:38:48 2010 +0000

    hw/xwin: Process one Windows message per wakeup, rather than all of them.
    
    De-queuing Windows messages and X events happens in the same thread of
    execution.  Draining the windows message queue can lead to the X event queue
    overflowing if lots of those windows messages cause X events (e.g. if a keyboard
    macro program has just dumped thousands of keypresses into the Windows message
    queue).  See the mailing list thread [1] for more details.
    
    Processing one Windows message per wakeup, rather than all of them gives the X
    server a chance to do stuff as well after each message.
    
    [1] http://cygwin.com/ml/cygwin-xfree/2010-01/msg00056.html
    
    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/winblock.c b/hw/xwin/winblock.c
index a4ae866..c3ef4be 100644
--- a/hw/xwin/winblock.c
+++ b/hw/xwin/winblock.c
@@ -42,14 +42,26 @@ winBlockHandler(ScreenPtr pScreen,
 #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
     winScreenPriv(pScreen);
 #endif
-    MSG msg;
 
 #ifndef HAS_DEVWINDOWS
     struct timeval **tvp = pTimeout;
 
     if (*tvp != NULL) {
+      if (GetQueueStatus(QS_ALLINPUT | QS_ALLPOSTMESSAGE) != 0) {
+        /* If there are still messages to process on the Windows message
+           queue, make sure select() just polls rather than blocking.
+        */
+        (*tvp)->tv_sec = 0;
+        (*tvp)->tv_usec = 0;
+      }
+      else {
+        /* Otherwise, lacking /dev/windows, we must wake up again in
+           a reasonable time to check the Windows message queue. without
+           noticeable delay.
+         */
         (*tvp)->tv_sec = 0;
         (*tvp)->tv_usec = 100;
+      }
     }
 #endif
 
@@ -68,24 +80,12 @@ winBlockHandler(ScreenPtr pScreen,
         if (iReturn != 0) {
             ErrorF("winBlockHandler - pthread_mutex_unlock () failed: %d\n",
                    iReturn);
-            goto winBlockHandler_ProcessMessages;
         }
-
-        winDebug("winBlockHandler - pthread_mutex_unlock () returned\n");
-    }
-
- winBlockHandler_ProcessMessages:
-#endif
-
-    /* Process all messages on our queue */
-    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
-        if ((g_hDlgDepthChange == 0
-             || !IsDialogMessage(g_hDlgDepthChange, &msg))
-            && (g_hDlgExit == 0 || !IsDialogMessage(g_hDlgExit, &msg))
-            && (g_hDlgAbout == 0 || !IsDialogMessage(g_hDlgAbout, &msg))) {
-            DispatchMessage(&msg);
+        else {
+            winDebug("winBlockHandler - pthread_mutex_unlock () returned\n");
         }
     }
+#endif
 
   /*
     At least one X client has asked to suspend the screensaver, so
diff --git a/hw/xwin/winwakeup.c b/hw/xwin/winwakeup.c
index 77c1605..795221a 100644
--- a/hw/xwin/winwakeup.c
+++ b/hw/xwin/winwakeup.c
@@ -43,8 +43,8 @@ winWakeupHandler(ScreenPtr pScreen,
 {
     MSG msg;
 
-    /* Process all messages on our queue */
-    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+    /* Process one message from our queue */
+    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
         if ((g_hDlgDepthChange == 0
              || !IsDialogMessage(g_hDlgDepthChange, &msg))
             && (g_hDlgExit == 0 || !IsDialogMessage(g_hDlgExit, &msg))
commit e30e1ea98720acc583f34c830a1c1b7e3e88f694
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Dec 17 22:38:25 2012 +0000

    hw/xwin: Fix some comments in winkeybd.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/winkeybd.c b/hw/xwin/winkeybd.c
index a70cdcd..27c114c 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -56,7 +56,7 @@ static void
 static void
  winKeybdCtrl(DeviceIntPtr pDevice, KeybdCtrl * pCtrl);
 
-/* 
+/*
  * Translate a Windows WM_[SYS]KEY(UP/DOWN) message
  * into an ASCII scan code.
  *
@@ -134,7 +134,7 @@ winKeybdCtrl(DeviceIntPtr pDevice, KeybdCtrl * pCtrl)
 {
 }
 
-/* 
+/*
  * See Porting Layer Definition - p. 18
  * winKeybdProc is known as a DeviceProc.
  */
@@ -509,8 +509,8 @@ winCheckKeyPressed(WPARAM wParam, LPARAM lParam)
     return FALSE;
 }
 
-/* Only on shift release message is sent even if both are pressed.
- * Fix this here 
+/* Only one shift release message is sent even if both are pressed.
+ * Fix this here
  */
 void
 winFixShiftKeys(int iScanCode)
commit 6f4a48f8a55bc54b6d3e9d80734be05750c024de
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Apr 1 15:08:26 2010 +0100

    hw/xwin: Bring the X screen window to the front on a single left-click on the tray icon
    
    Bring the X screen window to the front on a single left click on the tray icon,
    like the comment says we do
    
    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/wintrayicon.c b/hw/xwin/wintrayicon.c
index dbc4725..f168b88 100644
--- a/hw/xwin/wintrayicon.c
+++ b/hw/xwin/wintrayicon.c
@@ -114,7 +114,7 @@ winHandleIconMessage(HWND hwnd, UINT message,
     switch (lParam) {
     case WM_LBUTTONUP:
         /* Restack and bring all windows to top */
-        SetForegroundWindow(hwnd);
+        SetForegroundWindow (pScreenPriv->hwndScreen);
 
 #ifdef XWIN_MULTIWINDOWEXTWM
         if (pScreenInfo->fMWExtWM)
commit 6703a7c7cf1a349c137e247a0c8eb462ff7b07be
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Jan 8 20:24:32 2013 -0800

    hw/xfree86: Require only one working CRTC to start the server.
    
    Instead of requiring every mode set to complete successfully, start up
    as long as at least one CRTC is working. This avoids failures when one
    or more CRTCs can't start due to mode setting conflicts.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 13251cf..b3ded5a 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2605,6 +2605,7 @@ xf86SetDesiredModes(ScrnInfoPtr scrn)
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
     xf86CrtcPtr crtc = config->crtc[0];
     int c;
+    int enabled = 0;
 
     /* A driver with this hook will take care of this */
     if (!crtc->funcs->set_mode_major) {
@@ -2655,14 +2656,20 @@ xf86SetDesiredModes(ScrnInfoPtr scrn)
             transform = &crtc->desiredTransform;
         else
             transform = NULL;
-        if (!xf86CrtcSetModeTransform
+        if (xf86CrtcSetModeTransform
             (crtc, &crtc->desiredMode, crtc->desiredRotation, transform,
-             crtc->desiredX, crtc->desiredY))
-            return FALSE;
+             crtc->desiredX, crtc->desiredY)) {
+            ++enabled;
+        } else {
+            for (o = 0; o < config->num_output; o++)
+                if (config->output[o]->crtc == crtc)
+                    config->output[o]->crtc = NULL;
+            crtc->enabled = FALSE;
+	}
     }
 
     xf86DisableUnusedFunctions(scrn);
-    return TRUE;
+    return enabled != 0;
 }
 
 /**
commit 0e1ab433f4048b3367bb2f01d16cd00502538e4d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 4 12:26:58 2013 +1000

    dix: remove already-moved hunk
    
    Should've been removed in bc1f90a615018c05994fae3e678dd2341256cd82a, but got
    left here due to a botched rebase.
    
    Fixes stray button events sent to clients after deactivating an async
    pointer grab on a pointer-emulating-touch.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/events.c b/dix/events.c
index b742f67..a46aaf6 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1551,15 +1551,6 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
         ReattachToOldMaster(mouse);
 
     ComputeFreezes();
-
-    /* If an explicit grab was deactivated, we must remove it from the head of
-     * all the touches' listener lists. */
-    for (i = 0; mouse->touch && i < mouse->touch->num_touches; i++) {
-        TouchPointInfoPtr ti = mouse->touch->touches + i;
-
-        if (ti->active && TouchResourceIsOwner(ti, grab_resource))
-            TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
-    }
 }
 
 /**
commit 32a6d8a6b59c42f8d65002d7ca1cafb1957b656f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 20 16:25:43 2012 +1000

    dix: check for the right device's xi2 mask
    
    events.c: In function 'DeactivatePointerGrab':
    events.c:1524:51: warning: 'dev' may be used uninitialized in this function
    [-Wuninitialized
    
    dev is unset when we get here, the device to check is "mouse".
    Introduced in ece8157a59751b3ed492fb2e1eb8d5f20221e195.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/events.c b/dix/events.c
index bea68cc..b742f67 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1522,7 +1522,7 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
                emulate a ButtonRelease here. So pretend the listener
                already has the end event */
             if (grab->grabtype == CORE || grab->grabtype == XI ||
-                    !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))
+                    !xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin))
                 ti->listeners[0].state = LISTENER_HAS_END;
             TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
         }
commit f59499b5d05fde83813709e9848152951592120d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Oct 30 12:44:08 2012 +1000

    dix: add resource type to touch listeners
    
    Instead of guessing what resource type the listener is and what property to
    retrieve, store the resource type in the listener directly.
    
    Breaks XIT test cases:
    TouchGrabTestMultipleTaps.PassiveGrabPointerEmulationMultipleTouchesFastSuccession
    
    Fixes https://bugs.freedesktop.org/show_bug.cgi?id=56557
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Chase Douglas <chase.douglas at ubuntu.com>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 22bb563..74f3610 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1305,13 +1305,9 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
         *mask = (*grab)->xi2mask;
     }
     else {
-        if (listener->level == CORE)
-            rc = dixLookupWindow(win, listener->listener,
-                                 serverClient, DixSendAccess);
-        else
-            rc = dixLookupResourceByType((pointer *) win, listener->listener,
-                                         RT_INPUTCLIENT,
-                                         serverClient, DixSendAccess);
+        rc = dixLookupResourceByType((pointer *) win, listener->listener,
+                                     listener->resource_type,
+                                     serverClient, DixSendAccess);
         if (rc != Success)
             return FALSE;
 
@@ -1452,6 +1448,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
             l = &ti->listeners[ti->num_listeners - 1];
             l->listener = devgrab->resource;
             l->grab = devgrab;
+            //l->resource_type = RT_NONE;
 
             if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
                 l->type = LISTENER_POINTER_GRAB;
diff --git a/dix/touch.c b/dix/touch.c
index 99f105b..0db842c 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -675,12 +675,13 @@ TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource)
  * Add the resource to this touch's listeners.
  */
 void
-TouchAddListener(TouchPointInfoPtr ti, XID resource, enum InputLevel level,
-                 enum TouchListenerType type, enum TouchListenerState state,
-                 WindowPtr window,
+TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
+                 enum InputLevel level, enum TouchListenerType type,
+                 enum TouchListenerState state, WindowPtr window,
                  GrabPtr grab)
 {
     ti->listeners[ti->num_listeners].listener = resource;
+    ti->listeners[ti->num_listeners].resource_type = resource_type;
     ti->listeners[ti->num_listeners].level = level;
     ti->listeners[ti->num_listeners].state = state;
     ti->listeners[ti->num_listeners].type = type;
@@ -741,7 +742,8 @@ TouchAddGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
         type = LISTENER_POINTER_GRAB;
     }
 
-    TouchAddListener(ti, grab->resource, grab->grabtype,
+    /* grab listeners are always RT_NONE since we keep the grab pointer */
+    TouchAddListener(ti, grab->resource, RT_NONE, grab->grabtype,
                      type, LISTENER_AWAITING_BEGIN, grab->window, grab);
 }
 
@@ -797,7 +799,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
             if (!xi2mask_isset(iclients->xi2mask, dev, XI_TouchOwnership))
                 TouchEventHistoryAllocate(ti);
 
-            TouchAddListener(ti, iclients->resource, XI2,
+            TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI2,
                              type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
@@ -812,7 +814,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
                 continue;
 
             TouchEventHistoryAllocate(ti);
-            TouchAddListener(ti, iclients->resource, XI,
+            TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
                              win, NULL);
             return TRUE;
@@ -827,7 +829,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
         /* window owner */
         if (IsMaster(dev) && (win->eventMask & core_filter)) {
             TouchEventHistoryAllocate(ti);
-            TouchAddListener(ti, win->drawable.id, CORE,
+            TouchAddListener(ti, win->drawable.id, RT_WINDOW, CORE,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
                              win, NULL);
             return TRUE;
@@ -839,7 +841,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
                 continue;
 
             TouchEventHistoryAllocate(ti);
-            TouchAddListener(ti, oclients->resource, CORE,
+            TouchAddListener(ti, oclients->resource, RT_OTHERCLIENT, CORE,
                              type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
diff --git a/include/input.h b/include/input.h
index 79739e2..f53ed99 100644
--- a/include/input.h
+++ b/include/input.h
@@ -565,7 +565,7 @@ extern void TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev);
 extern void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev,
                                     XID resource);
 extern Bool TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource);
-extern void TouchAddListener(TouchPointInfoPtr ti, XID resource,
+extern void TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
                              enum InputLevel level, enum TouchListenerType type,
                              enum TouchListenerState state, WindowPtr window, GrabPtr grab);
 extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource);
diff --git a/include/inputstr.h b/include/inputstr.h
index 32d7b62..fc21913 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -301,6 +301,7 @@ typedef struct _ValuatorClassRec {
 typedef struct _TouchListener {
     XID listener;           /* grabs/event selection IDs receiving
                              * events for this touch */
+    int resource_type;      /* listener's resource type */
     enum TouchListenerType type;
     enum TouchListenerState state;
     enum InputLevel level;  /* matters only for emulating touches */
commit 9ad0fdb135a1c336771aee1f6eab75a6ad874aff
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Nov 27 11:21:17 2012 -0800

    input: Record grab pointer in TouchListener
    
    This places a pointer to the grab related to a TouchListener directly
    in the TouchListener structure rather than hoping to find the grab
    later on using the resource ID.
    
    Passive grabs have resource ID in the resource DB so they can be
    removed when a client exits, and those resource IDs get copied when
    activated, but implicit grabs are constructed on-the-fly and have no
    resource DB entry.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 58fe493..22bb563 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1187,7 +1187,6 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
               TouchOwnershipEvent *ev)
 {
     Bool was_owner = (resource == ti->listeners[0].listener);
-    void *grab;
     int i;
 
     /* Send a TouchEnd event to the resource being removed, but only if they
@@ -1202,11 +1201,7 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
 
     /* Remove the resource from the listener list, updating
      * ti->num_listeners, as well as ti->num_grabs if it was a grab. */
-    if (TouchRemoveListener(ti, resource)) {
-        if (dixLookupResourceByType(&grab, resource, RT_PASSIVEGRAB,
-                                    serverClient, DixGetAttrAccess) == Success)
-            ti->num_grabs--;
-    }
+    TouchRemoveListener(ti, resource);
 
     /* If the current owner was removed and there are further listeners, deliver
      * the TouchOwnership or TouchBegin event to the new owner. */
@@ -1300,21 +1295,10 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
 
     if (listener->type == LISTENER_GRAB ||
         listener->type == LISTENER_POINTER_GRAB) {
-        rc = dixLookupResourceByType((pointer *) grab, listener->listener,
-                                     RT_PASSIVEGRAB,
-                                     serverClient, DixSendAccess);
-        if (rc != Success) {
-            /* the grab doesn't exist but we have a grabbing listener - this
-             * is an implicit/active grab */
-            rc = dixLookupClient(client, listener->listener, serverClient,
-                                 DixSendAccess);
-            if (rc != Success)
-                return FALSE;
-
-            *grab = dev->deviceGrab.grab;
-            if (!*grab)
-                return FALSE;
-        }
+
+        *grab = listener->grab;
+
+        BUG_RETURN_VAL(!*grab, FALSE);
 
         *client = rClient(*grab);
         *win = (*grab)->window;
@@ -1467,6 +1451,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
              */
             l = &ti->listeners[ti->num_listeners - 1];
             l->listener = devgrab->resource;
+            l->grab = devgrab;
 
             if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
                 l->type = LISTENER_POINTER_GRAB;
diff --git a/dix/events.c b/dix/events.c
index 7359362..bea68cc 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1438,6 +1438,7 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
                 ti->listeners[0].type = LISTENER_POINTER_GRAB;
             else
                 ti->listeners[0].type = LISTENER_GRAB;
+            ti->listeners[0].grab = grab;
         }
     }
 }
diff --git a/dix/touch.c b/dix/touch.c
index d890b62..99f105b 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -677,13 +677,17 @@ TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource)
 void
 TouchAddListener(TouchPointInfoPtr ti, XID resource, enum InputLevel level,
                  enum TouchListenerType type, enum TouchListenerState state,
-                 WindowPtr window)
+                 WindowPtr window,
+                 GrabPtr grab)
 {
     ti->listeners[ti->num_listeners].listener = resource;
     ti->listeners[ti->num_listeners].level = level;
     ti->listeners[ti->num_listeners].state = state;
     ti->listeners[ti->num_listeners].type = type;
     ti->listeners[ti->num_listeners].window = window;
+    ti->listeners[ti->num_listeners].grab = grab;
+    if (grab)
+        ti->num_grabs++;
     ti->num_listeners++;
 }
 
@@ -702,6 +706,11 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
         if (ti->listeners[i].listener == resource) {
             int j;
 
+            if (ti->listeners[i].grab) {
+                ti->listeners[i].grab = NULL;
+                ti->num_grabs--;
+            }
+
             for (j = i; j < ti->num_listeners - 1; j++)
                 ti->listeners[j] = ti->listeners[j + 1];
             ti->num_listeners--;
@@ -733,8 +742,7 @@ TouchAddGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
     }
 
     TouchAddListener(ti, grab->resource, grab->grabtype,
-                     type, LISTENER_AWAITING_BEGIN, grab->window);
-    ti->num_grabs++;
+                     type, LISTENER_AWAITING_BEGIN, grab->window, grab);
 }
 
 /**
@@ -790,7 +798,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
                 TouchEventHistoryAllocate(ti);
 
             TouchAddListener(ti, iclients->resource, XI2,
-                             type, LISTENER_AWAITING_BEGIN, win);
+                             type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
     }
@@ -806,7 +814,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
             TouchEventHistoryAllocate(ti);
             TouchAddListener(ti, iclients->resource, XI,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
-                             win);
+                             win, NULL);
             return TRUE;
         }
     }
@@ -821,7 +829,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
             TouchEventHistoryAllocate(ti);
             TouchAddListener(ti, win->drawable.id, CORE,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
-                             win);
+                             win, NULL);
             return TRUE;
         }
 
@@ -832,7 +840,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
 
             TouchEventHistoryAllocate(ti);
             TouchAddListener(ti, oclients->resource, CORE,
-                             type, LISTENER_AWAITING_BEGIN, win);
+                             type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
     }
diff --git a/include/input.h b/include/input.h
index 23a20b5..79739e2 100644
--- a/include/input.h
+++ b/include/input.h
@@ -567,7 +567,7 @@ extern void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev,
 extern Bool TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource);
 extern void TouchAddListener(TouchPointInfoPtr ti, XID resource,
                              enum InputLevel level, enum TouchListenerType type,
-                             enum TouchListenerState state, WindowPtr window);
+                             enum TouchListenerState state, WindowPtr window, GrabPtr grab);
 extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource);
 extern void TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti,
                                 InternalEvent *ev);
diff --git a/include/inputstr.h b/include/inputstr.h
index a9d46cc..32d7b62 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -305,6 +305,7 @@ typedef struct _TouchListener {
     enum TouchListenerState state;
     enum InputLevel level;  /* matters only for emulating touches */
     WindowPtr window;
+    GrabPtr grab;
 } TouchListener;
 
 typedef struct _TouchPointInfo {
commit 91ab237358c6e33da854914d3de493a9cbea7637
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Nov 27 11:21:16 2012 -0800

    input: Pull TouchListener declaration to top-level
    
    No reason to have a struct declared inside another struct
    
    Signed-off-by: Keith Packard <keithp at keithp.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/include/inputstr.h b/include/inputstr.h
index 17cee98..a9d46cc 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -298,6 +298,15 @@ typedef struct _ValuatorClassRec {
     int v_scroll_axis;          /* vert smooth-scrolling axis */
 } ValuatorClassRec;
 
+typedef struct _TouchListener {
+    XID listener;           /* grabs/event selection IDs receiving
+                             * events for this touch */
+    enum TouchListenerType type;
+    enum TouchListenerState state;
+    enum InputLevel level;  /* matters only for emulating touches */
+    WindowPtr window;
+} TouchListener;
+
 typedef struct _TouchPointInfo {
     uint32_t client_id;         /* touch ID as seen in client events */
     int sourceid;               /* Source device's ID for this touchpoint */
@@ -306,14 +315,7 @@ typedef struct _TouchPointInfo {
                                  * but still owned by a grab */
     SpriteRec sprite;           /* window trace for delivery */
     ValuatorMask *valuators;    /* last recorded axis values */
-    struct _TouchListener {
-        XID listener;           /* grabs/event selection IDs receiving
-                                 * events for this touch */
-        enum TouchListenerType type;
-        enum TouchListenerState state;
-        enum InputLevel level;  /* matters only for emulating touches */
-        WindowPtr window;
-    } *listeners;
+    TouchListener *listeners;   /* set of listeners */
     int num_listeners;
     int num_grabs;              /* number of open grabs on this touch
                                  * which have not accepted or rejected */
commit 3578cc3c2e1b5cb8eb191e2d12ad88e1bc9e6e1e
Author: Andreas Wettstein <wettstein509 at solnet.ch>
Date:   Wed Dec 19 18:13:21 2012 +0100

    xkb: Do not use base group as an array index.
    
    The base group is not brought into range and, therefore, using it as an array
    index crashed the X server.  Also, at this place, we should ignore locked
    groups, but not latched groups.  Therefore, use sum of base and latched groups,
    brought into range.
    
    Reproducible with:
    key <FK07> {
        type= "ONE_LEVEL",
        symbols[Group1]= [              NoSymbol ],
        actions[Group1]= [ LatchGroup(group=-1, clearLocks) ]
    };
    
    And hitting F7 will exceed the group level and access arbitrary memory.
    
    Signed-off-by: Andreas Wettstein <wettstein509 at solnet.ch>
    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/xkbUtils.c b/xkb/xkbUtils.c
index c23cd77..6c6af60 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -642,6 +642,7 @@ XkbComputeCompatState(XkbSrvInfoPtr xkbi)
     CARD16 grp_mask;
     XkbStatePtr state = &xkbi->state;
     XkbCompatMapPtr map;
+    XkbControlsPtr ctrls;
 
     if (!state || !xkbi->desc || !xkbi->desc->ctrls || !xkbi->desc->compat)
         return;
@@ -650,9 +651,14 @@ XkbComputeCompatState(XkbSrvInfoPtr xkbi)
     grp_mask = map->groups[state->group].mask;
     state->compat_state = state->mods | grp_mask;
     state->compat_lookup_mods = state->lookup_mods | grp_mask;
+    ctrls= xkbi->desc->ctrls;
 
-    if (xkbi->desc->ctrls->enabled_ctrls & XkbIgnoreGroupLockMask)
-        grp_mask = map->groups[state->base_group].mask;
+    if (ctrls->enabled_ctrls & XkbIgnoreGroupLockMask) {
+	unsigned char grp = state->base_group+state->latched_group;
+	if (grp >= ctrls->num_groups)
+	    grp = XkbAdjustGroup(XkbCharToInt(grp), ctrls);
+        grp_mask = map->groups[grp].mask;
+    }
     state->compat_grab_mods = state->grab_mods | grp_mask;
     return;
 }
commit df746a73410b892a4d41a2934cf9cd2e8ad7ba51
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Wed Dec 19 18:42:39 2012 +0100

    render: Unwrap early on the animated cursor BlockHandler
    
    The loop above the previous call may end up triggering other
    handlers attaching to the same function slot, so unwrapping
    the handler after that could leave the just attached handler
    in a dangling but not unset state.
    
    This issue was most visible on the XO, where destroying a
    window with an animated cursor set and running  would trigger
    this inconsistent state, never calling the miSpriteBlockHandler
    again after the animated cursor is unset.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/render/animcur.c b/render/animcur.c
index ebc5b8e..9cbba83 100644
--- a/render/animcur.c
+++ b/render/animcur.c
@@ -143,6 +143,8 @@ AnimCurScreenBlockHandler(ScreenPtr pScreen,
     Bool activeDevice = FALSE;
     CARD32 now = 0, soonest = ~0;       /* earliest time to wakeup again */
 
+    Unwrap(as, pScreen, BlockHandler);
+
     for (dev = inputInfo.devices; dev; dev = dev->next) {
         if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) {
             if (!activeDevice) {
@@ -180,7 +182,6 @@ AnimCurScreenBlockHandler(ScreenPtr pScreen,
     if (activeDevice)
         AdjustWaitForDelay(pTimeout, soonest - now);
 
-    Unwrap(as, pScreen, BlockHandler);
     (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
     if (activeDevice)
         Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
commit 0fbd779a82919d5dbf8776be9b57a76c0eae6b14
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Wed Dec 19 18:42:38 2012 +0100

    mi: Ensure pointer emulating touch events update the sprite
    
    Different miPointerSpriteFuncRec implementations do a varying
    business at ultimately calling miPointerUpdateSprite(), this
    particularly fails when using the plain mi sprite on touch events,
    where the sprite is just moved/updated on cursor changes.
    
    So, ensure miPointerUpdateSprite() is called generically for
    pointer emulating touch events as with regular motion events.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/mieq.c b/mi/mieq.c
index 22f8c91..d7d73de 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -627,7 +627,11 @@ mieqProcessInputEvents(void)
         mieqProcessDeviceEvent(dev, &event, screen);
 
         /* Update the sprite now. Next event may be from different device. */
-        if (event.any.type == ET_Motion && master)
+        if (master &&
+            (event.any.type == ET_Motion ||
+             ((event.any.type == ET_TouchBegin ||
+               event.any.type == ET_TouchUpdate) &&
+              event.device_event.flags & TOUCH_POINTER_EMULATED)))
             miPointerUpdateSprite(dev);
 
 #ifdef XQUARTZ
commit 8b328d4ee3873bc0a7a34f2cb9d301827244b98c
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Fri Dec 21 07:37:33 2012 -0800

    dix: Make small bitfields that store enums unsigned
    
    Commit 31bf81772e146af79b0c456aae2159eba8b0280f changed the clientState field
    from a signed int to a signed int 2-bit bitfield.  The ClientState enum that is
    expected to be assigned to this field has four values: ClientStateInitial (0),
    ClientStateRunning (1), ClientStateRetained (2), and ClientStateGone (3).
    However, because this bitfield is signed, ClientStateRetained becomes -2 when
    assigned, and ClientStateGone becomes -1.  This causes warnings:
    
     test.c:54:10: error: case label value exceeds maximum value for type [-Werror]
     test.c:55:10: error: case label value exceeds maximum value for type [-Werror]
    
    The code here is a switch statement:
    
     53     switch (client->clientState) {
     54     case ClientStateGone:
     55     case ClientStateRetained:
     56         [...]
     57         break;
     58
     59     default:
     60         [...]
     61         break;
     62     }
    
    It also causes bizarre problems like this:
    
     client->clientState = ClientStateGone;
     assert(client->clientState == ClientStateGone); // this assert fails
    
    Also change the signedness of nearby bitfields to match.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-by:  Colin Harrison <colin.harrison at virgin.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/dixstruct.h b/include/dixstruct.h
index c1236f5..6784819 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -90,12 +90,12 @@ typedef struct _Client {
     Mask clientAsMask;
     short index;
     unsigned char majorOp, minorOp;
-    int swapped:1;
-    int local:1;
-    int big_requests:1;          /* supports large requests */
-    int clientGone:1;
-    int closeDownMode:2;
-    int clientState:2;
+    unsigned int swapped:1;
+    unsigned int local:1;
+    unsigned int big_requests:1; /* supports large requests */
+    unsigned int clientGone:1;
+    unsigned int closeDownMode:2;
+    unsigned int clientState:2;
     char smart_priority;
     short noClientException;      /* this client died or needs to be killed */
     int priority;
commit 8f4820be7a2e0f6e286ddc85c4b75bccdbe8a730
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 20 12:44:16 2012 +1000

    test/xi2: fix compiler warning
    
    protocol-xiwarppointer.c: In function ‘ScreenSetCursorPosition’:
    protocol-xiwarppointer.c:71:53: warning: declaration of ‘screen’ shadows a
    global declaration [-Wshadow]
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/xi2/protocol-xiwarppointer.c b/test/xi2/protocol-xiwarppointer.c
index 4bea333..f7986c1 100644
--- a/test/xi2/protocol-xiwarppointer.c
+++ b/test/xi2/protocol-xiwarppointer.c
@@ -68,7 +68,7 @@ __wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client, Mask access)
  * This function overrides the one in the screen rec.
  */
 static Bool
-ScreenSetCursorPosition(DeviceIntPtr dev, ScreenPtr screen,
+ScreenSetCursorPosition(DeviceIntPtr dev, ScreenPtr scr,
                         int x, int y, Bool generateEvent)
 {
     assert(x == expected_x);
commit bd91b05b631f13afd1f7a9d6cbc4f0c5408b523a
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 19 12:47:35 2012 -0800

    Update to version 1.13.99.901 (1.14 RC1)
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index ee0fa78..435a38f 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.13.99.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2012-10-04"
-RELEASE_NAME="Horchata"
+AC_INIT([xorg-server], 1.13.99.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2012-12-19"
+RELEASE_NAME="Egg Nog"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 
commit 2a0b544f5c09f79e4ab04ea8103a5ecf59ee2e7b
Merge: 0eb1559 ba4bb3b
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 19 12:26:00 2012 -0800

    Merge remote-tracking branch 'jeremyhu/master'

commit 0eb1559eb29d11e63c2b33e317590a88d86fe313
Merge: 386e4d7 ea1d76d
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 19 12:21:31 2012 -0800

    Merge remote-tracking branch 'yselkowitz/master'
    
    I checked this patch with diff -w to check that it only affected
    whitespace.

commit 386e4d76baaffe226d2d561ff936509454eb0ac2
Merge: 014a5c8 9ff2e83
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 19 12:17:59 2012 -0800

    Merge remote-tracking branch 'alanc/master'

commit 014a5c8a9d86f2f992183bff9106354fac2c3b0e
Merge: f793b5f 2eefa5d
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 19 12:09:31 2012 -0800

    Merge remote-tracking branch 'whot/barriers'
    
    Conflicts:
    	Xi/xichangehierarchy.c
    
    Small conflict with the patch from
    
    	Xi: don't use devices after removing them
    
    Was easily resolved by hand.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

commit 9ff2e831517875f96477862f979abff394e8d551
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Dec 18 00:41:08 2012 -0800

    EnableDisableExtensionError: Use ARRAY_SIZE rather than sentinel
    
    d785368e0e converted the other miinitext functions to use ARRAY_SIZE,
    and removed the sentinel, but missed EnableDisableExtensionError so
    passing an invalid extension name could cause the server to walk off
    the end off the list looking for a sentinel that wasn't there.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/miinitext.c b/mi/miinitext.c
index 369da5e..81c663a 100644
--- a/mi/miinitext.c
+++ b/mi/miinitext.c
@@ -212,10 +212,12 @@ EnableDisableExtension(const char *name, Bool enable)
 void
 EnableDisableExtensionError(const char *name, Bool enable)
 {
-    ExtensionToggle *ext = &ExtensionToggleList[0];
+    ExtensionToggle *ext;
+    int i;
     Bool found = FALSE;
 
-    for (ext = &ExtensionToggleList[0]; ext->name != NULL; ext++) {
+    for (i = 0; i < ARRAY_SIZE(ExtensionToggleList); i++) {
+        ext = &ExtensionToggleList[i];
         if ((strcmp(name, ext->name) == 0) && (ext->disablePtr == NULL)) {
             ErrorF("[mi] Extension \"%s\" can not be disabled\n", name);
             found = TRUE;
@@ -226,7 +228,8 @@ EnableDisableExtensionError(const char *name, Bool enable)
         ErrorF("[mi] Extension \"%s\" is not recognized\n", name);
     ErrorF("[mi] Only the following extensions can be run-time %s:\n",
            enable ? "enabled" : "disabled");
-    for (ext = &ExtensionToggleList[0]; ext->name != NULL; ext++) {
+    for (i = 0; i < ARRAY_SIZE(ExtensionToggleList); i++) {
+        ext = &ExtensionToggleList[i];
         if (ext->disablePtr != NULL) {
             ErrorF("[mi]    %s\n", ext->name);
         }
commit 07a91fa6c6d535f3f05d4c3bd9c4d2b8c382c475
Author: Rob Clark <robdclark at gmail.com>
Date:   Wed Dec 5 23:21:27 2012 +0000

    hw/dmx: fix build without GLX
    
    Fixes this compile break that showed up on arm recently:
    
    dmxinit.c:746:26: error: 'glxSupported' undeclared (first use in this function)
    dmxinit.c:746:26: note: each undeclared identifier is reported only once for each function it appears in
    
    Signed-off-by: Rob Clark <robdclark at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c
index 7a50aeb..7de402b 100644
--- a/hw/dmx/dmxinit.c
+++ b/hw/dmx/dmxinit.c
@@ -740,10 +740,10 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
     /* Check if GLX extension exists on all back-end servers */
     for (i = 0; i < dmxNumScreens; i++)
         glxSupported &= (dmxScreens[i].glxMajorOpcode > 0);
-#endif
 
     if (serverGeneration == 1)
         dmxAddExtensions(glxSupported);
+#endif
 
     /* Tell dix layer about the backend displays */
     for (i = 0; i < dmxNumScreens; i++) {
commit 5692a1e8f5befd3698134b1a5516a4dadda00115
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Thu Dec 6 16:15:50 2012 -0800

    Support compilers with alternate spellings of typeof
    
    The AC_C_TYPEOF adds a #undef typeof to its autogenerated config.h.in
    template, but b8ab93dfbc7f292 didn't copy that to dix-config.h.in
    when HAVE_TYPEOF was, so the macro could claim typeof support but not
    make it work, when used with compilers like Solaris Studio 12.1 which
    only recognize it as __typeof__.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Acked-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index b270a32..e1cb9eb 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -429,6 +429,9 @@
 /* Define to 1 if typeof works with your compiler. */
 #undef HAVE_TYPEOF
 
+/* Define to __typeof__ if your compiler spells it that way. */
+#undef typeof
+
 /* The compiler supported TLS storage class, prefering initial-exec if tls_model is supported */
 #undef TLS
 
commit f793b5fd3eb16a2ada130367c2ffebeede69a322
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Dec 11 13:36:02 2012 +1000

    dix: don't copy the wrong event mask when activating a passive grab
    
    GrabMask is a union of core, XI1 and XI2 masks. If a XI2 grab is activated,
    the value is a random pointer value, using it as mask has unpredictable
    effects.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/grabs.c b/dix/grabs.c
index fe79674..3b02352 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -219,7 +219,10 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
     grab->resource = FakeClientID(client);
     grab->device = device;
     grab->window = window;
-    grab->eventMask = mask->core;       /* same for XI */
+    if (grabtype == CORE || grabtype == XI)
+        grab->eventMask = mask->core;       /* same for XI */
+    else
+        grab->eventMask = 0;
     grab->deviceMask = 0;
     grab->ownerEvents = param->ownerEvents;
     grab->keyboardMode = param->this_device_mode;
commit dd3242c87a0a58cba055eb99c0c3fcf03153e4b8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Dec 14 11:34:15 2012 +1000

    dix: don't allow overriding a grab with a different type of grab (#58255)
    
    If a client has a core grab, don't allow re-grabbing with type XI2, etc.
    This was the intent of the original commit
    xorg-server-1.5.99.1-782-g09f9a86, but ineffective.
    
    X.Org Bug 58255 <http://bugs.freedesktop.org/show_bug.cgi?id=58255>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/events.c b/dix/events.c
index 31f8d87..3836d2f 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -5043,7 +5043,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
     grab = grabInfo->grab;
     if (grab && grab->grabtype != grabtype)
         *status = AlreadyGrabbed;
-    if (grab && !SameClient(grab, client))
+    else if (grab && !SameClient(grab, client))
         *status = AlreadyGrabbed;
     else if ((!pWin->realized) ||
              (confineTo &&
commit 2eefa5d6e870c57ac6a5930883d8cfe3a3882a43
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 13 14:42:32 2012 +1000

    Xi: if a MD is removed, send a barrier leave event (if applicable)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 1714634..7b7b83f 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -714,12 +714,41 @@ static void remove_master_func(pointer res, XID id, pointer devid)
     struct PointerBarrierDevice *pbd;
     struct PointerBarrierClient *barrier;
     struct PointerBarrier *b;
+    DeviceIntPtr dev;
     int *deviceid = devid;
+    int rc;
+    Time ms = GetTimeInMillis();
+
+    rc = dixLookupDevice(&dev, *deviceid, serverClient, DixSendAccess);
+    if (rc != Success)
+        return;
 
     b = res;
     barrier = container_of(b, struct PointerBarrierClient, barrier);
 
     pbd = GetBarrierDevice(barrier, *deviceid);
+
+    if (pbd->hit) {
+        BarrierEvent ev = {
+            .header = ET_Internal,
+            .type =ET_BarrierLeave,
+            .length = sizeof (BarrierEvent),
+            .time = ms,
+            .deviceid = *deviceid,
+            .sourceid = 0,
+            .dx = 0,
+            .dy = 0,
+            .root = barrier->screen->root->drawable.id,
+            .window = barrier->window,
+            .dt = ms - pbd->last_timestamp,
+            .flags = XIBarrierPointerReleased,
+            .event_id = pbd->barrier_event_id,
+            .barrierid = barrier->id,
+        };
+
+        mieqEnqueue(dev, (InternalEvent *) &ev);
+    }
+
     xorg_list_del(&pbd->entry);
     free(pbd);
 }
@@ -731,7 +760,6 @@ void XIBarrierNewMasterDevice(ClientPtr client, int deviceid)
 
 void XIBarrierRemoveMasterDevice(ClientPtr client, int deviceid)
 {
-    /* FIXME: send LeaveNotify */
     FindClientResourcesByType(client, PointerBarrierType, remove_master_func, &deviceid);
 }
 
commit e2423b627ef7e4d08ea0685af5e771ddd2b511ce
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 13 14:04:13 2012 +1000

    Xi: don't store the window pointer in barriers, store the window ID
    
    When a client shuts down and resources are being freed, the window may have
    been freed already, so accessing it to get the window ID is bad. Plus, we
    never care about the window anyway other than for stuffing it into the
    event.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 7e8b2e6..1714634 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -80,7 +80,7 @@ struct PointerBarrierDevice {
 struct PointerBarrierClient {
     XID id;
     ScreenPtr screen;
-    WindowPtr window;
+    Window window;
     struct PointerBarrier barrier;
     struct xorg_list entry;
     /* num_devices/device_ids are devices the barrier applies to */
@@ -467,7 +467,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         ev.barrierid = c->id;
 
         ev.dt = ms - pbd->last_timestamp;
-        ev.window = c->window->drawable.id;
+        ev.window = c->window;
         pbd->last_timestamp = ms;
 
         /* root x/y is filled in later */
@@ -501,7 +501,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         ev.barrierid = c->id;
 
         ev.dt = ms - pbd->last_timestamp;
-        ev.window = c->window->drawable.id;
+        ev.window = c->window;
         pbd->last_timestamp = ms;
 
         /* root x/y is filled in later */
@@ -566,7 +566,7 @@ CreatePointerBarrierClient(ClientPtr client,
     cs = GetBarrierScreen(screen);
 
     ret->screen = screen;
-    ret->window = pWin;
+    ret->window = stuff->window;
     ret->num_devices = stuff->num_devices;
     if (ret->num_devices > 0)
         ret->device_ids = (int*)&ret[1];
@@ -656,7 +656,7 @@ BarrierFreeBarrier(void *data, XID id)
             /* .deviceid */
             .sourceid = 0,
             .barrierid = c->id,
-            .window = c->window->drawable.id,
+            .window = c->window,
             .root = screen->root->drawable.id,
             .dx = 0,
             .dy = 0,
commit f71c2f895c9e2f9d0d42feaac2a3e1d2deb71f67
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Dec 12 15:41:32 2012 +1000

    Xi: fix per-device barrier handling
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 048af62..7e8b2e6 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -67,19 +67,28 @@ static DevPrivateKeyRec BarrierScreenPrivateKeyRec;
 
 typedef struct PointerBarrierClient *PointerBarrierClientPtr;
 
+struct PointerBarrierDevice {
+    struct xorg_list entry;
+    int deviceid;
+    Time last_timestamp;
+    int barrier_event_id;
+    int release_event_id;
+    Bool hit;
+    Bool seen;
+};
+
 struct PointerBarrierClient {
     XID id;
     ScreenPtr screen;
     WindowPtr window;
     struct PointerBarrier barrier;
     struct xorg_list entry;
+    /* num_devices/device_ids are devices the barrier applies to */
     int num_devices;
     int *device_ids; /* num_devices */
-    Time last_timestamp;
-    int barrier_event_id;
-    int release_event_id;
-    Bool hit;
-    Bool seen;
+
+    /* per_device keeps track of devices actually blocked by barriers */
+    struct xorg_list per_device;
 };
 
 typedef struct _BarrierScreen {
@@ -90,6 +99,47 @@ typedef struct _BarrierScreen {
 #define GetBarrierScreenIfSet(s) GetBarrierScreen(s)
 #define SetBarrierScreen(s,p) dixSetPrivate(&(s)->devPrivates, BarrierScreenPrivateKey, p)
 
+static struct PointerBarrierDevice *AllocBarrierDevice(void)
+{
+    struct PointerBarrierDevice *pbd = NULL;
+
+    pbd = malloc(sizeof(struct PointerBarrierDevice));
+    if (!pbd)
+        return NULL;
+
+    pbd->deviceid = -1; /* must be set by caller */
+    pbd->barrier_event_id = 1;
+    pbd->release_event_id = 0;
+    pbd->hit = FALSE;
+    pbd->seen = FALSE;
+    xorg_list_init(&pbd->entry);
+
+    return pbd;
+}
+
+static void FreePointerBarrierClient(struct PointerBarrierClient *c)
+{
+    struct PointerBarrierDevice *pbd = NULL, *tmp = NULL;
+
+    xorg_list_for_each_entry_safe(pbd, tmp, &c->per_device, entry) {
+        free(pbd);
+    }
+    free(c);
+}
+
+static struct PointerBarrierDevice *GetBarrierDevice(struct PointerBarrierClient *c, int deviceid)
+{
+    struct PointerBarrierDevice *pbd = NULL;
+
+    xorg_list_for_each_entry(pbd, &c->per_device, entry) {
+        if (pbd->deviceid == deviceid)
+            break;
+    }
+
+    BUG_WARN(!pbd);
+    return pbd;
+}
+
 static BOOL
 barrier_is_horizontal(const struct PointerBarrier *barrier)
 {
@@ -283,9 +333,11 @@ barrier_find_nearest(BarrierScreenPtr cs, DeviceIntPtr dev,
 
     xorg_list_for_each_entry(c, &cs->barriers, entry) {
         struct PointerBarrier *b = &c->barrier;
+        struct PointerBarrierDevice *pbd;
         double distance;
 
-        if (c->seen)
+        pbd = GetBarrierDevice(c, dev->id);
+        if (pbd->seen)
             continue;
 
         if (!barrier_is_blocking_direction(b, dir))
@@ -358,6 +410,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         .root = screen->root->drawable.id,
     };
     InternalEvent *barrier_events = events;
+    DeviceIntPtr master;
 
     if (nevents)
         *nevents = 0;
@@ -365,6 +418,13 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
     if (xorg_list_is_empty(&cs->barriers) || IsFloating(dev))
         goto out;
 
+    /**
+     * This function is only called for slave devices, but pointer-barriers
+     * are for master-devices only. Flip the device to the master here,
+     * continue with that.
+     */
+    master = GetMaster(dev, MASTER_POINTER);
+
     /* How this works:
      * Given the origin and the movement vector, get the nearest barrier
      * to the origin that is blocking the movement.
@@ -375,16 +435,19 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
     dir = barrier_get_direction(current_x, current_y, x, y);
 
     while (dir != 0) {
-        c = barrier_find_nearest(cs, dev, dir, current_x, current_y, x, y);
+        struct PointerBarrierDevice *pbd;
+
+        c = barrier_find_nearest(cs, master, dir, current_x, current_y, x, y);
         if (!c)
             break;
 
         nearest = &c->barrier;
 
-        c->seen = TRUE;
-        c->hit = TRUE;
+        pbd = GetBarrierDevice(c, master->id);
+        pbd->seen = TRUE;
+        pbd->hit = TRUE;
 
-        if (c->barrier_event_id == c->release_event_id)
+        if (pbd->barrier_event_id == pbd->release_event_id)
             continue;
 
         ev.type = ET_BarrierHit;
@@ -400,12 +463,12 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         }
 
         ev.flags = 0;
-        ev.event_id = c->barrier_event_id;
+        ev.event_id = pbd->barrier_event_id;
         ev.barrierid = c->id;
 
-        ev.dt = ms - c->last_timestamp;
+        ev.dt = ms - pbd->last_timestamp;
         ev.window = c->window->drawable.id;
-        c->last_timestamp = ms;
+        pbd->last_timestamp = ms;
 
         /* root x/y is filled in later */
 
@@ -415,28 +478,31 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
     }
 
     xorg_list_for_each_entry(c, &cs->barriers, entry) {
+        struct PointerBarrierDevice *pbd;
         int flags = 0;
-        c->seen = FALSE;
-        if (!c->hit)
+
+        pbd = GetBarrierDevice(c, master->id);
+        pbd->seen = FALSE;
+        if (!pbd->hit)
             continue;
 
         if (barrier_inside_hit_box(&c->barrier, x, y))
             continue;
 
-        c->hit = FALSE;
+        pbd->hit = FALSE;
 
         ev.type = ET_BarrierLeave;
 
-        if (c->barrier_event_id == c->release_event_id)
+        if (pbd->barrier_event_id == pbd->release_event_id)
             flags |= XIBarrierPointerReleased;
 
         ev.flags = flags;
-        ev.event_id = c->barrier_event_id;
+        ev.event_id = pbd->barrier_event_id;
         ev.barrierid = c->id;
 
-        ev.dt = ms - c->last_timestamp;
+        ev.dt = ms - pbd->last_timestamp;
         ev.window = c->window->drawable.id;
-        c->last_timestamp = ms;
+        pbd->last_timestamp = ms;
 
         /* root x/y is filled in later */
 
@@ -446,7 +512,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
 
         /* If we've left the hit box, this is the
          * start of a new event ID. */
-        c->barrier_event_id++;
+        pbd->barrier_event_id++;
     }
 
  out:
@@ -479,6 +545,7 @@ CreatePointerBarrierClient(ClientPtr client,
     int i;
     struct PointerBarrierClient *ret;
     CARD16 *in_devices;
+    DeviceIntPtr dev;
 
     size = sizeof(*ret) + sizeof(DeviceIntPtr) * stuff->num_devices;
     ret = malloc(size);
@@ -487,6 +554,8 @@ CreatePointerBarrierClient(ClientPtr client,
         return BadAlloc;
     }
 
+    xorg_list_init(&ret->per_device);
+
     err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
     if (err != Success) {
         client->errorValue = stuff->window;
@@ -524,11 +593,25 @@ CreatePointerBarrierClient(ClientPtr client,
         ret->device_ids[i] = device_id;
     }
 
+    /* Alloc one per master pointer, they're the ones that can be blocked */
+    xorg_list_init(&ret->per_device);
+    nt_list_for_each_entry(dev, inputInfo.devices, next) {
+        struct PointerBarrierDevice *pbd;
+
+        if (dev->type != MASTER_POINTER)
+            continue;
+
+        pbd = AllocBarrierDevice();
+        if (!pbd) {
+            err = BadAlloc;
+            goto error;
+        }
+        pbd->deviceid = dev->id;
+
+        xorg_list_add(&pbd->entry, &ret->per_device);
+    }
+
     ret->id = stuff->barrier;
-    ret->barrier_event_id = 1;
-    ret->release_event_id = 0;
-    ret->hit = FALSE;
-    ret->seen = FALSE;
     ret->barrier.x1 = stuff->x1;
     ret->barrier.x2 = stuff->x2;
     ret->barrier.y1 = stuff->y1;
@@ -547,7 +630,7 @@ CreatePointerBarrierClient(ClientPtr client,
 
  error:
     *client_out = NULL;
-    free(ret);
+    FreePointerBarrierClient(ret);
     return err;
 }
 
@@ -556,13 +639,15 @@ BarrierFreeBarrier(void *data, XID id)
 {
     struct PointerBarrierClient *c;
     Time ms = GetTimeInMillis();
+    DeviceIntPtr dev = NULL;
+    ScreenPtr screen;
 
     c = container_of(data, struct PointerBarrierClient, barrier);
+    screen = c->screen;
 
-    /* FIXME: this is really broken for multidevice */
-    if (c->hit) {
-        DeviceIntPtr dev = NULL;
-        ScreenPtr screen = c->screen;
+    for (dev = inputInfo.devices; dev; dev = dev->next) {
+        struct PointerBarrierDevice *pbd;
+        int root_x, root_y;
         BarrierEvent ev = {
             .header = ET_Internal,
             .type = ET_BarrierLeave,
@@ -577,36 +662,79 @@ BarrierFreeBarrier(void *data, XID id)
             .dy = 0,
             /* .root_x */
             /* .root_y */
-            .dt = ms - c->last_timestamp,
-            .event_id = c->barrier_event_id,
+            /* .dt */
+            /* .event_id */
             .flags = XIBarrierPointerReleased,
         };
 
-        for (dev = inputInfo.devices; dev; dev = dev->next) {
-            int root_x, root_y;
 
-            if (dev->type != MASTER_POINTER)
-                continue;
+        if (dev->type != MASTER_POINTER)
+            continue;
 
-            if (!barrier_blocks_device(c, dev))
-                continue;
+        pbd = GetBarrierDevice(c, dev->id);
+        if (!pbd->hit)
+            continue;
 
-            ev.deviceid = dev->id;
+        ev.deviceid = dev->id;
+        ev.event_id = pbd->barrier_event_id,
+        ev.dt = ms - pbd->last_timestamp,
 
-            GetSpritePosition(dev, &root_x, &root_y);
-            ev.root_x = root_x;
-            ev.root_y = root_y;
+        GetSpritePosition(dev, &root_x, &root_y);
+        ev.root_x = root_x;
+        ev.root_y = root_y;
 
-            mieqEnqueue(dev, (InternalEvent *) &ev);
-        }
+        mieqEnqueue(dev, (InternalEvent *) &ev);
     }
 
     xorg_list_del(&c->entry);
 
-    free(c);
+    FreePointerBarrierClient(c);
     return Success;
 }
 
+static void add_master_func(pointer res, XID id, pointer devid)
+{
+    struct PointerBarrier *b;
+    struct PointerBarrierClient *barrier;
+    struct PointerBarrierDevice *pbd;
+    int *deviceid = devid;
+
+    b = res;
+    barrier = container_of(b, struct PointerBarrierClient, barrier);
+
+
+    pbd = AllocBarrierDevice();
+    pbd->deviceid = *deviceid;
+
+    xorg_list_add(&pbd->entry, &barrier->per_device);
+}
+
+static void remove_master_func(pointer res, XID id, pointer devid)
+{
+    struct PointerBarrierDevice *pbd;
+    struct PointerBarrierClient *barrier;
+    struct PointerBarrier *b;
+    int *deviceid = devid;
+
+    b = res;
+    barrier = container_of(b, struct PointerBarrierClient, barrier);
+
+    pbd = GetBarrierDevice(barrier, *deviceid);
+    xorg_list_del(&pbd->entry);
+    free(pbd);
+}
+
+void XIBarrierNewMasterDevice(ClientPtr client, int deviceid)
+{
+    FindClientResourcesByType(client, PointerBarrierType, add_master_func, &deviceid);
+}
+
+void XIBarrierRemoveMasterDevice(ClientPtr client, int deviceid)
+{
+    /* FIXME: send LeaveNotify */
+    FindClientResourcesByType(client, PointerBarrierType, remove_master_func, &deviceid);
+}
+
 int
 XICreatePointerBarrier(ClientPtr client,
                        xXFixesCreatePointerBarrierReq * stuff)
@@ -698,14 +826,19 @@ ProcXIBarrierReleasePointer(ClientPtr client)
 
     info = (xXIBarrierReleasePointerInfo*) &stuff[1];
     for (i = 0; i < stuff->num_barriers; i++, info++) {
+        struct PointerBarrierDevice *pbd;
+        DeviceIntPtr dev;
         CARD32 barrier_id, event_id;
         _X_UNUSED CARD32 device_id;
 
         barrier_id = info->barrier;
         event_id = info->eventid;
 
-        /* FIXME: per-device releases */
-        device_id = info->deviceid;
+        err = dixLookupDevice(&dev, info->deviceid, client, DixReadAccess);
+        if (err != Success) {
+            client->errorValue = BadDevice;
+            return err;
+        }
 
         err = dixLookupResourceByType((void **) &b, barrier_id,
                                       PointerBarrierType, client, DixReadAccess);
@@ -717,9 +850,13 @@ ProcXIBarrierReleasePointer(ClientPtr client)
         if (CLIENT_ID(barrier_id) != client->index)
             return BadAccess;
 
+
         barrier = container_of(b, struct PointerBarrierClient, barrier);
-        if (barrier->barrier_event_id == event_id)
-            barrier->release_event_id = event_id;
+
+        pbd = GetBarrierDevice(barrier, dev->id);
+
+        if (pbd->barrier_event_id == event_id)
+            pbd->release_event_id = event_id;
     }
 
     return Success;
diff --git a/Xi/xibarriers.h b/Xi/xibarriers.h
index bdcb0b2..11e84ec 100644
--- a/Xi/xibarriers.h
+++ b/Xi/xibarriers.h
@@ -42,4 +42,7 @@ XIBarrierInit(void);
 int SProcXIBarrierReleasePointer(ClientPtr client);
 int ProcXIBarrierReleasePointer(ClientPtr client);
 
+void XIBarrierNewMasterDevice(ClientPtr client, int deviceid);
+void XIBarrierRemoveMasterDevice(ClientPtr client, int deviceid);
+
 #endif /* _XIBARRIERS_H_ */
diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
index 89f16d8..a2cb832 100644
--- a/Xi/xichangehierarchy.c
+++ b/Xi/xichangehierarchy.c
@@ -52,6 +52,7 @@
 #include "xkbsrv.h"
 
 #include "xichangehierarchy.h"
+#include "xibarriers.h"
 
 /**
  * Send the current state of the device hierarchy to all clients.
@@ -189,6 +190,8 @@ add_master(ClientPtr client, xXIAddMasterInfo * c, int flags[MAXDEVICES])
     flags[XTestptr->id] |= XISlaveAttached;
     flags[XTestkeybd->id] |= XISlaveAttached;
 
+    XIBarrierNewMasterDevice(client, ptr->id);
+
  unwind:
     free(name);
     return rc;
@@ -293,6 +296,8 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES])
         }
     }
 
+    XIBarrierRemoveMasterDevice(client, ptr->id);
+
     /* disable the remove the devices, XTest devices must be done first
        else the sprites they rely on will be destroyed  */
     DisableDevice(XTestptr, FALSE);
@@ -313,6 +318,7 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES])
     flags[keybd->id] |= XIMasterRemoved;
     flags[ptr->id] |= XIMasterRemoved;
 
+
  unwind:
     return rc;
 }
commit 58bff17e43a80eb21b3ff6d4bb1596230e61f707
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 13 11:49:54 2012 +1000

    Xi: don't use devices after removing them
    
    RemoveDevice() frees the DeviceIntPtr, we shouldn't use the pointer after
    that
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
index 89f16d8..4dc3d76 100644
--- a/Xi/xichangehierarchy.c
+++ b/Xi/xichangehierarchy.c
@@ -304,15 +304,16 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES])
     flags[keybd->id] |= XIDeviceDisabled;
     flags[ptr->id] |= XIDeviceDisabled;
 
-    RemoveDevice(XTestptr, FALSE);
-    RemoveDevice(XTestkeybd, FALSE);
-    RemoveDevice(keybd, FALSE);
-    RemoveDevice(ptr, FALSE);
     flags[XTestptr->id] |= XISlaveRemoved;
     flags[XTestkeybd->id] |= XISlaveRemoved;
     flags[keybd->id] |= XIMasterRemoved;
     flags[ptr->id] |= XIMasterRemoved;
 
+    RemoveDevice(XTestptr, FALSE);
+    RemoveDevice(XTestkeybd, FALSE);
+    RemoveDevice(keybd, FALSE);
+    RemoveDevice(ptr, FALSE);
+
  unwind:
     return rc;
 }
commit cc10ac8f0e07854647e1fd7cc70b7e9f8d919fd1
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Dec 10 11:00:46 2012 +1000

    Xi: fix swapping for barrier events
    
    Protocol events don't contain pointers, so it's easier to copy everything
    over, then swap in-place.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index 606d61c..73b084c 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -845,30 +845,27 @@ STouchOwnershipEvent(xXITouchOwnershipEvent * from, xXITouchOwnershipEvent * to)
 static void
 SBarrierEvent(xXIBarrierEvent * from,
               xXIBarrierEvent * to) {
-    to->type = from->type;
-
-    cpswaps(from->sequenceNumber, to->sequenceNumber);
-    cpswapl(from->length, to->length);
-    cpswaps(from->evtype, to->evtype);
-    cpswapl(from->time, to->time);
-    cpswaps(from->deviceid, to->deviceid);
-    cpswaps(from->sourceid, to->sourceid);
-    cpswapl(from->event, to->event);
-    cpswapl(from->root, to->root);
-    cpswapl(from->root_x, to->root_x);
-    cpswapl(from->root_y, to->root_y);
-
-#define SWAP_FP3232(x, y)                       \
-    do {                                        \
-        cpswapl((x).integral, (y).integral);    \
-        cpswapl((x).frac, (y).frac);            \
-    } while(0)
-
-    SWAP_FP3232(from->dx, to->dx);
-    SWAP_FP3232(from->dy, to->dy);
-    cpswapl(from->dtime, to->dtime);
-    cpswapl(from->barrier, to->barrier);
-    cpswapl(from->eventid, to->eventid);
+
+    *to = *from;
+
+    swaps(&from->sequenceNumber);
+    swapl(&from->length);
+    swaps(&from->evtype);
+    swapl(&from->time);
+    swaps(&from->deviceid);
+    swaps(&from->sourceid);
+    swapl(&from->event);
+    swapl(&from->root);
+    swapl(&from->root_x);
+    swapl(&from->root_y);
+
+    swapl(&from->dx.integral);
+    swapl(&from->dx.frac);
+    swapl(&from->dy.integral);
+    swapl(&from->dy.frac);
+    swapl(&from->dtime);
+    swapl(&from->barrier);
+    swapl(&from->eventid);
 }
 
 /** Event swapping function for XI2 events. */
commit 151d44149a09dd125e25b3d94f22a609f0221548
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Dec 10 10:53:49 2012 +1000

    Xi: swap sequence number and evtype in barrier events
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index 175d89b..606d61c 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -847,7 +847,9 @@ SBarrierEvent(xXIBarrierEvent * from,
               xXIBarrierEvent * to) {
     to->type = from->type;
 
+    cpswaps(from->sequenceNumber, to->sequenceNumber);
     cpswapl(from->length, to->length);
+    cpswaps(from->evtype, to->evtype);
     cpswapl(from->time, to->time);
     cpswaps(from->deviceid, to->deviceid);
     cpswaps(from->sourceid, to->sourceid);
commit d4065493b211e90b46f9d4178f23f347afd8043f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Dec 10 11:02:32 2012 +1000

    tests/xi2: at protocol conversion test for barrier events
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/test/xi2/protocol-eventconvert.c b/test/xi2/protocol-eventconvert.c
index bb3177c..3957747 100644
--- a/test/xi2/protocol-eventconvert.c
+++ b/test/xi2/protocol-eventconvert.c
@@ -984,6 +984,221 @@ test_convert_XITouchOwnershipEvent(void)
     }
 }
 
+static void
+test_XIBarrierEvent(BarrierEvent *in)
+{
+    xXIBarrierEvent *out, *swapped;
+    int count;
+    int rc;
+    int eventlen;
+    FP3232 value;
+
+    rc = EventToXI((InternalEvent*)in, (xEvent**)&out, &count);
+    assert(rc == BadMatch);
+
+    rc = EventToCore((InternalEvent*)in, (xEvent**)&out, &count);
+    assert(rc == BadMatch);
+
+    rc = EventToXI2((InternalEvent*)in, (xEvent**)&out);
+
+    assert(out->type == GenericEvent);
+    assert(out->extension == 0); /* IReqCode defaults to 0 */
+    assert(out->evtype == GetXI2Type(in->type));
+    assert(out->time == in->time);
+    assert(out->deviceid == in->deviceid);
+    assert(out->sourceid == in->sourceid);
+    assert(out->barrier == in->barrierid);
+    assert(out->flags == in->flags);
+    assert(out->event == in->window);
+    assert(out->root == in->root);
+    assert(out->dtime == in->dt);
+    assert(out->eventid == in->event_id);
+    assert(out->root_x == double_to_fp1616(in->root_x));
+    assert(out->root_y == double_to_fp1616(in->root_y));
+
+    value = double_to_fp3232(in->dx);
+    assert(out->dx.integral == value.integral);
+    assert(out->dx.frac == value.frac);
+    value = double_to_fp3232(in->dy);
+    assert(out->dy.integral == value.integral);
+    assert(out->dy.frac == value.frac);
+
+    eventlen = sizeof(xEvent) + out->length * 4;
+    swapped = calloc(1, eventlen);
+    XI2EventSwap((xGenericEvent *) out, (xGenericEvent *) swapped);
+
+    swaps(&swapped->sequenceNumber);
+    swapl(&swapped->length);
+    swaps(&swapped->evtype);
+    swaps(&swapped->deviceid);
+    swapl(&swapped->time);
+    swapl(&swapped->eventid);
+    swapl(&swapped->root);
+    swapl(&swapped->event);
+    swapl(&swapped->barrier);
+    swapl(&swapped->dtime);
+    swaps(&swapped->sourceid);
+    swapl(&swapped->root_x);
+    swapl(&swapped->root_y);
+    swapl(&swapped->dx.integral);
+    swapl(&swapped->dx.frac);
+    swapl(&swapped->dy.integral);
+    swapl(&swapped->dy.frac);
+
+    assert(memcmp(swapped, out, eventlen) == 0);
+
+    free(swapped);
+    free(out);
+}
+
+static void
+test_convert_XIBarrierEvent(void)
+{
+    BarrierEvent in;
+
+    memset(&in, 0, sizeof(in));
+    in.header = ET_Internal;
+    in.type = ET_BarrierHit;
+    in.length = sizeof(in);
+    in.time = 0;
+    in.deviceid = 1;
+    in.sourceid = 2;
+
+    test_XIBarrierEvent(&in);
+
+    in.deviceid = 1;
+    while(in.deviceid & 0xFFFF) {
+        test_XIBarrierEvent(&in);
+        in.deviceid <<= 1;
+    }
+    in.deviceid = 0;
+
+    in.sourceid = 1;
+    while(in.sourceid & 0xFFFF) {
+        test_XIBarrierEvent(&in);
+        in.sourceid <<= 1;
+    }
+    in.sourceid = 0;
+
+    in.flags = 1;
+    while(in.flags) {
+        test_XIBarrierEvent(&in);
+        in.flags <<= 1;
+    }
+
+    in.barrierid = 1;
+    while(in.barrierid) {
+        test_XIBarrierEvent(&in);
+        in.barrierid <<= 1;
+    }
+
+    in.dt = 1;
+    while(in.dt) {
+        test_XIBarrierEvent(&in);
+        in.dt <<= 1;
+    }
+
+    in.event_id = 1;
+    while(in.event_id) {
+        test_XIBarrierEvent(&in);
+        in.event_id <<= 1;
+    }
+
+    in.window = 1;
+    while(in.window) {
+        test_XIBarrierEvent(&in);
+        in.window <<= 1;
+    }
+
+    in.root = 1;
+    while(in.root) {
+        test_XIBarrierEvent(&in);
+        in.root <<= 1;
+    }
+
+    /* pseudo-random 16 bit numbers */
+    in.root_x = 1;
+    test_XIBarrierEvent(&in);
+    in.root_x = 1.3;
+    test_XIBarrierEvent(&in);
+    in.root_x = 264.908;
+    test_XIBarrierEvent(&in);
+    in.root_x = 35638.292;
+    test_XIBarrierEvent(&in);
+
+    in.root_x = -1;
+    test_XIBarrierEvent(&in);
+    in.root_x = -1.3;
+    test_XIBarrierEvent(&in);
+    in.root_x = -264.908;
+    test_XIBarrierEvent(&in);
+    in.root_x = -35638.292;
+    test_XIBarrierEvent(&in);
+
+    in.root_y = 1;
+    test_XIBarrierEvent(&in);
+    in.root_y = 1.3;
+    test_XIBarrierEvent(&in);
+    in.root_y = 264.908;
+    test_XIBarrierEvent(&in);
+    in.root_y = 35638.292;
+    test_XIBarrierEvent(&in);
+
+    in.root_y = -1;
+    test_XIBarrierEvent(&in);
+    in.root_y = -1.3;
+    test_XIBarrierEvent(&in);
+    in.root_y = -264.908;
+    test_XIBarrierEvent(&in);
+    in.root_y = -35638.292;
+    test_XIBarrierEvent(&in);
+
+    /* equally pseudo-random 32 bit numbers */
+    in.dx = 1;
+    test_XIBarrierEvent(&in);
+    in.dx = 1.3;
+    test_XIBarrierEvent(&in);
+    in.dx = 264.908;
+    test_XIBarrierEvent(&in);
+    in.dx = 35638.292;
+    test_XIBarrierEvent(&in);
+    in.dx = 2947813871.2342;
+    test_XIBarrierEvent(&in);
+
+    in.dx = -1;
+    test_XIBarrierEvent(&in);
+    in.dx = -1.3;
+    test_XIBarrierEvent(&in);
+    in.dx = -264.908;
+    test_XIBarrierEvent(&in);
+    in.dx = -35638.292;
+    test_XIBarrierEvent(&in);
+    in.dx = -2947813871.2342;
+    test_XIBarrierEvent(&in);
+
+    in.dy = 1;
+    test_XIBarrierEvent(&in);
+    in.dy = 1.3;
+    test_XIBarrierEvent(&in);
+    in.dy = 264.908;
+    test_XIBarrierEvent(&in);
+    in.dy = 35638.292;
+    test_XIBarrierEvent(&in);
+    in.dy = 2947813871.2342;
+    test_XIBarrierEvent(&in);
+
+    in.dy = -1;
+    test_XIBarrierEvent(&in);
+    in.dy = -1.3;
+    test_XIBarrierEvent(&in);
+    in.dy = -264.908;
+    test_XIBarrierEvent(&in);
+    in.dy = -35638.292;
+    test_XIBarrierEvent(&in);
+    in.dy = -2947813871.2342;
+    test_XIBarrierEvent(&in);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -992,6 +1207,7 @@ main(int argc, char **argv)
     test_convert_XIDeviceEvent();
     test_convert_XIDeviceChangedEvent();
     test_convert_XITouchOwnershipEvent();
+    test_convert_XIBarrierEvent();
 
     return 0;
 }
commit 938187f2fec006daf4cc677df26d5b0b6999b54b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Dec 7 15:55:59 2012 +1000

    Require inputproto 2.2.99.1
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/configure.ac b/configure.ac
index 38ac240..ee0fa78 100644
--- a/configure.ac
+++ b/configure.ac
@@ -788,7 +788,7 @@ XPROTO="xproto >= 7.0.22"
 RANDRPROTO="randrproto >= 1.4.0"
 RENDERPROTO="renderproto >= 0.11"
 XEXTPROTO="xextproto >= 7.1.99"
-INPUTPROTO="inputproto >= 2.1.99.6"
+INPUTPROTO="inputproto >= 2.2.99.1"
 KBPROTO="kbproto >= 1.0.3"
 FONTSPROTO="fontsproto"
 FIXESPROTO="fixesproto >= 5.0"
commit 78376a9217058aa66e52a0399fc2be469d70ce32
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Dec 7 09:26:13 2012 +1000

    mi: rename mipointer's internal event list
    
    Avoid name shadowing warnings, change the event list to a more specific
    name.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/mi/mipointer.c b/mi/mipointer.c
index 7bc0983..b8503f4 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -98,7 +98,7 @@ static void miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen);
 static void miPointerMoveNoEvent(DeviceIntPtr pDev, ScreenPtr pScreen, int x,
                                  int y);
 
-static InternalEvent *events;   /* for WarpPointer MotionNotifies */
+static InternalEvent *mipointermove_events;   /* for WarpPointer MotionNotifies */
 
 Bool
 miPointerInitialize(ScreenPtr pScreen,
@@ -143,7 +143,7 @@ miPointerInitialize(ScreenPtr pScreen,
     pScreen->DeviceCursorInitialize = miPointerDeviceInitialize;
     pScreen->DeviceCursorCleanup = miPointerDeviceCleanup;
 
-    events = NULL;
+    mipointermove_events = NULL;
     return TRUE;
 }
 
@@ -160,8 +160,8 @@ miPointerCloseScreen(ScreenPtr pScreen)
 
     pScreen->CloseScreen = pScreenPriv->CloseScreen;
     free((pointer) pScreenPriv);
-    FreeEventList(events, GetMaximumEventsNum());
-    events = NULL;
+    FreeEventList(mipointermove_events, GetMaximumEventsNum());
+    mipointermove_events = NULL;
     return (*pScreen->CloseScreen) (pScreen);
 }
 
@@ -710,17 +710,17 @@ miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
     valuators[0] = x;
     valuators[1] = y;
 
-    if (!events) {
-        events = InitEventList(GetMaximumEventsNum());
+    if (!mipointermove_events) {
+        mipointermove_events = InitEventList(GetMaximumEventsNum());
 
-        if (!events) {
+        if (!mipointermove_events) {
             FatalError("Could not allocate event store.\n");
             return;
         }
     }
 
     valuator_mask_set_range(&mask, 0, 2, valuators);
-    nevents = GetPointerEvents(events, pDev, MotionNotify, 0,
+    nevents = GetPointerEvents(mipointermove_events, pDev, MotionNotify, 0,
                                POINTER_SCREEN | POINTER_ABSOLUTE |
                                POINTER_NORAW, &mask);
 
@@ -729,7 +729,7 @@ miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
     darwinEvents_lock();
 #endif
     for (i = 0; i < nevents; i++)
-        mieqEnqueue(pDev, &events[i]);
+        mieqEnqueue(pDev, &mipointermove_events[i]);
 #ifdef XQUARTZ
     darwinEvents_unlock();
 #endif
commit 88a2cccc37cac4e171f9bfc020017ddfa66ae417
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Dec 7 09:11:13 2012 +1000

    Xi: if the device is currently grabbed, flag the barrier event
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index a7ec0c4..f025dd1 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1655,6 +1655,9 @@ ProcessBarrierEvent(InternalEvent *e, DeviceIntPtr dev)
     if (dixLookupWindow(&pWin, be->window, serverClient, DixReadAccess) != Success)
         return;
 
+    if (grab)
+        be->flags |= XIBarrierDeviceIsGrabbed;
+
     rc = EventToXI2(e, &ev);
     if (rc != Success) {
         ErrorF("[Xi] event conversion from %s failed with code %d\n", __func__, rc);
commit 353aa515922e1095047161ec47a2722772218f20
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 6 15:09:27 2012 +1000

    Xi: deliver barrier events as grabbed events where necessary
    
    If the grab_window is the barrier window and the client owns the grab,
    deliver as normal grabbed event (respecting owner_events). Otherwise,
    deliver as usual.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index e606d9e..a7ec0c4 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1647,6 +1647,7 @@ ProcessBarrierEvent(InternalEvent *e, DeviceIntPtr dev)
     BarrierEvent *be = &e->barrier_event;
     xEvent *ev;
     int rc;
+    GrabPtr grab = dev->deviceGrab.grab;
 
     if (!IsMaster(dev))
         return;
@@ -1660,10 +1661,21 @@ ProcessBarrierEvent(InternalEvent *e, DeviceIntPtr dev)
         return;
     }
 
-    filter = GetEventFilter(dev, ev);
+    /* A client has a grab, deliver to this client if the grab_window is the
+       barrier window.
+
+       Otherwise, deliver normally to the client.
+     */
+    if (grab &&
+        CLIENT_ID(be->barrierid) == CLIENT_ID(grab->resource) &&
+        grab->window->drawable.id == be->window) {
+        DeliverGrabbedEvent(e, dev, FALSE);
+    } else {
+        filter = GetEventFilter(dev, ev);
 
-    DeliverEventsToWindow(dev, pWin, ev, 1,
-                          filter, NullGrab);
+        DeliverEventsToWindow(dev, pWin, ev, 1,
+                              filter, NullGrab);
+    }
     free(ev);
 }
 
commit 3b161401700a2d916da0f81f99b39e75fdbe78df
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 6 14:13:26 2012 +1000

    dix: ignore barrier events in FixUpEventFromWindow
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/dix/events.c b/dix/events.c
index 49b8bc5..c98a2de 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2436,6 +2436,8 @@ FixUpEventFromWindow(SpritePtr pSprite,
         case XI_DeviceChanged:
         case XI_HierarchyChanged:
         case XI_PropertyEvent:
+        case XI_BarrierHit:
+        case XI_BarrierLeave:
             return;
         default:
             break;
commit a1eeb6fbecf0bd9665a9158b27c273e83b3ab351
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 6 13:25:29 2012 +1000

    dix: handle barrier events properly when converting to core/XI 1.x
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index bb5c8d3..47dcf8b 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -161,6 +161,8 @@ EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
     case ET_TouchUpdate:
     case ET_TouchEnd:
     case ET_TouchOwnership:
+    case ET_BarrierHit:
+    case ET_BarrierLeave:
         ret = BadMatch;
         break;
     default:
@@ -217,6 +219,8 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count)
     case ET_TouchUpdate:
     case ET_TouchEnd:
     case ET_TouchOwnership:
+    case ET_BarrierHit:
+    case ET_BarrierLeave:
         *count = 0;
         *xi = NULL;
         return BadMatch;
commit 1b83775f6712a7e48c49a3411a87103e8e906e67
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 6 12:39:04 2012 +1000

    dix: skip delivery if it's not the right pointer barrier client
    
    Only deliver to the client that created the barrier, not to other clients.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/dix/events.c b/dix/events.c
index 3282ef8..49b8bc5 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -219,6 +219,9 @@ static void CheckVirtualMotion(DeviceIntPtr pDev, QdEventPtr qe,
 static void CheckPhysLimits(DeviceIntPtr pDev, CursorPtr cursor,
                             Bool generateEvents, Bool confineToScreen,
                             ScreenPtr pScreen);
+static Bool IsWrongPointerBarrierClient(ClientPtr client,
+                                        DeviceIntPtr dev,
+                                        xEvent *event);
 
 /** Key repeat hack. Do not use but in TryClientEvents */
 extern BOOL EventIsKeyRepeat(xEvent *event);
@@ -2076,6 +2079,9 @@ DeliverEventToInputClients(DeviceIntPtr dev, InputClients * inputclients,
         if (IsInterferingGrab(client, dev, events))
             continue;
 
+        if (IsWrongPointerBarrierClient(client, dev, events))
+            continue;
+
         mask = GetEventMask(dev, events, inputclients);
 
         if (XaceHook(XACE_RECEIVE_ACCESS, client, win, events, count))
@@ -6064,3 +6070,19 @@ IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent *event)
 
     return FALSE;
 }
+
+/* PointerBarrier events are only delivered to the client that created that
+ * barrier */
+static Bool
+IsWrongPointerBarrierClient(ClientPtr client, DeviceIntPtr dev, xEvent *event)
+{
+    xXIBarrierEvent *ev = (xXIBarrierEvent*)event;
+
+    if (ev->type != GenericEvent || ev->extension != IReqCode)
+        return FALSE;
+
+    if (ev->evtype != XI_BarrierHit && ev->evtype != XI_BarrierLeave)
+        return FALSE;
+
+    return client->index != CLIENT_ID(ev->barrier);
+}
commit c50db6faba4ee1c27b735c6e9c98a4276ba3c7ff
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 6 12:58:55 2012 +1000

    Xi: fill in barrier root x/y after clamping to RandR outputs
    
    x/y for barrier events should contain the actual pointer position.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 104280c..048af62 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -407,6 +407,8 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         ev.window = c->window->drawable.id;
         c->last_timestamp = ms;
 
+        /* root x/y is filled in later */
+
         barrier_events->barrier_event = ev;
         barrier_events++;
         *nevents += 1;
@@ -436,6 +438,8 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         ev.window = c->window->drawable.id;
         c->last_timestamp = ms;
 
+        /* root x/y is filled in later */
+
         barrier_events->barrier_event = ev;
         barrier_events++;
         *nevents += 1;
diff --git a/mi/mipointer.c b/mi/mipointer.c
index f4fbd29..7bc0983 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -573,6 +573,8 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx,
     ScreenPtr newScreen;
     int x, y;
     Bool switch_screen = FALSE;
+    Bool should_constrain_barriers = FALSE;
+    int i;
 
     miPointerPtr pPointer;
 
@@ -589,7 +591,9 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx,
     x -= pScreen->x;
     y -= pScreen->y;
 
-    if (mode == Relative) {
+    should_constrain_barriers = (mode == Relative);
+
+    if (should_constrain_barriers) {
         /* coordinates after clamped to a barrier */
         int constrained_x, constrained_y;
         int current_x, current_y; /* current position in per-screen coord */
@@ -637,6 +641,18 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx,
     if (pPointer->x != x || pPointer->y != y || pPointer->pScreen != pScreen)
         miPointerMoveNoEvent(pDev, pScreen, x, y);
 
+    /* check if we generated any barrier events and if so, update root x/y
+     * to the fully constrained coords */
+    if (should_constrain_barriers) {
+        for (i = 0; i < *nevents; i++) {
+            if (events[i].any.type == ET_BarrierHit ||
+                events[i].any.type == ET_BarrierLeave) {
+                events[i].barrier_event.root_x = x;
+                events[i].barrier_event.root_y = y;
+            }
+        }
+    }
+
     /* Convert to desktop coordinates again */
     x += pScreen->x;
     y += pScreen->y;
commit 21a15f9a04ec0a6c8f654eef943561e98db2475d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Dec 3 10:41:16 2012 +1000

    Pass the event list through to the pointer barrier code to return it
    
    Instead of having the pointer barrier code enqueue events separately from
    GetPointerEvents, pass the event list through and let it add to it.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 27b21ee..104280c 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -335,7 +335,8 @@ void
 input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
                        int current_x, int current_y,
                        int dest_x, int dest_y,
-                       int *out_x, int *out_y)
+                       int *out_x, int *out_y,
+                       int *nevents, InternalEvent* events)
 {
     /* Clamped coordinates here refer to screen edge clamping. */
     BarrierScreenPtr cs = GetBarrierScreen(screen);
@@ -356,6 +357,10 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         .dy = dest_y - current_y,
         .root = screen->root->drawable.id,
     };
+    InternalEvent *barrier_events = events;
+
+    if (nevents)
+        *nevents = 0;
 
     if (xorg_list_is_empty(&cs->barriers) || IsFloating(dev))
         goto out;
@@ -402,7 +407,9 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         ev.window = c->window->drawable.id;
         c->last_timestamp = ms;
 
-        mieqEnqueue(dev, (InternalEvent *) &ev);
+        barrier_events->barrier_event = ev;
+        barrier_events++;
+        *nevents += 1;
     }
 
     xorg_list_for_each_entry(c, &cs->barriers, entry) {
@@ -429,7 +436,9 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         ev.window = c->window->drawable.id;
         c->last_timestamp = ms;
 
-        mieqEnqueue(dev, (InternalEvent *) &ev);
+        barrier_events->barrier_event = ev;
+        barrier_events++;
+        *nevents += 1;
 
         /* If we've left the hit box, this is the
          * start of a new event ID. */
diff --git a/dix/getevents.c b/dix/getevents.c
index fa538d9..3d41e1e 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -916,10 +916,13 @@ scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask,
  * @param[in,out] devy y desktop-wide coordinate in device coordinate system
  * @param[in,out] screenx x coordinate in desktop coordinate system
  * @param[in,out] screeny y coordinate in desktop coordinate system
+ * @param[out] nevents Number of barrier events added to events
+ * @param[in,out] events List of events barrier events are added to
  */
 static ScreenPtr
 positionSprite(DeviceIntPtr dev, int mode, ValuatorMask *mask,
-               double *devx, double *devy, double *screenx, double *screeny)
+               double *devx, double *devy, double *screenx, double *screeny,
+               int *nevents, InternalEvent* events)
 {
     ScreenPtr scr = miPointerGetScreen(dev);
     double tmpx, tmpy;
@@ -933,7 +936,7 @@ positionSprite(DeviceIntPtr dev, int mode, ValuatorMask *mask,
     /* miPointerSetPosition takes care of crossing screens for us, as well as
      * clipping to the current screen. Coordinates returned are in desktop
      * coord system */
-    scr = miPointerSetPosition(dev, mode, screenx, screeny);
+    scr = miPointerSetPosition(dev, mode, screenx, screeny, nevents, events);
 
     /* If we were constrained, rescale x/y from the screen coordinates so
      * the device valuators reflect the correct position. For screen
@@ -1319,6 +1322,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
     int sx, sy;                         /* for POINTER_SCREEN */
     ValuatorMask mask;
     ScreenPtr scr;
+    int num_barrier_events = 0;
 
     switch (type) {
     case MotionNotify:
@@ -1395,7 +1399,10 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
     }
 
     scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
-                         &mask, &devx, &devy, &screenx, &screeny);
+                         &mask, &devx, &devy, &screenx, &screeny,
+                         &num_barrier_events, events);
+    num_events += num_barrier_events;
+    events += num_barrier_events;
 
     /* screenx, screeny are in desktop coordinates,
        mask is in device coordinates per-screen (the event data)
@@ -1945,7 +1952,7 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
         scr = scale_to_desktop(dev, &mask, &devx, &devy, &screenx, &screeny);
     if (emulate_pointer)
         scr = positionSprite(dev, Absolute, &mask,
-                             &devx, &devy, &screenx, &screeny);
+                             &devx, &devy, &screenx, &screeny, NULL, NULL);
 
     /* see fill_pointer_events for coordinate systems */
     if (emulate_pointer)
diff --git a/include/input.h b/include/input.h
index a5d0462..23a20b5 100644
--- a/include/input.h
+++ b/include/input.h
@@ -681,6 +681,7 @@ extern _X_HIDDEN void update_desktop_dimensions(void);
 extern _X_HIDDEN void input_constrain_cursor(DeviceIntPtr pDev, ScreenPtr screen,
                                              int current_x, int current_y,
                                              int dest_x, int dest_y,
-                                             int *out_x, int *out_y);
+                                             int *out_x, int *out_y,
+                                             int *nevents, InternalEvent* events);
 
 #endif                          /* INPUT_H */
diff --git a/mi/mipointer.c b/mi/mipointer.c
index d170824..f4fbd29 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -565,7 +565,8 @@ miPointerMoveNoEvent(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
  */
 ScreenPtr
 miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx,
-                     double *screeny)
+                     double *screeny,
+                     int *nevents, InternalEvent* events)
 {
     miPointerScreenPtr pScreenPriv;
     ScreenPtr pScreen;
@@ -598,7 +599,8 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx,
 
         input_constrain_cursor(pDev, pScreen,
                                current_x, current_y, x, y,
-                               &constrained_x, &constrained_y);
+                               &constrained_x, &constrained_y,
+                               nevents, events);
 
         x = constrained_x;
         y = constrained_y;
diff --git a/mi/mipointer.h b/mi/mipointer.h
index 1500e21..f89dff3 100644
--- a/mi/mipointer.h
+++ b/mi/mipointer.h
@@ -115,7 +115,8 @@ miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y);
 /* Moves the cursor to the specified position.  May clip the co-ordinates:
  * x and y are modified in-place. */
 extern _X_EXPORT ScreenPtr
-miPointerSetPosition(DeviceIntPtr pDev, int mode, double *x, double *y);
+miPointerSetPosition(DeviceIntPtr pDev, int mode, double *x, double *y,
+                     int *nevents, InternalEvent *events);
 
 extern _X_EXPORT void
 miPointerUpdateSprite(DeviceIntPtr pDev);
commit 707b4dc61f18960611409ef5ad8947be189f7296
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Tue Nov 27 15:31:52 2012 -0500

    barriers: Support line and ray barriers
    
    This allows clients to add barriers that extend to the edge of the
    screen. Clients are encouraged to use these instead of precise coordinates
    in these cases to help prevent pointer leaks.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index a65d208..27b21ee 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -140,6 +140,19 @@ barrier_is_blocking_direction(const struct PointerBarrier * barrier,
     return (barrier->directions & direction) != direction;
 }
 
+static BOOL
+inside_segment(int v, int v1, int v2)
+{
+    if (v1 < 0 && v2 < 0) /* line */
+        return TRUE;
+    else if (v1 < 0)      /* ray */
+        return v <= v2;
+    else if (v2 < 0)      /* ray */
+        return v >= v1;
+    else                  /* line segment */
+        return v >= v1 && v <= v2;
+}
+
 #define T(v, a, b) (((float)v) - (a)) / ((b) - (a))
 #define F(t, a, b) ((t) * ((a) - (b)) + (a))
 
@@ -171,7 +184,7 @@ barrier_is_blocking(const struct PointerBarrier * barrier,
             return FALSE;
 
         y = F(t, y1, y2);
-        if (y < barrier->y1 || y > barrier->y2)
+        if (!inside_segment(y, barrier->y1, barrier->y2))
             return FALSE;
 
         *distance = sqrt((pow(y - y1, 2) + pow(barrier->x1 - x1, 2)));
@@ -188,7 +201,7 @@ barrier_is_blocking(const struct PointerBarrier * barrier,
             return FALSE;
 
         x = F(t, x1, x2);
-        if (x < barrier->x1 || x > barrier->x2)
+        if (!inside_segment(x, barrier->x1, barrier->x2))
             return FALSE;
 
         *distance = sqrt((pow(x - x1, 2) + pow(barrier->y1 - y1, 2)));
@@ -428,6 +441,18 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
     *out_y = y;
 }
 
+static void
+sort_min_max(INT16 *a, INT16 *b)
+{
+    INT16 A, B;
+    if (*a < 0 || *b < 0)
+        return;
+    A = *a;
+    B = *b;
+    *a = min(A, B);
+    *b = max(A, B);
+}
+
 static int
 CreatePointerBarrierClient(ClientPtr client,
                            xXFixesCreatePointerBarrierReq * stuff,
@@ -491,10 +516,12 @@ CreatePointerBarrierClient(ClientPtr client,
     ret->release_event_id = 0;
     ret->hit = FALSE;
     ret->seen = FALSE;
-    ret->barrier.x1 = min(stuff->x1, stuff->x2);
-    ret->barrier.x2 = max(stuff->x1, stuff->x2);
-    ret->barrier.y1 = min(stuff->y1, stuff->y2);
-    ret->barrier.y2 = max(stuff->y1, stuff->y2);
+    ret->barrier.x1 = stuff->x1;
+    ret->barrier.x2 = stuff->x2;
+    ret->barrier.y1 = stuff->y1;
+    ret->barrier.y2 = stuff->y2;
+    sort_min_max(&ret->barrier.x1, &ret->barrier.x2);
+    sort_min_max(&ret->barrier.y1, &ret->barrier.y2);
     ret->barrier.directions = stuff->directions & 0x0f;
     if (barrier_is_horizontal(&ret->barrier))
         ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
@@ -587,6 +614,13 @@ XICreatePointerBarrier(ClientPtr client,
     if (barrier_is_horizontal(&b) && barrier_is_vertical(&b))
         return BadValue;
 
+    /* no infinite barriers on the wrong axis */
+    if (barrier_is_horizontal(&b) && (b.y1 < 0 || b.y2 < 0))
+        return BadValue;
+
+    if (barrier_is_vertical(&b) && (b.x1 < 0 || b.x2 < 0))
+        return BadValue;
+
     if ((err = CreatePointerBarrierClient(client, stuff, &barrier)))
         return err;
 
diff --git a/Xi/xibarriers.h b/Xi/xibarriers.h
index f29bb6c..bdcb0b2 100644
--- a/Xi/xibarriers.h
+++ b/Xi/xibarriers.h
@@ -11,7 +11,7 @@
 extern _X_EXPORT RESTYPE PointerBarrierType;
 
 struct PointerBarrier {
-    CARD16 x1, x2, y1, y2;
+    INT16 x1, x2, y1, y2;
     CARD32 directions;
 };
 
diff --git a/test/fixes.c b/test/fixes.c
index 7807c73..4ac6750 100644
--- a/test/fixes.c
+++ b/test/fixes.c
@@ -265,6 +265,32 @@ fixes_pointer_barriers_test(void)
     x2 = x + 100;
     assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance));
 
+    /* ray vert barrier */
+    barrier.x1 = x;
+    barrier.x2 = x;
+    barrier.y1 = -1;
+    barrier.y2 = y + 100;
+
+    /* ray barrier simple case */
+    y1 = y;
+    y2 = y;
+    x1 = x + 50;
+    x2 = x - 50;
+    assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance));
+
+    /* endpoint outside y range; should be blocked */
+    y1 = y - 1000;
+    y2 = y - 1000;
+    x1 = x + 50;
+    x2 = x - 50;
+    assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance));
+
+    /* endpoint outside y range */
+    y1 = y + 150;
+    y2 = y + 150;
+    x1 = x + 50;
+    x2 = x - 50;
+    assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance));
 }
 
 static void
commit 0a5a0d7c242add4d79721c1b90073b603a475534
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Tue Nov 27 14:29:52 2012 -0500

    barriers: Replace complex intersection test with simpler math
    
    Since barriers are axis-aligned, we can do the intersection test with
    simple interpolation rather than line-segment intersection. This also
    helps us out in the future when we want the barriers to extend to be
    rays and lines rather than just segments.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 2e7f2cc..a65d208 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -140,6 +140,9 @@ barrier_is_blocking_direction(const struct PointerBarrier * barrier,
     return (barrier->directions & direction) != direction;
 }
 
+#define T(v, a, b) (((float)v) - (a)) / ((b) - (a))
+#define F(t, a, b) ((t) * ((a) - (b)) + (a))
+
 /**
  * Test if the movement vector x1/y1 → x2/y2 is intersecting with the
  * barrier. A movement vector with the startpoint or endpoint adjacent to
@@ -157,67 +160,40 @@ BOOL
 barrier_is_blocking(const struct PointerBarrier * barrier,
                     int x1, int y1, int x2, int y2, double *distance)
 {
-    BOOL rc = FALSE;
-    float ua, ub, ud;
-    int dir = barrier_get_direction(x1, y1, x2, y2);
-
-    /* Algorithm below doesn't handle edge cases well, hence the extra
-     * checks. */
     if (barrier_is_vertical(barrier)) {
-        /* handle immediate barrier adjacency, moving away */
-        if (dir & BarrierPositiveX && x1 == barrier->x1)
+        float t, y;
+        t = T(barrier->x1, x1, x2);
+        if (t < 0 || t > 1)
             return FALSE;
-        if (dir & BarrierNegativeX && x1 == (barrier->x1 - 1))
+
+        /* Edge case: moving away from barrier. */
+        if (x2 > x1 && t == 0)
             return FALSE;
-        /* startpoint adjacent to barrier, moving towards -> block */
-        if (dir & BarrierPositiveX && x1 == (barrier->x1 - 1) && y1 >= barrier->y1 && y1 <= barrier->y2) {
-            *distance = 0;
-            return TRUE;
-        }
-        if (dir & BarrierNegativeX && x1 == barrier->x1 && y1 >= barrier->y1 && y1 <= barrier->y2) {
-            *distance = 0;
-            return TRUE;
-        }
+
+        y = F(t, y1, y2);
+        if (y < barrier->y1 || y > barrier->y2)
+            return FALSE;
+
+        *distance = sqrt((pow(y - y1, 2) + pow(barrier->x1 - x1, 2)));
+        return TRUE;
     }
     else {
-        /* handle immediate barrier adjacency, moving away */
-        if (dir & BarrierPositiveY && y1 == barrier->y1)
+        float t, x;
+        t = T(barrier->y1, y1, y2);
+        if (t < 0 || t > 1)
             return FALSE;
-        if (dir & BarrierNegativeY && y1 == (barrier->y1 - 1))
-            return FALSE;
-        /* startpoint adjacent to barrier, moving towards -> block */
-        if (dir & BarrierPositiveY && y1 == (barrier->y1 - 1) && x1 >= barrier->x1 && x1 <= barrier->x2) {
-            *distance = 0;
-            return TRUE;
-        }
-        if (dir & BarrierNegativeY && y1 == barrier->y1 && x1 >= barrier->x1 && x1 <= barrier->x2) {
-            *distance = 0;
-            return TRUE;
-        }
-    }
 
-    /* not an edge case, compute distance */
-    ua = 0;
-    ud = (barrier->y2 - barrier->y1) * (x2 - x1) - (barrier->x2 -
-                                                    barrier->x1) * (y2 - y1);
-    if (ud != 0) {
-        ua = ((barrier->x2 - barrier->x1) * (y1 - barrier->y1) -
-              (barrier->y2 - barrier->y1) * (x1 - barrier->x1)) / ud;
-        ub = ((x2 - x1) * (y1 - barrier->y1) -
-              (y2 - y1) * (x1 - barrier->x1)) / ud;
-        if (ua < 0 || ua > 1 || ub < 0 || ub > 1)
-            ua = 0;
-    }
+        /* Edge case: moving away from barrier. */
+        if (y2 > y1 && t == 0)
+            return FALSE;
 
-    if (ua > 0 && ua <= 1) {
-        double ix = barrier->x1 + ua * (barrier->x2 - barrier->x1);
-        double iy = barrier->y1 + ua * (barrier->y2 - barrier->y1);
+        x = F(t, x1, x2);
+        if (x < barrier->x1 || x > barrier->x2)
+            return FALSE;
 
-        *distance = sqrt(pow(x1 - ix, 2) + pow(y1 - iy, 2));
-        rc = TRUE;
+        *distance = sqrt((pow(x - x1, 2) + pow(barrier->y1 - y1, 2)));
+        return TRUE;
     }
-
-    return rc;
 }
 
 #define HIT_EDGE_EXTENTS 2
commit 6401317bdcf58b2717214ac65c8f47b0c384a7db
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sun Dec 9 19:45:48 2012 -0500

    barriers: Send an XI_BarrierLeave event when a barrier is destroyed
    
    This ensures that we always complete an event sequence.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index b62a18e..2e7f2cc 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -539,8 +539,52 @@ static int
 BarrierFreeBarrier(void *data, XID id)
 {
     struct PointerBarrierClient *c;
+    Time ms = GetTimeInMillis();
 
     c = container_of(data, struct PointerBarrierClient, barrier);
+
+    /* FIXME: this is really broken for multidevice */
+    if (c->hit) {
+        DeviceIntPtr dev = NULL;
+        ScreenPtr screen = c->screen;
+        BarrierEvent ev = {
+            .header = ET_Internal,
+            .type = ET_BarrierLeave,
+            .length = sizeof (BarrierEvent),
+            .time = ms,
+            /* .deviceid */
+            .sourceid = 0,
+            .barrierid = c->id,
+            .window = c->window->drawable.id,
+            .root = screen->root->drawable.id,
+            .dx = 0,
+            .dy = 0,
+            /* .root_x */
+            /* .root_y */
+            .dt = ms - c->last_timestamp,
+            .event_id = c->barrier_event_id,
+            .flags = XIBarrierPointerReleased,
+        };
+
+        for (dev = inputInfo.devices; dev; dev = dev->next) {
+            int root_x, root_y;
+
+            if (dev->type != MASTER_POINTER)
+                continue;
+
+            if (!barrier_blocks_device(c, dev))
+                continue;
+
+            ev.deviceid = dev->id;
+
+            GetSpritePosition(dev, &root_x, &root_y);
+            ev.root_x = root_x;
+            ev.root_y = root_y;
+
+            mieqEnqueue(dev, (InternalEvent *) &ev);
+        }
+    }
+
     xorg_list_del(&c->entry);
 
     free(c);
commit 207e8dee00dd26ff4363edb72058b48b8a76b824
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sun Dec 9 19:44:13 2012 -0500

    barriers: Clean up code
    
    Rename a variable. This is to make the diff in the next commit cleaner.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 75ea4f7..b62a18e 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -538,12 +538,12 @@ CreatePointerBarrierClient(ClientPtr client,
 static int
 BarrierFreeBarrier(void *data, XID id)
 {
-    struct PointerBarrierClient *barrier;
+    struct PointerBarrierClient *c;
 
-    barrier = container_of(data, struct PointerBarrierClient, barrier);
-    xorg_list_del(&barrier->entry);
+    c = container_of(data, struct PointerBarrierClient, barrier);
+    xorg_list_del(&c->entry);
 
-    free(barrier);
+    free(c);
     return Success;
 }
 
commit 7fabecd8e3efe76caeb740d905a02ae4256e3246
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Wed Dec 5 19:58:05 2012 -0500

    barriers: Send a BarrierLeave event when we leave the hitbox
    
    Additionally, add flags when the pointer is released.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 45e97cf..75ea4f7 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -417,6 +417,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
     }
 
     xorg_list_for_each_entry(c, &cs->barriers, entry) {
+        int flags = 0;
         c->seen = FALSE;
         if (!c->hit)
             continue;
@@ -425,6 +426,22 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
             continue;
 
         c->hit = FALSE;
+
+        ev.type = ET_BarrierLeave;
+
+        if (c->barrier_event_id == c->release_event_id)
+            flags |= XIBarrierPointerReleased;
+
+        ev.flags = flags;
+        ev.event_id = c->barrier_event_id;
+        ev.barrierid = c->id;
+
+        ev.dt = ms - c->last_timestamp;
+        ev.window = c->window->drawable.id;
+        c->last_timestamp = ms;
+
+        mieqEnqueue(dev, (InternalEvent *) &ev);
+
         /* If we've left the hit box, this is the
          * start of a new event ID. */
         c->barrier_event_id++;
commit dac9e13a6c874f3b99ba4cf9085ed0e63beb0871
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Mon Nov 26 20:37:56 2012 -0500

    barriers: Increment event ID on hit box leave
    
    We eventually want to send a new notify event on hitbox leave,
    which signifies the dawn of a new barrier event ID, so it's
    convenient if we can put the code here.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 95a62ae..45e97cf 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -418,8 +418,16 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
 
     xorg_list_for_each_entry(c, &cs->barriers, entry) {
         c->seen = FALSE;
-        if (c->hit && !barrier_inside_hit_box(&c->barrier, x, y))
-            c->hit = FALSE;
+        if (!c->hit)
+            continue;
+
+        if (barrier_inside_hit_box(&c->barrier, x, y))
+            continue;
+
+        c->hit = FALSE;
+        /* If we've left the hit box, this is the
+         * start of a new event ID. */
+        c->barrier_event_id++;
     }
 
  out:
@@ -486,7 +494,7 @@ CreatePointerBarrierClient(ClientPtr client,
     }
 
     ret->id = stuff->barrier;
-    ret->barrier_event_id = 0;
+    ret->barrier_event_id = 1;
     ret->release_event_id = 0;
     ret->hit = FALSE;
     ret->seen = FALSE;
commit e3a734d081ebda4460e6c1eb7dcdd0f7c10ba9b4
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sat Nov 24 21:42:56 2012 -0500

    barriers: Add a couple pixels of elbow room for the hit detection
    
    Pointers (and the hands that drive them) aren't very precise, and the
    slightest amount of nudging to either side might be enough to reset
    the event ID, making clients think they have an entirely new hit. Allow
    for a slightly bigger "hit box" before these barriers get reset.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index ac94927..95a62ae 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -79,7 +79,7 @@ struct PointerBarrierClient {
     int barrier_event_id;
     int release_event_id;
     Bool hit;
-    Bool last_hit;
+    Bool seen;
 };
 
 typedef struct _BarrierScreen {
@@ -220,6 +220,35 @@ barrier_is_blocking(const struct PointerBarrier * barrier,
     return rc;
 }
 
+#define HIT_EDGE_EXTENTS 2
+static BOOL
+barrier_inside_hit_box(struct PointerBarrier *barrier, int x, int y)
+{
+    int x1, x2, y1, y2;
+    int dir;
+
+    x1 = barrier->x1;
+    x2 = barrier->x2;
+    y1 = barrier->y1;
+    y2 = barrier->y2;
+    dir = ~(barrier->directions);
+
+    if (barrier_is_vertical(barrier)) {
+        if (dir & BarrierPositiveX)
+            x1 -= HIT_EDGE_EXTENTS;
+        if (dir & BarrierNegativeX)
+            x2 += HIT_EDGE_EXTENTS;
+    }
+    if (barrier_is_horizontal(barrier)) {
+        if (dir & BarrierPositiveY)
+            y1 -= HIT_EDGE_EXTENTS;
+        if (dir & BarrierNegativeY)
+            y2 += HIT_EDGE_EXTENTS;
+    }
+
+    return x >= x1 && x <= x2 && y >= y1 && y <= y2;
+}
+
 static BOOL
 barrier_blocks_device(struct PointerBarrierClient *client,
                       DeviceIntPtr dev)
@@ -267,7 +296,7 @@ barrier_find_nearest(BarrierScreenPtr cs, DeviceIntPtr dev,
         struct PointerBarrier *b = &c->barrier;
         double distance;
 
-        if (c->hit)
+        if (c->seen)
             continue;
 
         if (!barrier_is_blocking_direction(b, dir))
@@ -388,8 +417,9 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
     }
 
     xorg_list_for_each_entry(c, &cs->barriers, entry) {
-        c->last_hit = c->hit;
-        c->hit = FALSE;
+        c->seen = FALSE;
+        if (c->hit && !barrier_inside_hit_box(&c->barrier, x, y))
+            c->hit = FALSE;
     }
 
  out:
@@ -459,7 +489,7 @@ CreatePointerBarrierClient(ClientPtr client,
     ret->barrier_event_id = 0;
     ret->release_event_id = 0;
     ret->hit = FALSE;
-    ret->last_hit = FALSE;
+    ret->seen = FALSE;
     ret->barrier.x1 = min(stuff->x1, stuff->x2);
     ret->barrier.x2 = max(stuff->x1, stuff->x2);
     ret->barrier.y1 = min(stuff->y1, stuff->y2);
commit 3b2fbcfa6c75ab072926ab9659adf785b324ce28
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Thu Nov 8 01:17:40 2012 -0500

    barriers: Add support for edge cases when releasing barriers
    
    If we release a barrier, we want to ensure that we block all
    other barriers afterwards, rather than capping the limit to
    the two nearest barriers.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 8f12253..ac94927 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -267,6 +267,9 @@ barrier_find_nearest(BarrierScreenPtr cs, DeviceIntPtr dev,
         struct PointerBarrier *b = &c->barrier;
         double distance;
 
+        if (c->hit)
+            continue;
+
         if (!barrier_is_blocking_direction(b, dir))
             continue;
 
@@ -321,7 +324,6 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
     int x = dest_x,
         y = dest_y;
     int dir;
-    int i;
     struct PointerBarrier *nearest = NULL;
     PointerBarrierClientPtr c;
     Time ms = GetTimeInMillis();
@@ -349,8 +351,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
      */
     dir = barrier_get_direction(current_x, current_y, x, y);
 
-#define MAX_BARRIERS 2
-    for (i = 0; i < MAX_BARRIERS; i++) {
+    while (dir != 0) {
         c = barrier_find_nearest(cs, dev, dir, current_x, current_y, x, y);
         if (!c)
             break;
commit a1ee26e624e6a7030ecb37a608190cb8e3d1f65b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 6 12:06:28 2012 +1000

    barriers: Don't allow releasing the pointer on other client's barriers
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 86e811e..8f12253 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -591,6 +591,9 @@ ProcXIBarrierReleasePointer(ClientPtr client)
             return err;
         }
 
+        if (CLIENT_ID(barrier_id) != client->index)
+            return BadAccess;
+
         barrier = container_of(b, struct PointerBarrierClient, barrier);
         if (barrier->barrier_event_id == event_id)
             barrier->release_event_id = event_id;
commit 2884b249294e3e8fc749bbb81e2a897314fa0818
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 6 11:59:53 2012 +1000

    barriers: Don't allow destroying other client's barriers
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index f16094d..86e811e 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -534,6 +534,9 @@ XIDestroyPointerBarrier(ClientPtr client,
         return err;
     }
 
+    if (CLIENT_ID(stuff->barrier) != client->index)
+        return BadAccess;
+
     FreeResource(stuff->barrier, RT_NONE);
     return Success;
 }
commit e130a46ab45839f91b29ee75bf19a597dfe3da28
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Thu Nov 1 16:06:40 2012 -0400

    Add support for XI2.3: Pointer barrier events and releases.
    
    This adds support for clients that would like to get a notification
    every time a barrier is hit, and allows clients to temporarily release
    a barrier so that pointers can go through them, without having to
    destroy and recreate barriers.
    
    Based on work by Chris Halse Rogers <chris.halse.rogers at canonical.com>
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 2caf98c..e606d9e 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1639,6 +1639,34 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
         UpdateDeviceState(dev, &ev->device_event);
 }
 
+static void
+ProcessBarrierEvent(InternalEvent *e, DeviceIntPtr dev)
+{
+    Mask filter;
+    WindowPtr pWin;
+    BarrierEvent *be = &e->barrier_event;
+    xEvent *ev;
+    int rc;
+
+    if (!IsMaster(dev))
+        return;
+
+    if (dixLookupWindow(&pWin, be->window, serverClient, DixReadAccess) != Success)
+        return;
+
+    rc = EventToXI2(e, &ev);
+    if (rc != Success) {
+        ErrorF("[Xi] event conversion from %s failed with code %d\n", __func__, rc);
+        return;
+    }
+
+    filter = GetEventFilter(dev, ev);
+
+    DeliverEventsToWindow(dev, pWin, ev, 1,
+                          filter, NullGrab);
+    free(ev);
+}
+
 /**
  * Process DeviceEvents and DeviceChangedEvents.
  */
@@ -1788,6 +1816,10 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
     case ET_TouchEnd:
         ProcessTouchEvent(ev, device);
         break;
+    case ET_BarrierHit:
+    case ET_BarrierLeave:
+        ProcessBarrierEvent(ev, device);
+        break;
     default:
         ProcessDeviceEvent(ev, device);
         break;
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 1074b23..175d89b 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -252,7 +252,8 @@ static int (*ProcIVector[]) (ClientPtr) = {
         ProcXIChangeProperty,   /* 57 */
         ProcXIDeleteProperty,   /* 58 */
         ProcXIGetProperty,      /* 59 */
-        ProcXIGetSelectedEvents /* 60 */
+        ProcXIGetSelectedEvents, /* 60 */
+        ProcXIBarrierReleasePointer /* 61 */
 };
 
 /* For swapped clients */
@@ -317,7 +318,8 @@ static int (*SProcIVector[]) (ClientPtr) = {
         SProcXIChangeProperty,  /* 57 */
         SProcXIDeleteProperty,  /* 58 */
         SProcXIGetProperty,     /* 59 */
-        SProcXIGetSelectedEvents        /* 60 */
+        SProcXIGetSelectedEvents,       /* 60 */
+        SProcXIBarrierReleasePointer /* 61 */
 };
 
 /*****************************************************************
@@ -840,6 +842,33 @@ STouchOwnershipEvent(xXITouchOwnershipEvent * from, xXITouchOwnershipEvent * to)
     swapl(&to->child);
 }
 
+static void
+SBarrierEvent(xXIBarrierEvent * from,
+              xXIBarrierEvent * to) {
+    to->type = from->type;
+
+    cpswapl(from->length, to->length);
+    cpswapl(from->time, to->time);
+    cpswaps(from->deviceid, to->deviceid);
+    cpswaps(from->sourceid, to->sourceid);
+    cpswapl(from->event, to->event);
+    cpswapl(from->root, to->root);
+    cpswapl(from->root_x, to->root_x);
+    cpswapl(from->root_y, to->root_y);
+
+#define SWAP_FP3232(x, y)                       \
+    do {                                        \
+        cpswapl((x).integral, (y).integral);    \
+        cpswapl((x).frac, (y).frac);            \
+    } while(0)
+
+    SWAP_FP3232(from->dx, to->dx);
+    SWAP_FP3232(from->dy, to->dy);
+    cpswapl(from->dtime, to->dtime);
+    cpswapl(from->barrier, to->barrier);
+    cpswapl(from->eventid, to->eventid);
+}
+
 /** Event swapping function for XI2 events. */
 void
 XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
@@ -886,6 +915,11 @@ XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
     case XI_RawTouchEnd:
         SRawEvent((xXIRawEvent *) from, (xXIRawEvent *) to);
         break;
+    case XI_BarrierHit:
+    case XI_BarrierLeave:
+        SBarrierEvent((xXIBarrierEvent *) from,
+                      (xXIBarrierEvent *) to);
+        break;
     default:
         ErrorF("[Xi] Unknown event type to swap. This is a bug.\n");
         break;
diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 0affde6..f16094d 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -56,6 +56,8 @@
 #include "xace.h"
 #include "list.h"
 #include "exglobals.h"
+#include "eventstr.h"
+#include "mi.h"
 
 RESTYPE PointerBarrierType;
 
@@ -66,11 +68,18 @@ static DevPrivateKeyRec BarrierScreenPrivateKeyRec;
 typedef struct PointerBarrierClient *PointerBarrierClientPtr;
 
 struct PointerBarrierClient {
+    XID id;
     ScreenPtr screen;
+    WindowPtr window;
     struct PointerBarrier barrier;
     struct xorg_list entry;
     int num_devices;
     int *device_ids; /* num_devices */
+    Time last_timestamp;
+    int barrier_event_id;
+    int release_event_id;
+    Bool hit;
+    Bool last_hit;
 };
 
 typedef struct _BarrierScreen {
@@ -315,6 +324,18 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
     int i;
     struct PointerBarrier *nearest = NULL;
     PointerBarrierClientPtr c;
+    Time ms = GetTimeInMillis();
+    BarrierEvent ev = {
+        .header = ET_Internal,
+        .type = 0,
+        .length = sizeof (BarrierEvent),
+        .time = ms,
+        .deviceid = dev->id,
+        .sourceid = dev->id,
+        .dx = dest_x - current_x,
+        .dy = dest_y - current_y,
+        .root = screen->root->drawable.id,
+    };
 
     if (xorg_list_is_empty(&cs->barriers) || IsFloating(dev))
         goto out;
@@ -336,6 +357,13 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
 
         nearest = &c->barrier;
 
+        c->seen = TRUE;
+        c->hit = TRUE;
+
+        if (c->barrier_event_id == c->release_event_id)
+            continue;
+
+        ev.type = ET_BarrierHit;
         barrier_clamp_to_barrier(nearest, dir, &x, &y);
 
         if (barrier_is_vertical(nearest)) {
@@ -346,6 +374,21 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
             dir &= ~(BarrierNegativeY | BarrierPositiveY);
             current_y = y;
         }
+
+        ev.flags = 0;
+        ev.event_id = c->barrier_event_id;
+        ev.barrierid = c->id;
+
+        ev.dt = ms - c->last_timestamp;
+        ev.window = c->window->drawable.id;
+        c->last_timestamp = ms;
+
+        mieqEnqueue(dev, (InternalEvent *) &ev);
+    }
+
+    xorg_list_for_each_entry(c, &cs->barriers, entry) {
+        c->last_hit = c->hit;
+        c->hit = FALSE;
     }
 
  out:
@@ -384,6 +427,7 @@ CreatePointerBarrierClient(ClientPtr client,
     cs = GetBarrierScreen(screen);
 
     ret->screen = screen;
+    ret->window = pWin;
     ret->num_devices = stuff->num_devices;
     if (ret->num_devices > 0)
         ret->device_ids = (int*)&ret[1];
@@ -410,6 +454,11 @@ CreatePointerBarrierClient(ClientPtr client,
         ret->device_ids[i] = device_id;
     }
 
+    ret->id = stuff->barrier;
+    ret->barrier_event_id = 0;
+    ret->release_event_id = 0;
+    ret->hit = FALSE;
+    ret->last_hit = FALSE;
     ret->barrier.x1 = min(stuff->x1, stuff->x2);
     ret->barrier.x2 = max(stuff->x1, stuff->x2);
     ret->barrier.y1 = min(stuff->y1, stuff->y2);
@@ -489,6 +538,64 @@ XIDestroyPointerBarrier(ClientPtr client,
     return Success;
 }
 
+int
+SProcXIBarrierReleasePointer(ClientPtr client)
+{
+    xXIBarrierReleasePointerInfo *info;
+    REQUEST(xXIBarrierReleasePointerReq);
+    int i;
+
+    info = (xXIBarrierReleasePointerInfo*) &stuff[1];
+
+    swaps(&stuff->length);
+    swapl(&stuff->num_barriers);
+    for (i = 0; i < stuff->num_barriers; i++, info++) {
+        swaps(&info->deviceid);
+        swapl(&info->barrier);
+        swapl(&info->eventid);
+    }
+
+    return (ProcXIBarrierReleasePointer(client));
+}
+
+int
+ProcXIBarrierReleasePointer(ClientPtr client)
+{
+    int i;
+    int err;
+    struct PointerBarrierClient *barrier;
+    struct PointerBarrier *b;
+    xXIBarrierReleasePointerInfo *info;
+
+    REQUEST(xXIBarrierReleasePointerReq);
+    REQUEST_AT_LEAST_SIZE(xXIBarrierReleasePointerReq);
+
+    info = (xXIBarrierReleasePointerInfo*) &stuff[1];
+    for (i = 0; i < stuff->num_barriers; i++, info++) {
+        CARD32 barrier_id, event_id;
+        _X_UNUSED CARD32 device_id;
+
+        barrier_id = info->barrier;
+        event_id = info->eventid;
+
+        /* FIXME: per-device releases */
+        device_id = info->deviceid;
+
+        err = dixLookupResourceByType((void **) &b, barrier_id,
+                                      PointerBarrierType, client, DixReadAccess);
+        if (err != Success) {
+            client->errorValue = barrier_id;
+            return err;
+        }
+
+        barrier = container_of(b, struct PointerBarrierClient, barrier);
+        if (barrier->barrier_event_id == event_id)
+            barrier->release_event_id = event_id;
+    }
+
+    return Success;
+}
+
 Bool
 XIBarrierInit(void)
 {
diff --git a/Xi/xibarriers.h b/Xi/xibarriers.h
index 8f2993f..f29bb6c 100644
--- a/Xi/xibarriers.h
+++ b/Xi/xibarriers.h
@@ -39,9 +39,7 @@ XIDestroyPointerBarrier(ClientPtr client,
 Bool
 XIBarrierInit(void);
 
-#endif /* _XIBARRIERS_H_ */
-
-
-
-
+int SProcXIBarrierReleasePointer(ClientPtr client);
+int ProcXIBarrierReleasePointer(ClientPtr client);
 
+#endif /* _XIBARRIERS_H_ */
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 2e422d7..bb5c8d3 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -57,6 +57,7 @@ static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
 static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
 static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
 static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
+static int eventToBarrierEvent(BarrierEvent *ev, xEvent **xi);
 static int eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi);
 
 /* Do not use, read comments below */
@@ -277,6 +278,9 @@ EventToXI2(InternalEvent *ev, xEvent **xi)
     case ET_RawTouchUpdate:
     case ET_RawTouchEnd:
         return eventToRawEvent(&ev->raw_event, xi);
+    case ET_BarrierHit:
+    case ET_BarrierLeave:
+        return eventToBarrierEvent(&ev->barrier_event, xi);
     default:
         break;
     }
@@ -782,6 +786,35 @@ eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
     return Success;
 }
 
+static int
+eventToBarrierEvent(BarrierEvent *ev, xEvent **xi)
+{
+    xXIBarrierEvent *barrier;
+    int len = sizeof(xXIBarrierEvent);
+
+    *xi = calloc(1, len);
+    barrier = (xXIBarrierEvent*) *xi;
+    barrier->type = GenericEvent;
+    barrier->extension = IReqCode;
+    barrier->evtype = GetXI2Type(ev->type);
+    barrier->length = bytes_to_int32(len - sizeof(xEvent));
+    barrier->deviceid = ev->deviceid;
+    barrier->sourceid = ev->sourceid;
+    barrier->time = ev->time;
+    barrier->event = ev->window;
+    barrier->root = ev->root;
+    barrier->dx = double_to_fp3232(ev->dx);
+    barrier->dy = double_to_fp3232(ev->dy);
+    barrier->dtime = ev->dt;
+    barrier->flags = ev->flags;
+    barrier->eventid = ev->event_id;
+    barrier->barrier = ev->barrierid;
+    barrier->root_x = double_to_fp1616(ev->root_x);
+    barrier->root_y = double_to_fp1616(ev->root_y);
+
+    return Success;
+}
+
 /**
  * Return the corresponding core type for the given event or 0 if no core
  * equivalent exists.
@@ -929,6 +962,12 @@ GetXI2Type(enum EventType type)
     case ET_TouchOwnership:
         xi2type = XI_TouchOwnership;
         break;
+    case ET_BarrierHit:
+        xi2type = XI_BarrierHit;
+        break;
+    case ET_BarrierLeave:
+        xi2type = XI_BarrierLeave;
+        break;
     default:
         break;
     }
diff --git a/include/events.h b/include/events.h
index 222bf32..c0ef45d 100644
--- a/include/events.h
+++ b/include/events.h
@@ -27,6 +27,7 @@
 typedef struct _DeviceEvent DeviceEvent;
 typedef struct _DeviceChangedEvent DeviceChangedEvent;
 typedef struct _TouchOwnershipEvent TouchOwnershipEvent;
+typedef struct _BarrierEvent BarrierEvent;
 
 #if XFreeXDGA
 typedef struct _DGAEvent DGAEvent;
diff --git a/include/eventstr.h b/include/eventstr.h
index eddba87..38fab4f 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -72,6 +72,8 @@ enum EventType {
     ET_RawTouchUpdate,
     ET_RawTouchEnd,
     ET_XQuartz,
+    ET_BarrierHit,
+    ET_BarrierLeave,
     ET_Internal = 0xFF          /* First byte */
 };
 
@@ -227,6 +229,25 @@ struct _RawDeviceEvent {
     uint32_t flags;       /**< Flags to be copied into the generated event */
 };
 
+struct _BarrierEvent {
+    unsigned char header; /**<  Always ET_Internal */
+    enum EventType type;  /**<  ET_BarrierHit, ET_BarrierLeave */
+    int length;           /**<  Length in bytes */
+    Time time;            /**<  Time in ms */
+    int deviceid;         /**< Device to post this event for */
+    int sourceid;         /**< The physical source device */
+    int barrierid;
+    Window window;
+    Window root;
+    double dx;
+    double dy;
+    double root_x;
+    double root_y;
+    int16_t dt;
+    int32_t event_id;
+    uint32_t flags;
+};
+
 #ifdef XQUARTZ
 #define XQUARTZ_EVENT_MAXARGS 5
 struct _XQuartzEvent {
@@ -253,6 +274,7 @@ union _InternalEvent {
     DeviceEvent device_event;
     DeviceChangedEvent changed_event;
     TouchOwnershipEvent touch_ownership_event;
+    BarrierEvent barrier_event;
 #if XFreeXDGA
     DGAEvent dga_event;
 #endif
diff --git a/include/inputstr.h b/include/inputstr.h
index bb0a779..17cee98 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -71,7 +71,7 @@ extern _X_EXPORT int CountBits(const uint8_t * mask, int len);
  * events to the protocol, the server will not support these events until
  * this number here is bumped.
  */
-#define XI2LASTEVENT    XI_RawTouchEnd
+#define XI2LASTEVENT    XI_BarrierLeave
 #define XI2MASKSIZE     ((XI2LASTEVENT >> 3) + 1)       /* no of bytes for masks */
 
 /**
diff --git a/mi/mieq.c b/mi/mieq.c
index b2c7769..22f8c91 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -407,6 +407,10 @@ ChangeDeviceID(DeviceIntPtr dev, InternalEvent *event)
     case ET_RawTouchUpdate:
         event->raw_event.deviceid = dev->id;
         break;
+    case ET_BarrierHit:
+    case ET_BarrierLeave:
+        event->barrier_event.deviceid = dev->id;
+        break;
     default:
         ErrorF("[mi] Unknown event type (%d), cannot change id.\n",
                event->any.type);
commit 85a37ddcc2ff49adaec4075532b60e7d015f901c
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sun Dec 9 22:48:18 2012 -0500

    barriers: Reindent the constrainment hook
    
    This is to make future diffs much cleaner. Best viewed with -w.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 21ad6c7..0affde6 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -311,43 +311,44 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
     BarrierScreenPtr cs = GetBarrierScreen(screen);
     int x = dest_x,
         y = dest_y;
+    int dir;
+    int i;
+    struct PointerBarrier *nearest = NULL;
+    PointerBarrierClientPtr c;
+
+    if (xorg_list_is_empty(&cs->barriers) || IsFloating(dev))
+        goto out;
 
-    if (!xorg_list_is_empty(&cs->barriers) && !IsFloating(dev)) {
-        int dir;
-        int i;
-        struct PointerBarrier *nearest = NULL;
-        PointerBarrierClientPtr c;
-
-        /* How this works:
-         * Given the origin and the movement vector, get the nearest barrier
-         * to the origin that is blocking the movement.
-         * Clamp to that barrier.
-         * Then, check from the clamped intersection to the original
-         * destination, again finding the nearest barrier and clamping.
-         */
-        dir = barrier_get_direction(current_x, current_y, x, y);
+    /* How this works:
+     * Given the origin and the movement vector, get the nearest barrier
+     * to the origin that is blocking the movement.
+     * Clamp to that barrier.
+     * Then, check from the clamped intersection to the original
+     * destination, again finding the nearest barrier and clamping.
+     */
+    dir = barrier_get_direction(current_x, current_y, x, y);
 
 #define MAX_BARRIERS 2
-        for (i = 0; i < MAX_BARRIERS; i++) {
-            c = barrier_find_nearest(cs, dev, dir, current_x, current_y, x, y);
-            if (!c)
-                break;
+    for (i = 0; i < MAX_BARRIERS; i++) {
+        c = barrier_find_nearest(cs, dev, dir, current_x, current_y, x, y);
+        if (!c)
+            break;
 
-            nearest = &c->barrier;
+        nearest = &c->barrier;
 
-            barrier_clamp_to_barrier(nearest, dir, &x, &y);
+        barrier_clamp_to_barrier(nearest, dir, &x, &y);
 
-            if (barrier_is_vertical(nearest)) {
-                dir &= ~(BarrierNegativeX | BarrierPositiveX);
-                current_x = x;
-            }
-            else if (barrier_is_horizontal(nearest)) {
-                dir &= ~(BarrierNegativeY | BarrierPositiveY);
-                current_y = y;
-            }
+        if (barrier_is_vertical(nearest)) {
+            dir &= ~(BarrierNegativeX | BarrierPositiveX);
+            current_x = x;
+        }
+        else if (barrier_is_horizontal(nearest)) {
+            dir &= ~(BarrierNegativeY | BarrierPositiveY);
+            current_y = y;
         }
     }
 
+ out:
     *out_x = x;
     *out_y = y;
 }
commit 97da74c80e8b8eb03f7c1e34180cf5cd343bd608
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sun Dec 9 22:19:14 2012 -0500

    barriers: Switch to finding the nearest barrier client
    
    When we add events, we eventually want to add more state to the
    PointerBarrierClient, so return one of these instead of the dummy
    public structure that's not very interesting.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 9c7affd..21ad6c7 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -237,7 +237,7 @@ barrier_blocks_device(struct PointerBarrierClient *client,
 }
 
 /**
- * Find the nearest barrier that is blocking movement from x1/y1 to x2/y2.
+ * Find the nearest barrier client that is blocking movement from x1/y1 to x2/y2.
  *
  * @param dir Only barriers blocking movement in direction dir are checked
  * @param x1 X start coordinate of movement vector
@@ -246,13 +246,12 @@ barrier_blocks_device(struct PointerBarrierClient *client,
  * @param y2 Y end coordinate of movement vector
  * @return The barrier nearest to the movement origin that blocks this movement.
  */
-static struct PointerBarrier *
+static struct PointerBarrierClient *
 barrier_find_nearest(BarrierScreenPtr cs, DeviceIntPtr dev,
                      int dir,
                      int x1, int y1, int x2, int y2)
 {
-    struct PointerBarrierClient *c;
-    struct PointerBarrier *nearest = NULL;
+    struct PointerBarrierClient *c, *nearest = NULL;
     double min_distance = INT_MAX;      /* can't get higher than that in X anyway */
 
     xorg_list_for_each_entry(c, &cs->barriers, entry) {
@@ -268,7 +267,7 @@ barrier_find_nearest(BarrierScreenPtr cs, DeviceIntPtr dev,
         if (barrier_is_blocking(b, x1, y1, x2, y2, &distance)) {
             if (min_distance > distance) {
                 min_distance = distance;
-                nearest = b;
+                nearest = c;
             }
         }
     }
@@ -317,6 +316,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
         int dir;
         int i;
         struct PointerBarrier *nearest = NULL;
+        PointerBarrierClientPtr c;
 
         /* How this works:
          * Given the origin and the movement vector, get the nearest barrier
@@ -329,10 +329,12 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
 
 #define MAX_BARRIERS 2
         for (i = 0; i < MAX_BARRIERS; i++) {
-            nearest = barrier_find_nearest(cs, dev, dir, current_x, current_y, x, y);
-            if (!nearest)
+            c = barrier_find_nearest(cs, dev, dir, current_x, current_y, x, y);
+            if (!c)
                 break;
 
+            nearest = &c->barrier;
+
             barrier_clamp_to_barrier(nearest, dir, &x, &y);
 
             if (barrier_is_vertical(nearest)) {
commit 7e16dd3628334a5991b6713d778a46c1ce3b8b78
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sat Nov 24 19:39:47 2012 -0500

    barriers: Switch to an explicit hook for barrier constrainment
    
    Rather than riding on the ConstrainCursorHarder hook, which has
    several issues, move to an explicit hook, which will help us with
    some RANDR interaction issues.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 9e43196..9c7affd 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -74,16 +74,12 @@ struct PointerBarrierClient {
 };
 
 typedef struct _BarrierScreen {
-    CloseScreenProcPtr CloseScreen;
-    ConstrainCursorHarderProcPtr ConstrainCursorHarder;
     struct xorg_list barriers;
 } BarrierScreenRec, *BarrierScreenPtr;
 
 #define GetBarrierScreen(s) ((BarrierScreenPtr)dixLookupPrivate(&(s)->devPrivates, BarrierScreenPrivateKey))
 #define GetBarrierScreenIfSet(s) GetBarrierScreen(s)
 #define SetBarrierScreen(s,p) dixSetPrivate(&(s)->devPrivates, BarrierScreenPrivateKey, p)
-#define Wrap(as,s,elt,func)	(((as)->elt = (s)->elt), (s)->elt = func)
-#define Unwrap(as,s,elt,backup)	(((backup) = (s)->elt), (s)->elt = (as)->elt)
 
 static BOOL
 barrier_is_horizontal(const struct PointerBarrier *barrier)
@@ -306,22 +302,22 @@ barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x,
     }
 }
 
-static void
-BarrierConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
-                             int *x, int *y)
+void
+input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
+                       int current_x, int current_y,
+                       int dest_x, int dest_y,
+                       int *out_x, int *out_y)
 {
+    /* Clamped coordinates here refer to screen edge clamping. */
     BarrierScreenPtr cs = GetBarrierScreen(screen);
+    int x = dest_x,
+        y = dest_y;
 
-    if (!xorg_list_is_empty(&cs->barriers) && !IsFloating(dev) &&
-        mode == Relative) {
-        int ox, oy;
+    if (!xorg_list_is_empty(&cs->barriers) && !IsFloating(dev)) {
         int dir;
         int i;
         struct PointerBarrier *nearest = NULL;
 
-        /* where are we coming from */
-        miPointerGetPosition(dev, &ox, &oy);
-
         /* How this works:
          * Given the origin and the movement vector, get the nearest barrier
          * to the origin that is blocking the movement.
@@ -329,32 +325,29 @@ BarrierConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
          * Then, check from the clamped intersection to the original
          * destination, again finding the nearest barrier and clamping.
          */
-        dir = barrier_get_direction(ox, oy, *x, *y);
+        dir = barrier_get_direction(current_x, current_y, x, y);
 
 #define MAX_BARRIERS 2
         for (i = 0; i < MAX_BARRIERS; i++) {
-            nearest = barrier_find_nearest(cs, dev, dir, ox, oy, *x, *y);
+            nearest = barrier_find_nearest(cs, dev, dir, current_x, current_y, x, y);
             if (!nearest)
                 break;
 
-            barrier_clamp_to_barrier(nearest, dir, x, y);
+            barrier_clamp_to_barrier(nearest, dir, &x, &y);
 
             if (barrier_is_vertical(nearest)) {
                 dir &= ~(BarrierNegativeX | BarrierPositiveX);
-                ox = *x;
+                current_x = x;
             }
             else if (barrier_is_horizontal(nearest)) {
                 dir &= ~(BarrierNegativeY | BarrierPositiveY);
-                oy = *y;
+                current_y = y;
             }
         }
     }
 
-    if (cs->ConstrainCursorHarder) {
-        screen->ConstrainCursorHarder = cs->ConstrainCursorHarder;
-        screen->ConstrainCursorHarder(dev, screen, mode, x, y);
-        screen->ConstrainCursorHarder = BarrierConstrainCursorHarder;
-    }
+    *out_x = x;
+    *out_y = y;
 }
 
 static int
@@ -493,21 +486,6 @@ XIDestroyPointerBarrier(ClientPtr client,
     return Success;
 }
 
-static Bool
-BarrierCloseScreen(ScreenPtr pScreen)
-{
-    BarrierScreenPtr cs = GetBarrierScreen(pScreen);
-    Bool ret;
-    _X_UNUSED CloseScreenProcPtr close_proc;
-    _X_UNUSED ConstrainCursorHarderProcPtr constrain_proc;
-
-    Unwrap(cs, pScreen, CloseScreen, close_proc);
-    Unwrap(cs, pScreen, ConstrainCursorHarder, constrain_proc);
-    ret = (*pScreen->CloseScreen) (pScreen);
-    free(cs);
-    return ret;
-}
-
 Bool
 XIBarrierInit(void)
 {
@@ -524,8 +502,6 @@ XIBarrierInit(void)
         if (!cs)
             return FALSE;
         xorg_list_init(&cs->barriers);
-        Wrap(cs, pScreen, CloseScreen, BarrierCloseScreen);
-        Wrap(cs, pScreen, ConstrainCursorHarder, BarrierConstrainCursorHarder);
         SetBarrierScreen(pScreen, cs);
     }
 
diff --git a/include/input.h b/include/input.h
index 2387dbf..a5d0462 100644
--- a/include/input.h
+++ b/include/input.h
@@ -678,4 +678,9 @@ extern _X_EXPORT void input_option_set_value(InputOption *opt,
 extern _X_HIDDEN Bool point_on_screen(ScreenPtr pScreen, int x, int y);
 extern _X_HIDDEN void update_desktop_dimensions(void);
 
+extern _X_HIDDEN void input_constrain_cursor(DeviceIntPtr pDev, ScreenPtr screen,
+                                             int current_x, int current_y,
+                                             int dest_x, int dest_y,
+                                             int *out_x, int *out_y);
+
 #endif                          /* INPUT_H */
diff --git a/mi/mipointer.c b/mi/mipointer.c
index f345063..d170824 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -588,6 +588,22 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx,
     x -= pScreen->x;
     y -= pScreen->y;
 
+    if (mode == Relative) {
+        /* coordinates after clamped to a barrier */
+        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;
+
+        input_constrain_cursor(pDev, pScreen,
+                               current_x, current_y, x, y,
+                               &constrained_x, &constrained_y);
+
+        x = constrained_x;
+        y = constrained_y;
+    }
+
     if (switch_screen) {
         pScreenPriv = GetScreenPrivate(pScreen);
         if (!pPointer->confined) {
commit 2868a93945f043e1efd897d56543fe673e341faf
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sun Dec 9 18:41:52 2012 -0500

    barriers: Don't loop over the server to destroy a barrier
    
    This is completely pointless as far as I can tell.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index ba9fd06..9e43196 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -437,22 +437,10 @@ CreatePointerBarrierClient(ClientPtr client,
 static int
 BarrierFreeBarrier(void *data, XID id)
 {
-    struct PointerBarrierClient *b = NULL, *barrier;
-    ScreenPtr screen;
-    BarrierScreenPtr cs;
+    struct PointerBarrierClient *barrier;
 
     barrier = container_of(data, struct PointerBarrierClient, barrier);
-
-    screen = barrier->screen;
-    cs = GetBarrierScreen(screen);
-
-    /* find and unlink from the screen private */
-    xorg_list_for_each_entry(b, &cs->barriers, entry) {
-        if (b == barrier) {
-            xorg_list_del(&b->entry);
-            break;
-        }
-    }
+    xorg_list_del(&barrier->entry);
 
     free(barrier);
     return Success;
commit 482e0cb35225dc3b0664f9429db19c61b0c98ef6
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Thu Nov 1 14:14:13 2012 -0400

    cursor: Move pointer barrier code over to XI
    
    In order to send events to specific windows associated with the barrier,
    we need to move the code that handles barriers to somewhere where it's
    easier to construct and send events. Rather than duplicating XSync with
    its XSyncSelectAlarm, re-use the existing XI infrastructure.
    
    For now, just move a bunch of code over, rename some things, and initialize
    the new structures, but still consider it a separate codebase. Pointer barrier
    requests are still handled by XFixes, so this is a weird intermediate state.
    It's unknown whether we'll add explicit requests to pointer barriers inside
    XI.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index 69c7886..af85bd0 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -78,6 +78,8 @@ libXi_la_SOURCES =	\
 	ungrdevk.h \
 	xiallowev.c \
 	xiallowev.h \
+	xibarriers.c \
+	xibarriers.h \
 	xichangecursor.c \
 	xichangecursor.h \
 	xichangehierarchy.c \
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 7e30755..1074b23 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -122,6 +122,7 @@ SOFTWARE.
 #include "xiqueryversion.h"
 #include "xisetclientpointer.h"
 #include "xiwarppointer.h"
+#include "xibarriers.h"
 
 /* Masks for XI events have to be aligned with core event (partially anyway).
  * If DeviceButtonMotionMask is != ButtonMotionMask, event delivery
@@ -1263,6 +1264,9 @@ XInputExtensionInit(void)
     if (!AddCallback(&ClientStateCallback, XIClientCallback, 0))
         FatalError("Failed to add callback to XI.\n");
 
+    if (!XIBarrierInit())
+        FatalError("Could not initialize barriers.\n");
+
     extEntry = AddExtension(INAME, IEVENTS, IERRORS, ProcIDispatch,
                             SProcIDispatch, IResetProc, StandardMinorOpcode);
     if (extEntry) {
diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
new file mode 100644
index 0000000..ba9fd06
--- /dev/null
+++ b/Xi/xibarriers.c
@@ -0,0 +1,548 @@
+/*
+ * Copyright 2012 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.
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 "xibarriers.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "dixevents.h"
+#include "servermd.h"
+#include "mipointer.h"
+#include "inputstr.h"
+#include "windowstr.h"
+#include "xace.h"
+#include "list.h"
+#include "exglobals.h"
+
+RESTYPE PointerBarrierType;
+
+static DevPrivateKeyRec BarrierScreenPrivateKeyRec;
+
+#define BarrierScreenPrivateKey (&BarrierScreenPrivateKeyRec)
+
+typedef struct PointerBarrierClient *PointerBarrierClientPtr;
+
+struct PointerBarrierClient {
+    ScreenPtr screen;
+    struct PointerBarrier barrier;
+    struct xorg_list entry;
+    int num_devices;
+    int *device_ids; /* num_devices */
+};
+
+typedef struct _BarrierScreen {
+    CloseScreenProcPtr CloseScreen;
+    ConstrainCursorHarderProcPtr ConstrainCursorHarder;
+    struct xorg_list barriers;
+} BarrierScreenRec, *BarrierScreenPtr;
+
+#define GetBarrierScreen(s) ((BarrierScreenPtr)dixLookupPrivate(&(s)->devPrivates, BarrierScreenPrivateKey))
+#define GetBarrierScreenIfSet(s) GetBarrierScreen(s)
+#define SetBarrierScreen(s,p) dixSetPrivate(&(s)->devPrivates, BarrierScreenPrivateKey, p)
+#define Wrap(as,s,elt,func)	(((as)->elt = (s)->elt), (s)->elt = func)
+#define Unwrap(as,s,elt,backup)	(((backup) = (s)->elt), (s)->elt = (as)->elt)
+
+static BOOL
+barrier_is_horizontal(const struct PointerBarrier *barrier)
+{
+    return barrier->y1 == barrier->y2;
+}
+
+static BOOL
+barrier_is_vertical(const struct PointerBarrier *barrier)
+{
+    return barrier->x1 == barrier->x2;
+}
+
+/**
+ * @return The set of barrier movement directions the movement vector
+ * x1/y1 → x2/y2 represents.
+ */
+int
+barrier_get_direction(int x1, int y1, int x2, int y2)
+{
+    int direction = 0;
+
+    /* which way are we trying to go */
+    if (x2 > x1)
+        direction |= BarrierPositiveX;
+    if (x2 < x1)
+        direction |= BarrierNegativeX;
+    if (y2 > y1)
+        direction |= BarrierPositiveY;
+    if (y2 < y1)
+        direction |= BarrierNegativeY;
+
+    return direction;
+}
+
+/**
+ * Test if the barrier may block movement in the direction defined by
+ * x1/y1 → x2/y2. This function only tests whether the directions could be
+ * blocked, it does not test if the barrier actually blocks the movement.
+ *
+ * @return TRUE if the barrier blocks the direction of movement or FALSE
+ * otherwise.
+ */
+BOOL
+barrier_is_blocking_direction(const struct PointerBarrier * barrier,
+                              int direction)
+{
+    /* Barriers define which way is ok, not which way is blocking */
+    return (barrier->directions & direction) != direction;
+}
+
+/**
+ * Test if the movement vector x1/y1 → x2/y2 is intersecting with the
+ * barrier. A movement vector with the startpoint or endpoint adjacent to
+ * the barrier itself counts as intersecting.
+ *
+ * @param x1 X start coordinate of movement vector
+ * @param y1 Y start coordinate of movement vector
+ * @param x2 X end coordinate of movement vector
+ * @param y2 Y end coordinate of movement vector
+ * @param[out] distance The distance between the start point and the
+ * intersection with the barrier (if applicable).
+ * @return TRUE if the barrier intersects with the given vector
+ */
+BOOL
+barrier_is_blocking(const struct PointerBarrier * barrier,
+                    int x1, int y1, int x2, int y2, double *distance)
+{
+    BOOL rc = FALSE;
+    float ua, ub, ud;
+    int dir = barrier_get_direction(x1, y1, x2, y2);
+
+    /* Algorithm below doesn't handle edge cases well, hence the extra
+     * checks. */
+    if (barrier_is_vertical(barrier)) {
+        /* handle immediate barrier adjacency, moving away */
+        if (dir & BarrierPositiveX && x1 == barrier->x1)
+            return FALSE;
+        if (dir & BarrierNegativeX && x1 == (barrier->x1 - 1))
+            return FALSE;
+        /* startpoint adjacent to barrier, moving towards -> block */
+        if (dir & BarrierPositiveX && x1 == (barrier->x1 - 1) && y1 >= barrier->y1 && y1 <= barrier->y2) {
+            *distance = 0;
+            return TRUE;
+        }
+        if (dir & BarrierNegativeX && x1 == barrier->x1 && y1 >= barrier->y1 && y1 <= barrier->y2) {
+            *distance = 0;
+            return TRUE;
+        }
+    }
+    else {
+        /* handle immediate barrier adjacency, moving away */
+        if (dir & BarrierPositiveY && y1 == barrier->y1)
+            return FALSE;
+        if (dir & BarrierNegativeY && y1 == (barrier->y1 - 1))
+            return FALSE;
+        /* startpoint adjacent to barrier, moving towards -> block */
+        if (dir & BarrierPositiveY && y1 == (barrier->y1 - 1) && x1 >= barrier->x1 && x1 <= barrier->x2) {
+            *distance = 0;
+            return TRUE;
+        }
+        if (dir & BarrierNegativeY && y1 == barrier->y1 && x1 >= barrier->x1 && x1 <= barrier->x2) {
+            *distance = 0;
+            return TRUE;
+        }
+    }
+
+    /* not an edge case, compute distance */
+    ua = 0;
+    ud = (barrier->y2 - barrier->y1) * (x2 - x1) - (barrier->x2 -
+                                                    barrier->x1) * (y2 - y1);
+    if (ud != 0) {
+        ua = ((barrier->x2 - barrier->x1) * (y1 - barrier->y1) -
+              (barrier->y2 - barrier->y1) * (x1 - barrier->x1)) / ud;
+        ub = ((x2 - x1) * (y1 - barrier->y1) -
+              (y2 - y1) * (x1 - barrier->x1)) / ud;
+        if (ua < 0 || ua > 1 || ub < 0 || ub > 1)
+            ua = 0;
+    }
+
+    if (ua > 0 && ua <= 1) {
+        double ix = barrier->x1 + ua * (barrier->x2 - barrier->x1);
+        double iy = barrier->y1 + ua * (barrier->y2 - barrier->y1);
+
+        *distance = sqrt(pow(x1 - ix, 2) + pow(y1 - iy, 2));
+        rc = TRUE;
+    }
+
+    return rc;
+}
+
+static BOOL
+barrier_blocks_device(struct PointerBarrierClient *client,
+                      DeviceIntPtr dev)
+{
+    int i;
+    int master_id;
+
+    /* Clients with no devices are treated as
+     * if they specified XIAllDevices. */
+    if (client->num_devices == 0)
+        return TRUE;
+
+    master_id = GetMaster(dev, POINTER_OR_FLOAT)->id;
+
+    for (i = 0; i < client->num_devices; i++) {
+        int device_id = client->device_ids[i];
+        if (device_id == XIAllDevices ||
+            device_id == XIAllMasterDevices ||
+            device_id == master_id)
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+/**
+ * Find the nearest barrier that is blocking movement from x1/y1 to x2/y2.
+ *
+ * @param dir Only barriers blocking movement in direction dir are checked
+ * @param x1 X start coordinate of movement vector
+ * @param y1 Y start coordinate of movement vector
+ * @param x2 X end coordinate of movement vector
+ * @param y2 Y end coordinate of movement vector
+ * @return The barrier nearest to the movement origin that blocks this movement.
+ */
+static struct PointerBarrier *
+barrier_find_nearest(BarrierScreenPtr cs, DeviceIntPtr dev,
+                     int dir,
+                     int x1, int y1, int x2, int y2)
+{
+    struct PointerBarrierClient *c;
+    struct PointerBarrier *nearest = NULL;
+    double min_distance = INT_MAX;      /* can't get higher than that in X anyway */
+
+    xorg_list_for_each_entry(c, &cs->barriers, entry) {
+        struct PointerBarrier *b = &c->barrier;
+        double distance;
+
+        if (!barrier_is_blocking_direction(b, dir))
+            continue;
+
+        if (!barrier_blocks_device(c, dev))
+            continue;
+
+        if (barrier_is_blocking(b, x1, y1, x2, y2, &distance)) {
+            if (min_distance > distance) {
+                min_distance = distance;
+                nearest = b;
+            }
+        }
+    }
+
+    return nearest;
+}
+
+/**
+ * Clamp to the given barrier given the movement direction specified in dir.
+ *
+ * @param barrier The barrier to clamp to
+ * @param dir The movement direction
+ * @param[out] x The clamped x coordinate.
+ * @param[out] y The clamped x coordinate.
+ */
+void
+barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x,
+                         int *y)
+{
+    if (barrier_is_vertical(barrier)) {
+        if ((dir & BarrierNegativeX) & ~barrier->directions)
+            *x = barrier->x1;
+        if ((dir & BarrierPositiveX) & ~barrier->directions)
+            *x = barrier->x1 - 1;
+    }
+    if (barrier_is_horizontal(barrier)) {
+        if ((dir & BarrierNegativeY) & ~barrier->directions)
+            *y = barrier->y1;
+        if ((dir & BarrierPositiveY) & ~barrier->directions)
+            *y = barrier->y1 - 1;
+    }
+}
+
+static void
+BarrierConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
+                             int *x, int *y)
+{
+    BarrierScreenPtr cs = GetBarrierScreen(screen);
+
+    if (!xorg_list_is_empty(&cs->barriers) && !IsFloating(dev) &&
+        mode == Relative) {
+        int ox, oy;
+        int dir;
+        int i;
+        struct PointerBarrier *nearest = NULL;
+
+        /* where are we coming from */
+        miPointerGetPosition(dev, &ox, &oy);
+
+        /* How this works:
+         * Given the origin and the movement vector, get the nearest barrier
+         * to the origin that is blocking the movement.
+         * Clamp to that barrier.
+         * Then, check from the clamped intersection to the original
+         * destination, again finding the nearest barrier and clamping.
+         */
+        dir = barrier_get_direction(ox, oy, *x, *y);
+
+#define MAX_BARRIERS 2
+        for (i = 0; i < MAX_BARRIERS; i++) {
+            nearest = barrier_find_nearest(cs, dev, dir, ox, oy, *x, *y);
+            if (!nearest)
+                break;
+
+            barrier_clamp_to_barrier(nearest, dir, x, y);
+
+            if (barrier_is_vertical(nearest)) {
+                dir &= ~(BarrierNegativeX | BarrierPositiveX);
+                ox = *x;
+            }
+            else if (barrier_is_horizontal(nearest)) {
+                dir &= ~(BarrierNegativeY | BarrierPositiveY);
+                oy = *y;
+            }
+        }
+    }
+
+    if (cs->ConstrainCursorHarder) {
+        screen->ConstrainCursorHarder = cs->ConstrainCursorHarder;
+        screen->ConstrainCursorHarder(dev, screen, mode, x, y);
+        screen->ConstrainCursorHarder = BarrierConstrainCursorHarder;
+    }
+}
+
+static int
+CreatePointerBarrierClient(ClientPtr client,
+                           xXFixesCreatePointerBarrierReq * stuff,
+                           PointerBarrierClientPtr *client_out)
+{
+    WindowPtr pWin;
+    ScreenPtr screen;
+    BarrierScreenPtr cs;
+    int err;
+    int size;
+    int i;
+    struct PointerBarrierClient *ret;
+    CARD16 *in_devices;
+
+    size = sizeof(*ret) + sizeof(DeviceIntPtr) * stuff->num_devices;
+    ret = malloc(size);
+
+    if (!ret) {
+        return BadAlloc;
+    }
+
+    err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
+    if (err != Success) {
+        client->errorValue = stuff->window;
+        goto error;
+    }
+
+    screen = pWin->drawable.pScreen;
+    cs = GetBarrierScreen(screen);
+
+    ret->screen = screen;
+    ret->num_devices = stuff->num_devices;
+    if (ret->num_devices > 0)
+        ret->device_ids = (int*)&ret[1];
+    else
+        ret->device_ids = NULL;
+
+    in_devices = (CARD16 *) &stuff[1];
+    for (i = 0; i < stuff->num_devices; i++) {
+        int device_id = in_devices[i];
+        DeviceIntPtr device;
+
+        if ((err = dixLookupDevice (&device, device_id,
+                                    client, DixReadAccess))) {
+            client->errorValue = device_id;
+            goto error;
+        }
+
+        if (!IsMaster (device)) {
+            client->errorValue = device_id;
+            err = BadDevice;
+            goto error;
+        }
+
+        ret->device_ids[i] = device_id;
+    }
+
+    ret->barrier.x1 = min(stuff->x1, stuff->x2);
+    ret->barrier.x2 = max(stuff->x1, stuff->x2);
+    ret->barrier.y1 = min(stuff->y1, stuff->y2);
+    ret->barrier.y2 = max(stuff->y1, stuff->y2);
+    ret->barrier.directions = stuff->directions & 0x0f;
+    if (barrier_is_horizontal(&ret->barrier))
+        ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
+    if (barrier_is_vertical(&ret->barrier))
+        ret->barrier.directions &= ~(BarrierPositiveY | BarrierNegativeY);
+    xorg_list_add(&ret->entry, &cs->barriers);
+
+    *client_out = ret;
+    return Success;
+
+ error:
+    *client_out = NULL;
+    free(ret);
+    return err;
+}
+
+static int
+BarrierFreeBarrier(void *data, XID id)
+{
+    struct PointerBarrierClient *b = NULL, *barrier;
+    ScreenPtr screen;
+    BarrierScreenPtr cs;
+
+    barrier = container_of(data, struct PointerBarrierClient, barrier);
+
+    screen = barrier->screen;
+    cs = GetBarrierScreen(screen);
+
+    /* find and unlink from the screen private */
+    xorg_list_for_each_entry(b, &cs->barriers, entry) {
+        if (b == barrier) {
+            xorg_list_del(&b->entry);
+            break;
+        }
+    }
+
+    free(barrier);
+    return Success;
+}
+
+int
+XICreatePointerBarrier(ClientPtr client,
+                       xXFixesCreatePointerBarrierReq * stuff)
+{
+    int err;
+    struct PointerBarrierClient *barrier;
+    struct PointerBarrier b;
+
+    b.x1 = stuff->x1;
+    b.x2 = stuff->x2;
+    b.y1 = stuff->y1;
+    b.y2 = stuff->y2;
+
+    if (!barrier_is_horizontal(&b) && !barrier_is_vertical(&b))
+        return BadValue;
+
+    /* no 0-sized barriers */
+    if (barrier_is_horizontal(&b) && barrier_is_vertical(&b))
+        return BadValue;
+
+    if ((err = CreatePointerBarrierClient(client, stuff, &barrier)))
+        return err;
+
+    if (!AddResource(stuff->barrier, PointerBarrierType, &barrier->barrier))
+        return BadAlloc;
+
+    return Success;
+}
+
+int
+XIDestroyPointerBarrier(ClientPtr client,
+                        xXFixesDestroyPointerBarrierReq * stuff)
+{
+    int err;
+    void *barrier;
+
+    err = dixLookupResourceByType((void **) &barrier, stuff->barrier,
+                                  PointerBarrierType, client, DixDestroyAccess);
+    if (err != Success) {
+        client->errorValue = stuff->barrier;
+        return err;
+    }
+
+    FreeResource(stuff->barrier, RT_NONE);
+    return Success;
+}
+
+static Bool
+BarrierCloseScreen(ScreenPtr pScreen)
+{
+    BarrierScreenPtr cs = GetBarrierScreen(pScreen);
+    Bool ret;
+    _X_UNUSED CloseScreenProcPtr close_proc;
+    _X_UNUSED ConstrainCursorHarderProcPtr constrain_proc;
+
+    Unwrap(cs, pScreen, CloseScreen, close_proc);
+    Unwrap(cs, pScreen, ConstrainCursorHarder, constrain_proc);
+    ret = (*pScreen->CloseScreen) (pScreen);
+    free(cs);
+    return ret;
+}
+
+Bool
+XIBarrierInit(void)
+{
+    int i;
+
+    if (!dixRegisterPrivateKey(&BarrierScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
+        return FALSE;
+
+    for (i = 0; i < screenInfo.numScreens; i++) {
+        ScreenPtr pScreen = screenInfo.screens[i];
+        BarrierScreenPtr cs;
+
+        cs = (BarrierScreenPtr) calloc(1, sizeof(BarrierScreenRec));
+        if (!cs)
+            return FALSE;
+        xorg_list_init(&cs->barriers);
+        Wrap(cs, pScreen, CloseScreen, BarrierCloseScreen);
+        Wrap(cs, pScreen, ConstrainCursorHarder, BarrierConstrainCursorHarder);
+        SetBarrierScreen(pScreen, cs);
+    }
+
+    PointerBarrierType = CreateNewResourceType(BarrierFreeBarrier,
+                                               "XIPointerBarrier");
+
+    return PointerBarrierType;
+}
diff --git a/Xi/xibarriers.h b/Xi/xibarriers.h
new file mode 100644
index 0000000..8f2993f
--- /dev/null
+++ b/Xi/xibarriers.h
@@ -0,0 +1,47 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _XIBARRIERS_H_
+#define _XIBARRIERS_H_
+
+#include "resource.h"
+
+extern _X_EXPORT RESTYPE PointerBarrierType;
+
+struct PointerBarrier {
+    CARD16 x1, x2, y1, y2;
+    CARD32 directions;
+};
+
+int
+barrier_get_direction(int, int, int, int);
+BOOL
+barrier_is_blocking(const struct PointerBarrier *, int, int, int, int,
+                        double *);
+BOOL
+barrier_is_blocking_direction(const struct PointerBarrier *, int);
+void
+barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x,
+                             int *y);
+
+#include <xfixesint.h>
+
+int
+XICreatePointerBarrier(ClientPtr client,
+                       xXFixesCreatePointerBarrierReq * stuff);
+
+int
+XIDestroyPointerBarrier(ClientPtr client,
+                        xXFixesDestroyPointerBarrierReq * stuff);
+
+Bool
+XIBarrierInit(void);
+
+#endif /* _XIBARRIERS_H_ */
+
+
+
+
+
diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index ffee4d6..568e717 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -56,12 +56,11 @@
 #include "windowstr.h"
 #include "xace.h"
 #include "list.h"
-#include "exglobals.h"
+#include "xibarriers.h"
 
 static RESTYPE CursorClientType;
 static RESTYPE CursorHideCountType;
 static RESTYPE CursorWindowType;
-RESTYPE PointerBarrierType;
 static CursorPtr CursorCurrent[MAXDEVICES];
 
 static DevPrivateKeyRec CursorScreenPrivateKeyRec;
@@ -113,16 +112,6 @@ typedef struct _CursorHideCountRec {
     XID resource;
 } CursorHideCountRec;
 
-typedef struct PointerBarrierClient *PointerBarrierClientPtr;
-
-struct PointerBarrierClient {
-    ScreenPtr screen;
-    struct PointerBarrier barrier;
-    struct xorg_list entry;
-    int num_devices;
-    int *device_ids; /* num_devices */
-};
-
 /*
  * Wrap DisplayCursor to catch cursor change events
  */
@@ -130,9 +119,7 @@ struct PointerBarrierClient {
 typedef struct _CursorScreen {
     DisplayCursorProcPtr DisplayCursor;
     CloseScreenProcPtr CloseScreen;
-    ConstrainCursorHarderProcPtr ConstrainCursorHarder;
     CursorHideCountPtr pCursorHideCounts;
-    struct xorg_list barriers;
 } CursorScreenRec, *CursorScreenPtr;
 
 #define GetCursorScreen(s) ((CursorScreenPtr)dixLookupPrivate(&(s)->devPrivates, CursorScreenPrivateKey))
@@ -199,11 +186,9 @@ CursorCloseScreen(ScreenPtr pScreen)
     Bool ret;
     _X_UNUSED CloseScreenProcPtr close_proc;
     _X_UNUSED DisplayCursorProcPtr display_proc;
-    _X_UNUSED ConstrainCursorHarderProcPtr constrain_proc;
 
     Unwrap(cs, pScreen, CloseScreen, close_proc);
     Unwrap(cs, pScreen, DisplayCursor, display_proc);
-    Unwrap(cs, pScreen, ConstrainCursorHarder, constrain_proc);
     deleteCursorHideCountsForScreen(pScreen);
     ret = (*pScreen->CloseScreen) (pScreen);
     free(cs);
@@ -1013,384 +998,15 @@ CursorFreeWindow(pointer data, XID id)
     return 1;
 }
 
-static BOOL
-barrier_is_horizontal(const struct PointerBarrier *barrier)
-{
-    return barrier->y1 == barrier->y2;
-}
-
-static BOOL
-barrier_is_vertical(const struct PointerBarrier *barrier)
-{
-    return barrier->x1 == barrier->x2;
-}
-
-/**
- * @return The set of barrier movement directions the movement vector
- * x1/y1 → x2/y2 represents.
- */
-int
-barrier_get_direction(int x1, int y1, int x2, int y2)
-{
-    int direction = 0;
-
-    /* which way are we trying to go */
-    if (x2 > x1)
-        direction |= BarrierPositiveX;
-    if (x2 < x1)
-        direction |= BarrierNegativeX;
-    if (y2 > y1)
-        direction |= BarrierPositiveY;
-    if (y2 < y1)
-        direction |= BarrierNegativeY;
-
-    return direction;
-}
-
-/**
- * Test if the barrier may block movement in the direction defined by
- * x1/y1 → x2/y2. This function only tests whether the directions could be
- * blocked, it does not test if the barrier actually blocks the movement.
- *
- * @return TRUE if the barrier blocks the direction of movement or FALSE
- * otherwise.
- */
-BOOL
-barrier_is_blocking_direction(const struct PointerBarrier * barrier,
-                              int direction)
-{
-    /* Barriers define which way is ok, not which way is blocking */
-    return (barrier->directions & direction) != direction;
-}
-
-/**
- * Test if the movement vector x1/y1 → x2/y2 is intersecting with the
- * barrier. A movement vector with the startpoint or endpoint adjacent to
- * the barrier itself counts as intersecting.
- *
- * @param x1 X start coordinate of movement vector
- * @param y1 Y start coordinate of movement vector
- * @param x2 X end coordinate of movement vector
- * @param y2 Y end coordinate of movement vector
- * @param[out] distance The distance between the start point and the
- * intersection with the barrier (if applicable).
- * @return TRUE if the barrier intersects with the given vector
- */
-BOOL
-barrier_is_blocking(const struct PointerBarrier * barrier,
-                    int x1, int y1, int x2, int y2, double *distance)
-{
-    BOOL rc = FALSE;
-    float ua, ub, ud;
-    int dir = barrier_get_direction(x1, y1, x2, y2);
-
-    /* Algorithm below doesn't handle edge cases well, hence the extra
-     * checks. */
-    if (barrier_is_vertical(barrier)) {
-        /* handle immediate barrier adjacency, moving away */
-        if (dir & BarrierPositiveX && x1 == barrier->x1)
-            return FALSE;
-        if (dir & BarrierNegativeX && x1 == (barrier->x1 - 1))
-            return FALSE;
-        /* startpoint adjacent to barrier, moving towards -> block */
-        if (dir & BarrierPositiveX && x1 == (barrier->x1 - 1) && y1 >= barrier->y1 && y1 <= barrier->y2) {
-            *distance = 0;
-            return TRUE;
-        }
-        if (dir & BarrierNegativeX && x1 == barrier->x1 && y1 >= barrier->y1 && y1 <= barrier->y2) {
-            *distance = 0;
-            return TRUE;
-        }
-    }
-    else {
-        /* handle immediate barrier adjacency, moving away */
-        if (dir & BarrierPositiveY && y1 == barrier->y1)
-            return FALSE;
-        if (dir & BarrierNegativeY && y1 == (barrier->y1 - 1))
-            return FALSE;
-        /* startpoint adjacent to barrier, moving towards -> block */
-        if (dir & BarrierPositiveY && y1 == (barrier->y1 - 1) && x1 >= barrier->x1 && x1 <= barrier->x2) {
-            *distance = 0;
-            return TRUE;
-        }
-        if (dir & BarrierNegativeY && y1 == barrier->y1 && x1 >= barrier->x1 && x1 <= barrier->x2) {
-            *distance = 0;
-            return TRUE;
-        }
-    }
-
-    /* not an edge case, compute distance */
-    ua = 0;
-    ud = (barrier->y2 - barrier->y1) * (x2 - x1) - (barrier->x2 -
-                                                    barrier->x1) * (y2 - y1);
-    if (ud != 0) {
-        ua = ((barrier->x2 - barrier->x1) * (y1 - barrier->y1) -
-              (barrier->y2 - barrier->y1) * (x1 - barrier->x1)) / ud;
-        ub = ((x2 - x1) * (y1 - barrier->y1) -
-              (y2 - y1) * (x1 - barrier->x1)) / ud;
-        if (ua < 0 || ua > 1 || ub < 0 || ub > 1)
-            ua = 0;
-    }
-
-    if (ua > 0 && ua <= 1) {
-        double ix = barrier->x1 + ua * (barrier->x2 - barrier->x1);
-        double iy = barrier->y1 + ua * (barrier->y2 - barrier->y1);
-
-        *distance = sqrt(pow(x1 - ix, 2) + pow(y1 - iy, 2));
-        rc = TRUE;
-    }
-
-    return rc;
-}
-
-static BOOL
-barrier_blocks_device(struct PointerBarrierClient *client,
-                      DeviceIntPtr dev)
-{
-    int i;
-    int master_id;
-
-    /* Clients with no devices are treated as
-     * if they specified XIAllDevices. */
-    if (client->num_devices == 0)
-        return TRUE;
-
-    master_id = GetMaster(dev, POINTER_OR_FLOAT)->id;
-
-    for (i = 0; i < client->num_devices; i++) {
-        int device_id = client->device_ids[i];
-        if (device_id == XIAllDevices ||
-            device_id == XIAllMasterDevices ||
-            device_id == master_id)
-            return TRUE;
-    }
-
-    return FALSE;
-}
-
-/**
- * Find the nearest barrier that is blocking movement from x1/y1 to x2/y2.
- *
- * @param dir Only barriers blocking movement in direction dir are checked
- * @param x1 X start coordinate of movement vector
- * @param y1 Y start coordinate of movement vector
- * @param x2 X end coordinate of movement vector
- * @param y2 Y end coordinate of movement vector
- * @return The barrier nearest to the movement origin that blocks this movement.
- */
-static struct PointerBarrier *
-barrier_find_nearest(CursorScreenPtr cs, DeviceIntPtr dev,
-                     int dir,
-                     int x1, int y1, int x2, int y2)
-{
-    struct PointerBarrierClient *c;
-    struct PointerBarrier *nearest = NULL;
-    double min_distance = INT_MAX;      /* can't get higher than that in X anyway */
-
-    xorg_list_for_each_entry(c, &cs->barriers, entry) {
-        struct PointerBarrier *b = &c->barrier;
-        double distance;
-
-        if (!barrier_is_blocking_direction(b, dir))
-            continue;
-
-        if (!barrier_blocks_device(c, dev))
-            continue;
-
-        if (barrier_is_blocking(b, x1, y1, x2, y2, &distance)) {
-            if (min_distance > distance) {
-                min_distance = distance;
-                nearest = b;
-            }
-        }
-    }
-
-    return nearest;
-}
-
-/**
- * Clamp to the given barrier given the movement direction specified in dir.
- *
- * @param barrier The barrier to clamp to
- * @param dir The movement direction
- * @param[out] x The clamped x coordinate.
- * @param[out] y The clamped x coordinate.
- */
-void
-barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x,
-                         int *y)
-{
-    if (barrier_is_vertical(barrier)) {
-        if ((dir & BarrierNegativeX) & ~barrier->directions)
-            *x = barrier->x1;
-        if ((dir & BarrierPositiveX) & ~barrier->directions)
-            *x = barrier->x1 - 1;
-    }
-    if (barrier_is_horizontal(barrier)) {
-        if ((dir & BarrierNegativeY) & ~barrier->directions)
-            *y = barrier->y1;
-        if ((dir & BarrierPositiveY) & ~barrier->directions)
-            *y = barrier->y1 - 1;
-    }
-}
-
-static void
-CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
-                            int *x, int *y)
-{
-    CursorScreenPtr cs = GetCursorScreen(screen);
-
-    if (!xorg_list_is_empty(&cs->barriers) && !IsFloating(dev) &&
-        mode == Relative) {
-        int ox, oy;
-        int dir;
-        int i;
-        struct PointerBarrier *nearest = NULL;
-
-        /* where are we coming from */
-        miPointerGetPosition(dev, &ox, &oy);
-
-        /* How this works:
-         * Given the origin and the movement vector, get the nearest barrier
-         * to the origin that is blocking the movement.
-         * Clamp to that barrier.
-         * Then, check from the clamped intersection to the original
-         * destination, again finding the nearest barrier and clamping.
-         */
-        dir = barrier_get_direction(ox, oy, *x, *y);
-
-#define MAX_BARRIERS 2
-        for (i = 0; i < MAX_BARRIERS; i++) {
-            nearest = barrier_find_nearest(cs, dev, dir, ox, oy, *x, *y);
-            if (!nearest)
-                break;
-
-            barrier_clamp_to_barrier(nearest, dir, x, y);
-
-            if (barrier_is_vertical(nearest)) {
-                dir &= ~(BarrierNegativeX | BarrierPositiveX);
-                ox = *x;
-            }
-            else if (barrier_is_horizontal(nearest)) {
-                dir &= ~(BarrierNegativeY | BarrierPositiveY);
-                oy = *y;
-            }
-        }
-    }
-
-    if (cs->ConstrainCursorHarder) {
-        screen->ConstrainCursorHarder = cs->ConstrainCursorHarder;
-        screen->ConstrainCursorHarder(dev, screen, mode, x, y);
-        screen->ConstrainCursorHarder = CursorConstrainCursorHarder;
-    }
-}
-
-static int
-CreatePointerBarrierClient(ScreenPtr screen, ClientPtr client,
-                           xXFixesCreatePointerBarrierReq * stuff,
-                           PointerBarrierClientPtr *client_out)
-{
-    CursorScreenPtr cs = GetCursorScreen(screen);
-    int err;
-    int size;
-    int i;
-    CARD16 *in_devices;
-    struct PointerBarrierClient *ret;
-
-    size = sizeof(*ret) + sizeof(int) * stuff->num_devices;
-    ret = malloc(size);
-
-    *client_out = NULL;
-
-    if (!ret) {
-        return BadAlloc;
-    }
-
-    ret->screen = screen;
-    ret->num_devices = stuff->num_devices;
-    if (ret->num_devices > 0)
-        ret->device_ids = (int*)&ret[1];
-    else
-        ret->device_ids = NULL;
-
-    in_devices = (CARD16 *) &stuff[1];
-    for (i = 0; i < stuff->num_devices; i++) {
-        int device_id = in_devices[i];
-        DeviceIntPtr device;
-
-        if ((err = dixLookupDevice (&device, device_id,
-                                    client, DixReadAccess))) {
-            client->errorValue = device_id;
-            goto error;
-        }
-
-        if (!IsMaster (device)) {
-            client->errorValue = device_id;
-            err = BadDevice;
-            goto error;
-        }
-
-        ret->device_ids[i] = device_id;
-    }
-
-    ret->barrier.x1 = min(stuff->x1, stuff->x2);
-    ret->barrier.x2 = max(stuff->x1, stuff->x2);
-    ret->barrier.y1 = min(stuff->y1, stuff->y2);
-    ret->barrier.y2 = max(stuff->y1, stuff->y2);
-    ret->barrier.directions = stuff->directions & 0x0f;
-    if (barrier_is_horizontal(&ret->barrier))
-        ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
-    if (barrier_is_vertical(&ret->barrier))
-        ret->barrier.directions &= ~(BarrierPositiveY | BarrierNegativeY);
-    xorg_list_add(&ret->entry, &cs->barriers);
-
-    *client_out = ret;
-    return Success;
-
- error:
-    free(ret);
-    return err;
-}
-
 int
 ProcXFixesCreatePointerBarrier(ClientPtr client)
 {
-    int err;
-    WindowPtr pWin;
-    struct PointerBarrierClient *barrier;
-    struct PointerBarrier b;
-
     REQUEST(xXFixesCreatePointerBarrierReq);
 
     REQUEST_FIXED_SIZE(xXFixesCreatePointerBarrierReq, pad_to_int32(stuff->num_devices));
     LEGAL_NEW_RESOURCE(stuff->barrier, client);
 
-    err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
-    if (err != Success) {
-        client->errorValue = stuff->window;
-        return err;
-    }
-
-    b.x1 = stuff->x1;
-    b.x2 = stuff->x2;
-    b.y1 = stuff->y1;
-    b.y2 = stuff->y2;
-
-    if (!barrier_is_horizontal(&b) && !barrier_is_vertical(&b))
-        return BadValue;
-
-    /* no 0-sized barriers */
-    if (barrier_is_horizontal(&b) && barrier_is_vertical(&b))
-        return BadValue;
-
-    if ((err = CreatePointerBarrierClient(pWin->drawable.pScreen,
-                                          client, stuff, &barrier)))
-        return err;
-
-    if (!AddResource(stuff->barrier, PointerBarrierType, &barrier->barrier))
-        return BadAlloc;
-
-    return Success;
+    return XICreatePointerBarrier(client, stuff);
 }
 
 int
@@ -1418,49 +1034,14 @@ SProcXFixesCreatePointerBarrier(ClientPtr client)
     return ProcXFixesVector[stuff->xfixesReqType] (client);
 }
 
-static int
-CursorFreeBarrier(void *data, XID id)
-{
-    struct PointerBarrierClient *b = NULL, *barrier;
-    ScreenPtr screen;
-    CursorScreenPtr cs;
-
-    barrier = container_of(data, struct PointerBarrierClient, barrier);
-
-    screen = barrier->screen;
-    cs = GetCursorScreen(screen);
-
-    /* find and unlink from the screen private */
-    xorg_list_for_each_entry(b, &cs->barriers, entry) {
-        if (b == barrier) {
-            xorg_list_del(&b->entry);
-            break;
-        }
-    }
-
-    free(barrier);
-    return Success;
-}
-
 int
 ProcXFixesDestroyPointerBarrier(ClientPtr client)
 {
-    int err;
-    void *barrier;
-
     REQUEST(xXFixesDestroyPointerBarrierReq);
 
     REQUEST_SIZE_MATCH(xXFixesDestroyPointerBarrierReq);
 
-    err = dixLookupResourceByType((void **) &barrier, stuff->barrier,
-                                  PointerBarrierType, client, DixDestroyAccess);
-    if (err != Success) {
-        client->errorValue = stuff->barrier;
-        return err;
-    }
-
-    FreeResource(stuff->barrier, RT_NONE);
-    return Success;
+    return XIDestroyPointerBarrier(client, stuff);
 }
 
 int
@@ -1492,10 +1073,8 @@ XFixesCursorInit(void)
         cs = (CursorScreenPtr) calloc(1, sizeof(CursorScreenRec));
         if (!cs)
             return FALSE;
-        xorg_list_init(&cs->barriers);
         Wrap(cs, pScreen, CloseScreen, CursorCloseScreen);
         Wrap(cs, pScreen, DisplayCursor, CursorDisplayCursor);
-        Wrap(cs, pScreen, ConstrainCursorHarder, CursorConstrainCursorHarder);
         cs->pCursorHideCounts = NULL;
         SetCursorScreen(pScreen, cs);
     }
@@ -1505,9 +1084,6 @@ XFixesCursorInit(void)
                                                 "XFixesCursorHideCount");
     CursorWindowType = CreateNewResourceType(CursorFreeWindow,
                                              "XFixesCursorWindow");
-    PointerBarrierType = CreateNewResourceType(CursorFreeBarrier,
-                                               "XFixesPointerBarrier");
 
-    return CursorClientType && CursorHideCountType && CursorWindowType &&
-        PointerBarrierType;
+    return CursorClientType && CursorHideCountType && CursorWindowType;
 }
diff --git a/xfixes/xfixes.h b/xfixes/xfixes.h
index 19af09f..9882871 100644
--- a/xfixes/xfixes.h
+++ b/xfixes/xfixes.h
@@ -30,7 +30,6 @@
 #include "resource.h"
 
 extern _X_EXPORT RESTYPE RegionResType;
-extern _X_EXPORT RESTYPE PointerBarrierType;
 extern _X_EXPORT int XFixesErrorBase;
 
 #define VERIFY_REGION(pRegion, rid, client, mode)			\
@@ -52,20 +51,6 @@ extern _X_EXPORT int XFixesErrorBase;
 extern _X_EXPORT RegionPtr
  XFixesRegionCopy(RegionPtr pRegion);
 
-struct PointerBarrier {
-    CARD16 x1, x2, y1, y2;
-    CARD32 directions;
-};
-
-extern int
- barrier_get_direction(int, int, int, int);
-extern BOOL
-barrier_is_blocking(const struct PointerBarrier *, int, int, int, int,
-                    double *);
-extern BOOL barrier_is_blocking_direction(const struct PointerBarrier *, int);
-extern void
-
-barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x,
-                         int *y);
+#include "xibarriers.h"
 
 #endif                          /* _XFIXES_H_ */
commit b34cffd27b9ef46e1dd477219cbb90e36d5609e3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Dec 3 11:39:08 2012 +1000

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

diff --git a/include/eventstr.h b/include/eventstr.h
index dd6fbef..eddba87 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -130,7 +130,7 @@ struct _DeviceEvent {
  */
 struct _TouchOwnershipEvent {
     unsigned char header; /**< Always ET_Internal */
-    enum EventType type;  /**< One of EventType */
+    enum EventType type;  /**< ET_TouchOwnership */
     int length;           /**< Length in bytes */
     Time time;            /**< Time in ms */
     int deviceid;         /**< Device to post this event for */
commit ea1d76d1b68c7cbcedcaa1f967c5027e0cc1c7a2
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Mon Nov 5 23:50:58 2012 -0600

    Fix formatting of address operators
    
    The formatter confused address operators preceded by casts with
    bitwise-and expressions, placing spaces on either side of both.
    That syntax isn't used by ordinary address operators, however,
    so fix them for consistency.
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/saver.c b/Xext/saver.c
index f73e2a2..8de043f 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -837,7 +837,7 @@ ScreenSaverSetAttributes(ClientPtr client)
     if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) {
         fOK = FALSE;
         for (idepth = 0; idepth < pScreen->numDepths; idepth++) {
-            pDepth = (DepthPtr) & pScreen->allowedDepths[idepth];
+            pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
             if ((depth == pDepth->depth) || (depth == 0)) {
                 for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) {
                     if (visual == pDepth->vids[ivisual]) {
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 7e30755..06b8027 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -646,7 +646,7 @@ SDeviceChangedEvent(xXIDeviceChangedEvent * from, xXIDeviceChangedEvent * to)
     *to = *from;
     memcpy(&to[1], &from[1], from->length * 4);
 
-    any = (xXIAnyInfo *) & to[1];
+    any = (xXIAnyInfo *) &to[1];
     for (i = 0; i < to->num_classes; i++) {
         int length = any->length;
 
@@ -654,7 +654,7 @@ SDeviceChangedEvent(xXIDeviceChangedEvent * from, xXIDeviceChangedEvent * to)
         case KeyClass:
         {
             xXIKeyInfo *ki = (xXIKeyInfo *) any;
-            uint32_t *key = (uint32_t *) & ki[1];
+            uint32_t *key = (uint32_t *) &ki[1];
 
             for (j = 0; j < ki->num_keycodes; j++, key++)
                 swapl(key);
@@ -765,7 +765,7 @@ SDeviceHierarchyEvent(xXIHierarchyEvent * from, xXIHierarchyEvent * to)
     swapl(&to->flags);
     swaps(&to->num_info);
 
-    info = (xXIHierarchyInfo *) & to[1];
+    info = (xXIHierarchyInfo *) &to[1];
     for (i = 0; i < from->num_info; i++) {
         swaps(&info->deviceid);
         swaps(&info->attachment);
diff --git a/Xi/gtmotion.c b/Xi/gtmotion.c
index 4642b19..cde5351 100644
--- a/Xi/gtmotion.c
+++ b/Xi/gtmotion.c
@@ -131,7 +131,7 @@ ProcXGetDeviceMotionEvents(ClientPtr client)
     num_events = v->numMotionEvents;
     if (num_events) {
         size = sizeof(Time) + (axes * sizeof(INT32));
-        rep.nEvents = GetMotionHistory(dev, (xTimecoord **) & coords,   /* XXX */
+        rep.nEvents = GetMotionHistory(dev, (xTimecoord **) &coords,   /* XXX */
                                        start.milliseconds, stop.milliseconds,
                                        (ScreenPtr) NULL, FALSE);
     }
diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
index 89f16d8..15cbac3 100644
--- a/Xi/xichangehierarchy.c
+++ b/Xi/xichangehierarchy.c
@@ -79,7 +79,7 @@ XISendDeviceHierarchyEvent(int flags[MAXDEVICES])
     ev->flags = 0;
     ev->num_info = inputInfo.numDevices;
 
-    info = (xXIHierarchyInfo *) & ev[1];
+    info = (xXIHierarchyInfo *) &ev[1];
     for (dev = inputInfo.devices; dev; dev = dev->next) {
         info->deviceid = dev->id;
         info->enabled = dev->enabled;
diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c
index 85c1dd8..4e544f0 100644
--- a/Xi/xiquerydevice.c
+++ b/Xi/xiquerydevice.c
@@ -304,7 +304,7 @@ ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo * info)
     info->length = sizeof(xXIKeyInfo) / 4 + info->num_keycodes;
     info->sourceid = dev->key->sourceid;
 
-    kc = (uint32_t *) & info[1];
+    kc = (uint32_t *) &info[1];
     for (i = xkb->min_key_code; i <= xkb->max_key_code; i++, kc++)
         *kc = i;
 
@@ -321,7 +321,7 @@ SwapKeyInfo(DeviceIntPtr dev, xXIKeyInfo * info)
     swaps(&info->length);
     swaps(&info->sourceid);
 
-    for (i = 0, key = (uint32_t *) & info[1]; i < info->num_keycodes;
+    for (i = 0, key = (uint32_t *) &info[1]; i < info->num_keycodes;
          i++, key++)
         swapl(key);
 
diff --git a/dix/colormap.c b/dix/colormap.c
index a43e279..39fddc9 100644
--- a/dix/colormap.c
+++ b/dix/colormap.c
@@ -658,15 +658,15 @@ FreeCell(ColormapPtr pmap, Pixel i, int channel)
     default:         /* so compiler can see that everything gets initialized */
     case PSEUDOMAP:
     case REDMAP:
-        pent = (EntryPtr) & pmap->red[i];
+        pent = (EntryPtr) &pmap->red[i];
         pCount = &pmap->freeRed;
         break;
     case GREENMAP:
-        pent = (EntryPtr) & pmap->green[i];
+        pent = (EntryPtr) &pmap->green[i];
         pCount = &pmap->freeGreen;
         break;
     case BLUEMAP:
-        pent = (EntryPtr) & pmap->blue[i];
+        pent = (EntryPtr) &pmap->blue[i];
         pCount = &pmap->freeBlue;
         break;
     }
@@ -1400,7 +1400,7 @@ QueryColors(ColormapPtr pmap, int count, Pixel * ppixIn, xrgb * prgbList,
                 errVal = BadValue;
             }
             else {
-                pent = (EntryPtr) & pmap->red[pixel];
+                pent = (EntryPtr) &pmap->red[pixel];
                 if (pent->fShared) {
                     prgb->red = pent->co.shco.red->color;
                     prgb->green = pent->co.shco.green->color;
diff --git a/dix/devices.c b/dix/devices.c
index 613323f..3c7d480 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -283,7 +283,7 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
     dev->coreEvents = TRUE;
 
     /* sprite defaults */
-    dev->spriteInfo = (SpriteInfoPtr) & dev[1];
+    dev->spriteInfo = (SpriteInfoPtr) &dev[1];
 
     /*  security creation/labeling check
      */
@@ -944,7 +944,7 @@ CloseDevice(DeviceIntPtr dev)
 
     free(dev->name);
 
-    classes = (ClassesPtr) & dev->key;
+    classes = (ClassesPtr) &dev->key;
     FreeAllDeviceClasses(classes);
 
     if (IsMaster(dev)) {
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 99ba277..8d61735 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -2454,7 +2454,7 @@ ProcListInstalledColormaps(ClientPtr client)
     preply->type = X_Reply;
     preply->sequenceNumber = client->sequence;
     nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
-        (pWin->drawable.pScreen, (Colormap *) & preply[1]);
+        (pWin->drawable.pScreen, (Colormap *) &preply[1]);
     preply->nColormaps = nummaps;
     preply->length = nummaps;
     WriteReplyToClient(client, sizeof(xListInstalledColormapsReply), preply);
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 2e422d7..218c954 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -451,7 +451,7 @@ appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo * info)
     info->length = sizeof(xXIKeyInfo) / 4 + info->num_keycodes;
     info->sourceid = dce->sourceid;
 
-    kc = (uint32_t *) & info[1];
+    kc = (uint32_t *) &info[1];
     for (i = 0; i < info->num_keycodes; i++)
         *kc++ = i + dce->keys.min_keycode;
 
diff --git a/dix/window.c b/dix/window.c
index 99b3e0a..a5b28a6 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -680,7 +680,7 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w,
     if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) {
         fOK = FALSE;
         for (idepth = 0; idepth < pScreen->numDepths; idepth++) {
-            pDepth = (DepthPtr) & pScreen->allowedDepths[idepth];
+            pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
             if ((depth == pDepth->depth) || (depth == 0)) {
                 for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) {
                     if (visual == pDepth->vids[ivisual]) {
diff --git a/exa/exa.c b/exa/exa.c
index d12344f..f8e499c 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -620,8 +620,8 @@ exaCreateGC(GCPtr pGC)
 
     swap(pExaScr, pScreen, CreateGC);
     if ((ret = (*pScreen->CreateGC) (pGC))) {
-        wrap(pExaGC, pGC, funcs, (GCFuncs *) & exaGCFuncs);
-        wrap(pExaGC, pGC, ops, (GCOps *) & exaOps);
+        wrap(pExaGC, pGC, funcs, (GCFuncs *) &exaGCFuncs);
+        wrap(pExaGC, pGC, ops, (GCOps *) &exaOps);
     }
     swap(pExaScr, pScreen, CreateGC);
 
diff --git a/fb/fbgc.c b/fb/fbgc.c
index e6f8279..f4d7f3a 100644
--- a/fb/fbgc.c
+++ b/fb/fbgc.c
@@ -64,8 +64,8 @@ const GCOps fbGCOps = {
 Bool
 fbCreateGC(GCPtr pGC)
 {
-    pGC->ops = (GCOps *) & fbGCOps;
-    pGC->funcs = (GCFuncs *) & fbGCFuncs;
+    pGC->ops = (GCOps *) &fbGCOps;
+    pGC->funcs = (GCFuncs *) &fbGCFuncs;
 
     /* fb wants to translate before scan conversion */
     pGC->miTranslate = 1;
diff --git a/glx/glapi.c b/glx/glapi.c
index 02e06ac..ad7329e 100644
--- a/glx/glapi.c
+++ b/glx/glapi.c
@@ -490,7 +490,7 @@ init_glapi_relocs(void)
     char run_time_patch[] = {
         0x65, 0xa1, 0, 0, 0, 0  /* movl %gs:0,%eax */
     };
-    GLuint *offset = (GLuint *) & run_time_patch[2];    /* 32-bits for x86/32 */
+    GLuint *offset = (GLuint *) &run_time_patch[2];    /* 32-bits for x86/32 */
     const GLubyte *const get_disp = (const GLubyte *) run_time_patch;
     GLubyte *curr_func = (GLubyte *) gl_dispatch_functions_start;
 
diff --git a/glx/glxdri.c b/glx/glxdri.c
index a5d87ec..da46468 100644
--- a/glx/glxdri.c
+++ b/glx/glxdri.c
@@ -1069,7 +1069,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 
     /* Map the framebuffer region. */
     status = drmMap(fd, hFB, framebuffer.size,
-                    (drmAddressPtr) & framebuffer.base);
+                    (drmAddressPtr) &framebuffer.base);
     if (status != 0) {
         LogMessage(X_ERROR, "AIGLX error: drmMap of framebuffer failed (%s)\n",
                    strerror(-status));
diff --git a/glx/indirect_program.c b/glx/indirect_program.c
index 3b50ecd..0114d73 100644
--- a/glx/indirect_program.c
+++ b/glx/indirect_program.c
@@ -109,7 +109,7 @@ DoGetProgramString(struct __GLXclientStateRec *cl, GLbyte * pc,
         }
         else {
             __GLX_BEGIN_REPLY(compsize);
-            ((xGLXGetTexImageReply *) & __glXReply)->width = compsize;
+            ((xGLXGetTexImageReply *) &__glXReply)->width = compsize;
             __GLX_SEND_HEADER();
             __GLX_SEND_VOID_ARRAY(compsize);
         }
diff --git a/glx/indirect_texture_compression.c b/glx/indirect_texture_compression.c
index 49d6db5..5c2d06b 100644
--- a/glx/indirect_texture_compression.c
+++ b/glx/indirect_texture_compression.c
@@ -72,7 +72,7 @@ __glXDisp_GetCompressedTexImageARB(struct __GLXclientStateRec *cl, GLbyte * pc)
         }
         else {
             __GLX_BEGIN_REPLY(compsize);
-            ((xGLXGetTexImageReply *) & __glXReply)->width = compsize;
+            ((xGLXGetTexImageReply *) &__glXReply)->width = compsize;
             __GLX_SEND_HEADER();
             __GLX_SEND_VOID_ARRAY(compsize);
         }
@@ -118,7 +118,7 @@ __glXDispSwap_GetCompressedTexImageARB(struct __GLXclientStateRec *cl,
         }
         else {
             __GLX_BEGIN_REPLY(compsize);
-            ((xGLXGetTexImageReply *) & __glXReply)->width = compsize;
+            ((xGLXGetTexImageReply *) &__glXReply)->width = compsize;
             __GLX_SEND_HEADER();
             __GLX_SEND_VOID_ARRAY(compsize);
         }
diff --git a/glx/renderpixswap.c b/glx/renderpixswap.c
index 0655b74..24423cd 100644
--- a/glx/renderpixswap.c
+++ b/glx/renderpixswap.c
@@ -51,17 +51,17 @@ __glXDispSwap_SeparableFilter2D(GLbyte * pc)
 
     hdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_HDR_SIZE);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->internalformat);
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->height);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->internalformat);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->height);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
diff --git a/glx/singlepix.c b/glx/singlepix.c
index 55cd443..fb6868d 100644
--- a/glx/singlepix.c
+++ b/glx/singlepix.c
@@ -150,9 +150,9 @@ __glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc)
     }
     else {
         __GLX_BEGIN_REPLY(compsize);
-        ((xGLXGetTexImageReply *) & __glXReply)->width = width;
-        ((xGLXGetTexImageReply *) & __glXReply)->height = height;
-        ((xGLXGetTexImageReply *) & __glXReply)->depth = depth;
+        ((xGLXGetTexImageReply *) &__glXReply)->width = width;
+        ((xGLXGetTexImageReply *) &__glXReply)->height = height;
+        ((xGLXGetTexImageReply *) &__glXReply)->depth = depth;
         __GLX_SEND_HEADER();
         __GLX_SEND_VOID_ARRAY(compsize);
     }
@@ -252,8 +252,8 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
     }
     else {
         __GLX_BEGIN_REPLY(compsize + compsize2);
-        ((xGLXGetSeparableFilterReply *) & __glXReply)->width = width;
-        ((xGLXGetSeparableFilterReply *) & __glXReply)->height = height;
+        ((xGLXGetSeparableFilterReply *) &__glXReply)->width = width;
+        ((xGLXGetSeparableFilterReply *) &__glXReply)->height = height;
         __GLX_SEND_HEADER();
         __GLX_SEND_VOID_ARRAY(compsize + compsize2);
     }
@@ -330,8 +330,8 @@ GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
     }
     else {
         __GLX_BEGIN_REPLY(compsize);
-        ((xGLXGetConvolutionFilterReply *) & __glXReply)->width = width;
-        ((xGLXGetConvolutionFilterReply *) & __glXReply)->height = height;
+        ((xGLXGetConvolutionFilterReply *) &__glXReply)->width = width;
+        ((xGLXGetConvolutionFilterReply *) &__glXReply)->height = height;
         __GLX_SEND_HEADER();
         __GLX_SEND_VOID_ARRAY(compsize);
     }
@@ -399,7 +399,7 @@ GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
     }
     else {
         __GLX_BEGIN_REPLY(compsize);
-        ((xGLXGetHistogramReply *) & __glXReply)->width = width;
+        ((xGLXGetHistogramReply *) &__glXReply)->width = width;
         __GLX_SEND_HEADER();
         __GLX_SEND_VOID_ARRAY(compsize);
     }
@@ -528,7 +528,7 @@ GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
     }
     else {
         __GLX_BEGIN_REPLY(compsize);
-        ((xGLXGetColorTableReply *) & __glXReply)->width = width;
+        ((xGLXGetColorTableReply *) &__glXReply)->width = width;
         __GLX_SEND_HEADER();
         __GLX_SEND_VOID_ARRAY(compsize);
     }
diff --git a/glx/singlepixswap.c b/glx/singlepixswap.c
index b6d6283..c777cea 100644
--- a/glx/singlepixswap.c
+++ b/glx/singlepixswap.c
@@ -176,9 +176,9 @@ __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc)
         __GLX_SWAP_INT(&width);
         __GLX_SWAP_INT(&height);
         __GLX_SWAP_INT(&depth);
-        ((xGLXGetTexImageReply *) & __glXReply)->width = width;
-        ((xGLXGetTexImageReply *) & __glXReply)->height = height;
-        ((xGLXGetTexImageReply *) & __glXReply)->depth = depth;
+        ((xGLXGetTexImageReply *) &__glXReply)->width = width;
+        ((xGLXGetTexImageReply *) &__glXReply)->height = height;
+        ((xGLXGetTexImageReply *) &__glXReply)->depth = depth;
         __GLX_SEND_HEADER();
         __GLX_SEND_VOID_ARRAY(compsize);
     }
@@ -290,8 +290,8 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
         __GLX_SWAP_REPLY_HEADER();
         __GLX_SWAP_INT(&width);
         __GLX_SWAP_INT(&height);
-        ((xGLXGetSeparableFilterReply *) & __glXReply)->width = width;
-        ((xGLXGetSeparableFilterReply *) & __glXReply)->height = height;
+        ((xGLXGetSeparableFilterReply *) &__glXReply)->width = width;
+        ((xGLXGetSeparableFilterReply *) &__glXReply)->height = height;
         __GLX_SEND_VOID_ARRAY(compsize + compsize2);
     }
 
@@ -376,8 +376,8 @@ GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
         __GLX_SWAP_REPLY_HEADER();
         __GLX_SWAP_INT(&width);
         __GLX_SWAP_INT(&height);
-        ((xGLXGetConvolutionFilterReply *) & __glXReply)->width = width;
-        ((xGLXGetConvolutionFilterReply *) & __glXReply)->height = height;
+        ((xGLXGetConvolutionFilterReply *) &__glXReply)->width = width;
+        ((xGLXGetConvolutionFilterReply *) &__glXReply)->height = height;
         __GLX_SEND_VOID_ARRAY(compsize);
     }
 
@@ -452,7 +452,7 @@ GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
         __GLX_BEGIN_REPLY(compsize);
         __GLX_SWAP_REPLY_HEADER();
         __GLX_SWAP_INT(&width);
-        ((xGLXGetHistogramReply *) & __glXReply)->width = width;
+        ((xGLXGetHistogramReply *) &__glXReply)->width = width;
         __GLX_SEND_VOID_ARRAY(compsize);
     }
 
@@ -594,7 +594,7 @@ GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
         __GLX_BEGIN_REPLY(compsize);
         __GLX_SWAP_REPLY_HEADER();
         __GLX_SWAP_INT(&width);
-        ((xGLXGetColorTableReply *) & __glXReply)->width = width;
+        ((xGLXGetColorTableReply *) &__glXReply)->width = width;
         __GLX_SEND_VOID_ARRAY(compsize);
     }
 
diff --git a/glx/xfont.c b/glx/xfont.c
index 037ed9e..b203866 100644
--- a/glx/xfont.c
+++ b/glx/xfont.c
@@ -168,7 +168,7 @@ __glXDisp_UseXFont(__GLXclientState * cl, GLbyte * pc)
     }
 
     CALL_GetIntegerv(GET_DISPATCH(),
-                     (GL_LIST_INDEX, (GLint *) & currentListIndex));
+                     (GL_LIST_INDEX, (GLint *) &currentListIndex));
     if (currentListIndex != 0) {
         /*
          ** A display list is currently being made.  It is an error
diff --git a/hw/dmx/config/Canvas.c b/hw/dmx/config/Canvas.c
index 34a47a2..f0586e5 100644
--- a/hw/dmx/config/Canvas.c
+++ b/hw/dmx/config/Canvas.c
@@ -76,7 +76,7 @@ CanvasExpose(Widget w, XEvent * event, Region region)
 
     if (!XtIsRealized(w))
         return;
-    XtCallCallbacks(w, XtNcanvasExposeCallback, (XtPointer) & data);
+    XtCallCallbacks(w, XtNcanvasExposeCallback, (XtPointer) &data);
 }
 
 static void
@@ -162,4 +162,4 @@ CanvasClassRec canvasClassRec = {
      }
 };
 
-WidgetClass canvasWidgetClass = (WidgetClass) & canvasClassRec;
+WidgetClass canvasWidgetClass = (WidgetClass) &canvasClassRec;
diff --git a/hw/dmx/dmx_glxvisuals.c b/hw/dmx/dmx_glxvisuals.c
index 9fcc0e5..f903b74 100644
--- a/hw/dmx/dmx_glxvisuals.c
+++ b/hw/dmx/dmx_glxvisuals.c
@@ -61,7 +61,7 @@ GetGLXVisualConfigs(Display * dpy, int screen, int *nconfigs)
     req->reqType = majorOpcode;
     req->glxCode = X_GLXGetVisualConfigs;
     req->screen = screen;
-    if (!_XReply(dpy, (xReply *) & reply, 0, False)) {
+    if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
         /* Something is busted. Punt. */
         UnlockDisplay(dpy);
         SyncHandle();
@@ -252,7 +252,7 @@ GetGLXFBConfigs(Display * dpy, int glxMajorOpcode, int *nconfigs)
 
     *nconfigs = 0;
 
-    if (!_XReply(dpy, (xReply *) & reply, 0, False)) {
+    if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
         /* Something is busted. Punt. */
         UnlockDisplay(dpy);
         SyncHandle();
diff --git a/hw/dmx/dmxwindow.c b/hw/dmx/dmxwindow.c
index 855e56b..9b8a384 100644
--- a/hw/dmx/dmxwindow.c
+++ b/hw/dmx/dmxwindow.c
@@ -786,7 +786,7 @@ dmxWindowExposures(WindowPtr pWindow, RegionPtr prgn, RegionPtr other_exposed)
     if (pWinPriv->window) {
         while (XCheckIfEvent(dmxScreen->beDisplay, &ev,
                              dmxWindowExposurePredicate,
-                             (XPointer) & pWinPriv->window)) {
+                             (XPointer) &pWinPriv->window)) {
             /* Handle expose events -- this should not be necessary
                since the base window in which the root window was
                created is guaranteed to be on top (override_redirect),
diff --git a/hw/dmx/examples/xinput.c b/hw/dmx/examples/xinput.c
index db66010..6eddc6a 100644
--- a/hw/dmx/examples/xinput.c
+++ b/hw/dmx/examples/xinput.c
@@ -303,8 +303,8 @@ main(int argc, char **argv)
 
             XNextEvent(display, &event);
             for (i = 0; i < cnt; i++) {
-                XDeviceMotionEvent *e = (XDeviceMotionEvent *) & event;
-                XDeviceButtonEvent *b = (XDeviceButtonEvent *) & event;
+                XDeviceMotionEvent *e = (XDeviceMotionEvent *) &event;
+                XDeviceButtonEvent *b = (XDeviceButtonEvent *) &event;
 
                 if (event.type == event_type[i]) {
                     printf("%s id=%lu (%d @ %d,%d; s=0x%04x, d=%d, t=%lu)"
diff --git a/hw/dmx/glxProxy/glxcmds.c b/hw/dmx/glxProxy/glxcmds.c
index 91011d1..4538274 100644
--- a/hw/dmx/glxProxy/glxcmds.c
+++ b/hw/dmx/glxProxy/glxcmds.c
@@ -1276,7 +1276,7 @@ MakeCurrent(__GLXclientState * cl,
             be_req->context =
                 (unsigned int) (glxc ? glxc->real_ids[s - from_screen] : 0);
             be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
-            if (!_XReply(dpy, (xReply *) & be_reply, 0, False)) {
+            if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) {
 
                 /* The make current failed */
                 UnlockDisplay(dpy);
@@ -1331,7 +1331,7 @@ MakeCurrent(__GLXclientState * cl,
                 be_new_req->context =
                     (unsigned int) (glxc ? glxc->real_ids[s - from_screen] : 0);
                 be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
-                if (!_XReply(dpy, (xReply *) & be_new_reply, 0, False)) {
+                if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) {
 
                     /* The make current failed */
                     UnlockDisplay(dpy);
@@ -1362,7 +1362,7 @@ MakeCurrent(__GLXclientState * cl,
                 ext_req->context =
                     (unsigned int) (glxc ? glxc->real_ids[s - from_screen] : 0);
                 ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
-                if (!_XReply(dpy, (xReply *) & ext_reply, 0, False)) {
+                if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) {
 
                     /* The make current failed */
                     UnlockDisplay(dpy);
@@ -2177,7 +2177,7 @@ __glXDoSwapBuffers(__GLXclientState * cl, XID drawId, GLXContextTag tag)
             finishReq->glxCode = X_GLsop_Finish;
             finishReq->contextTag =
                 (tag ? GetCurrentBackEndTag(cl, tag, s) : 0);
-            (void) _XReply(dpy, (xReply *) & reply, 0, False);
+            (void) _XReply(dpy, (xReply *) &reply, 0, False);
             UnlockDisplay(dpy);
             SyncHandle();
         }
@@ -2605,7 +2605,7 @@ __glXQueryExtensionsString(__GLXclientState * cl, GLbyte * pc)
     be_req->reqType = dmxScreen->glxMajorOpcode;
     be_req->glxCode = X_GLXQueryServerString;
     be_req->screen = DefaultScreen(dpy);
-    _XReply(dpy, (xReply *) & be_reply, 0, False);
+    _XReply(dpy, (xReply *) &be_reply, 0, False);
     len = (int) be_reply.length;
     numbytes = (int) be_reply.n;
     slop = numbytes * __GLX_SIZE_INT8 & 3;
@@ -2690,7 +2690,7 @@ __glXQueryServerString(__GLXclientState * cl, GLbyte * pc)
     be_req->glxCode = X_GLXQueryServerString;
     be_req->screen = DefaultScreen(dpy);
     be_req->name = name;
-    _XReply(dpy, (xReply *) & be_reply, 0, False);
+    _XReply(dpy, (xReply *) &be_reply, 0, False);
     len = (int) be_reply.length;
     numbytes = (int) be_reply.n;
     slop = numbytes * __GLX_SIZE_INT8 & 3;
@@ -3045,7 +3045,7 @@ __glXGetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc)
     new_req.length = req->length;
     new_req.screen = req->screen;
 
-    return (__glXGetFBConfigs(cl, (GLbyte *) & new_req));
+    return (__glXGetFBConfigs(cl, (GLbyte *) &new_req));
 }
 
 int
@@ -3591,7 +3591,7 @@ __glXGetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
     be_req->glxCode = X_GLXGetDrawableAttributes;
     be_req->drawable = be_drawable;
     be_req->length = req->length;
-    if (!_XReply(dpy, (xReply *) & reply, 0, False)) {
+    if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
         UnlockDisplay(dpy);
         SyncHandle();
         return (BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code));
diff --git a/hw/dmx/glxProxy/glxcmdsswap.c b/hw/dmx/glxProxy/glxcmdsswap.c
index ac79cda..ab3e7ed 100644
--- a/hw/dmx/glxProxy/glxcmdsswap.c
+++ b/hw/dmx/glxProxy/glxcmdsswap.c
@@ -1051,7 +1051,7 @@ __glXSwapGetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc)
     new_req.length = req->length;
     new_req.screen = req->screen;
 
-    return (__glXSwapGetFBConfigs(cl, (GLbyte *) & new_req));
+    return (__glXSwapGetFBConfigs(cl, (GLbyte *) &new_req));
 }
 
 int
diff --git a/hw/dmx/glxProxy/glxscreens.c b/hw/dmx/glxProxy/glxscreens.c
index f725bd1..2a19092 100644
--- a/hw/dmx/glxProxy/glxscreens.c
+++ b/hw/dmx/glxProxy/glxscreens.c
@@ -88,7 +88,7 @@ CalcServerVersionAndExtensions(void)
         req->glxCode = X_GLXQueryVersion;
         req->majorVersion = GLX_SERVER_MAJOR_VERSION;
         req->minorVersion = GLX_SERVER_MINOR_VERSION;
-        _XReply(dpy, (xReply *) & reply, 0, False);
+        _XReply(dpy, (xReply *) &reply, 0, False);
         UnlockDisplay(dpy);
         SyncHandle();
 
@@ -147,7 +147,7 @@ CalcServerVersionAndExtensions(void)
         req->glxCode = X_GLXQueryServerString;
         req->screen = DefaultScreen(dpy);
         req->name = GLX_EXTENSIONS;
-        _XReply(dpy, (xReply *) & reply, 0, False);
+        _XReply(dpy, (xReply *) &reply, 0, False);
 
         length = (int) reply.length;
         numbytes = (int) reply.n;
diff --git a/hw/dmx/glxProxy/glxsingle.c b/hw/dmx/glxProxy/glxsingle.c
index 8784200..e60cfeb 100644
--- a/hw/dmx/glxProxy/glxsingle.c
+++ b/hw/dmx/glxProxy/glxsingle.c
@@ -249,7 +249,7 @@ __glXForwardPipe0WithReply(__GLXclientState * cl, GLbyte * pc)
     /*
      * get the reply from the back-end server
      */
-    _XReply(dpy, (xReply *) & be_reply, 0, False);
+    _XReply(dpy, (xReply *) &be_reply, 0, False);
     be_buf_size = be_reply.length << 2;
     if (be_buf_size > 0) {
         be_buf = (char *) malloc(be_buf_size);
@@ -348,7 +348,7 @@ __glXForwardAllWithReply(__GLXclientState * cl, GLbyte * pc)
         /*
          * get the reply from the back-end server
          */
-        _XReply(dpy, (xReply *) & be_reply, 0, False);
+        _XReply(dpy, (xReply *) &be_reply, 0, False);
         be_buf_size = be_reply.length << 2;
         if (be_buf_size > 0) {
             be_buf = (char *) malloc(be_buf_size);
@@ -919,7 +919,7 @@ __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc)
                 *(GLboolean *) (be_pc + 24) = swapBytes;
                 *(GLboolean *) (be_pc + 25) = lsbFirst;
 
-                _XReply(dpy, (xReply *) & be_reply, 0, False);
+                _XReply(dpy, (xReply *) &be_reply, 0, False);
 
                 if (be_reply.length > 0) {
                     char *be_buf;
diff --git a/hw/dmx/glxProxy/glxvendor.c b/hw/dmx/glxProxy/glxvendor.c
index e5c8da1..5777c6a 100644
--- a/hw/dmx/glxProxy/glxvendor.c
+++ b/hw/dmx/glxProxy/glxvendor.c
@@ -237,7 +237,7 @@ __glXVForwardPipe0WithReply(__GLXclientState * cl, GLbyte * pc)
     /*
      * get the reply from the back-end server
      */
-    _XReply(dpy, (xReply *) & be_reply, 0, False);
+    _XReply(dpy, (xReply *) &be_reply, 0, False);
     be_buf_size = be_reply.length << 2;
     if (be_buf_size > 0) {
         be_buf = (char *) malloc(be_buf_size);
@@ -331,7 +331,7 @@ __glXVForwardAllWithReply(__GLXclientState * cl, GLbyte * pc)
         /*
          * get the reply from the back-end server
          */
-        _XReply(dpy, (xReply *) & be_reply, 0, False);
+        _XReply(dpy, (xReply *) &be_reply, 0, False);
         be_buf_size = be_reply.length << 2;
         if (be_buf_size > 0) {
             be_buf = (char *) malloc(be_buf_size);
diff --git a/hw/dmx/glxProxy/renderpixswap.c b/hw/dmx/glxProxy/renderpixswap.c
index 3458e61..32df0d5 100644
--- a/hw/dmx/glxProxy/renderpixswap.c
+++ b/hw/dmx/glxProxy/renderpixswap.c
@@ -39,10 +39,10 @@ __glXDispSwap_PolygonStipple(GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
     hdr->swapBytes = !hdr->swapBytes;
 }
@@ -54,17 +54,17 @@ __glXDispSwap_Bitmap(GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->height);
-    __GLX_SWAP_FLOAT((GLbyte *) & hdr->xorig);
-    __GLX_SWAP_FLOAT((GLbyte *) & hdr->yorig);
-    __GLX_SWAP_FLOAT((GLbyte *) & hdr->xmove);
-    __GLX_SWAP_FLOAT((GLbyte *) & hdr->ymove);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->height);
+    __GLX_SWAP_FLOAT((GLbyte *) &hdr->xorig);
+    __GLX_SWAP_FLOAT((GLbyte *) &hdr->yorig);
+    __GLX_SWAP_FLOAT((GLbyte *) &hdr->xmove);
+    __GLX_SWAP_FLOAT((GLbyte *) &hdr->ymove);
 
     hdr->swapBytes = !hdr->swapBytes;
 
@@ -77,19 +77,19 @@ __glXDispSwap_TexImage1D(GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->level);
-    __GLX_SWAP_INT((GLbyte *) & hdr->components);
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->height);
-    __GLX_SWAP_INT((GLbyte *) & hdr->border);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->level);
+    __GLX_SWAP_INT((GLbyte *) &hdr->components);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->height);
+    __GLX_SWAP_INT((GLbyte *) &hdr->border);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
@@ -105,19 +105,19 @@ __glXDispSwap_TexImage2D(GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->level);
-    __GLX_SWAP_INT((GLbyte *) & hdr->components);
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->height);
-    __GLX_SWAP_INT((GLbyte *) & hdr->border);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->level);
+    __GLX_SWAP_INT((GLbyte *) &hdr->components);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->height);
+    __GLX_SWAP_INT((GLbyte *) &hdr->border);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
@@ -133,25 +133,25 @@ __glXDispSwap_TexImage3D(GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->imageHeight);
-    __GLX_SWAP_INT((GLbyte *) & hdr->imageDepth);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipImages);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipVolumes);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
-
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->level);
-    __GLX_SWAP_INT((GLbyte *) & hdr->internalformat);
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->height);
-    __GLX_SWAP_INT((GLbyte *) & hdr->depth);
-    __GLX_SWAP_INT((GLbyte *) & hdr->size4d);
-    __GLX_SWAP_INT((GLbyte *) & hdr->border);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->imageHeight);
+    __GLX_SWAP_INT((GLbyte *) &hdr->imageDepth);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipImages);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipVolumes);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
+
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->level);
+    __GLX_SWAP_INT((GLbyte *) &hdr->internalformat);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->height);
+    __GLX_SWAP_INT((GLbyte *) &hdr->depth);
+    __GLX_SWAP_INT((GLbyte *) &hdr->size4d);
+    __GLX_SWAP_INT((GLbyte *) &hdr->border);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
@@ -167,15 +167,15 @@ __glXDispSwap_DrawPixels(GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->height);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->height);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
@@ -191,17 +191,17 @@ __glXDispSwap_TexSubImage1D(GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->level);
-    __GLX_SWAP_INT((GLbyte *) & hdr->xoffset);
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->level);
+    __GLX_SWAP_INT((GLbyte *) &hdr->xoffset);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
@@ -217,19 +217,19 @@ __glXDispSwap_TexSubImage2D(GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->level);
-    __GLX_SWAP_INT((GLbyte *) & hdr->xoffset);
-    __GLX_SWAP_INT((GLbyte *) & hdr->yoffset);
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->height);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->level);
+    __GLX_SWAP_INT((GLbyte *) &hdr->xoffset);
+    __GLX_SWAP_INT((GLbyte *) &hdr->yoffset);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->height);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
@@ -246,26 +246,26 @@ __glXDispSwap_TexSubImage3D(GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->imageHeight);
-    __GLX_SWAP_INT((GLbyte *) & hdr->imageDepth);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipImages);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipVolumes);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
-
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->level);
-    __GLX_SWAP_INT((GLbyte *) & hdr->xoffset);
-    __GLX_SWAP_INT((GLbyte *) & hdr->yoffset);
-    __GLX_SWAP_INT((GLbyte *) & hdr->zoffset);
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->height);
-    __GLX_SWAP_INT((GLbyte *) & hdr->depth);
-    __GLX_SWAP_INT((GLbyte *) & hdr->size4d);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->imageHeight);
+    __GLX_SWAP_INT((GLbyte *) &hdr->imageDepth);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipImages);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipVolumes);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
+
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->level);
+    __GLX_SWAP_INT((GLbyte *) &hdr->xoffset);
+    __GLX_SWAP_INT((GLbyte *) &hdr->yoffset);
+    __GLX_SWAP_INT((GLbyte *) &hdr->zoffset);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->height);
+    __GLX_SWAP_INT((GLbyte *) &hdr->depth);
+    __GLX_SWAP_INT((GLbyte *) &hdr->size4d);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
@@ -281,16 +281,16 @@ __glXDispSwap_ColorTable(GLbyte * pc)
 
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->internalformat);
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->internalformat);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
@@ -306,16 +306,16 @@ __glXDispSwap_ColorSubTable(GLbyte * pc)
         (__GLXdispatchColorSubTableHeader *) pc;
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->start);
-    __GLX_SWAP_INT((GLbyte *) & hdr->count);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->start);
+    __GLX_SWAP_INT((GLbyte *) &hdr->count);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
@@ -331,16 +331,16 @@ __glXDispSwap_ConvolutionFilter1D(GLbyte * pc)
         (__GLXdispatchConvolutionFilterHeader *) pc;
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->internalformat);
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->internalformat);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
@@ -356,17 +356,17 @@ __glXDispSwap_ConvolutionFilter2D(GLbyte * pc)
         (__GLXdispatchConvolutionFilterHeader *) pc;
     __GLX_DECLARE_SWAP_VARIABLES;
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->internalformat);
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->height);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->internalformat);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->height);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
@@ -386,17 +386,17 @@ __glXDispSwap_SeparableFilter2D(GLbyte * pc)
 
     hdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_HDR_SIZE);
 
-    __GLX_SWAP_INT((GLbyte *) & hdr->rowLength);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipRows);
-    __GLX_SWAP_INT((GLbyte *) & hdr->skipPixels);
-    __GLX_SWAP_INT((GLbyte *) & hdr->alignment);
-
-    __GLX_SWAP_INT((GLbyte *) & hdr->target);
-    __GLX_SWAP_INT((GLbyte *) & hdr->internalformat);
-    __GLX_SWAP_INT((GLbyte *) & hdr->width);
-    __GLX_SWAP_INT((GLbyte *) & hdr->height);
-    __GLX_SWAP_INT((GLbyte *) & hdr->format);
-    __GLX_SWAP_INT((GLbyte *) & hdr->type);
+    __GLX_SWAP_INT((GLbyte *) &hdr->rowLength);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipRows);
+    __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels);
+    __GLX_SWAP_INT((GLbyte *) &hdr->alignment);
+
+    __GLX_SWAP_INT((GLbyte *) &hdr->target);
+    __GLX_SWAP_INT((GLbyte *) &hdr->internalformat);
+    __GLX_SWAP_INT((GLbyte *) &hdr->width);
+    __GLX_SWAP_INT((GLbyte *) &hdr->height);
+    __GLX_SWAP_INT((GLbyte *) &hdr->format);
+    __GLX_SWAP_INT((GLbyte *) &hdr->type);
 
     /*
      ** Just invert swapBytes flag; the GL will figure out if it needs to swap
diff --git a/hw/kdrive/ephyr/XF86dri.c b/hw/kdrive/ephyr/XF86dri.c
index 74bf676..9d742f3 100644
--- a/hw/kdrive/ephyr/XF86dri.c
+++ b/hw/kdrive/ephyr/XF86dri.c
@@ -151,7 +151,7 @@ XF86DRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion,
     GetReq(XF86DRIQueryVersion, req);
     req->reqType = info->codes->major_opcode;
     req->driReqType = X_XF86DRIQueryVersion;
-    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
         UnlockDisplay(dpy);
         SyncHandle();
         TRACE("QueryVersion... return False");
@@ -181,7 +181,7 @@ XF86DRIQueryDirectRenderingCapable(Display * dpy, int screen, Bool *isCapable)
     req->reqType = info->codes->major_opcode;
     req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
     req->screen = screen;
-    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
         UnlockDisplay(dpy);
         SyncHandle();
         TRACE("QueryDirectRenderingCapable... return False");
@@ -210,7 +210,7 @@ XF86DRIOpenConnection(Display * dpy, int screen,
     req->reqType = info->codes->major_opcode;
     req->driReqType = X_XF86DRIOpenConnection;
     req->screen = screen;
-    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
         UnlockDisplay(dpy);
         SyncHandle();
         TRACE("OpenConnection... return False");
@@ -260,7 +260,7 @@ XF86DRIAuthConnection(Display * dpy, int screen, drm_magic_t magic)
     req->screen = screen;
     req->magic = magic;
     rep.authenticated = 0;
-    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
+    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse) || !rep.authenticated) {
         UnlockDisplay(dpy);
         SyncHandle();
         TRACE("AuthConnection... return False");
@@ -311,7 +311,7 @@ XF86DRIGetClientDriverName(Display * dpy, int screen,
     req->reqType = info->codes->major_opcode;
     req->driReqType = X_XF86DRIGetClientDriverName;
     req->screen = screen;
-    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
         UnlockDisplay(dpy);
         SyncHandle();
         TRACE("GetClientDriverName... return False");
@@ -362,7 +362,7 @@ XF86DRICreateContextWithConfig(Display * dpy, int screen, int configID,
     req->screen = screen;
     *context = XAllocID(dpy);
     req->context = *context;
-    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
         UnlockDisplay(dpy);
         SyncHandle();
         TRACE("CreateContext... return False");
@@ -421,7 +421,7 @@ XF86DRICreateDrawable(Display * dpy, int screen,
     req->driReqType = X_XF86DRICreateDrawable;
     req->screen = screen;
     req->drawable = drawable;
-    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
         UnlockDisplay(dpy);
         SyncHandle();
         TRACE("CreateDrawable... return False");
@@ -503,7 +503,7 @@ XF86DRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
     req->screen = screen;
     req->drawable = drawable;
 
-    if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) {
+    if (!_XReply(dpy, (xReply *) &rep, 1, xFalse)) {
         UnlockDisplay(dpy);
         SyncHandle();
         TRACE("GetDrawableInfo... return False");
@@ -585,7 +585,7 @@ XF86DRIGetDeviceInfo(Display * dpy, int screen, drm_handle_t * hFrameBuffer,
     req->reqType = info->codes->major_opcode;
     req->driReqType = X_XF86DRIGetDeviceInfo;
     req->screen = screen;
-    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
         UnlockDisplay(dpy);
         SyncHandle();
         TRACE("GetDeviceInfo... return False");
diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index 1a98a2d..144c6e1 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -754,7 +754,7 @@ ProcXF86DRICreateContext(register ClientPtr client)
     if (!ephyrDRICreateContext(stuff->screen,
                                stuff->visual,
                                &context_id,
-                               (drm_context_t *) & rep.hHWContext)) {
+                               (drm_context_t *) &rep.hHWContext)) {
         return BadValue;
     }
 
@@ -964,7 +964,7 @@ ProcXF86DRICreateDrawable(ClientPtr client)
 
     if (!ephyrDRICreateDrawable(stuff->screen,
                                 remote_win,
-                                (drm_drawable_t *) & rep.hHWDrawable)) {
+                                (drm_drawable_t *) &rep.hHWDrawable)) {
         EPHYR_LOG_ERROR("failed to create dri drawable\n");
         return BadValue;
     }
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
index 392489a..5c6c40f 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.c
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -121,7 +121,7 @@ ephyrHostGLXQueryVersion(int *a_major, int *a_minor)
     req->glxCode = X_GLXQueryVersion;
     req->majorVersion = 2;
     req->minorVersion = 1;
-    _XReply(dpy, (xReply *) & reply, 0, False);
+    _XReply(dpy, (xReply *) &reply, 0, False);
     UnlockDisplay(dpy);
     SyncHandle();
 
@@ -207,7 +207,7 @@ ephyrHostGLXGetStringFromServer(int a_screen_number,
     req->for_whom = default_screen;
     req->name = a_string_name;
 
-    _XReply(dpy, (xReply *) & reply, 0, False);
+    _XReply(dpy, (xReply *) &reply, 0, False);
 
     length = reply.length * 4;
     if (!length) {
@@ -303,7 +303,7 @@ ephyrHostGLXGetVisualConfigsInternal(enum VisualConfRequestType a_type,
         break;
     }
 
-    if (!_XReply(dpy, (xReply *) & reply, 0, False)) {
+    if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
         EPHYR_LOG_ERROR("unknown error\n");
         UnlockDisplay(dpy);
         goto out;
@@ -615,7 +615,7 @@ ephyrHostGLXMakeCurrent(int a_drawable, int a_readable,
     }
 
     memset(&reply, 0, sizeof(reply));
-    if (!_XReply(dpy, (xReply *) & reply, 0, False)) {
+    if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
         EPHYR_LOG_ERROR("failed to get reply from host\n");
         UnlockDisplay(dpy);
         SyncHandle();
@@ -735,7 +735,7 @@ ephyrHostIsContextDirect(int a_ctxt_id, int *a_is_direct)
     req->reqType = major_opcode;
     req->glxCode = X_GLXIsDirect;
     req->context = remote_glx_ctxt_id;
-    if (!_XReply(dpy, (xReply *) & reply, 0, False)) {
+    if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
         EPHYR_LOG_ERROR("fail in reading reply from host\n");
         UnlockDisplay(dpy);
         SyncHandle();
diff --git a/hw/kdrive/ephyr/ephyrhostproxy.c b/hw/kdrive/ephyr/ephyrhostproxy.c
index 410e6b6..a4f25c1 100644
--- a/hw/kdrive/ephyr/ephyrhostproxy.c
+++ b/hw/kdrive/ephyr/ephyrhostproxy.c
@@ -73,7 +73,7 @@ ephyrHostProxyDoForward(pointer a_request_buffer,
     GetXReq(forward_req);
     memmove(forward_req, in_req, 4);
 
-    if (!_XReply(dpy, (xReply *) & reply, 0, FALSE)) {
+    if (!_XReply(dpy, (xReply *) &reply, 0, FALSE)) {
         EPHYR_LOG_ERROR("failed to get reply\n");
         goto out;
     }
diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c
index 05a821b..362aa05 100644
--- a/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -304,7 +304,7 @@ ephyrHostXVAdaptorArrayAt(const EphyrHostXVAdaptorArray * a_this, int a_index)
 
     if (a_index >= a_this->nb_adaptors)
         return NULL;
-    return (EphyrHostXVAdaptor *) & a_this->adaptors[a_index];
+    return (EphyrHostXVAdaptor *) &a_this->adaptors[a_index];
 }
 
 char
@@ -668,7 +668,7 @@ ephyrHostXVQueryImageAttributes(int a_port_id,
     /*
      * read the reply
      */
-    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
         EPHYR_LOG_ERROR("QeryImageAttribute req failed\n");
         goto out;
     }
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 67eadd1..55dbd2e 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -495,7 +495,7 @@ ephyrXVPrivQueryHostAdaptors(EphyrXVPriv * a_this)
         port_priv_offset = a_this->adaptors[i].nPorts;
         for (j = 0; j < a_this->adaptors[i].nPorts; j++) {
             EphyrPortPriv *port_privs_base =
-                (EphyrPortPriv *) & a_this->adaptors[i].
+                (EphyrPortPriv *) &a_this->adaptors[i].
                 pPortPrivates[port_priv_offset];
             EphyrPortPriv *port_priv = &port_privs_base[j];
 
diff --git a/hw/xfree86/common/xf86cmap.c b/hw/xfree86/common/xf86cmap.c
index 25f84e5..85f35f8 100644
--- a/hw/xfree86/common/xf86cmap.c
+++ b/hw/xfree86/common/xf86cmap.c
@@ -608,7 +608,7 @@ CMapRefreshColors(ColormapPtr pmap, int defs, int *indices)
     case GrayScale:
         for (i = 0; i < defs; i++) {
             index = indices[i];
-            entry = (EntryPtr) & pmap->red[index];
+            entry = (EntryPtr) &pmap->red[index];
 
             if (entry->fShared) {
                 colors[index].red =
diff --git a/hw/xfree86/dri/xf86dri.c b/hw/xfree86/dri/xf86dri.c
index 0b2e8fa..086e833 100644
--- a/hw/xfree86/dri/xf86dri.c
+++ b/hw/xfree86/dri/xf86dri.c
@@ -280,7 +280,7 @@ ProcXF86DRICreateContext(register ClientPtr client)
 
     if (!DRICreateContext(pScreen,
                           NULL,
-                          stuff->context, (drm_context_t *) & rep.hHWContext)) {
+                          stuff->context, (drm_context_t *) &rep.hHWContext)) {
         return BadValue;
     }
 
@@ -329,7 +329,7 @@ ProcXF86DRICreateDrawable(ClientPtr client)
         return rc;
 
     if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client,
-                           pDrawable, (drm_drawable_t *) & rep.hHWDrawable)) {
+                           pDrawable, (drm_drawable_t *) &rep.hHWDrawable)) {
         return BadValue;
     }
 
diff --git a/hw/xfree86/i2c/fi1236.c b/hw/xfree86/i2c/fi1236.c
index 282fe7e..2eb27ba 100644
--- a/hw/xfree86/i2c/fi1236.c
+++ b/hw/xfree86/i2c/fi1236.c
@@ -91,7 +91,7 @@ MT2032_getid(FI1236Ptr f)
     CARD8 in;
 
     in = 0x11;
-    I2C_WriteRead(&(f->d), (I2CByte *) & in, 1, out, 4);
+    I2C_WriteRead(&(f->d), (I2CByte *) &in, 1, out, 4);
     xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO,
                "MT2032: Company code 0x%02x%02x, part code 0x%02x, revision code 0x%02x\n",
                out[0], out[1], out[2], out[3]);
@@ -432,7 +432,7 @@ MT2032_get_afc_hint(FI1236Ptr f)
     CARD8 AFC;
 
     in = 0x0e;
-    I2C_WriteRead(&(f->d), (I2CByte *) & in, 1, out, 2);
+    I2C_WriteRead(&(f->d), (I2CByte *) &in, 1, out, 2);
     AFC = (out[0] >> 4) & 0x7;
 #if 0
     xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC=%d TAD1=%d TAD2=%d\n",
@@ -467,7 +467,7 @@ MT2032_dump_status(FI1236Ptr f)
     CARD8 TAD2, TAD1;
 
     in = 0x0e;
-    I2C_WriteRead(&(f->d), (I2CByte *) & in, 1, out, 2);
+    I2C_WriteRead(&(f->d), (I2CByte *) &in, 1, out, 2);
     XOK = out[0] & 1;
     LO1LK = (out[0] >> 2) & 1;
     LO2LK = (out[0] >> 1) & 1;
@@ -589,12 +589,12 @@ FI1236_tune(FI1236Ptr f, CARD32 frequency)
 
     if ((f->type == TUNER_TYPE_FM1216ME) || (f->type == TUNER_TYPE_FI1236W)) {
         f->tuner_data.aux = 0x20;
-        I2C_WriteRead(&(f->d), (I2CByte *) & (f->tuner_data), 5, NULL, 0);
+        I2C_WriteRead(&(f->d), (I2CByte *) &(f->tuner_data), 5, NULL, 0);
         I2C_WriteRead(&(f->d), NULL, 0, &data, 1);
         xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Tuner status %x\n", data);
     }
     else
-        I2C_WriteRead(&(f->d), (I2CByte *) & (f->tuner_data), 4, NULL, 0);
+        I2C_WriteRead(&(f->d), (I2CByte *) &(f->tuner_data), 4, NULL, 0);
 }
 
 void
diff --git a/hw/xfree86/i2c/tda9850.c b/hw/xfree86/i2c/tda9850.c
index c2ce697..d258bda 100644
--- a/hw/xfree86/i2c/tda9850.c
+++ b/hw/xfree86/i2c/tda9850.c
@@ -131,6 +131,6 @@ tda9850_getstatus(TDA9850Ptr t)
 {
     CARD16 status;
 
-    I2C_WriteRead(&(t->d), NULL, 0, (I2CByte *) & status, 2);
+    I2C_WriteRead(&(t->d), NULL, 0, (I2CByte *) &status, 2);
     return status;
 }
diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 78ff74f..04c17b7 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -1042,7 +1042,7 @@ winCheckDisplayNumber(void)
                       NULL,
                       GetLastError(),
                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                      (LPTSTR) & lpMsgBuf, 0, NULL);
+                      (LPTSTR) &lpMsgBuf, 0, NULL);
         ErrorF("winCheckDisplayNumber - CreateMutex failed: %s\n",
                (LPSTR) lpMsgBuf);
         LocalFree(lpMsgBuf);
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 22c5abc..00cef36 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -224,7 +224,7 @@ glxWinErrorMessage(void)
     if (!FormatMessage
         (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
          FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, last_error, 0,
-         (LPTSTR) & errorbuffer, sizeof(errorbuffer), NULL)) {
+         (LPTSTR) &errorbuffer, sizeof(errorbuffer), NULL)) {
         snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error");
     }
 
@@ -1370,7 +1370,7 @@ glxWinDeferredCreateContext(__GLXWinContext * gc, __GLXWinDrawable * draw)
             }
 
             draw->hDIB =
-                CreateDIBSection(draw->dibDC, (BITMAPINFO *) & bmpHeader,
+                CreateDIBSection(draw->dibDC, (BITMAPINFO *) &bmpHeader,
                                  DIB_RGB_COLORS, &pBits, 0, 0);
             if (draw->dibDC == NULL) {
                 ErrorF("CreateDIBSection error: %s\n", glxWinErrorMessage());
diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c
index 5cae98c..226c3f0 100644
--- a/hw/xwin/winclipboardxevents.c
+++ b/hw/xwin/winclipboardxevents.c
@@ -157,7 +157,7 @@ winClipboardFlushXEvents(HWND hwnd,
                  */
                 iReturn = XSendEvent(pDisplay,
                                      eventSelection.requestor,
-                                     False, 0L, (XEvent *) & eventSelection);
+                                     False, 0L, (XEvent *) &eventSelection);
                 if (iReturn == BadValue || iReturn == BadWindow) {
                     ErrorF("winClipboardFlushXEvents - SelectionRequest - "
                            "XSendEvent () failed\n");
@@ -341,7 +341,7 @@ winClipboardFlushXEvents(HWND hwnd,
             /* Notify the requesting window that the operation has completed */
             iReturn = XSendEvent(pDisplay,
                                  eventSelection.requestor,
-                                 False, 0L, (XEvent *) & eventSelection);
+                                 False, 0L, (XEvent *) &eventSelection);
             if (iReturn == BadValue || iReturn == BadWindow) {
                 ErrorF("winClipboardFlushXEvents - SelectionRequest - "
                        "XSendEvent () failed\n");
@@ -380,7 +380,7 @@ winClipboardFlushXEvents(HWND hwnd,
                 /* Notify the requesting window that the operation is complete */
                 iReturn = XSendEvent(pDisplay,
                                      eventSelection.requestor,
-                                     False, 0L, (XEvent *) & eventSelection);
+                                     False, 0L, (XEvent *) &eventSelection);
                 if (iReturn == BadValue || iReturn == BadWindow) {
                     /*
                      * Should not be a problem if XSendEvent fails because
diff --git a/hw/xwin/wincursor.c b/hw/xwin/wincursor.c
index b5ea0db..2962d06 100644
--- a/hw/xwin/wincursor.c
+++ b/hw/xwin/wincursor.c
@@ -104,7 +104,7 @@ winPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
 
         /* Translate the client area coords to screen coords */
         MapWindowPoints(pScreenPriv->hwndScreen,
-                        HWND_DESKTOP, (LPPOINT) & rcClient, 2);
+                        HWND_DESKTOP, (LPPOINT) &rcClient, 2);
 
         /* 
          * Update the Windows cursor position so that we don't
@@ -275,7 +275,7 @@ winLoadCursor(ScreenPtr pScreen, CursorPtr pCursor, int screen)
     if (!lpBits) {
         /* Bicolor, use a palettized DIB */
         WIN_DEBUG_MSG("winLoadCursor: Trying two color cursor\n");
-        pbmi = (BITMAPINFO *) & bi;
+        pbmi = (BITMAPINFO *) &bi;
         memset(pbmi, 0, sizeof(BITMAPINFOHEADER));
         pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
         pbmi->bmiHeader.biWidth = pScreenPriv->cursor.sm_cx;
@@ -358,7 +358,7 @@ winLoadCursor(ScreenPtr pScreen, CursorPtr pCursor, int screen)
                 CreateCompatibleBitmap(hDC, pScreenPriv->cursor.sm_cx,
                                        pScreenPriv->cursor.sm_cy);
             SetDIBits(hDC, hXor, 0, pScreenPriv->cursor.sm_cy, lpBits,
-                      (BITMAPINFO *) & bi, DIB_RGB_COLORS);
+                      (BITMAPINFO *) &bi, DIB_RGB_COLORS);
             ReleaseDC(NULL, hDC);
         }
         free(lpBits);
diff --git a/hw/xwin/winengine.c b/hw/xwin/winengine.c
index b2007d7..1f55ada 100644
--- a/hw/xwin/winengine.c
+++ b/hw/xwin/winengine.c
@@ -108,7 +108,7 @@ winDetectSupportedEngines(void)
         /* Try to query for DirectDraw4 interface */
         ddrval = IDirectDraw_QueryInterface(lpdd,
                                             &IID_IDirectDraw4,
-                                            (LPVOID *) & lpdd4);
+                                            (LPVOID *) &lpdd4);
         if (SUCCEEDED(ddrval)) {
             /* We have DirectDraw4 */
             winErrorFVerb(2,
diff --git a/hw/xwin/wingc.c b/hw/xwin/wingc.c
index 7ac305d..814d531 100644
--- a/hw/xwin/wingc.c
+++ b/hw/xwin/wingc.c
@@ -130,8 +130,8 @@ winCreateGCNativeGDI(GCPtr pGC)
     ErrorF("winCreateGCNativeGDI - depth: %d\n", pGC->depth);
 #endif
 
-    pGC->ops = (GCOps *) & winGCOps;
-    pGC->funcs = (GCFuncs *) & winGCFuncs;
+    pGC->ops = (GCOps *) &winGCOps;
+    pGC->funcs = (GCFuncs *) &winGCFuncs;
 
     /* We want all coordinates passed to spans functions to be screen relative */
     pGC->miTranslate = TRUE;
diff --git a/hw/xwin/winmsg.c b/hw/xwin/winmsg.c
index 57c1d18..56e7a09 100644
--- a/hw/xwin/winmsg.c
+++ b/hw/xwin/winmsg.c
@@ -137,7 +137,7 @@ winW32ErrorEx(int verb, const char *msg, DWORD errorcode)
                        NULL,
                        errorcode,
                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                       (LPTSTR) & buffer, 0, NULL)) {
+                       (LPTSTR) &buffer, 0, NULL)) {
         winErrorFVerb(verb, "Unknown error in FormatMessage!\n");
     }
     else {
diff --git a/hw/xwin/winmultiwindowicons.c b/hw/xwin/winmultiwindowicons.c
index b8357e7..0322d98 100644
--- a/hw/xwin/winmultiwindowicons.c
+++ b/hw/xwin/winmultiwindowicons.c
@@ -253,7 +253,7 @@ NetWMToWinIconAlpha(uint32_t * icon)
     ii.fIcon = TRUE;
     ii.xHotspot = 0;            /* ignored */
     ii.yHotspot = 0;            /* ignored */
-    ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO *) & bmh,
+    ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO *) &bmh,
                                    DIB_RGB_COLORS, (void **) &DIB_pixels, NULL,
                                    0);
     ReleaseDC(NULL, hdc);
diff --git a/hw/xwin/winmultiwindowshape.c b/hw/xwin/winmultiwindowshape.c
index d5200cd..cb0f389 100644
--- a/hw/xwin/winmultiwindowshape.c
+++ b/hw/xwin/winmultiwindowshape.c
@@ -137,7 +137,7 @@ winReshapeMultiWindow(WindowPtr pWin)
 
         /* Translate client rectangle coords to screen coords */
         /* NOTE: Only transforms top and left members */
-        ClientToScreen(pWinPriv->hWnd, (LPPOINT) & rcClient);
+        ClientToScreen(pWinPriv->hWnd, (LPPOINT) &rcClient);
 
         /* Get window rectangle */
         if (!GetWindowRect(pWinPriv->hWnd, &rcWindow)) {
diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index 4180a3a..c2292c6 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -498,7 +498,7 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                           NULL,
                           GetLastError(),
                           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                          (LPTSTR) & lpMsgBuf, 0, NULL);
+                          (LPTSTR) &lpMsgBuf, 0, NULL);
 
             ErrorF("winTopLevelWindowProc - BitBlt failed: %s\n",
                    (LPSTR) lpMsgBuf);
diff --git a/hw/xwin/winpfbdd.c b/hw/xwin/winpfbdd.c
index 0fd0efe..ee6ea72 100644
--- a/hw/xwin/winpfbdd.c
+++ b/hw/xwin/winpfbdd.c
@@ -78,7 +78,7 @@ winAllocateFBPrimaryDD(ScreenPtr pScreen)
     /* Get client area location in screen coords */
     GetClientRect(pScreenPriv->hwndScreen, &rcClient);
     MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) & rcClient, 2);
+                    HWND_DESKTOP, (LPPOINT) &rcClient, 2);
 
     /* Create a DirectDraw object, store the address at lpdd */
     ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL);
@@ -88,7 +88,7 @@ winAllocateFBPrimaryDD(ScreenPtr pScreen)
     /* Get a DirectDraw2 interface pointer */
     ddrval = IDirectDraw_QueryInterface(pScreenPriv->pdd,
                                         &IID_IDirectDraw2,
-                                        (LPVOID *) & pScreenPriv->pdd2);
+                                        (LPVOID *) &pScreenPriv->pdd2);
     if (FAILED(ddrval)) {
         ErrorF("winAllocateFBShadowDD - Failed DD2 query: %08x\n",
                (unsigned int) ddrval);
@@ -465,7 +465,7 @@ winActivateAppPrimaryDD(ScreenPtr pScreen)
     /* Get client area in screen coords */
     GetClientRect(pScreenPriv->hwndScreen, &rcClient);
     MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) & rcClient, 2);
+                    HWND_DESKTOP, (LPPOINT) &rcClient, 2);
 
     /* Setup a source rectangle */
     rcSrc.left = 0;
@@ -530,7 +530,7 @@ winHotKeyAltTabPrimaryDD(ScreenPtr pScreen)
     /* Get client area in screen coords */
     GetClientRect(pScreenPriv->hwndScreen, &rcClient);
     MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) & rcClient, 2);
+                    HWND_DESKTOP, (LPPOINT) &rcClient, 2);
 
     /* Did we loose the primary surface? */
     ddrval = IDirectDrawSurface2_IsLost(pScreenPriv->pddsPrimary);
diff --git a/hw/xwin/winpixmap.c b/hw/xwin/winpixmap.c
index cb8ba91..d8a12d5 100644
--- a/hw/xwin/winpixmap.c
+++ b/hw/xwin/winpixmap.c
@@ -109,7 +109,7 @@ winCreatePixmapNativeGDI(ScreenPtr pScreen,
     /* Create a DIB for the pixmap */
     pPixmapPriv->hBitmap = winCreateDIBNativeGDI(iWidth, iHeight, iDepth,
                                                  &pPixmapPriv->pbBits,
-                                                 (BITMAPINFO **) & pPixmapPriv->
+                                                 (BITMAPINFO **) &pPixmapPriv->
                                                  pbmih);
 
 #if CYGDEBUG
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index 639a99c..e776bdb 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -550,7 +550,7 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
                        &pScreenPriv->ptWMProc,
                        &pScreenPriv->ptXMsgProc,
                        &pScreenPriv->pmServerStarted,
-                       pScreenInfo->dwScreen, (HWND) & pScreenPriv->hwndScreen,
+                       pScreenInfo->dwScreen, (HWND) &pScreenPriv->hwndScreen,
 #ifdef XWIN_MULTIWINDOWEXTWM
                        pScreenInfo->fInternalWM ||
 #endif
diff --git a/hw/xwin/winsetsp.c b/hw/xwin/winsetsp.c
index 8f75991..f102f9f 100644
--- a/hw/xwin/winsetsp.c
+++ b/hw/xwin/winsetsp.c
@@ -107,7 +107,7 @@ winSetSpansNativeGDI(DrawablePtr pDrawable,
                           0, 0,
                           *piWidths, 1,
                           pSrcs,
-                          (BITMAPINFO *) & bmi,
+                          (BITMAPINFO *) &bmi,
                           DIB_RGB_COLORS, g_copyROP[pGC->alu]);
 
             pSrcs += PixmapBytePad(*piWidths, pDrawable->depth);
@@ -150,7 +150,7 @@ winSetSpansNativeGDI(DrawablePtr pDrawable,
                           0, 0,
                           *piWidths, 1,
                           pSrcs,
-                          (BITMAPINFO *) & bmi,
+                          (BITMAPINFO *) &bmi,
                           DIB_RGB_COLORS, g_copyROP[pGC->alu]);
 
             pSrcs += PixmapBytePad(*piWidths, pDrawable->depth);
diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c
index aad3a02..2e70608 100644
--- a/hw/xwin/winshaddd.c
+++ b/hw/xwin/winshaddd.c
@@ -232,7 +232,7 @@ winAllocateFBShadowDD(ScreenPtr pScreen)
     /* Get a DirectDraw2 interface pointer */
     ddrval = IDirectDraw_QueryInterface(pScreenPriv->pdd,
                                         &IID_IDirectDraw2,
-                                        (LPVOID *) & pScreenPriv->pdd2);
+                                        (LPVOID *) &pScreenPriv->pdd2);
     if (FAILED(ddrval)) {
         ErrorF("winAllocateFBShadowDD - Failed DD2 query: %08x\n",
                (unsigned int) ddrval);
@@ -507,7 +507,7 @@ winShadowUpdateDD(ScreenPtr pScreen, shadowBufPtr pBuf)
     ptOrigin.x = pScreenInfo->dwXOffset;
     ptOrigin.y = pScreenInfo->dwYOffset;
     MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) & ptOrigin, 1);
+                    HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
 
     /* Unlock the shadow surface, so we can blit */
     ddrval = IDirectDrawSurface2_Unlock(pScreenPriv->pddsShadow, NULL);
@@ -853,7 +853,7 @@ winBltExposedRegionsShadowDD(ScreenPtr pScreen)
     ptOrigin.y = pScreenInfo->dwYOffset;
 
     MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) & ptOrigin, 1);
+                    HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
     rcDest.left = ptOrigin.x;
     rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
     rcDest.top = ptOrigin.y;
@@ -996,7 +996,7 @@ winRedrawScreenShadowDD(ScreenPtr pScreen)
     ptOrigin.x = pScreenInfo->dwXOffset;
     ptOrigin.y = pScreenInfo->dwYOffset;
     MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) & ptOrigin, 1);
+                    HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
     rcDest.left = ptOrigin.x;
     rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
     rcDest.top = ptOrigin.y;
diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c
index 7668bd1..01097f2 100644
--- a/hw/xwin/winshadddnl.c
+++ b/hw/xwin/winshadddnl.c
@@ -249,7 +249,7 @@ winAllocateFBShadowDDNL(ScreenPtr pScreen)
 
     /* Create a DirectDraw object, store the address at lpdd */
     ddrval = (*g_fpDirectDrawCreate) (NULL,
-                                      (LPDIRECTDRAW *) & pScreenPriv->pdd,
+                                      (LPDIRECTDRAW *) &pScreenPriv->pdd,
                                       NULL);
     if (FAILED(ddrval)) {
         ErrorF("winAllocateFBShadowDDNL - Could not start "
@@ -264,7 +264,7 @@ winAllocateFBShadowDDNL(ScreenPtr pScreen)
     /* Get a DirectDraw4 interface pointer */
     ddrval = IDirectDraw_QueryInterface(pScreenPriv->pdd,
                                         &IID_IDirectDraw4,
-                                        (LPVOID *) & pScreenPriv->pdd4);
+                                        (LPVOID *) &pScreenPriv->pdd4);
     if (FAILED(ddrval)) {
         ErrorF("winAllocateFBShadowDDNL - Failed DD4 query: %08x\n",
                (unsigned int) ddrval);
@@ -541,7 +541,7 @@ winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf)
     ptOrigin.x = pScreenInfo->dwXOffset;
     ptOrigin.y = pScreenInfo->dwYOffset;
     MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) & ptOrigin, 1);
+                    HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
 
     /*
      * Handle small regions with multiple blits,
@@ -880,7 +880,7 @@ winBltExposedRegionsShadowDDNL(ScreenPtr pScreen)
     ptOrigin.y = pScreenInfo->dwYOffset;
 
     MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) & ptOrigin, 1);
+                    HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
     rcDest.left = ptOrigin.x;
     rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
     rcDest.top = ptOrigin.y;
@@ -990,7 +990,7 @@ winRedrawScreenShadowDDNL(ScreenPtr pScreen)
     ptOrigin.x = pScreenInfo->dwXOffset;
     ptOrigin.y = pScreenInfo->dwYOffset;
     MapWindowPoints(pScreenPriv->hwndScreen,
-                    HWND_DESKTOP, (LPPOINT) & ptOrigin, 1);
+                    HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
     rcDest.left = ptOrigin.x;
     rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
     rcDest.top = ptOrigin.y;
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index 912f7e4..ebc2339 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -337,7 +337,7 @@ winAllocateFBShadowGDI(ScreenPtr pScreen)
     pScreenPriv->hbmpShadow = CreateDIBSection(pScreenPriv->hdcScreen,
                                                (BITMAPINFO *) pScreenPriv->
                                                pbmih, DIB_RGB_COLORS,
-                                               (VOID **) & pScreenInfo->pfb,
+                                               (VOID **) &pScreenInfo->pfb,
                                                NULL, 0);
     if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) {
         winW32Error(2, "winAllocateFBShadowGDI - CreateDIBSection failed:");
diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 9743092..210fea3 100644
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -634,7 +634,7 @@ winMWExtWMReshapeFrame(RootlessFrameID wid, RegionPtr pShape)
     /* Create region for non-client area */
     GetWindowRect(pRLWinPriv->hWnd, &rcWindow);
     GetClientRect(pRLWinPriv->hWnd, &rcClient);
-    MapWindowPoints(pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT) & rcClient, 2);
+    MapWindowPoints(pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT) &rcClient, 2);
     OffsetRgn(hRgn, rcClient.left - rcWindow.left, rcClient.top - rcWindow.top);
     OffsetRect(&rcClient, -rcWindow.left, -rcWindow.top);
     OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
@@ -725,7 +725,7 @@ winMWExtWMStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
             hbmpNew = CreateDIBSection(pRLWinPriv->hdcScreen,
                                        (BITMAPINFO *) pRLWinPriv->pbmihShadow,
                                        DIB_RGB_COLORS,
-                                       (VOID **) & pRLWinPriv->pfb, NULL, 0);
+                                       (VOID **) &pRLWinPriv->pfb, NULL, 0);
             if (hbmpNew == NULL || pRLWinPriv->pfb == NULL) {
                 ErrorF("winMWExtWMStartDrawing - CreateDIBSection failed\n");
                 //return FALSE;
@@ -883,7 +883,7 @@ winMWExtWMUpdateRegion(RootlessFrameID wid, RegionPtr pDamage)
                       NULL,
                       GetLastError(),
                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                      (LPTSTR) & lpMsgBuf, 0, NULL);
+                      (LPTSTR) &lpMsgBuf, 0, NULL);
 
         ErrorF("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n",
                (LPSTR) lpMsgBuf);
diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c
index 436f9ed..13df186 100644
--- a/hw/xwin/winwin32rootlesswndproc.c
+++ b/hw/xwin/winwin32rootlesswndproc.c
@@ -780,7 +780,7 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                           NULL,
                           GetLastError(),
                           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                          (LPTSTR) & lpMsgBuf, 0, NULL);
+                          (LPTSTR) &lpMsgBuf, 0, NULL);
 
             ErrorF("winMWExtWMWindowProc - BitBlt failed: %s\n",
                    (LPSTR) lpMsgBuf);
@@ -1058,7 +1058,7 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             if (!pRLWinPriv->fMovingOrSizing
                 /*&& (pWinPos->flags & SWP_SHOWWINDOW) */ ) {
                 GetClientRect(hwnd, &rcClient);
-                MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT) & rcClient, 2);
+                MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT) &rcClient, 2);
 
                 if (!(pWinPos->flags & SWP_NOMOVE)
                     && !(pWinPos->flags & SWP_NOSIZE)) {
@@ -1263,7 +1263,7 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         GetClientRect(hwnd, &rcClient);
 
-        MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT) & rcClient, 2);
+        MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT) &rcClient, 2);
 
         if (winIsInternalWMRunning(pScreenInfo))
             winAdjustXWindow(pWin, hwnd);
diff --git a/os/access.c b/os/access.c
index 104b6a7..88a44d9 100644
--- a/os/access.c
+++ b/os/access.c
@@ -471,7 +471,7 @@ in6_fillscopeid(struct sockaddr_in6 *sin6)
 #if defined(__KAME__)
     if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
         sin6->sin6_scope_id =
-            ntohs(*(u_int16_t *) & sin6->sin6_addr.s6_addr[2]);
+            ntohs(*(u_int16_t *) &sin6->sin6_addr.s6_addr[2]);
         sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
     }
 #endif
diff --git a/os/utils.c b/os/utils.c
index 6f75c17..e396ba4 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1639,7 +1639,7 @@ System(const char *cmdline)
                            NULL,
                            GetLastError(),
                            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                           (LPTSTR) & buffer, 0, NULL)) {
+                           (LPTSTR) &buffer, 0, NULL)) {
             ErrorF("[xkb] Starting '%s' failed!\n", cmdline);
         }
         else {
diff --git a/os/xdmcp.c b/os/xdmcp.c
index 87f04b4..0538ac5 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -751,7 +751,7 @@ receive_packet(int socketfd)
     XdmcpHeader header;
 
     /* read message off socket */
-    if (!XdmcpFill(socketfd, &buffer, (XdmcpNetaddr) & from, &fromlen))
+    if (!XdmcpFill(socketfd, &buffer, (XdmcpNetaddr) &from, &fromlen))
         return;
 
     /* reset retransmission backoff */
@@ -1059,7 +1059,7 @@ send_query_msg(void)
 
         for (i = 0; i < NumBroadcastAddresses; i++)
             XdmcpFlush(xdmcpSocket, &buffer,
-                       (XdmcpNetaddr) & BroadcastAddresses[i],
+                       (XdmcpNetaddr) &BroadcastAddresses[i],
                        sizeof(struct sockaddr_in));
     }
 #if defined(IPv6) && defined(AF_INET6)
@@ -1098,7 +1098,7 @@ send_query_msg(void)
         if (SOCKADDR_FAMILY(ManagerAddress) == AF_INET6)
             socketfd = xdmcpSocket6;
 #endif
-        XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) & ManagerAddress,
+        XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) &ManagerAddress,
                    ManagerAddressLen);
     }
 }
@@ -1223,7 +1223,7 @@ send_request_msg(void)
         socketfd = xdmcpSocket6;
 #endif
     if (XdmcpFlush(socketfd, &buffer,
-                   (XdmcpNetaddr) & req_sockaddr, req_socklen))
+                   (XdmcpNetaddr) &req_sockaddr, req_socklen))
         state = XDM_AWAIT_REQUEST_RESPONSE;
 }
 
@@ -1316,7 +1316,7 @@ send_manage_msg(void)
     if (SOCKADDR_FAMILY(req_sockaddr) == AF_INET6)
         socketfd = xdmcpSocket6;
 #endif
-    XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) & req_sockaddr, req_socklen);
+    XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) &req_sockaddr, req_socklen);
 }
 
 static void
@@ -1373,7 +1373,7 @@ send_keepalive_msg(void)
     if (SOCKADDR_FAMILY(req_sockaddr) == AF_INET6)
         socketfd = xdmcpSocket6;
 #endif
-    XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) & req_sockaddr, req_socklen);
+    XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) &req_sockaddr, req_socklen);
 }
 
 static void
diff --git a/test/input.c b/test/input.c
index 191c817..be988a4 100644
--- a/test/input.c
+++ b/test/input.c
@@ -406,7 +406,7 @@ _dix_test_xi_convert(DeviceEvent *ev, int expected_rc, int expected_count)
         assert(kbp->same_screen == FALSE);
 
         while (--count > 0) {
-            deviceValuator *v = (deviceValuator *) & xi[count];
+            deviceValuator *v = (deviceValuator *) &xi[count];
 
             assert(v->type == DeviceValuator);
             assert(v->num_valuators <= 6);
diff --git a/test/xi2/protocol-eventconvert.c b/test/xi2/protocol-eventconvert.c
index bb3177c..5db691c 100644
--- a/test/xi2/protocol-eventconvert.c
+++ b/test/xi2/protocol-eventconvert.c
@@ -694,7 +694,7 @@ test_values_XIDeviceChangedEvent(DeviceChangedEvent *in,
             assert(k->num_keycodes == in->keys.max_keycode -
                    in->keys.min_keycode + 1);
 
-            kc = (uint32_t *) & k[1];
+            kc = (uint32_t *) &k[1];
             for (j = 0; j < k->num_keycodes; j++) {
                 if (swap) {
                     swapl(&kc[j]);
diff --git a/test/xi2/protocol-xiquerydevice.c b/test/xi2/protocol-xiquerydevice.c
index 9d13bbb..c066daa 100644
--- a/test/xi2/protocol-xiquerydevice.c
+++ b/test/xi2/protocol-xiquerydevice.c
@@ -171,7 +171,7 @@ reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void *closure)
                        (xkb->max_key_code - xkb->min_key_code + 1));
                 assert(any->length == (2 + ki->num_keycodes));
 
-                kc = (uint32_t *) & ki[1];
+                kc = (uint32_t *) &ki[1];
                 for (k = 0; k < ki->num_keycodes; k++, kc++) {
                     if (client->swapped)
                         swapl(kc);
diff --git a/test/xi2/protocol-xiselectevents.c b/test/xi2/protocol-xiselectevents.c
index 8f6b947..183746f 100644
--- a/test/xi2/protocol-xiselectevents.c
+++ b/test/xi2/protocol-xiselectevents.c
@@ -98,7 +98,7 @@ request_XISelectEvent(xXISelectEventsReq * req, int error)
     xXIEventMask *mask, *next;
 
     req->length = (sz_xXISelectEventsReq / 4);
-    mask = (xXIEventMask *) & req[1];
+    mask = (xXIEventMask *) &req[1];
     for (i = 0; i < req->num_masks; i++) {
         req->length += sizeof(xXIEventMask) / 4 + mask->mask_len;
         mask = (xXIEventMask *) ((char *) &mask[1] + mask->mask_len * 4);
@@ -111,7 +111,7 @@ request_XISelectEvent(xXISelectEventsReq * req, int error)
 
     client.swapped = TRUE;
 
-    mask = (xXIEventMask *) & req[1];
+    mask = (xXIEventMask *) &req[1];
     for (i = 0; i < req->num_masks; i++) {
         next = (xXIEventMask *) ((char *) &mask[1] + mask->mask_len * 4);
         swaps(&mask->deviceid);
@@ -156,7 +156,7 @@ request_XISelectEvents_masks(xXISelectEventsReq * req)
     int nmasks = (XI2LASTEVENT + 7) / 8;
     unsigned char *bits;
 
-    mask = (xXIEventMask *) & req[1];
+    mask = (xXIEventMask *) &req[1];
     req->win = ROOT_WINDOW_ID;
 
     /* if a clients submits more than 100 masks, consider it insane and untested */
@@ -312,7 +312,7 @@ test_XISelectEvents(void)
     req->num_masks = 1;
 
     printf("Triggering bogus mask length error\n");
-    mask = (xXIEventMask *) & req[1];
+    mask = (xXIEventMask *) &req[1];
     mask->deviceid = 0;
     mask->mask_len = 0xFFFF;
     request_XISelectEvent(req, BadLength);
@@ -320,7 +320,7 @@ test_XISelectEvents(void)
     /* testing various device ids */
     printf("Testing existing device ids.\n");
     for (i = 0; i < 6; i++) {
-        mask = (xXIEventMask *) & req[1];
+        mask = (xXIEventMask *) &req[1];
         mask->deviceid = i;
         mask->mask_len = 1;
         req->win = ROOT_WINDOW_ID;
@@ -332,7 +332,7 @@ test_XISelectEvents(void)
     for (i = 6; i <= 0xFFFF; i++) {
         req->win = ROOT_WINDOW_ID;
         req->num_masks = 1;
-        mask = (xXIEventMask *) & req[1];
+        mask = (xXIEventMask *) &req[1];
         mask->deviceid = i;
         mask->mask_len = 1;
         request_XISelectEvent(req, BadDevice);
diff --git a/xkb/xkb.c b/xkb/xkb.c
index c67896f..7e51e40 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -1650,8 +1650,8 @@ CheckKeyTypes(ClientPtr client,
             xkbKTSetMapEntryWireDesc *mapWire;
             xkbModsWireDesc *preWire;
 
-            mapWire = (xkbKTSetMapEntryWireDesc *) & wire[1];
-            preWire = (xkbModsWireDesc *) & mapWire[wire->nMapEntries];
+            mapWire = (xkbKTSetMapEntryWireDesc *) &wire[1];
+            preWire = (xkbModsWireDesc *) &mapWire[wire->nMapEntries];
             for (n = 0; n < wire->nMapEntries; n++) {
                 if (client->swapped) {
                     swaps(&mapWire[n].virtualMods);
@@ -1761,8 +1761,8 @@ CheckKeySyms(ClientPtr client,
             *errorRtrn = _XkbErrCode3(0x17, i + req->firstKeySym, wire->nSyms);
             return 0;
         }
-        pSyms = (KeySym *) & wire[1];
-        wire = (xkbSymMapWireDesc *) & pSyms[wire->nSyms];
+        pSyms = (KeySym *) &wire[1];
+        wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms];
     }
 
     map = &xkb->map->key_sym_map[i];
@@ -2039,7 +2039,7 @@ SetKeyTypes(XkbDescPtr xkb,
             unsigned tmp;
 
             mapWire = (xkbKTSetMapEntryWireDesc *) map;
-            preWire = (xkbModsWireDesc *) & mapWire[wire->nMapEntries];
+            preWire = (xkbModsWireDesc *) &mapWire[wire->nMapEntries];
             for (n = 0; n < wire->nMapEntries; n++) {
                 pOld->map[n].active = 1;
                 pOld->map[n].mods.mask = mapWire[n].realMods;
@@ -2098,7 +2098,7 @@ SetKeySyms(ClientPtr client,
 
     oldMap = &xkb->map->key_sym_map[req->firstKeySym];
     for (i = 0; i < req->nKeySyms; i++, oldMap++) {
-        pSyms = (KeySym *) & wire[1];
+        pSyms = (KeySym *) &wire[1];
         if (wire->nSyms > 0) {
             newSyms = XkbResizeKeySyms(xkb, i + req->firstKeySym, wire->nSyms);
             for (s = 0; s < wire->nSyms; s++) {
@@ -2116,7 +2116,7 @@ SetKeySyms(ClientPtr client,
         oldMap->kt_index[3] = wire->ktIndex[3];
         oldMap->group_info = wire->groupInfo;
         oldMap->width = wire->width;
-        wire = (xkbSymMapWireDesc *) & pSyms[wire->nSyms];
+        wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms];
     }
     first = req->firstKeySym;
     last = first + req->nKeySyms - 1;
@@ -2408,7 +2408,7 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
     }
 
     if ((req->present & XkbKeyTypesMask) &&
-        (!CheckKeyTypes(client, xkb, req, (xkbKeyTypeWireDesc **) & values,
+        (!CheckKeyTypes(client, xkb, req, (xkbKeyTypeWireDesc **) &values,
                         &nTypes, mapWidths))) {
         client->errorValue = nTypes;
         return BadValue;
@@ -2433,7 +2433,7 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
 
     if ((req->present & XkbKeySymsMask) &&
         (!CheckKeySyms(client, xkb, req, nTypes, mapWidths, symsPerKey,
-                       (xkbSymMapWireDesc **) & values, &error))) {
+                       (xkbSymMapWireDesc **) &values, &error))) {
         client->errorValue = error;
         return BadValue;
     }
@@ -2447,7 +2447,7 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
 
     if ((req->present & XkbKeyBehaviorsMask) &&
         (!CheckKeyBehaviors
-         (xkb, req, (xkbBehaviorWireDesc **) & values, &error))) {
+         (xkb, req, (xkbBehaviorWireDesc **) &values, &error))) {
         client->errorValue = error;
         return BadValue;
     }
@@ -2469,7 +2469,7 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
     }
     if ((req->present & XkbVirtualModMapMask) &&
         (!CheckVirtualModMap
-         (xkb, req, (xkbVModMapWireDesc **) & values, &error))) {
+         (xkb, req, (xkbVModMapWireDesc **) &values, &error))) {
         client->errorValue = error;
         return BadValue;
     }
@@ -5097,7 +5097,7 @@ _CheckSetOverlay(char **wire_inout,
     }
     CHK_ATOM_ONLY(olWire->name);
     ol = XkbAddGeomOverlay(section, olWire->name, olWire->nRows);
-    rWire = (xkbOverlayRowWireDesc *) & olWire[1];
+    rWire = (xkbOverlayRowWireDesc *) &olWire[1];
     for (r = 0; r < olWire->nRows; r++) {
         register int k;
         xkbOverlayKeyWireDesc *kWire;
@@ -5109,7 +5109,7 @@ _CheckSetOverlay(char **wire_inout,
             return BadMatch;
         }
         row = XkbAddGeomOverlayRow(ol, rWire->rowUnder, rWire->nKeys);
-        kWire = (xkbOverlayKeyWireDesc *) & rWire[1];
+        kWire = (xkbOverlayKeyWireDesc *) &rWire[1];
         for (k = 0; k < rWire->nKeys; k++, kWire++) {
             if (XkbAddGeomOverlayKey(ol, row,
                                      (char *) kWire->over,
@@ -5163,7 +5163,7 @@ _CheckSetSections(XkbGeometryPtr geom,
         section->width = sWire->width;
         section->height = sWire->height;
         section->angle = sWire->angle;
-        rWire = (xkbRowWireDesc *) & sWire[1];
+        rWire = (xkbRowWireDesc *) &sWire[1];
         for (r = 0; r < sWire->nRows; r++) {
             register int k;
             XkbRowPtr row;
@@ -5179,7 +5179,7 @@ _CheckSetSections(XkbGeometryPtr geom,
             row->top = rWire->top;
             row->left = rWire->left;
             row->vertical = rWire->vertical;
-            kWire = (xkbKeyWireDesc *) & rWire[1];
+            kWire = (xkbKeyWireDesc *) &rWire[1];
             for (k = 0; k < rWire->nKeys; k++) {
                 XkbKeyPtr key;
 
@@ -5201,7 +5201,7 @@ _CheckSetSections(XkbGeometryPtr geom,
                     return BadMatch;
                 }
             }
-            rWire = (xkbRowWireDesc *) & kWire[rWire->nKeys];
+            rWire = (xkbRowWireDesc *) &kWire[rWire->nKeys];
         }
         wire = (char *) rWire;
         if (sWire->nDoodads > 0) {
@@ -5265,7 +5265,7 @@ _CheckSetShapes(XkbGeometryPtr geom,
                 if (!ol)
                     return BadAlloc;
                 ol->corner_radius = olWire->cornerRadius;
-                ptWire = (xkbPointWireDesc *) & olWire[1];
+                ptWire = (xkbPointWireDesc *) &olWire[1];
                 for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++) {
                     pt->x = ptWire[p].x;
                     pt->y = ptWire[p].y;
@@ -6348,7 +6348,7 @@ ProcXkbGetDeviceInfo(ClientPtr client)
         xkbActionWireDesc *awire;
 
         sz = rep.nBtnsRtrn * SIZEOF(xkbActionWireDesc);
-        awire = (xkbActionWireDesc *) & dev->button->xkb_acts[rep.firstBtnRtrn];
+        awire = (xkbActionWireDesc *) &dev->button->xkb_acts[rep.firstBtnRtrn];
         WriteToClient(client, sz, awire);
         length -= sz;
     }
diff --git a/xkb/xkbout.c b/xkb/xkbout.c
index cd1ae0b..7bb6cea 100644
--- a/xkb/xkbout.c
+++ b/xkb/xkbout.c
@@ -522,7 +522,7 @@ XkbWriteXKBSymbols(FILE * file,
                     for (s = 0; s < XkbKeyGroupWidth(xkb, i, g); s++) {
                         if (s != 0)
                             fprintf(file, ", ");
-                        WriteXKBAction(file, xkb, (XkbAnyAction *) & acts[s]);
+                        WriteXKBAction(file, xkb, (XkbAnyAction *) &acts[s]);
                     }
                     fprintf(file, " ]");
                     acts += XkbKeyGroupsWidth(xkb, i);


More information about the Xquartz-changes mailing list