[Xquartz-changes] xserver: Branch 'server-1.9-apple' - 12 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Tue Sep 28 18:58:40 PDT 2010


Rebased ref, commits from common ancestor:
commit db8875abbe1af5e7e0a1b6960dce891f90937661
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 a06f98b..3b9efea 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -2080,11 +2080,8 @@ fbFillRegionSolid (DrawablePtr	pDrawable,
 		   FbBits	xor);
 
 extern _X_EXPORT pixman_image_t *
-image_from_pict (PicturePtr	pict,
-		 Bool		has_clip,
-		 int		*xoff,
-		 int		*yoff);
-
+image_from_pict (PicturePtr pict,
+		 Bool       has_clip);
 extern _X_EXPORT void free_pixman_pict (PicturePtr, pixman_image_t *);
 
 #endif /* _FB_H_ */
diff --git a/fb/fbpict.c b/fb/fbpict.c
index f7f1200..5467ee4 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -156,24 +156,19 @@ fbComposite (CARD8      op,
 	     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, xSrc - xDst, ySrc - yDst, width, height);
     if (pMask)
 	miCompositeSourceValidate (pMask, xMask - xDst, yMask - yDst, width, height);
     
-    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,
+				xSrc, ySrc, xMask, yMask, xDst, yDst,
 				width, height);
     }
 
@@ -271,22 +266,22 @@ create_conical_gradient_image (PictGradient *gradient)
 
 static pixman_image_t *
 create_bits_picture (PicturePtr pict,
-		     Bool       has_clip,
-		     int	*xoff,
-		     int	*yoff)
+		     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 (
 	pict->format,
-	pixmap->drawable.width, pixmap->drawable.height,
+	pict->pDrawable->width, pict->pDrawable->height,
 	(uint32_t *)bits, stride * sizeof (FbStride));
     
     
@@ -312,55 +307,33 @@ create_bits_picture (PicturePtr pict,
 	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);
+image_from_pict_internal (PicturePtr pict, Bool has_clip, 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, (pixman_transform_t *)pict->transform);
     }
     
     switch (pict->repeatType)
@@ -390,8 +363,7 @@ set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int
      */
     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);
+	pixman_image_t *alpha_map = image_from_pict_internal (pict->alphaMap, TRUE, TRUE);
 	
 	pixman_image_set_alpha_map (
 	    image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
@@ -424,7 +396,8 @@ set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int
 }
 
 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;
 
@@ -433,7 +406,7 @@ image_from_pict_internal (PicturePtr pict, Bool has_clip, int *xoff, int *yoff,
 
     if (pict->pDrawable)
     {
-	image = create_bits_picture (pict, has_clip, xoff, yoff);
+	image = create_bits_picture (pict, has_clip);
     }
     else if (pict->pSourcePict)
     {
@@ -454,19 +427,18 @@ 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 9f5c39f..9c55236 100644
--- a/fb/fbtrap.c
+++ b/fb/fbtrap.c
@@ -38,8 +38,7 @@ fbAddTraps (PicturePtr	pPicture,
 	    int		ntrap,
 	    xTrap	*traps)
 {
-    int image_xoff, image_yoff;
-    pixman_image_t *image = image_from_pict (pPicture, FALSE, &image_xoff, &image_yoff);
+    pixman_image_t *image = image_from_pict (pPicture, FALSE);
 
     if (!image)
 	return;
@@ -55,8 +54,7 @@ fbRasterizeTrapezoid (PicturePtr    pPicture,
 		      int	    x_off,
 		      int	    y_off)
 {
-    int	mask_xoff, mask_yoff;
-    pixman_image_t *image = image_from_pict (pPicture, FALSE, &mask_xoff, &mask_yoff);
+    pixman_image_t *image = image_from_pict (pPicture, FALSE);
 
     if (!image)
 	return;
commit 0d20328bebecdedb819b02ecbeebcf9751cbd39c
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 94258b8..4f25c23 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -521,6 +521,7 @@ void RootlessSetPixmapOfAncestors(WindowPtr pWin);
 void RootlessStartDrawing(WindowPtr pWin);
 void RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn);
 Bool IsFramedWindow(WindowPtr pWin);
+#include "../fb/fb.h"
 #endif 
 
 void
@@ -548,24 +549,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;
-
-    if(IsFramedWindow(pWin)) {
-        RootlessStartDrawing(pWin);
-        RootlessDamageRegion(pWin, prgn);
-    
-        if(pWin->backgroundState == ParentRelative) {
-            if((what == PW_BACKGROUND) || 
-               (what == PW_BORDER && !pWin->borderIsPixel))
-                RootlessSetPixmapOfAncestors(pWin);
-        }
-    }
 #endif
     
     if (what == PW_BACKGROUND)
     {
+#ifdef ROOTLESS
+	if(IsFramedWindow(pWin)) {
+	    RootlessStartDrawing(pWin);
+	    RootlessDamageRegion(pWin, prgn);
+
+	    if(pWin->backgroundState == ParentRelative) {
+		RootlessSetPixmapOfAncestors(pWin);
+	    }
+	}
+#endif
+
 	while (pWin->backgroundState == ParentRelative)
 	    pWin = pWin->parent;
 
@@ -587,6 +601,18 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     {
 	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;
 	
@@ -595,6 +621,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;
@@ -657,6 +689,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 6a0b4051972a4fa6f1a3b22ec1ae54bd1849bc9f
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Tue Aug 3 12:51:51 2010 -0700

    XQuartz: RandR: Refactor legacy mode-switching to be better integrated with RandR
    
    Adds three new functions
    void QuartzRandRSetFakeRootless (void);
    void QuartzRandRSetFakeFullscreen (void);
    void QuartzRandRToggleFullscreen (void);
    
    The first two are identical to requesting the fake modes from a RandR client
    The third responds to cmd-alt-a to leave fullscreen or RandR.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>
    (cherry picked from commit c45bea0c044ad37bedb42209f7e6ea8b587999f0)

diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 781dccc..8f4f23f 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -370,7 +370,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
                     break;
                     
                 case 18: /* ApplicationDidReactivate */
-                    if (XQuartzHasRoot) for_appkit = NO;
+                    if (XQuartzFullscreenVisible) for_appkit = NO;
                     break;
                     
                 case NSApplicationDeactivatedEventType:
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 4332202..74fadf4 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -241,17 +241,17 @@ static void DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr de
             DEBUG_LOG("kXquartzToggleFullscreen\n");
             if(XQuartzIsRootless)
                 ErrorF("Ignoring kXquartzToggleFullscreen because of rootless mode.");
-            else if (XQuartzHasRoot)
-                QuartzHide();
-            else
-                QuartzShow();
+            else 
+                QuartzRandRToggleFullscreen();
             break;
             
         case kXquartzSetRootless:
             DEBUG_LOG("kXquartzSetRootless\n");
-            QuartzSetRootless(e->data[0]);
-            if (!XQuartzIsRootless && !XQuartzHasRoot)
-                QuartzHide();
+            if(e->data[0]) {
+                QuartzRandRSetFakeRootless();
+            } else {
+                QuartzRandRSetFakeFullscreen(FALSE);
+            }
             break;
             
         case kXquartzSetRootClip:
diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index cd90457..e21303c 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -74,7 +74,7 @@ const char             *quartzOpenGLBundle = NULL;
 Bool XQuartzFullscreenDisableHotkeys = TRUE;
 Bool XQuartzOptionSendsAlt = FALSE;
 Bool XQuartzEnableKeyEquivalents = TRUE;
-Bool XQuartzHasRoot = FALSE;
+Bool XQuartzFullscreenVisible = FALSE;
 Bool XQuartzRootlessDefault = TRUE;
 Bool XQuartzIsRootless = TRUE;
 Bool XQuartzServerVisible = FALSE;
@@ -246,44 +246,58 @@ void QuartzUpdateScreens(void) {
     quartzProcs->UpdateScreen(pScreen);
 }
 
-void QuartzSetFullscreen(Bool state) {
+void QuartzShowFullscreen(int state) {
+    int i;
+    
+    DEBUG_LOG("QuartzShowFullscreen: state=%d\n", state);
     
-    DEBUG_LOG("QuartzSetFullscreen: state=%d\n", state);
+    if(XQuartzIsRootless) {
+        ErrorF("QuartzShowFullscreen called while in rootless mode.\n");
+        return;
+    }
     
-    if(XQuartzHasRoot == state)
+    if(XQuartzFullscreenVisible == state)
         return;
     
-    XQuartzHasRoot = state;
+    XQuartzFullscreenVisible = state;
     
     xp_disable_update ();
     
-    if (!XQuartzHasRoot && !XQuartzIsRootless)
+    if (!XQuartzFullscreenVisible)
         RootlessHideAllWindows();
     
-    RootlessUpdateRooted(XQuartzHasRoot);
+    RootlessUpdateRooted(XQuartzFullscreenVisible);
     
-    if (XQuartzHasRoot && !XQuartzIsRootless)
+    if (XQuartzFullscreenVisible) {
         RootlessShowAllWindows ();
-    
-    if (XQuartzHasRoot || XQuartzIsRootless) {
-        RootlessRepositionWindows(screenInfo.screens[0]);
+        for (i=0; i < screenInfo.numScreens; i++) {
+            ScreenPtr pScreen = screenInfo.screens[i];        
+            RootlessRepositionWindows(pScreen);
+            // JH: I don't think this is necessary, but keeping it here as a reminder
+            //RootlessUpdateScreenPixmap(pScreen);
+        }
     }
 
     /* Somehow the menubar manages to interfere with our event stream
      * in fullscreen mode, even though it's not visible. 
      */
-    X11ApplicationShowHideMenubar(!XQuartzHasRoot);
+    X11ApplicationShowHideMenubar(!XQuartzFullscreenVisible);
     
     xp_reenable_update ();
     
     if (XQuartzFullscreenDisableHotkeys)
-        xp_disable_hot_keys(XQuartzHasRoot);
+        xp_disable_hot_keys(XQuartzFullscreenVisible);
 }
 
-void QuartzSetRootless(Bool state) {
+void QuartzSetRootless(Bool state) {    
+    DEBUG_LOG("QuartzSetRootless state=%d\n", state);
+    
     if(XQuartzIsRootless == state)
         return;
     
+    if(state)
+        QuartzShowFullscreen(FALSE);
+    
     XQuartzIsRootless = state;
 
     xp_disable_update();
@@ -291,20 +305,17 @@ void QuartzSetRootless(Bool state) {
     /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */    
     QuartzUpdateScreens();
 
-    if(!XQuartzHasRoot) {
-        if(!XQuartzIsRootless) {
-            RootlessHideAllWindows();
-        } else {
-            RootlessShowAllWindows();
-        }
+    if(XQuartzIsRootless) {
+        RootlessShowAllWindows();
+    } else {
+        RootlessHideAllWindows();
     }
 
-    X11ApplicationShowHideMenubar(!XQuartzHasRoot);
+    X11ApplicationShowHideMenubar(TRUE);
 
     xp_reenable_update();
 
-    if (!XQuartzIsRootless && XQuartzFullscreenDisableHotkeys)
-        xp_disable_hot_keys(XQuartzHasRoot);
+    xp_disable_hot_keys(FALSE);
 }
 
 /*
@@ -327,7 +338,7 @@ void QuartzShow(void) {
     }
     
     if (!XQuartzIsRootless)
-        QuartzSetFullscreen(TRUE);
+        QuartzShowFullscreen(TRUE);
 }
 
 
@@ -348,8 +359,9 @@ void QuartzHide(void)
             }
         }
     }
-    
-    QuartzSetFullscreen(FALSE);
+
+    if(!XQuartzIsRootless)
+        QuartzShowFullscreen(FALSE);
     XQuartzServerVisible = FALSE;
 }
 
diff --git a/hw/xquartz/quartz.h b/hw/xquartz/quartz.h
index a0a17cb..7efb7e0 100644
--- a/hw/xquartz/quartz.h
+++ b/hw/xquartz/quartz.h
@@ -115,12 +115,8 @@ typedef struct _QuartzModeProcs {
 
 extern QuartzModeProcsPtr quartzProcs;
 
-extern Bool XQuartzHasRoot;          /* TODO: These two booleans are very similar and */
-extern Bool XQuartzServerVisible;    /* the code that uses them needs to be refactored
-                                      * XQuartzHasRoot is essentially the "saved" XQuartzServerVisible
-                                      * value from when the server was not in rootless mode.
-                                      */
-
+extern Bool XQuartzFullscreenVisible; /* Are the windows visible (predicated on !rootless) */
+extern Bool XQuartzServerVisible;     /* Is the server visible ... TODO: Refactor to "active" */
 extern Bool XQuartzEnableKeyEquivalents;
 extern Bool XQuartzRootlessDefault;  /* Is our default mode rootless? */
 extern Bool XQuartzIsRootless;       /* Is our current mode rootless (or FS)? */
@@ -144,7 +140,7 @@ void QuartzSetRootClip(BOOL enable);
 void QuartzSpaceChanged(uint32_t space_id);
 
 void QuartzSetRootless(Bool state);
-void QuartzSetFullscreen(Bool state);
+void QuartzShowFullscreen(Bool state);
 
 int server_main(int argc, char **argv, char **envp);
 #endif
diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c
index bbeebda..298ec0a 100644
--- a/hw/xquartz/quartzRandR.c
+++ b/hw/xquartz/quartzRandR.c
@@ -62,7 +62,7 @@ static Bool ignore_next_fake_mode_update = FALSE;
 #define CALLBACK_ERROR -1
 
 typedef int (*QuartzModeCallback)
-    (ScreenPtr, CGDirectDisplayID, QuartzModeInfoPtr, void *);
+    (ScreenPtr, QuartzModeInfoPtr, void *);
 
 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
 
@@ -98,6 +98,7 @@ static void QuartzRandRGetModeInfo (CFDictionaryRef modeRef,
     if (pMode->refresh == 0)
         pMode->refresh = DEFAULT_REFRESH;
     pMode->ref = NULL;
+    pMode->pSize = NULL;
 }
 
 static Bool QuartzRandRCopyCurrentModeInfo (CGDirectDisplayID screenId,
@@ -112,14 +113,13 @@ static Bool QuartzRandRCopyCurrentModeInfo (CGDirectDisplayID screenId,
     return TRUE;
 }
 
-static Bool QuartzRandRSetMode (CGDirectDisplayID screenId,
+static Bool QuartzRandRSetCGMode (CGDirectDisplayID screenId,
                                 QuartzModeInfoPtr pMode) {
     CFDictionaryRef modeRef = (CFDictionaryRef) pMode->ref;
     return (CGDisplaySwitchToMode(screenId, modeRef) == kCGErrorSuccess);
 }
 
 static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
-                                       CGDirectDisplayID screenId,
                                        QuartzModeCallback callback,
                                        void *data) {
     CFDictionaryRef curModeRef, modeRef;
@@ -127,28 +127,9 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
     CFArrayRef modes;
     QuartzModeInfo modeInfo;
     int i;
-    BOOL retval = TRUE;
+    BOOL retval = FALSE;
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
-
-    switch(callback(pScreen, screenId, &pQuartzScreen->rootlessMode, data)) {
-        case CALLBACK_SUCCESS:
-            return TRUE;
-        case CALLBACK_ERROR:
-            return FALSE;
-        case CALLBACK_CONTINUE:
-        default:
-            break;
-    }
-
-    switch(callback(pScreen, screenId, &pQuartzScreen->fullscreenMode, data)) {
-        case CALLBACK_SUCCESS:
-            return TRUE;
-        case CALLBACK_ERROR:
-            return FALSE;
-        case CALLBACK_CONTINUE:
-        default:
-            break;
-    }
+    CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
 
     curModeRef = CGDisplayCurrentMode(screenId);
     if (!curModeRef)
@@ -172,14 +153,37 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
 
         QuartzRandRGetModeInfo(modeRef, &modeInfo);
         modeInfo.ref = (void *)modeRef;
-        cb = callback(pScreen, screenId, &modeInfo, data);
-        if (cb == CALLBACK_SUCCESS)
+        cb = callback(pScreen, &modeInfo, data);
+        if (cb == CALLBACK_CONTINUE)
+            retval = TRUE;
+        else if (cb == CALLBACK_SUCCESS)
+            return TRUE;
+        else if (cb == CALLBACK_ERROR)
+            return FALSE;
+    }
+
+    switch(callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
+        case CALLBACK_SUCCESS:
+            return TRUE;
+        case CALLBACK_ERROR:
+            return FALSE;
+        case CALLBACK_CONTINUE:
+            retval = TRUE;
+        default:
             break;
-        if (cb == CALLBACK_ERROR) {
-            retval = FALSE;
+    }
+
+    switch(callback(pScreen, &pQuartzScreen->fullscreenMode, data)) {
+        case CALLBACK_SUCCESS:
+            return TRUE;
+        case CALLBACK_ERROR:
+            return FALSE;
+        case CALLBACK_CONTINUE:
+            retval = TRUE;
+        default:
             break;
-        }
     }
+
     return retval;
 }
 
@@ -193,6 +197,7 @@ static void QuartzRandRGetModeInfo (CGDisplayModeRef modeRef,
     if (pMode->refresh == 0)
         pMode->refresh = DEFAULT_REFRESH;
     pMode->ref = NULL;
+    pMode->pSize = NULL;
 }
 
 static Bool QuartzRandRCopyCurrentModeInfo (CGDirectDisplayID screenId,
@@ -206,7 +211,7 @@ static Bool QuartzRandRCopyCurrentModeInfo (CGDirectDisplayID screenId,
     return TRUE;
 }
 
-static Bool QuartzRandRSetMode (CGDirectDisplayID screenId,
+static Bool QuartzRandRSetCGMode (CGDirectDisplayID screenId,
                                 QuartzModeInfoPtr pMode) {
     CGDisplayModeRef modeRef = (CGDisplayModeRef) pMode->ref;
     if (!modeRef)
@@ -216,7 +221,6 @@ static Bool QuartzRandRSetMode (CGDirectDisplayID screenId,
 }
 
 static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
-                                       CGDirectDisplayID screenId,
                                        QuartzModeCallback callback,
                                        void *data) {
     CGDisplayModeRef curModeRef, modeRef;
@@ -225,29 +229,10 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
     CFArrayRef modes;
     QuartzModeInfo modeInfo;
     int i;
-    Bool retval = TRUE;
+    Bool retval = FALSE;
 
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
-
-    switch(callback(pScreen, screenId, &pQuartzScreen->rootlessMode, data)) {
-        case CALLBACK_SUCCESS:
-            return TRUE;
-        case CALLBACK_ERROR:
-            return FALSE;
-        case CALLBACK_CONTINUE:
-        default:
-            break;
-    }
-
-    switch(callback(pScreen, screenId, &pQuartzScreen->fullscreenMode, data)) {
-        case CALLBACK_SUCCESS:
-            return TRUE;
-        case CALLBACK_ERROR:
-            return FALSE;
-        case CALLBACK_CONTINUE:
-        default:
-            break;
-    }
+    CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
 
     curModeRef = CGDisplayCopyDisplayMode(screenId);
     if (!curModeRef)
@@ -277,18 +262,45 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
 
         QuartzRandRGetModeInfo(modeRef, &modeInfo);
         modeInfo.ref = modeRef;
-        cb = callback(pScreen, screenId, &modeInfo, data);
-        if (cb == CALLBACK_SUCCESS)
+        cb = callback(pScreen, &modeInfo, data);
+        if (cb == CALLBACK_CONTINUE) {
+            retval = TRUE;
+        } else if (cb == CALLBACK_SUCCESS) {
+            CFRelease(modes);
+            CFRelease(curPixelEnc);
+            return TRUE;
+        } else if (cb == CALLBACK_ERROR) {
+            CFRelease(modes);
+            CFRelease(curPixelEnc);
+            return FALSE;
+        }
+    }
+
+    CFRelease(modes);
+    CFRelease(curPixelEnc);
+
+    switch(callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
+        case CALLBACK_SUCCESS:
+            return TRUE;
+        case CALLBACK_ERROR:
+            return FALSE;
+        case CALLBACK_CONTINUE:
+            retval = TRUE;
+        default:
             break;
-		if (cb == CALLBACK_ERROR) {
-			retval = FALSE;
+    }
+
+    switch(callback(pScreen, &pQuartzScreen->fullscreenMode, data)) {
+        case CALLBACK_SUCCESS:
+            return TRUE;
+        case CALLBACK_ERROR:
+            return FALSE;
+        case CALLBACK_CONTINUE:
+            retval = TRUE;
+        default:
             break;
-		}
     }
-		
-    CFRelease(modes);
 
-    CFRelease(curPixelEnc);
     return retval;
 }
 
@@ -306,14 +318,15 @@ static Bool QuartzRandRRegisterMode (ScreenPtr pScreen,
                                      QuartzModeInfoPtr pMode) {
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
     Bool isCurrentMode = QuartzRandRModesEqual(&pQuartzScreen->currentMode, pMode);
-    RRScreenSizePtr pSize = RRRegisterSize(pScreen,
-        pMode->width, pMode->height, pScreen->mmWidth, pScreen->mmHeight);
-    if (pSize) {
+
+    /* TODO: DPI */
+    pMode->pSize = RRRegisterSize(pScreen, pMode->width, pMode->height, pScreen->mmWidth, pScreen->mmHeight);
+    if (pMode->pSize) {
         //DEBUG_LOG("registering: %d x %d @ %d %s\n", (int)pMode->width, (int)pMode->height, (int)pMode->refresh, isCurrentMode ? "*" : "");
-        RRRegisterRate(pScreen, pSize, pMode->refresh);
+        RRRegisterRate(pScreen, pMode->pSize, pMode->refresh);
 
         if (isCurrentMode)
-            RRSetCurrentConfig(pScreen, RR_Rotate_0, pMode->refresh, pSize);
+            RRSetCurrentConfig(pScreen, RR_Rotate_0, pMode->refresh, pMode->pSize);
 
         return TRUE;
     }
@@ -321,7 +334,6 @@ static Bool QuartzRandRRegisterMode (ScreenPtr pScreen,
 }
 
 static int QuartzRandRRegisterModeCallback (ScreenPtr pScreen,
-                                        CGDirectDisplayID screenId,
                                         QuartzModeInfoPtr pMode,
                                         void *data __unused) {
     if(QuartzRandRRegisterMode(pScreen, pMode)) {
@@ -331,40 +343,53 @@ static int QuartzRandRRegisterModeCallback (ScreenPtr pScreen,
     }
 }
 
+static Bool QuartzRandRSetMode(ScreenPtr pScreen, QuartzModeInfoPtr pMode, BOOL doRegister) {
+    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+    CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
+
+    if (pQuartzScreen->currentMode.ref && CFEqual(pMode->ref, pQuartzScreen->currentMode.ref)) {
+        DEBUG_LOG("Requested RandR resolution matches current CG mode\n");
+    } if (QuartzRandRSetCGMode(screenId, pMode)) {
+        ignore_next_fake_mode_update = TRUE;
+    } else {
+        DEBUG_LOG("Error while requesting CG resolution change.\n");
+        return FALSE;
+    }
+
+    /* If the client requested the fake rootless mode, switch to rootless.
+     * Otherwise, force fullscreen mode.
+     */
+    QuartzSetRootless(pMode->refresh == FAKE_REFRESH_ROOTLESS);
+    if (pMode->refresh != FAKE_REFRESH_ROOTLESS) {
+        QuartzShowFullscreen(TRUE);
+    }
+
+    if(pQuartzScreen->currentMode.ref)
+        CFRelease(pQuartzScreen->currentMode.ref);
+    pQuartzScreen->currentMode = *pMode;
+    CFRetain(pQuartzScreen->currentMode.ref);
+    
+    return TRUE;
+}
+
 static int QuartzRandRSetModeCallback (ScreenPtr pScreen,
-                                       CGDirectDisplayID screenId,
                                        QuartzModeInfoPtr pMode,
                                        void *data) {
     QuartzModeInfoPtr pReqMode = (QuartzModeInfoPtr) data;
-    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
 	
     if (!QuartzRandRModesEqual(pMode, pReqMode))
         return CALLBACK_CONTINUE;  /* continue enumeration */
 
     DEBUG_LOG("Found a match for requested RandR resolution (%dx%d@%d).\n", (int)pMode->width, (int)pMode->height, (int)pMode->refresh);
 
-    if (pQuartzScreen->currentMode.ref && CFEqual(pMode->ref, pQuartzScreen->currentMode.ref)) {
-        DEBUG_LOG("Requested RandR resolution matches current CG mode\n");
-        return CALLBACK_SUCCESS; /* We don't need to do anything in CG */
-    }
-
-    if (QuartzRandRSetMode(screenId, pMode)) {
-        if(pQuartzScreen->currentMode.ref)
-            CFRelease(pQuartzScreen->currentMode.ref);
-        pQuartzScreen->currentMode = *pMode;
-        CFRetain(pQuartzScreen->currentMode.ref);
-
-        ignore_next_fake_mode_update = TRUE;
+    if(QuartzRandRSetMode(pScreen, pMode, FALSE))
         return CALLBACK_SUCCESS;
-    } else {
-        DEBUG_LOG("Error while requesting CG resolution change.\n");
+    else
         return CALLBACK_ERROR;
-    }
 }
 
 static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
-    CGDirectDisplayID screenId;
 
     *rotations = RR_Rotate_0;  /* TODO: support rotation */
 
@@ -381,8 +406,7 @@ static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
         return TRUE;
     }
 
-    screenId = pQuartzScreen->displayIDs[0];
-    return QuartzRandREnumerateModes(pScreen, screenId, QuartzRandRRegisterModeCallback, NULL);
+    return QuartzRandREnumerateModes(pScreen, QuartzRandRRegisterModeCallback, NULL);
 }
 
 static Bool QuartzRandRSetConfig (ScreenPtr           pScreen,
@@ -390,39 +414,20 @@ static Bool QuartzRandRSetConfig (ScreenPtr           pScreen,
                                   int                 rate,
                                   RRScreenSizePtr     pSize) {
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
-    CGDirectDisplayID screenId;
     QuartzModeInfo reqMode;
 
     reqMode.width = pSize->width;
     reqMode.height = pSize->height;
     reqMode.refresh = rate;
 
-    /* If the client requested the fake rootless mode, switch to rootless.
-     * Otherwise, force fullscreen mode.
-     * TODO: Refactor all this fullscreen/rootless crap as it is spaghetti
-     *       has redundancies.
-     */
-    QuartzSetRootless(reqMode.refresh == FAKE_REFRESH_ROOTLESS);
-    QuartzSetFullscreen(reqMode.refresh != FAKE_REFRESH_ROOTLESS);
-    if(reqMode.refresh != FAKE_REFRESH_ROOTLESS &&
-       reqMode.refresh != FAKE_REFRESH_FULLSCREEN)
-        QuartzShow();
-
     if (pQuartzScreen->displayCount == 0)
         return FALSE;
-    if (pQuartzScreen->displayCount > 1) {
-        /* RandR operations are not well-defined for an X11 screen spanning
-           multiple CG displays. Do not accept any configuations that differ
-           from the current configuration. */
-        return TRUE;
-    }
 
     /* Do not switch modes if requested mode is equal to current mode. */
     if (QuartzRandRModesEqual(&reqMode, &pQuartzScreen->currentMode))
         return TRUE;
         
-    screenId = pQuartzScreen->displayIDs[0];
-    if (QuartzRandREnumerateModes(pScreen, screenId, QuartzRandRSetModeCallback, &reqMode)) {
+    if (QuartzRandREnumerateModes(pScreen, QuartzRandRSetModeCallback, &reqMode)) {
         return TRUE;
     }
     
@@ -499,3 +504,57 @@ Bool QuartzRandRInit (ScreenPtr pScreen) {
     pScrPriv->rrSetConfig = QuartzRandRSetConfig;
     return TRUE;
 }
+
+void QuartzRandRSetFakeRootless (void) {
+    int i;
+    
+    DEBUG_LOG("QuartzRandRSetFakeRootless called.\n");
+    
+    for (i=0; i < screenInfo.numScreens; i++) {
+        ScreenPtr pScreen = screenInfo.screens[i];
+        QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+
+        QuartzRandRSetMode(pScreen, &pQuartzScreen->rootlessMode, TRUE);
+    }
+}
+
+void QuartzRandRSetFakeFullscreen (BOOL state) {
+    int i;
+
+    DEBUG_LOG("QuartzRandRSetFakeFullscreen called.\n");
+    
+    for (i=0; i < screenInfo.numScreens; i++) {
+        ScreenPtr pScreen = screenInfo.screens[i];
+        QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+
+        QuartzRandRSetMode(pScreen, &pQuartzScreen->fullscreenMode, TRUE);
+    }
+    
+    QuartzShowFullscreen(state);
+}
+
+/* Toggle fullscreen mode.  If "fake" fullscreen is the current mode,
+ * this will just show/hide the X11 windows.  If we are in a RandR fullscreen
+ * mode, this will toggles us to the default fake mode and hide windows if
+ * it is fullscreen
+ */
+void QuartzRandRToggleFullscreen (void) {
+    ScreenPtr pScreen = screenInfo.screens[0];
+    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+
+    if (pQuartzScreen->currentMode.ref == NULL) {
+        ErrorF("Ignoring QuartzRandRToggleFullscreen because don't have a current mode set.\n");
+    } else if (pQuartzScreen->currentMode.refresh == FAKE_REFRESH_ROOTLESS) {
+        ErrorF("Ignoring QuartzRandRToggleFullscreen because we are in rootless mode.\n");
+    } else if (pQuartzScreen->currentMode.refresh == FAKE_REFRESH_FULLSCREEN) {
+        /* Legacy fullscreen mode.  Hide/Show */
+        QuartzShowFullscreen(!XQuartzFullscreenVisible);
+    } else {
+        /* RandR fullscreen mode.  Return to default mode and hide if it is fullscreen. */
+        if(XQuartzRootlessDefault) {
+            QuartzRandRSetFakeRootless();
+        } else {
+            QuartzRandRSetFakeFullscreen(FALSE);
+        }
+    }    
+}
diff --git a/hw/xquartz/quartzRandR.h b/hw/xquartz/quartzRandR.h
index b2d4d09..fb0ce0c 100644
--- a/hw/xquartz/quartzRandR.h
+++ b/hw/xquartz/quartzRandR.h
@@ -31,9 +31,12 @@
 #ifndef _QUARTZRANDR_H_
 #define _QUARTZRANDR_H_
 
+#include "randrstr.h"
+
 typedef struct {
     size_t width, height;
     int refresh;
+    RRScreenSizePtr pSize;
     void *ref; /* CGDisplayModeRef or CFDictionaryRef */
 } QuartzModeInfo, *QuartzModeInfoPtr;
 
@@ -57,4 +60,21 @@ void QuartzCopyDisplayIDs(ScreenPtr pScreen,
 Bool QuartzRandRUpdateFakeModes (BOOL force_update);
 Bool QuartzRandRInit (ScreenPtr pScreen);
 
+/* These two functions provide functionality expected by the legacy
+ * mode switching.  They are equivalent to a client requesting one
+ * of the modes corresponding to these "fake" modes.
+ * QuartzRandRSetFakeFullscreen takes an argument which is used to determine
+ * the visibility of the windows after the change.
+ */
+void QuartzRandRSetFakeRootless (void);
+void QuartzRandRSetFakeFullscreen (BOOL state);
+
+
+/* Toggle fullscreen mode.  If "fake" fullscreen is the current mode,
+ * this will just show/hide the X11 windows.  If we are in a RandR fullscreen
+ * mode, this will toggles us to the default fake mode and hide windows if
+ * it is fullscreen
+ */
+void QuartzRandRToggleFullscreen (void);
+
 #endif
commit abfb3c7994ee4459d2de93083e4d5ba388095d55
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Mon Jul 26 23:34:49 2010 -0700

    XQuartz: RandR: Don't change the rootless preference when changing RandR mode
    
    Also renames a bunch of other variables for better consistency.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>
    (cherry picked from commit 229323a19b06f80d9b03f487e598b933b9b31d87)

diff --git a/hw/xquartz/X11Application.h b/hw/xquartz/X11Application.h
index ce19e03..4621284 100644
--- a/hw/xquartz/X11Application.h
+++ b/hw/xquartz/X11Application.h
@@ -75,9 +75,6 @@ void X11ApplicationLaunchClient (const char *cmd);
 
 void X11ApplicationMain(int argc, char **argv, char **envp);
 
-extern int X11EnableKeyEquivalents;
-extern int quartzHasRoot, quartzEnableRootless, quartzFullscreenMenu;
-
 #define PREFS_APPSMENU              "apps_menu"
 #define PREFS_FAKEBUTTONS           "enable_fake_buttons"
 #define PREFS_SYSBEEP               "enable_system_beep"
diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 36c39e5..781dccc 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -38,6 +38,7 @@
 #import "X11Application.h"
 
 #include "darwin.h"
+#include "quartz.h"
 #include "darwinEvents.h"
 #include "quartzKeyboard.h"
 #include "quartz.h"
@@ -63,9 +64,6 @@ extern int xpbproxy_run (void);
 /* Stuck modifier / button state... force release when we context switch */
 static NSEventType keyState[NUM_KEYCODES];
 
-int X11EnableKeyEquivalents = TRUE, quartzFullscreenMenu = FALSE;
-int quartzHasRoot = FALSE, quartzEnableRootless = TRUE;
-
 extern Bool noTestExtensions;
 
 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
@@ -287,23 +285,23 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
                         do_swallow = YES;
                         for_x = NO;
 #if XPLUGIN_VERSION >= 1
-                    } else if(X11EnableKeyEquivalents &&
+                    } else if(XQuartzEnableKeyEquivalents &&
                              xp_is_symbolic_hotkey_event([e eventRef])) {
                         swallow_keycode = [e keyCode];
                         do_swallow = YES;
                         for_x = NO;
 #endif
-                    } else if(X11EnableKeyEquivalents &&
+                    } else if(XQuartzEnableKeyEquivalents &&
                               [[self mainMenu] performKeyEquivalent:e]) {
                         swallow_keycode = [e keyCode];
                         do_swallow = YES;
                         for_appkit = NO;
                         for_x = NO;
-                    } else if(!quartzEnableRootless
+                    } else if(!XQuartzIsRootless
                               && ([e modifierFlags] & ALL_KEY_MASKS) == (NSCommandKeyMask | NSAlternateKeyMask)
                               && ([e keyCode] == 0 /*a*/ || [e keyCode] == 53 /*Esc*/)) {
                         /* We have this here to force processing fullscreen 
-                         * toggle even if X11EnableKeyEquivalents is disabled */
+                         * toggle even if XQuartzEnableKeyEquivalents is disabled */
                         swallow_keycode = [e keyCode];
                         do_swallow = YES;
                         for_x = NO;
@@ -372,7 +370,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
                     break;
                     
                 case 18: /* ApplicationDidReactivate */
-                    if (quartzHasRoot) for_appkit = NO;
+                    if (XQuartzHasRoot) for_appkit = NO;
                     break;
                     
                 case NSApplicationDeactivatedEventType:
@@ -422,7 +420,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
     if ([state boolValue])
         SetSystemUIMode(kUIModeNormal, 0); 
     else
-        SetSystemUIMode(kUIModeAllHidden, quartzFullscreenMenu ? kUIOptionAutoShowMenuBar : 0); // kUIModeAllSuppressed or kUIOptionAutoShowMenuBar can be used to allow "mouse-activation"
+        SetSystemUIMode(kUIModeAllHidden, XQuartzFullscreenMenu ? kUIOptionAutoShowMenuBar : 0); // kUIModeAllSuppressed or kUIOptionAutoShowMenuBar can be used to allow "mouse-activation"
 }
 
 - (void) launch_client:(NSString *)cmd {
@@ -720,18 +718,18 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) {
     NSString *nsstr;
     const char *tem;
 	
-    quartzUseSysBeep = [self prefs_get_boolean:@PREFS_SYSBEEP
-                                       default:quartzUseSysBeep];
-    quartzEnableRootless = [self prefs_get_boolean:@PREFS_ROOTLESS
-                                           default:quartzEnableRootless];
-    quartzFullscreenMenu = [self prefs_get_boolean:@PREFS_FULLSCREEN_MENU
-                                           default:quartzFullscreenMenu];
-    quartzFullscreenDisableHotkeys = ![self prefs_get_boolean:@PREFS_FULLSCREEN_HOTKEYS
-                                                      default:!quartzFullscreenDisableHotkeys];
+    XQuartzUseSysBeep = [self prefs_get_boolean:@PREFS_SYSBEEP
+                                       default:XQuartzUseSysBeep];
+    XQuartzRootlessDefault = [self prefs_get_boolean:@PREFS_ROOTLESS
+                                           default:XQuartzRootlessDefault];
+    XQuartzFullscreenMenu = [self prefs_get_boolean:@PREFS_FULLSCREEN_MENU
+                                           default:XQuartzFullscreenMenu];
+    XQuartzFullscreenDisableHotkeys = ![self prefs_get_boolean:@PREFS_FULLSCREEN_HOTKEYS
+                                                      default:!XQuartzFullscreenDisableHotkeys];
     darwinFakeButtons = [self prefs_get_boolean:@PREFS_FAKEBUTTONS
                                         default:darwinFakeButtons];
-    quartzOptionSendsAlt = [self prefs_get_boolean:@PREFS_OPTION_SENDS_ALT
-                                           default:quartzOptionSendsAlt];
+    XQuartzOptionSendsAlt = [self prefs_get_boolean:@PREFS_OPTION_SENDS_ALT
+                                           default:XQuartzOptionSendsAlt];
 
     if (darwinFakeButtons) {
         const char *fake2, *fake3;
@@ -759,8 +757,8 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) {
         }
     }
 
-    X11EnableKeyEquivalents = [self prefs_get_boolean:@PREFS_KEYEQUIVS
-                                              default:X11EnableKeyEquivalents];
+    XQuartzEnableKeyEquivalents = [self prefs_get_boolean:@PREFS_KEYEQUIVS
+                                              default:XQuartzEnableKeyEquivalents];
 	
     darwinSyncKeymap = [self prefs_get_boolean:@PREFS_SYNC_KEYMAP
                                        default:darwinSyncKeymap];
@@ -1158,7 +1156,7 @@ static inline int ensure_flag(int flags, int device_independent, int device_depe
                 pDev = darwinTabletCurrent;
             }
 
-            if(!quartzServerVisible && noTestExtensions) {
+            if(!XQuartzServerVisible && noTestExtensions) {
 #if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION > 0
 /* Older libXplugin (Tiger/"Stock" Leopard) aren't thread safe, so we can't call xp_find_window from the Appkit thread */
                 xp_window_id wid = 0;
@@ -1218,7 +1216,7 @@ static inline int ensure_flag(int flags, int device_independent, int device_depe
             /* If we're in the background, we need to send a MotionNotify event
              * first, since we aren't getting them on background mouse motion
              */
-            if(!quartzServerVisible && noTestExtensions) {
+            if(!XQuartzServerVisible && noTestExtensions) {
                 bgMouseLocationUpdated = FALSE;
                 DarwinSendPointerEvents(darwinPointer, MotionNotify, 0, location.x,
                                         location.y, pressure, tilt.x, tilt.y);
diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m
index d66d039..13b6366 100644
--- a/hw/xquartz/X11Controller.m
+++ b/hw/xquartz/X11Controller.m
@@ -609,13 +609,13 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
 }
 
 - (IBAction) enable_fullscreen_changed:sender {
-    int value = ![enable_fullscreen intValue];
+    XQuartzRootlessDefault = ![enable_fullscreen intValue];
 
-    [enable_fullscreen_menu setEnabled:!value];
+    [enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault];
 
-    DarwinSendDDXEvent(kXquartzSetRootless, 1, value);
+    DarwinSendDDXEvent(kXquartzSetRootless, 1, XQuartzRootlessDefault);
 
-    [NSApp prefs_set_boolean:@PREFS_ROOTLESS value:value];
+    [NSApp prefs_set_boolean:@PREFS_ROOTLESS value:XQuartzRootlessDefault];
     [NSApp prefs_synchronize];
 }
 
@@ -638,24 +638,24 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
         darwinFakeButtons = [fake_buttons intValue];
         [NSApp prefs_set_boolean:@PREFS_FAKEBUTTONS value:darwinFakeButtons];
     } else if(sender == use_sysbeep) {
-        quartzUseSysBeep = [use_sysbeep intValue];
-        [NSApp prefs_set_boolean:@PREFS_SYSBEEP value:quartzUseSysBeep];
+        XQuartzUseSysBeep = [use_sysbeep intValue];
+        [NSApp prefs_set_boolean:@PREFS_SYSBEEP value:XQuartzUseSysBeep];
     } else if(sender == enable_keyequivs) {
-        X11EnableKeyEquivalents =  [enable_keyequivs intValue];
-        [NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:X11EnableKeyEquivalents];
+        XQuartzEnableKeyEquivalents =  [enable_keyequivs intValue];
+        [NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:XQuartzEnableKeyEquivalents];
     } else if(sender == sync_keymap) {
         darwinSyncKeymap = [sync_keymap intValue];
         [NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap];
     } else if(sender == enable_fullscreen_menu) {
-        quartzFullscreenMenu = [enable_fullscreen_menu intValue];
-        [NSApp prefs_set_boolean:@PREFS_FULLSCREEN_MENU value:quartzFullscreenMenu];
+        XQuartzFullscreenMenu = [enable_fullscreen_menu intValue];
+        [NSApp prefs_set_boolean:@PREFS_FULLSCREEN_MENU value:XQuartzFullscreenMenu];
     } else if(sender == option_sends_alt) {
-        BOOL prev_opt_sends_alt = quartzOptionSendsAlt;
+        BOOL prev_opt_sends_alt = XQuartzOptionSendsAlt;
         
-        quartzOptionSendsAlt = [option_sends_alt intValue];
-        [NSApp prefs_set_boolean:@PREFS_OPTION_SENDS_ALT value:quartzOptionSendsAlt];
+        XQuartzOptionSendsAlt = [option_sends_alt intValue];
+        [NSApp prefs_set_boolean:@PREFS_OPTION_SENDS_ALT value:XQuartzOptionSendsAlt];
 
-        if(prev_opt_sends_alt != quartzOptionSendsAlt)
+        if(prev_opt_sends_alt != XQuartzOptionSendsAlt)
             QuartsResyncKeymap(TRUE);
     } else if(sender == click_through) {
         [NSApp prefs_set_boolean:@PREFS_CLICK_THROUGH value:[click_through intValue]];
@@ -701,10 +701,10 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
     BOOL pbproxy_active = [NSApp prefs_get_boolean:@PREFS_SYNC_PB default:YES];
     
     [fake_buttons setIntValue:darwinFakeButtons];
-    [use_sysbeep setIntValue:quartzUseSysBeep];
-    [enable_keyequivs setIntValue:X11EnableKeyEquivalents];
+    [use_sysbeep setIntValue:XQuartzUseSysBeep];
+    [enable_keyequivs setIntValue:XQuartzEnableKeyEquivalents];
     [sync_keymap setIntValue:darwinSyncKeymap];
-    [option_sends_alt setIntValue:quartzOptionSendsAlt];
+    [option_sends_alt setIntValue:XQuartzOptionSendsAlt];
     [click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_CLICK_THROUGH default:NO]];
     [focus_follows_mouse setIntValue:[NSApp prefs_get_boolean:@PREFS_FFM default:NO]];
     [focus_on_new_window setIntValue:[NSApp prefs_get_boolean:@PREFS_FOCUS_ON_NEW_WINDOW default:YES]];
@@ -729,9 +729,9 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
     [sync_text1 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]];
     [sync_text2 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]];
 	
-    [enable_fullscreen setIntValue:!quartzEnableRootless];
-    [enable_fullscreen_menu setEnabled:!quartzEnableRootless];
-    [enable_fullscreen_menu setIntValue:quartzFullscreenMenu];
+    [enable_fullscreen setIntValue:!XQuartzRootlessDefault];
+    [enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault];
+    [enable_fullscreen_menu setIntValue:XQuartzFullscreenMenu];
     
     [prefs_panel makeKeyAndOrderFront:sender];
 }
@@ -752,7 +752,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
   NSMenu *menu = [item menu];
     
   if (item == toggle_fullscreen_item)
-    return !quartzEnableRootless;
+    return !XQuartzIsRootless;
   else if (menu == [X11App windowsMenu] || menu == dock_menu
 	   || (menu == [x11_about_item menu] && [item tag] == 42))
     return (AppleWMSelectedEvents () & AppleWMControllerNotifyMask) != 0;
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 7367068..4332202 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -239,9 +239,9 @@ static void DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr de
             
         case kXquartzToggleFullscreen:
             DEBUG_LOG("kXquartzToggleFullscreen\n");
-            if(quartzEnableRootless) 
+            if(XQuartzIsRootless)
                 ErrorF("Ignoring kXquartzToggleFullscreen because of rootless mode.");
-            else if (quartzHasRoot)
+            else if (XQuartzHasRoot)
                 QuartzHide();
             else
                 QuartzShow();
@@ -250,7 +250,7 @@ static void DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr de
         case kXquartzSetRootless:
             DEBUG_LOG("kXquartzSetRootless\n");
             QuartzSetRootless(e->data[0]);
-            if (!quartzEnableRootless && !quartzHasRoot)
+            if (!XQuartzIsRootless && !XQuartzHasRoot)
                 QuartzHide();
             break;
             
diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index a52cac9..cd90457 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -66,15 +66,20 @@
 #include <rootlessCommon.h>
 #include <Xplugin.h>
 
-// Shared global variables for Quartz modes
-int                     quartzUseSysBeep = 0;
-int                     quartzServerVisible = FALSE;
 DevPrivateKeyRec        quartzScreenKeyRec;
 int                     aquaMenuBarHeight = 0;
 QuartzModeProcsPtr      quartzProcs = NULL;
 const char             *quartzOpenGLBundle = NULL;
-int                     quartzFullscreenDisableHotkeys = TRUE;
-int                     quartzOptionSendsAlt = FALSE;
+
+Bool XQuartzFullscreenDisableHotkeys = TRUE;
+Bool XQuartzOptionSendsAlt = FALSE;
+Bool XQuartzEnableKeyEquivalents = TRUE;
+Bool XQuartzHasRoot = FALSE;
+Bool XQuartzRootlessDefault = TRUE;
+Bool XQuartzIsRootless = TRUE;
+Bool XQuartzServerVisible = FALSE;
+Bool XQuartzFullscreenMenu = FALSE;
+Bool XQuartzUseSysBeep = FALSE;
 
 /*
 ===========================================================================
@@ -245,61 +250,61 @@ void QuartzSetFullscreen(Bool state) {
     
     DEBUG_LOG("QuartzSetFullscreen: state=%d\n", state);
     
-    if(quartzHasRoot == state)
+    if(XQuartzHasRoot == state)
         return;
     
-    quartzHasRoot = state;
+    XQuartzHasRoot = state;
     
     xp_disable_update ();
     
-    if (!quartzHasRoot && !quartzEnableRootless)
+    if (!XQuartzHasRoot && !XQuartzIsRootless)
         RootlessHideAllWindows();
     
-    RootlessUpdateRooted(quartzHasRoot);
+    RootlessUpdateRooted(XQuartzHasRoot);
     
-    if (quartzHasRoot && !quartzEnableRootless)
+    if (XQuartzHasRoot && !XQuartzIsRootless)
         RootlessShowAllWindows ();
     
-    if (quartzHasRoot || quartzEnableRootless) {
+    if (XQuartzHasRoot || XQuartzIsRootless) {
         RootlessRepositionWindows(screenInfo.screens[0]);
     }
 
     /* Somehow the menubar manages to interfere with our event stream
      * in fullscreen mode, even though it's not visible. 
      */
-    X11ApplicationShowHideMenubar(!quartzHasRoot);
+    X11ApplicationShowHideMenubar(!XQuartzHasRoot);
     
     xp_reenable_update ();
     
-    if (quartzFullscreenDisableHotkeys)
-        xp_disable_hot_keys(quartzHasRoot);
+    if (XQuartzFullscreenDisableHotkeys)
+        xp_disable_hot_keys(XQuartzHasRoot);
 }
 
 void QuartzSetRootless(Bool state) {
-    if(quartzEnableRootless == state)
+    if(XQuartzIsRootless == state)
         return;
     
-    quartzEnableRootless = state;
+    XQuartzIsRootless = state;
 
     xp_disable_update();
 
     /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */    
     QuartzUpdateScreens();
 
-    if(!quartzHasRoot) {
-        if(!quartzEnableRootless) {
+    if(!XQuartzHasRoot) {
+        if(!XQuartzIsRootless) {
             RootlessHideAllWindows();
         } else {
             RootlessShowAllWindows();
         }
     }
 
-    X11ApplicationShowHideMenubar(!quartzHasRoot);
+    X11ApplicationShowHideMenubar(!XQuartzHasRoot);
 
     xp_reenable_update();
 
-    if (!quartzEnableRootless && quartzFullscreenDisableHotkeys)
-        xp_disable_hot_keys(quartzHasRoot);
+    if (!XQuartzIsRootless && XQuartzFullscreenDisableHotkeys)
+        xp_disable_hot_keys(XQuartzHasRoot);
 }
 
 /*
@@ -311,17 +316,17 @@ void QuartzSetRootless(Bool state) {
 void QuartzShow(void) {
     int i;
 
-    if (quartzServerVisible)
+    if (XQuartzServerVisible)
         return;
     
-    quartzServerVisible = TRUE;
+    XQuartzServerVisible = TRUE;
     for (i = 0; i < screenInfo.numScreens; i++) {
         if (screenInfo.screens[i]) {
             quartzProcs->ResumeScreen(screenInfo.screens[i]);
         }
     }
     
-    if (!quartzEnableRootless)
+    if (!XQuartzIsRootless)
         QuartzSetFullscreen(TRUE);
 }
 
@@ -336,7 +341,7 @@ void QuartzHide(void)
 {
     int i;
 
-    if (quartzServerVisible) {
+    if (XQuartzServerVisible) {
         for (i = 0; i < screenInfo.numScreens; i++) {
             if (screenInfo.screens[i]) {
                 quartzProcs->SuspendScreen(screenInfo.screens[i]);
@@ -345,7 +350,7 @@ void QuartzHide(void)
     }
     
     QuartzSetFullscreen(FALSE);
-    quartzServerVisible = FALSE;
+    XQuartzServerVisible = FALSE;
 }
 
 
@@ -358,7 +363,7 @@ void QuartzSetRootClip(
 {
     int i;
 
-    if (!quartzServerVisible)
+    if (!XQuartzServerVisible)
         return;
 
     for (i = 0; i < screenInfo.numScreens; i++) {
diff --git a/hw/xquartz/quartz.h b/hw/xquartz/quartz.h
index 1b924e7..a0a17cb 100644
--- a/hw/xquartz/quartz.h
+++ b/hw/xquartz/quartz.h
@@ -35,6 +35,7 @@
 
 #include "screenint.h"
 #include "window.h"
+#include "pixmap.h"
 
 /*------------------------------------------
    Quartz display mode function types
@@ -113,7 +114,20 @@ typedef struct _QuartzModeProcs {
 } QuartzModeProcsRec, *QuartzModeProcsPtr;
 
 extern QuartzModeProcsPtr quartzProcs;
-extern int quartzHasRoot, quartzEnableRootless;
+
+extern Bool XQuartzHasRoot;          /* TODO: These two booleans are very similar and */
+extern Bool XQuartzServerVisible;    /* the code that uses them needs to be refactored
+                                      * XQuartzHasRoot is essentially the "saved" XQuartzServerVisible
+                                      * value from when the server was not in rootless mode.
+                                      */
+
+extern Bool XQuartzEnableKeyEquivalents;
+extern Bool XQuartzRootlessDefault;  /* Is our default mode rootless? */
+extern Bool XQuartzIsRootless;       /* Is our current mode rootless (or FS)? */
+extern Bool XQuartzFullscreenMenu;   /* Show the menu bar (autohide) while in FS */
+extern Bool XQuartzFullscreenDisableHotkeys;
+extern Bool XQuartzOptionSendsAlt;   /* Alt or Mode_switch? */
+extern Bool XQuartzUseSysBeep;       /* Sys beep or our own? */
 
 Bool QuartzAddScreen(int index, ScreenPtr pScreen);
 Bool QuartzSetupScreen(int index, ScreenPtr pScreen);
@@ -129,8 +143,8 @@ void QuartzHide(void);
 void QuartzSetRootClip(BOOL enable);
 void QuartzSpaceChanged(uint32_t space_id);
 
-void QuartzSetFullscreen(Bool state);
 void QuartzSetRootless(Bool state);
+void QuartzSetFullscreen(Bool state);
 
 int server_main(int argc, char **argv, char **envp);
 #endif
diff --git a/hw/xquartz/quartzAudio.c b/hw/xquartz/quartzAudio.c
index 708202b..d0f7c53 100644
--- a/hw/xquartz/quartzAudio.c
+++ b/hw/xquartz/quartzAudio.c
@@ -42,7 +42,7 @@
 #include <dix-config.h>
 #endif
 
-#include "quartzCommon.h"
+#include "quartz.h"
 #include "quartzAudio.h"
 
 #include <CoreAudio/CoreAudio.h>
@@ -220,7 +220,7 @@ void DDXRingBell(
     int pitch,          // pitch is Hz
     int duration )      // duration is milliseconds
 {
-    if (quartzUseSysBeep) {
+    if (XQuartzUseSysBeep) {
         if (volume)
             NSBeep();
         return;
diff --git a/hw/xquartz/quartzCommon.h b/hw/xquartz/quartzCommon.h
index 718df4b..fbfe6f8 100644
--- a/hw/xquartz/quartzCommon.h
+++ b/hw/xquartz/quartzCommon.h
@@ -38,13 +38,7 @@
 #include <X11/Xdefs.h>
 #include "privates.h"
 
-// User preferences used by Quartz modes
-extern int              quartzUseSysBeep;
-extern int              quartzFullscreenDisableHotkeys;
-extern int              quartzOptionSendsAlt;
-
 // Other shared data
-extern int              quartzServerVisible;
 extern DevPrivateKeyRec quartzScreenKeyRec;
 #define quartzScreenKey (&quartzScreenKeyRec)
 extern int              aquaMenuBarHeight;
diff --git a/hw/xquartz/quartzKeyboard.c b/hw/xquartz/quartzKeyboard.c
index 75cf23f..f54c686 100644
--- a/hw/xquartz/quartzKeyboard.c
+++ b/hw/xquartz/quartzKeyboard.c
@@ -48,7 +48,7 @@
 #include <sys/stat.h>
 #include <AvailabilityMacros.h>
 
-#include "quartzCommon.h"
+#include "quartz.h"
 #include "darwin.h"
 #include "darwinEvents.h"
 
@@ -262,7 +262,7 @@ static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) {
             case XK_Alt_L:
                 info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
                 info->modMap[MIN_KEYCODE + i] = Mod1Mask;
-                if(!quartzOptionSendsAlt)
+                if(!XQuartzOptionSendsAlt)
                     *k = XK_Mode_switch; // Yes, this is ugly.  This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor.
                 break;
 
@@ -272,7 +272,7 @@ static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) {
 #else
                 info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
 #endif
-                if(!quartzOptionSendsAlt)
+                if(!XQuartzOptionSendsAlt)
                     *k = XK_Mode_switch; // Yes, this is ugly.  This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor.
                 info->modMap[MIN_KEYCODE + i] = Mod1Mask;
                 break;
diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c
index 782aa4d..bbeebda 100644
--- a/hw/xquartz/quartzRandR.c
+++ b/hw/xquartz/quartzRandR.c
@@ -140,7 +140,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
             break;
     }
 
-    switch(callback(pScreen, screenId, &pQuartzScreen->fullScreenMode, data)) {
+    switch(callback(pScreen, screenId, &pQuartzScreen->fullscreenMode, data)) {
         case CALLBACK_SUCCESS:
             return TRUE;
         case CALLBACK_ERROR:
@@ -239,7 +239,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
             break;
     }
 
-    switch(callback(pScreen, screenId, &pQuartzScreen->fullScreenMode, data)) {
+    switch(callback(pScreen, screenId, &pQuartzScreen->fullscreenMode, data)) {
         case CALLBACK_SUCCESS:
             return TRUE;
         case CALLBACK_ERROR:
@@ -377,7 +377,7 @@ static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
            resolution including/excluding the menu bar. */
 
         QuartzRandRRegisterMode(pScreen, &pQuartzScreen->rootlessMode);
-        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fullScreenMode);
+        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fullscreenMode);
         return TRUE;
     }
 
@@ -434,37 +434,37 @@ static Bool _QuartzRandRUpdateFakeModes (ScreenPtr pScreen) {
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
 
     if (pQuartzScreen->displayCount == 1) {
-        if(pQuartzScreen->fullScreenMode.ref)
-            CFRelease(pQuartzScreen->fullScreenMode.ref);
+        if(pQuartzScreen->fullscreenMode.ref)
+            CFRelease(pQuartzScreen->fullscreenMode.ref);
         if(pQuartzScreen->currentMode.ref)
             CFRelease(pQuartzScreen->currentMode.ref);
         
         if (!QuartzRandRCopyCurrentModeInfo(pQuartzScreen->displayIDs[0],
-                                            &pQuartzScreen->fullScreenMode))
+                                            &pQuartzScreen->fullscreenMode))
             return FALSE;
 
-        CFRetain(pQuartzScreen->fullScreenMode.ref);  /* This extra retain is for currentMode's copy */
+        CFRetain(pQuartzScreen->fullscreenMode.ref);  /* This extra retain is for currentMode's copy */
     } else {
-        pQuartzScreen->fullScreenMode.width = pScreen->width;
-        pQuartzScreen->fullScreenMode.height = pScreen->height;
-        if(quartzEnableRootless)
-            pQuartzScreen->fullScreenMode.height += aquaMenuBarHeight;
+        pQuartzScreen->fullscreenMode.width = pScreen->width;
+        pQuartzScreen->fullscreenMode.height = pScreen->height;
+        if(XQuartzIsRootless)
+            pQuartzScreen->fullscreenMode.height += aquaMenuBarHeight;
     }
 
-    pQuartzScreen->fullScreenMode.refresh = FAKE_REFRESH_FULLSCREEN;
+    pQuartzScreen->fullscreenMode.refresh = FAKE_REFRESH_FULLSCREEN;
 
-    pQuartzScreen->rootlessMode = pQuartzScreen->fullScreenMode;
+    pQuartzScreen->rootlessMode = pQuartzScreen->fullscreenMode;
     pQuartzScreen->rootlessMode.refresh = FAKE_REFRESH_ROOTLESS;
     pQuartzScreen->rootlessMode.height -= aquaMenuBarHeight;
 
-    if(quartzEnableRootless) {
+    if(XQuartzIsRootless) {
         pQuartzScreen->currentMode = pQuartzScreen->rootlessMode;
     } else {
-        pQuartzScreen->currentMode = pQuartzScreen->fullScreenMode;
+        pQuartzScreen->currentMode = pQuartzScreen->fullscreenMode;
     }
     
     DEBUG_LOG("rootlessMode: %d x %d\n", (int)pQuartzScreen->rootlessMode.width, (int)pQuartzScreen->rootlessMode.height);
-    DEBUG_LOG("fullScreenMode: %d x %d\n", (int)pQuartzScreen->fullScreenMode.width, (int)pQuartzScreen->fullScreenMode.height);
+    DEBUG_LOG("fullscreenMode: %d x %d\n", (int)pQuartzScreen->fullscreenMode.width, (int)pQuartzScreen->fullscreenMode.height);
     DEBUG_LOG("currentMode: %d x %d\n", (int)pQuartzScreen->currentMode.width, (int)pQuartzScreen->currentMode.height);
     
     return TRUE;
diff --git a/hw/xquartz/quartzRandR.h b/hw/xquartz/quartzRandR.h
index 4a7990e..b2d4d09 100644
--- a/hw/xquartz/quartzRandR.h
+++ b/hw/xquartz/quartzRandR.h
@@ -45,7 +45,7 @@ typedef struct {
     // No CG display will be covered by more than one X11 screen.
     int displayCount;
     CGDirectDisplayID *displayIDs;
-    QuartzModeInfo rootlessMode, fullScreenMode, currentMode;
+    QuartzModeInfo rootlessMode, fullscreenMode, currentMode;
 } QuartzScreenRec, *QuartzScreenPtr;
 
 #define QUARTZ_PRIV(pScreen) \
diff --git a/hw/xquartz/xpr/xprAppleWM.c b/hw/xquartz/xpr/xprAppleWM.c
index 4b31e3a..1a3d427 100644
--- a/hw/xquartz/xpr/xprAppleWM.c
+++ b/hw/xquartz/xpr/xprAppleWM.c
@@ -67,7 +67,7 @@ static int xprSetWindowLevel(
     if(!winRec)
         return BadWindow;
     
-    if(quartzEnableRootless)
+    if(XQuartzIsRootless)
         wc.window_level = normal_window_levels[level];
     else
         wc.window_level = rooted_window_levels[level];
diff --git a/hw/xquartz/xpr/xprCursor.c b/hw/xquartz/xpr/xprCursor.c
index a106e72..216678e 100644
--- a/hw/xquartz/xpr/xprCursor.c
+++ b/hw/xquartz/xpr/xprCursor.c
@@ -35,7 +35,7 @@
 #include <dix-config.h>
 #endif
 
-#include "quartzCommon.h"
+#include "quartz.h"
 #include "xpr.h"
 #include "darwin.h"
 #include "darwinEvents.h"
@@ -226,7 +226,7 @@ QuartzSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x,
 {
     QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
 
-    if (!quartzServerVisible)
+    if (!XQuartzServerVisible)
         return;
 
     if (pCursor == NULL)
@@ -295,7 +295,7 @@ QuartzCrossScreen(ScreenPtr pScreen, Bool entering)
 static void
 QuartzWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
 {
-    if (quartzServerVisible)
+    if (XQuartzServerVisible)
     {
         int sx, sy;
 
diff --git a/hw/xquartz/xpr/xprFrame.c b/hw/xquartz/xpr/xprFrame.c
index 42f06ef..ede5af5 100644
--- a/hw/xquartz/xpr/xprFrame.c
+++ b/hw/xquartz/xpr/xprFrame.c
@@ -171,7 +171,7 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
 
     pFrame->level = !IsRoot (pWin) ? AppleWMWindowLevelNormal : AppleWMNumWindowLevels;
 
-    if(quartzEnableRootless)
+    if(XQuartzIsRootless)
         wc.window_level = normal_window_levels[pFrame->level];
     else
         wc.window_level = rooted_window_levels[pFrame->level];
@@ -285,7 +285,7 @@ static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) {
         RootlessWindowRec *winRec = x_hash_table_lookup(window_hash, wid, NULL);
 
         if(winRec) {
-            if(quartzEnableRootless)
+            if(XQuartzIsRootless)
                 wc.window_level = normal_window_levels[winRec->level];
             else
                 wc.window_level = rooted_window_levels[winRec->level];
diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c
index b3ac693..599ef6f 100644
--- a/hw/xquartz/xpr/xprScreen.c
+++ b/hw/xquartz/xpr/xprScreen.c
@@ -158,7 +158,7 @@ displayScreenBounds(CGDirectDisplayID id)
               (int)frame.origin.x, (int)frame.origin.y);
     
     /* Remove menubar to help standard X11 window managers. */
-    if (quartzEnableRootless && 
+    if (XQuartzIsRootless && 
         frame.origin.x == 0 && frame.origin.y == 0) {
         frame.origin.y += aquaMenuBarHeight;
         frame.size.height -= aquaMenuBarHeight;
@@ -274,7 +274,8 @@ xprDisplayInit(void)
     AppleDRIExtensionInit();
     xprAppleWMInit();
 
-    if (!quartzEnableRootless)
+    XQuartzIsRootless = XQuartzRootlessDefault;
+    if (!XQuartzIsRootless)
         RootlessHideAllWindows();
 }
 
commit 92b3dc67eef47db336674cf55ced4af40a6c29d7
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Mon Jul 26 11:45:59 2010 -0700

    XQuartz: RandR: Better handle switching betwen RandR modes that share CG modes
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>
    (cherry picked from commit 721edc69c3597578d3e7f711769ff0195af6068a)

diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c
index 65dce22..782aa4d 100644
--- a/hw/xquartz/quartzRandR.c
+++ b/hw/xquartz/quartzRandR.c
@@ -57,9 +57,12 @@ static Bool ignore_next_fake_mode_update = FALSE;
 #define DEFAULT_REFRESH  60
 #define kDisplayModeUsableFlags  (kDisplayModeValidFlag | kDisplayModeSafeFlag)
 
-typedef Bool (*QuartzModeCallback)
-    (ScreenPtr, CGDirectDisplayID, QuartzModeInfoPtr, void *);
+#define CALLBACK_SUCCESS 0
+#define CALLBACK_CONTINUE 1
+#define CALLBACK_ERROR -1
 
+typedef int (*QuartzModeCallback)
+    (ScreenPtr, CGDirectDisplayID, QuartzModeInfoPtr, void *);
 
 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
 
@@ -97,20 +100,22 @@ static void QuartzRandRGetModeInfo (CFDictionaryRef modeRef,
     pMode->ref = NULL;
 }
 
-static Bool QuartzRandRGetCurrentModeInfo (CGDirectDisplayID screenId,
+static Bool QuartzRandRCopyCurrentModeInfo (CGDirectDisplayID screenId,
                                            QuartzModeInfoPtr pMode) {
     CFDictionaryRef curModeRef = CGDisplayCurrentMode(screenId);
     if (!curModeRef)
         return FALSE;
 
     QuartzRandRGetModeInfo(curModeRef, pMode);
+    pMode->ref = (void *)curModeRef;
+    CFRetain(pMode->ref);
     return TRUE;
 }
 
 static Bool QuartzRandRSetMode (CGDirectDisplayID screenId,
                                 QuartzModeInfoPtr pMode) {
     CFDictionaryRef modeRef = (CFDictionaryRef) pMode->ref;
-    return (CGDisplaySwitchToMode(screenId, modeRef) != kCGErrorSuccess);
+    return (CGDisplaySwitchToMode(screenId, modeRef) == kCGErrorSuccess);
 }
 
 static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
@@ -122,6 +127,28 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
     CFArrayRef modes;
     QuartzModeInfo modeInfo;
     int i;
+    BOOL retval = TRUE;
+    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+
+    switch(callback(pScreen, screenId, &pQuartzScreen->rootlessMode, data)) {
+        case CALLBACK_SUCCESS:
+            return TRUE;
+        case CALLBACK_ERROR:
+            return FALSE;
+        case CALLBACK_CONTINUE:
+        default:
+            break;
+    }
+
+    switch(callback(pScreen, screenId, &pQuartzScreen->fullScreenMode, data)) {
+        case CALLBACK_SUCCESS:
+            return TRUE;
+        case CALLBACK_ERROR:
+            return FALSE;
+        case CALLBACK_CONTINUE:
+        default:
+            break;
+    }
 
     curModeRef = CGDisplayCurrentMode(screenId);
     if (!curModeRef)
@@ -132,6 +159,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
     if (!modes)
         return FALSE;
     for (i = 0; i < CFArrayGetCount(modes); i++) {
+        int cb;
         modeRef = (CFDictionaryRef) CFArrayGetValueAtIndex(modes, i);
 
         /* Skip modes that are not usable on the current display or have a
@@ -143,11 +171,16 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
             continue;
 
         QuartzRandRGetModeInfo(modeRef, &modeInfo);
-        modeInfo.ref = modeRef;
-        if (!callback(pScreen, screenId, &modeInfo, data))
+        modeInfo.ref = (void *)modeRef;
+        cb = callback(pScreen, screenId, &modeInfo, data);
+        if (cb == CALLBACK_SUCCESS)
+            break;
+        if (cb == CALLBACK_ERROR) {
+            retval = FALSE;
             break;
+        }
     }
-    return TRUE;
+    return retval;
 }
 
 #else /* we have the new CG APIs from Snow Leopard */
@@ -162,14 +195,14 @@ static void QuartzRandRGetModeInfo (CGDisplayModeRef modeRef,
     pMode->ref = NULL;
 }
 
-static Bool QuartzRandRGetCurrentModeInfo (CGDirectDisplayID screenId,
-                                           QuartzModeInfoPtr pMode) {
+static Bool QuartzRandRCopyCurrentModeInfo (CGDirectDisplayID screenId,
+                                            QuartzModeInfoPtr pMode) {
     CGDisplayModeRef curModeRef = CGDisplayCopyDisplayMode(screenId);
     if (!curModeRef)
         return FALSE;
 
     QuartzRandRGetModeInfo(curModeRef, pMode);
-    CGDisplayModeRelease(curModeRef);
+    pMode->ref = curModeRef;
     return TRUE;
 }
 
@@ -179,7 +212,7 @@ static Bool QuartzRandRSetMode (CGDirectDisplayID screenId,
     if (!modeRef)
         return FALSE;
 
-    return (CGDisplaySetDisplayMode(screenId, modeRef, NULL) != kCGErrorSuccess);
+    return (CGDisplaySetDisplayMode(screenId, modeRef, NULL) == kCGErrorSuccess);
 }
 
 static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
@@ -192,6 +225,29 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
     CFArrayRef modes;
     QuartzModeInfo modeInfo;
     int i;
+    Bool retval = TRUE;
+
+    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+
+    switch(callback(pScreen, screenId, &pQuartzScreen->rootlessMode, data)) {
+        case CALLBACK_SUCCESS:
+            return TRUE;
+        case CALLBACK_ERROR:
+            return FALSE;
+        case CALLBACK_CONTINUE:
+        default:
+            break;
+    }
+
+    switch(callback(pScreen, screenId, &pQuartzScreen->fullScreenMode, data)) {
+        case CALLBACK_SUCCESS:
+            return TRUE;
+        case CALLBACK_ERROR:
+            return FALSE;
+        case CALLBACK_CONTINUE:
+        default:
+            break;
+    }
 
     curModeRef = CGDisplayCopyDisplayMode(screenId);
     if (!curModeRef)
@@ -205,6 +261,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
         return FALSE;
     }
     for (i = 0; i < CFArrayGetCount(modes); i++) {
+        int cb;
         modeRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
 
         /* Skip modes that are not usable on the current display or have a
@@ -220,13 +277,19 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
 
         QuartzRandRGetModeInfo(modeRef, &modeInfo);
         modeInfo.ref = modeRef;
-        if (!callback(pScreen, screenId, &modeInfo, data))
+        cb = callback(pScreen, screenId, &modeInfo, data);
+        if (cb == CALLBACK_SUCCESS)
+            break;
+		if (cb == CALLBACK_ERROR) {
+			retval = FALSE;
             break;
+		}
     }
+		
     CFRelease(modes);
 
     CFRelease(curPixelEnc);
-    return TRUE;
+    return retval;
 }
 
 #endif  /* Snow Leopard CoreGraphics APIs */
@@ -246,6 +309,7 @@ static Bool QuartzRandRRegisterMode (ScreenPtr pScreen,
     RRScreenSizePtr pSize = RRRegisterSize(pScreen,
         pMode->width, pMode->height, pScreen->mmWidth, pScreen->mmHeight);
     if (pSize) {
+        //DEBUG_LOG("registering: %d x %d @ %d %s\n", (int)pMode->width, (int)pMode->height, (int)pMode->refresh, isCurrentMode ? "*" : "");
         RRRegisterRate(pScreen, pSize, pMode->refresh);
 
         if (isCurrentMode)
@@ -256,34 +320,46 @@ static Bool QuartzRandRRegisterMode (ScreenPtr pScreen,
     return FALSE;
 }
 
-static Bool QuartzRandRRegisterModeCallback (ScreenPtr pScreen,
+static int QuartzRandRRegisterModeCallback (ScreenPtr pScreen,
                                         CGDirectDisplayID screenId,
                                         QuartzModeInfoPtr pMode,
                                         void *data __unused) {
-    return QuartzRandRRegisterMode(pScreen, pMode);
+    if(QuartzRandRRegisterMode(pScreen, pMode)) {
+        return CALLBACK_CONTINUE;
+    } else {
+        return CALLBACK_ERROR;
+    }
 }
 
-static Bool QuartzRandRSetModeCallback (ScreenPtr pScreen,
-                                        CGDirectDisplayID screenId,
-                                        QuartzModeInfoPtr pMode,
-                                        void *data) {
+static int QuartzRandRSetModeCallback (ScreenPtr pScreen,
+                                       CGDirectDisplayID screenId,
+                                       QuartzModeInfoPtr pMode,
+                                       void *data) {
     QuartzModeInfoPtr pReqMode = (QuartzModeInfoPtr) data;
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
-
+	
     if (!QuartzRandRModesEqual(pMode, pReqMode))
-        return TRUE;  /* continue enumeration */
+        return CALLBACK_CONTINUE;  /* continue enumeration */
+
+    DEBUG_LOG("Found a match for requested RandR resolution (%dx%d@%d).\n", (int)pMode->width, (int)pMode->height, (int)pMode->refresh);
 
-    if (pReqMode->ref == pQuartzScreen->currentMode.ref) {
+    if (pQuartzScreen->currentMode.ref && CFEqual(pMode->ref, pQuartzScreen->currentMode.ref)) {
         DEBUG_LOG("Requested RandR resolution matches current CG mode\n");
-        return FALSE; /* We don't need to do anything in CG */
+        return CALLBACK_SUCCESS; /* We don't need to do anything in CG */
     }
 
-    if (QuartzRandRSetMode(screenId, pMode) == FALSE) {
+    if (QuartzRandRSetMode(screenId, pMode)) {
+        if(pQuartzScreen->currentMode.ref)
+            CFRelease(pQuartzScreen->currentMode.ref);
+        pQuartzScreen->currentMode = *pMode;
+        CFRetain(pQuartzScreen->currentMode.ref);
+
         ignore_next_fake_mode_update = TRUE;
-        return FALSE;
+        return CALLBACK_SUCCESS;
     } else {
-        return TRUE;
-    };
+        DEBUG_LOG("Error while requesting CG resolution change.\n");
+        return CALLBACK_ERROR;
+    }
 }
 
 static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
@@ -295,17 +371,17 @@ static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
     if (pQuartzScreen->displayCount == 0)
         return FALSE;
 
-    QuartzRandRRegisterMode(pScreen, &pQuartzScreen->rootlessMode);
-    QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fullScreenMode);
-
     if (pQuartzScreen->displayCount > 1) {
         /* RandR operations are not well-defined for an X11 screen spanning
            multiple CG displays. Create two entries for the current virtual
            resolution including/excluding the menu bar. */
+
+        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->rootlessMode);
+        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fullScreenMode);
         return TRUE;
     }
-    screenId = pQuartzScreen->displayIDs[0];
 
+    screenId = pQuartzScreen->displayIDs[0];
     return QuartzRandREnumerateModes(pScreen, screenId, QuartzRandRRegisterModeCallback, NULL);
 }
 
@@ -323,9 +399,14 @@ static Bool QuartzRandRSetConfig (ScreenPtr           pScreen,
 
     /* If the client requested the fake rootless mode, switch to rootless.
      * Otherwise, force fullscreen mode.
+     * TODO: Refactor all this fullscreen/rootless crap as it is spaghetti
+     *       has redundancies.
      */
-    QuartzSetFullscreen(reqMode.refresh != FAKE_REFRESH_ROOTLESS);
     QuartzSetRootless(reqMode.refresh == FAKE_REFRESH_ROOTLESS);
+    QuartzSetFullscreen(reqMode.refresh != FAKE_REFRESH_ROOTLESS);
+    if(reqMode.refresh != FAKE_REFRESH_ROOTLESS &&
+       reqMode.refresh != FAKE_REFRESH_FULLSCREEN)
+        QuartzShow();
 
     if (pQuartzScreen->displayCount == 0)
         return FALSE;
@@ -342,12 +423,10 @@ static Bool QuartzRandRSetConfig (ScreenPtr           pScreen,
         
     screenId = pQuartzScreen->displayIDs[0];
     if (QuartzRandREnumerateModes(pScreen, screenId, QuartzRandRSetModeCallback, &reqMode)) {
-        pQuartzScreen->currentMode = reqMode;
         return TRUE;
     }
     
     DEBUG_LOG("Unable to find a matching config: %d x %d @ %d\n", (int)reqMode.width, (int)reqMode.height, (int)reqMode.refresh);
-
     return FALSE;
 }
 
@@ -355,9 +434,16 @@ static Bool _QuartzRandRUpdateFakeModes (ScreenPtr pScreen) {
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
 
     if (pQuartzScreen->displayCount == 1) {
-        if (!QuartzRandRGetCurrentModeInfo(pQuartzScreen->displayIDs[0],
-                                           &pQuartzScreen->fullScreenMode))
+        if(pQuartzScreen->fullScreenMode.ref)
+            CFRelease(pQuartzScreen->fullScreenMode.ref);
+        if(pQuartzScreen->currentMode.ref)
+            CFRelease(pQuartzScreen->currentMode.ref);
+        
+        if (!QuartzRandRCopyCurrentModeInfo(pQuartzScreen->displayIDs[0],
+                                            &pQuartzScreen->fullScreenMode))
             return FALSE;
+
+        CFRetain(pQuartzScreen->fullScreenMode.ref);  /* This extra retain is for currentMode's copy */
     } else {
         pQuartzScreen->fullScreenMode.width = pScreen->width;
         pQuartzScreen->fullScreenMode.height = pScreen->height;
diff --git a/hw/xquartz/quartzRandR.h b/hw/xquartz/quartzRandR.h
index 8ee2818..4a7990e 100644
--- a/hw/xquartz/quartzRandR.h
+++ b/hw/xquartz/quartzRandR.h
@@ -34,7 +34,7 @@
 typedef struct {
     size_t width, height;
     int refresh;
-    const void *ref;
+    void *ref; /* CGDisplayModeRef or CFDictionaryRef */
 } QuartzModeInfo, *QuartzModeInfoPtr;
 
 // Quartz specific per screen storage structure
commit 0402a4409641598427c7d3385aa006964ae0b75a
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Mon Jul 26 01:17:12 2010 -0700

    XQuartz: RandR: Respond better to resolution changes made outside X
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>
    (cherry picked from commit 026a47e21226b64eb9a7624ada3d74c3fe5fa763)

diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 7b34b8a..7367068 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -52,6 +52,7 @@ in this Software without prior written authorization from The Open Group.
 #include "darwin.h"
 #include "quartz.h"
 #include "quartzKeyboard.h"
+#include "quartzRandR.h"
 #include "darwinEvents.h"
 
 #include <sys/types.h>
@@ -276,7 +277,12 @@ static void DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr de
             break;
             
         case kXquartzDisplayChanged:
+            DEBUG_LOG("kXquartzDisplayChanged\n");
             QuartzUpdateScreens();
+#ifdef RANDR
+            /* Update our RandR info */
+            QuartzRandRUpdateFakeModes(TRUE);
+#endif
             break;
             
         default:
diff --git a/hw/xquartz/quartzCommon.h b/hw/xquartz/quartzCommon.h
index 851e74c..718df4b 100644
--- a/hw/xquartz/quartzCommon.h
+++ b/hw/xquartz/quartzCommon.h
@@ -38,29 +38,6 @@
 #include <X11/Xdefs.h>
 #include "privates.h"
 
-typedef struct {
-    size_t width, height;
-    int refresh;
-    const void *ref;
-} QuartzModeInfo, *QuartzModeInfoPtr;
-
-// Quartz specific per screen storage structure
-typedef struct {
-    // List of CoreGraphics displays that this X11 screen covers.
-    // This is more than one CG display for video mirroring and
-    // rootless PseudoramiX mode.
-    // No CG display will be covered by more than one X11 screen.
-    int displayCount;
-    CGDirectDisplayID *displayIDs;
-    QuartzModeInfo originalMode, fakeMode;
-} QuartzScreenRec, *QuartzScreenPtr;
-
-#define QUARTZ_PRIV(pScreen) \
-    ((QuartzScreenPtr)dixLookupPrivate(&pScreen->devPrivates, quartzScreenKey))
-
-void QuartzCopyDisplayIDs(ScreenPtr pScreen,
-                          int displayCount, CGDirectDisplayID *displayIDs);
-
 // User preferences used by Quartz modes
 extern int              quartzUseSysBeep;
 extern int              quartzFullscreenDisableHotkeys;
diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c
index e46e904..65dce22 100644
--- a/hw/xquartz/quartzRandR.c
+++ b/hw/xquartz/quartzRandR.c
@@ -38,6 +38,7 @@
 #include "quartzCommon.h"
 #include "quartzRandR.h"
 #include "quartz.h"
+#include "darwin.h"
 
 #include <AvailabilityMacros.h>
 
@@ -45,6 +46,13 @@
 #include <randrstr.h>
 #include <IOKit/graphics/IOGraphicsTypes.h>
 
+/* TODO: UGLY, find a better way!
+ * We want to ignore kXquartzDisplayChanged which are generated by us
+ */
+static Bool ignore_next_fake_mode_update = FALSE;
+
+#define FAKE_REFRESH_ROOTLESS 1
+#define FAKE_REFRESH_FULLSCREEN 2
 
 #define DEFAULT_REFRESH  60
 #define kDisplayModeUsableFlags  (kDisplayModeValidFlag | kDisplayModeSafeFlag)
@@ -171,8 +179,7 @@ static Bool QuartzRandRSetMode (CGDirectDisplayID screenId,
     if (!modeRef)
         return FALSE;
 
-    return (CGDisplaySetDisplayMode(screenId, modeRef, NULL) !=
-            kCGErrorSuccess);
+    return (CGDisplaySetDisplayMode(screenId, modeRef, NULL) != kCGErrorSuccess);
 }
 
 static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
@@ -227,18 +234,15 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
 
 static Bool QuartzRandRModesEqual (QuartzModeInfoPtr pMode1,
                                    QuartzModeInfoPtr pMode2) {
-    if (pMode1->width != pMode2->width)
-        return FALSE;
-    if (pMode1->height != pMode2->height)
-        return FALSE;
-    if (pMode1->refresh != pMode2->refresh)
-        return FALSE;
-    return TRUE;
+    return (pMode1->width == pMode2->width) &&
+           (pMode1->height == pMode2->height) &&
+           (pMode1->refresh == pMode2->refresh);
 }
 
 static Bool QuartzRandRRegisterMode (ScreenPtr pScreen,
-                                     QuartzModeInfoPtr pMode,
-                                     Bool isCurrentMode) {
+                                     QuartzModeInfoPtr pMode) {
+    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+    Bool isCurrentMode = QuartzRandRModesEqual(&pQuartzScreen->currentMode, pMode);
     RRScreenSizePtr pSize = RRRegisterSize(pScreen,
         pMode->width, pMode->height, pScreen->mmWidth, pScreen->mmHeight);
     if (pSize) {
@@ -252,14 +256,11 @@ static Bool QuartzRandRRegisterMode (ScreenPtr pScreen,
     return FALSE;
 }
 
-static Bool QuartzRandRGetModeCallback (ScreenPtr pScreen,
+static Bool QuartzRandRRegisterModeCallback (ScreenPtr pScreen,
                                         CGDirectDisplayID screenId,
                                         QuartzModeInfoPtr pMode,
-                                        void *data) {
-    QuartzModeInfoPtr pCurMode = (QuartzModeInfoPtr) data;
-
-    return QuartzRandRRegisterMode(pScreen, pMode,
-        QuartzRandRModesEqual(pMode, pCurMode));
+                                        void *data __unused) {
+    return QuartzRandRRegisterMode(pScreen, pMode);
 }
 
 static Bool QuartzRandRSetModeCallback (ScreenPtr pScreen,
@@ -267,73 +268,64 @@ static Bool QuartzRandRSetModeCallback (ScreenPtr pScreen,
                                         QuartzModeInfoPtr pMode,
                                         void *data) {
     QuartzModeInfoPtr pReqMode = (QuartzModeInfoPtr) data;
+    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
 
     if (!QuartzRandRModesEqual(pMode, pReqMode))
         return TRUE;  /* continue enumeration */
 
-    return QuartzRandRSetMode(screenId, pMode);
+    if (pReqMode->ref == pQuartzScreen->currentMode.ref) {
+        DEBUG_LOG("Requested RandR resolution matches current CG mode\n");
+        return FALSE; /* We don't need to do anything in CG */
+    }
+
+    if (QuartzRandRSetMode(screenId, pMode) == FALSE) {
+        ignore_next_fake_mode_update = TRUE;
+        return FALSE;
+    } else {
+        return TRUE;
+    };
 }
 
 static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
     CGDirectDisplayID screenId;
-    QuartzModeInfo curMode;
 
     *rotations = RR_Rotate_0;  /* TODO: support rotation */
 
     if (pQuartzScreen->displayCount == 0)
         return FALSE;
+
+    QuartzRandRRegisterMode(pScreen, &pQuartzScreen->rootlessMode);
+    QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fullScreenMode);
+
     if (pQuartzScreen->displayCount > 1) {
         /* RandR operations are not well-defined for an X11 screen spanning
            multiple CG displays. Create two entries for the current virtual
            resolution including/excluding the menu bar. */
-        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fakeMode,
-            !quartzHasRoot);
-        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->originalMode,
-            quartzHasRoot);
         return TRUE;
     }
     screenId = pQuartzScreen->displayIDs[0];
 
-    if (!QuartzRandRGetCurrentModeInfo(screenId, &curMode))
-        return FALSE;
-
-    /* Add a fake mode corresponding to the original resolution excluding the
-       height of the menu bar. */
-    if (!quartzHasRoot &&
-        QuartzRandRModesEqual(&pQuartzScreen->originalMode, &curMode)) {
-        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fakeMode, TRUE);
-        curMode = pQuartzScreen->fakeMode;
-    }
-    else
-        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fakeMode, FALSE);
-
-    return QuartzRandREnumerateModes(pScreen, screenId,
-        QuartzRandRGetModeCallback, &curMode);
+    return QuartzRandREnumerateModes(pScreen, screenId, QuartzRandRRegisterModeCallback, NULL);
 }
 
 static Bool QuartzRandRSetConfig (ScreenPtr           pScreen,
-			          Rotation            randr,
-			          int                 rate,
-			          RRScreenSizePtr     pSize) {
+                                  Rotation            randr,
+                                  int                 rate,
+                                  RRScreenSizePtr     pSize) {
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
     CGDirectDisplayID screenId;
-    QuartzModeInfo reqMode, curMode;
-    Bool rootless = FALSE;
+    QuartzModeInfo reqMode;
 
     reqMode.width = pSize->width;
     reqMode.height = pSize->height;
     reqMode.refresh = rate;
 
-    /* If the client requested the fake screen mode, switch to rootless mode.
-       Switch to fullscreen mode (root window visible) if a real screen mode was
-       requested. */
-    if (QuartzRandRModesEqual(&reqMode, &pQuartzScreen->fakeMode)) {
-        rootless = TRUE;
-        reqMode = pQuartzScreen->originalMode;
-    }
-    QuartzSetFullscreen(!rootless);
-    QuartzSetRootless(rootless);
+    /* If the client requested the fake rootless mode, switch to rootless.
+     * Otherwise, force fullscreen mode.
+     */
+    QuartzSetFullscreen(reqMode.refresh != FAKE_REFRESH_ROOTLESS);
+    QuartzSetRootless(reqMode.refresh == FAKE_REFRESH_ROOTLESS);
 
     if (pQuartzScreen->displayCount == 0)
         return FALSE;
@@ -341,38 +333,80 @@ static Bool QuartzRandRSetConfig (ScreenPtr           pScreen,
         /* RandR operations are not well-defined for an X11 screen spanning
            multiple CG displays. Do not accept any configuations that differ
            from the current configuration. */
-        return QuartzRandRModesEqual(&reqMode, &pQuartzScreen->originalMode);
+        return TRUE;
     }
-    screenId = pQuartzScreen->displayIDs[0];
 
     /* Do not switch modes if requested mode is equal to current mode. */
-    if (!QuartzRandRGetCurrentModeInfo(screenId, &curMode))
-        return FALSE;
-    if (QuartzRandRModesEqual(&reqMode, &curMode))
+    if (QuartzRandRModesEqual(&reqMode, &pQuartzScreen->currentMode))
         return TRUE;
+        
+    screenId = pQuartzScreen->displayIDs[0];
+    if (QuartzRandREnumerateModes(pScreen, screenId, QuartzRandRSetModeCallback, &reqMode)) {
+        pQuartzScreen->currentMode = reqMode;
+        return TRUE;
+    }
+    
+    DEBUG_LOG("Unable to find a matching config: %d x %d @ %d\n", (int)reqMode.width, (int)reqMode.height, (int)reqMode.refresh);
 
-    return QuartzRandREnumerateModes(pScreen, screenId,
-        QuartzRandRSetModeCallback, &reqMode);
+    return FALSE;
 }
 
-Bool QuartzRandRInit (ScreenPtr pScreen) {
-    rrScrPrivPtr    pScrPriv;
+static Bool _QuartzRandRUpdateFakeModes (ScreenPtr pScreen) {
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
-    
-    if (!RRScreenInit (pScreen)) return FALSE;
 
     if (pQuartzScreen->displayCount == 1) {
         if (!QuartzRandRGetCurrentModeInfo(pQuartzScreen->displayIDs[0],
-                                           &pQuartzScreen->originalMode))
+                                           &pQuartzScreen->fullScreenMode))
             return FALSE;
+    } else {
+        pQuartzScreen->fullScreenMode.width = pScreen->width;
+        pQuartzScreen->fullScreenMode.height = pScreen->height;
+        if(quartzEnableRootless)
+            pQuartzScreen->fullScreenMode.height += aquaMenuBarHeight;
     }
-    else {
-        pQuartzScreen->originalMode.width = pScreen->width;
-        pQuartzScreen->originalMode.height = pScreen->height;
-        pQuartzScreen->originalMode.refresh = DEFAULT_REFRESH;
+
+    pQuartzScreen->fullScreenMode.refresh = FAKE_REFRESH_FULLSCREEN;
+
+    pQuartzScreen->rootlessMode = pQuartzScreen->fullScreenMode;
+    pQuartzScreen->rootlessMode.refresh = FAKE_REFRESH_ROOTLESS;
+    pQuartzScreen->rootlessMode.height -= aquaMenuBarHeight;
+
+    if(quartzEnableRootless) {
+        pQuartzScreen->currentMode = pQuartzScreen->rootlessMode;
+    } else {
+        pQuartzScreen->currentMode = pQuartzScreen->fullScreenMode;
     }
-    pQuartzScreen->fakeMode = pQuartzScreen->originalMode;
-    pQuartzScreen->fakeMode.height -= aquaMenuBarHeight;
+    
+    DEBUG_LOG("rootlessMode: %d x %d\n", (int)pQuartzScreen->rootlessMode.width, (int)pQuartzScreen->rootlessMode.height);
+    DEBUG_LOG("fullScreenMode: %d x %d\n", (int)pQuartzScreen->fullScreenMode.width, (int)pQuartzScreen->fullScreenMode.height);
+    DEBUG_LOG("currentMode: %d x %d\n", (int)pQuartzScreen->currentMode.width, (int)pQuartzScreen->currentMode.height);
+    
+    return TRUE;
+}
+
+Bool QuartzRandRUpdateFakeModes (BOOL force_update) {
+    ScreenPtr pScreen = screenInfo.screens[0];
+    
+    if(ignore_next_fake_mode_update) {
+        DEBUG_LOG("Ignoring update request caused by RandR resolution change.\n");
+        ignore_next_fake_mode_update = FALSE;
+        return TRUE;
+    }
+    
+    if(!_QuartzRandRUpdateFakeModes(pScreen))
+        return FALSE;
+    
+    if(force_update)
+        RRGetInfo(pScreen, TRUE);
+
+    return TRUE;
+}
+
+Bool QuartzRandRInit (ScreenPtr pScreen) {
+    rrScrPrivPtr    pScrPriv;
+    
+    if (!RRScreenInit (pScreen)) return FALSE;
+    if (!_QuartzRandRUpdateFakeModes (pScreen)) return FALSE;
 
     pScrPriv = rrGetScrPriv(pScreen);
     pScrPriv->rrGetInfo = QuartzRandRGetInfo;
diff --git a/hw/xquartz/quartzRandR.h b/hw/xquartz/quartzRandR.h
index d57dc3b..8ee2818 100644
--- a/hw/xquartz/quartzRandR.h
+++ b/hw/xquartz/quartzRandR.h
@@ -31,6 +31,30 @@
 #ifndef _QUARTZRANDR_H_
 #define _QUARTZRANDR_H_
 
+typedef struct {
+    size_t width, height;
+    int refresh;
+    const void *ref;
+} QuartzModeInfo, *QuartzModeInfoPtr;
+
+// Quartz specific per screen storage structure
+typedef struct {
+    // List of CoreGraphics displays that this X11 screen covers.
+    // This is more than one CG display for video mirroring and
+    // rootless PseudoramiX mode.
+    // No CG display will be covered by more than one X11 screen.
+    int displayCount;
+    CGDirectDisplayID *displayIDs;
+    QuartzModeInfo rootlessMode, fullScreenMode, currentMode;
+} QuartzScreenRec, *QuartzScreenPtr;
+
+#define QUARTZ_PRIV(pScreen) \
+    ((QuartzScreenPtr)dixLookupPrivate(&pScreen->devPrivates, quartzScreenKey))
+
+void QuartzCopyDisplayIDs(ScreenPtr pScreen,
+                          int displayCount, CGDirectDisplayID *displayIDs);
+
+Bool QuartzRandRUpdateFakeModes (BOOL force_update);
 Bool QuartzRandRInit (ScreenPtr pScreen);
 
 #endif
diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c
index 0e36ee1..b3ac693 100644
--- a/hw/xquartz/xpr/xprScreen.c
+++ b/hw/xquartz/xpr/xprScreen.c
@@ -36,6 +36,7 @@
 #include "quartzCommon.h"
 #include "inputstr.h"
 #include "quartz.h"
+#include "quartzRandR.h"
 #include "xpr.h"
 #include "xprEvent.h"
 #include "pseudoramiX.h"
commit e540c517a831a256a6e76a8c2b92629fe87aa8df
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sun Jul 25 22:25:49 2010 -0700

    XQuartz: RandR: Use deprecated CG APIs only on Leopard and earlier
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>
    (cherry picked from commit 59cd93f48a3a0a34781d4a94a3cd05a575e2d4ba)

diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c
index b3b315c..e46e904 100644
--- a/hw/xquartz/quartzRandR.c
+++ b/hw/xquartz/quartzRandR.c
@@ -1,9 +1,9 @@
 /*
- *
  * Quartz-specific support for the XRandR extension
  *
  * Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons,
  *               2010      Jan Hauffa.
+ *               2010      Apple Inc.
  *                 All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -39,6 +39,8 @@
 #include "quartzRandR.h"
 #include "quartz.h"
 
+#include <AvailabilityMacros.h>
+
 #include <X11/extensions/randr.h>
 #include <randrstr.h>
 #include <IOKit/graphics/IOGraphicsTypes.h>
@@ -51,7 +53,7 @@ typedef Bool (*QuartzModeCallback)
     (ScreenPtr, CGDirectDisplayID, QuartzModeInfoPtr, void *);
 
 
-#if defined(USE_DEPRECATED_CG_API)
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
 
 static long getDictLong (CFDictionaryRef dictRef, CFStringRef key) {
     long value;
@@ -140,7 +142,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
     return TRUE;
 }
 
-#else  /* defined(USE_DEPRECATED_CG_API) */
+#else /* we have the new CG APIs from Snow Leopard */
 
 static void QuartzRandRGetModeInfo (CGDisplayModeRef modeRef,
                                     QuartzModeInfoPtr pMode) {
@@ -220,7 +222,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
     return TRUE;
 }
 
-#endif  /* defined(USE_DEPRECATED_CG_API) */
+#endif  /* Snow Leopard CoreGraphics APIs */
 
 
 static Bool QuartzRandRModesEqual (QuartzModeInfoPtr pMode1,
diff --git a/hw/xquartz/quartzRandR.h b/hw/xquartz/quartzRandR.h
index 711c3f3..d57dc3b 100644
--- a/hw/xquartz/quartzRandR.h
+++ b/hw/xquartz/quartzRandR.h
@@ -2,6 +2,7 @@
  * quartzRandR.h
  *
  * Copyright (c) 2010 Jan Hauffa.
+ *               2010 Apple Inc.
  *                 All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -27,6 +28,9 @@
  * use or other dealings in this Software without prior written authorization.
  */
 
-#define USE_DEPRECATED_CG_API 1
+#ifndef _QUARTZRANDR_H_
+#define _QUARTZRANDR_H_
 
 Bool QuartzRandRInit (ScreenPtr pScreen);
+
+#endif
commit e4918634ab166b72d9d44663d69443e13f153fd7
Author: Jan Hauffa <hauffa at in.tum.de>
Date:   Fri Jul 16 17:56:44 2010 +0200

    XQuartz: RandR: Remove FAKE_RANDR code.
    
    Signed-off-by: Jan Hauffa <hauffa at in.tum.de>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
    (cherry picked from commit 629c3f473b7415069a87ef4717ec3d701978dc48)

diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index a4d7474..a52cac9 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -119,7 +119,7 @@ Bool QuartzSetupScreen(
     if (! quartzProcs->InitCursor(pScreen))
         return FALSE;
 
-#if defined(RANDR) && !defined(FAKE_RANDR)
+#if defined(RANDR)
     if(!QuartzRandRInit(pScreen)) {
         DEBUG_LOG("Failed to init RandR extension.\n");
         return FALSE;
@@ -239,10 +239,6 @@ void QuartzUpdateScreens(void) {
     DeliverEvents(pRoot, &e, 1, NullWindow);
 
     quartzProcs->UpdateScreen(pScreen);
-    
-#ifdef FAKE_RANDR
-    RREditConnectionInfo(pScreen);
-#endif    
 }
 
 void QuartzSetFullscreen(Bool state) {
diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c
index f61ff93..b3b315c 100644
--- a/hw/xquartz/quartzRandR.c
+++ b/hw/xquartz/quartzRandR.c
@@ -39,60 +39,10 @@
 #include "quartzRandR.h"
 #include "quartz.h"
 
-#if defined(FAKE_RANDR)
-#include "scrnintstr.h"
-#include "windowstr.h"
-#else
 #include <X11/extensions/randr.h>
 #include <randrstr.h>
 #include <IOKit/graphics/IOGraphicsTypes.h>
-#endif
-
-
-#if defined(FAKE_RANDR)
-
-static const int padlength[4] = {0, 3, 2, 1};
-
-void
-RREditConnectionInfo (ScreenPtr pScreen)
-{
-    xConnSetup	    *connSetup;
-    char	    *vendor;
-    xPixmapFormat   *formats;
-    xWindowRoot	    *root;
-    xDepth	    *depth;
-    xVisualType	    *visual;
-    int		    screen = 0;
-    int		    d;
-
-    connSetup = (xConnSetup *) ConnectionInfo;
-    vendor = (char *) connSetup + sizeof (xConnSetup);
-    formats = (xPixmapFormat *) ((char *) vendor +
-				 connSetup->nbytesVendor +
-				 padlength[connSetup->nbytesVendor & 3]);
-    root = (xWindowRoot *) ((char *) formats +
-			    sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
-    while (screen != pScreen->myNum)
-    {
-	depth = (xDepth *) ((char *) root + 
-			    sizeof (xWindowRoot));
-	for (d = 0; d < root->nDepths; d++)
-	{
-	    visual = (xVisualType *) ((char *) depth +
-				      sizeof (xDepth));
-	    depth = (xDepth *) ((char *) visual +
-				depth->nVisuals * sizeof (xVisualType));
-	}
-	root = (xWindowRoot *) ((char *) depth);
-	screen++;
-    }
-    root->pixWidth = pScreen->width;
-    root->pixHeight = pScreen->height;
-    root->mmWidth = pScreen->mmWidth;
-    root->mmHeight = pScreen->mmHeight;
-}
 
-#else  /* defined(FAKE_RANDR) */
 
 #define DEFAULT_REFRESH  60
 #define kDisplayModeUsableFlags  (kDisplayModeValidFlag | kDisplayModeSafeFlag)
@@ -427,5 +377,3 @@ Bool QuartzRandRInit (ScreenPtr pScreen) {
     pScrPriv->rrSetConfig = QuartzRandRSetConfig;
     return TRUE;
 }
-
-#endif  /* defined(FAKE_RANDR) */
diff --git a/hw/xquartz/quartzRandR.h b/hw/xquartz/quartzRandR.h
index a190205..711c3f3 100644
--- a/hw/xquartz/quartzRandR.h
+++ b/hw/xquartz/quartzRandR.h
@@ -27,11 +27,6 @@
  * use or other dealings in this Software without prior written authorization.
  */
 
-/*define FAKE_RANDR 1*/
 #define USE_DEPRECATED_CG_API 1
 
-#if defined(FAKE_RANDR)
-void RREditConnectionInfo (ScreenPtr pScreen);
-#else
 Bool QuartzRandRInit (ScreenPtr pScreen);
-#endif
commit b374b9e68a8d8f18a8220e90a98d983ec4068938
Author: Jan Hauffa <hauffa at in.tum.de>
Date:   Fri Jul 16 17:54:55 2010 +0200

    XQuartz: RandR: Toggle rootless mode on XRandR mode switch.
    
    Report a fake screen mode that corresponds to the screen mode at startup of the
    server excluding the height of the menu bar. If a client requests this mode,
    rootless mode is enabled. In all other modes, the root window is shown.
    
    Signed-off-by: Jan Hauffa <hauffa at in.tum.de>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
    (cherry picked from commit 97b5f5306437bfd13390485fc7a58a363c261ec9)

diff --git a/hw/xquartz/quartzCommon.h b/hw/xquartz/quartzCommon.h
index d0d358b..851e74c 100644
--- a/hw/xquartz/quartzCommon.h
+++ b/hw/xquartz/quartzCommon.h
@@ -38,6 +38,12 @@
 #include <X11/Xdefs.h>
 #include "privates.h"
 
+typedef struct {
+    size_t width, height;
+    int refresh;
+    const void *ref;
+} QuartzModeInfo, *QuartzModeInfoPtr;
+
 // Quartz specific per screen storage structure
 typedef struct {
     // List of CoreGraphics displays that this X11 screen covers.
@@ -46,6 +52,7 @@ typedef struct {
     // No CG display will be covered by more than one X11 screen.
     int displayCount;
     CGDirectDisplayID *displayIDs;
+    QuartzModeInfo originalMode, fakeMode;
 } QuartzScreenRec, *QuartzScreenPtr;
 
 #define QUARTZ_PRIV(pScreen) \
diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c
index 6747752..f61ff93 100644
--- a/hw/xquartz/quartzRandR.c
+++ b/hw/xquartz/quartzRandR.c
@@ -37,6 +37,7 @@
 
 #include "quartzCommon.h"
 #include "quartzRandR.h"
+#include "quartz.h"
 
 #if defined(FAKE_RANDR)
 #include "scrnintstr.h"
@@ -96,12 +97,6 @@ RREditConnectionInfo (ScreenPtr pScreen)
 #define DEFAULT_REFRESH  60
 #define kDisplayModeUsableFlags  (kDisplayModeValidFlag | kDisplayModeSafeFlag)
 
-typedef struct {
-    size_t width, height;
-    int refresh;
-    const void *ref;
-} QuartzModeInfo, *QuartzModeInfoPtr;
-
 typedef Bool (*QuartzModeCallback)
     (ScreenPtr, CGDirectDisplayID, QuartzModeInfoPtr, void *);
 
@@ -289,21 +284,30 @@ static Bool QuartzRandRModesEqual (QuartzModeInfoPtr pMode1,
     return TRUE;
 }
 
-static Bool QuartzRandRGetModeCallback (ScreenPtr pScreen,
-                                        CGDirectDisplayID screenId,
-                                        QuartzModeInfoPtr pMode,
-                                        void *data) {
-    QuartzModeInfoPtr pCurMode = (QuartzModeInfoPtr) data;
-
+static Bool QuartzRandRRegisterMode (ScreenPtr pScreen,
+                                     QuartzModeInfoPtr pMode,
+                                     Bool isCurrentMode) {
     RRScreenSizePtr pSize = RRRegisterSize(pScreen,
         pMode->width, pMode->height, pScreen->mmWidth, pScreen->mmHeight);
     if (pSize) {
         RRRegisterRate(pScreen, pSize, pMode->refresh);
 
-        if (QuartzRandRModesEqual(pMode, pCurMode))
+        if (isCurrentMode)
             RRSetCurrentConfig(pScreen, RR_Rotate_0, pMode->refresh, pSize);
+
+        return TRUE;
     }
-    return TRUE;
+    return FALSE;
+}
+
+static Bool QuartzRandRGetModeCallback (ScreenPtr pScreen,
+                                        CGDirectDisplayID screenId,
+                                        QuartzModeInfoPtr pMode,
+                                        void *data) {
+    QuartzModeInfoPtr pCurMode = (QuartzModeInfoPtr) data;
+
+    return QuartzRandRRegisterMode(pScreen, pMode,
+        QuartzRandRModesEqual(pMode, pCurMode));
 }
 
 static Bool QuartzRandRSetModeCallback (ScreenPtr pScreen,
@@ -329,20 +333,29 @@ static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
         return FALSE;
     if (pQuartzScreen->displayCount > 1) {
         /* RandR operations are not well-defined for an X11 screen spanning
-           multiple CG displays. Create a single entry for the current virtual
-           resolution. */
-        RRScreenSizePtr pSize = RRRegisterSize(pScreen, pScreen->width,
-            pScreen->height, pScreen->mmWidth, pScreen->mmHeight);
-        if (pSize) {
-            RRRegisterRate(pScreen, pSize, DEFAULT_REFRESH);
-            RRSetCurrentConfig(pScreen, RR_Rotate_0, DEFAULT_REFRESH, pSize);
-        }
+           multiple CG displays. Create two entries for the current virtual
+           resolution including/excluding the menu bar. */
+        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fakeMode,
+            !quartzHasRoot);
+        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->originalMode,
+            quartzHasRoot);
         return TRUE;
     }
     screenId = pQuartzScreen->displayIDs[0];
 
     if (!QuartzRandRGetCurrentModeInfo(screenId, &curMode))
         return FALSE;
+
+    /* Add a fake mode corresponding to the original resolution excluding the
+       height of the menu bar. */
+    if (!quartzHasRoot &&
+        QuartzRandRModesEqual(&pQuartzScreen->originalMode, &curMode)) {
+        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fakeMode, TRUE);
+        curMode = pQuartzScreen->fakeMode;
+    }
+    else
+        QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fakeMode, FALSE);
+
     return QuartzRandREnumerateModes(pScreen, screenId,
         QuartzRandRGetModeCallback, &curMode);
 }
@@ -354,6 +367,21 @@ static Bool QuartzRandRSetConfig (ScreenPtr           pScreen,
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
     CGDirectDisplayID screenId;
     QuartzModeInfo reqMode, curMode;
+    Bool rootless = FALSE;
+
+    reqMode.width = pSize->width;
+    reqMode.height = pSize->height;
+    reqMode.refresh = rate;
+
+    /* If the client requested the fake screen mode, switch to rootless mode.
+       Switch to fullscreen mode (root window visible) if a real screen mode was
+       requested. */
+    if (QuartzRandRModesEqual(&reqMode, &pQuartzScreen->fakeMode)) {
+        rootless = TRUE;
+        reqMode = pQuartzScreen->originalMode;
+    }
+    QuartzSetFullscreen(!rootless);
+    QuartzSetRootless(rootless);
 
     if (pQuartzScreen->displayCount == 0)
         return FALSE;
@@ -361,15 +389,10 @@ static Bool QuartzRandRSetConfig (ScreenPtr           pScreen,
         /* RandR operations are not well-defined for an X11 screen spanning
            multiple CG displays. Do not accept any configuations that differ
            from the current configuration. */
-        return ((pSize->width == pScreen->width) &&
-                (pSize->height == pScreen->height));
+        return QuartzRandRModesEqual(&reqMode, &pQuartzScreen->originalMode);
     }
     screenId = pQuartzScreen->displayIDs[0];
 
-    reqMode.width = pSize->width;
-    reqMode.height = pSize->height;
-    reqMode.refresh = rate;
-
     /* Do not switch modes if requested mode is equal to current mode. */
     if (!QuartzRandRGetCurrentModeInfo(screenId, &curMode))
         return FALSE;
@@ -382,9 +405,23 @@ static Bool QuartzRandRSetConfig (ScreenPtr           pScreen,
 
 Bool QuartzRandRInit (ScreenPtr pScreen) {
     rrScrPrivPtr    pScrPriv;
+    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
     
     if (!RRScreenInit (pScreen)) return FALSE;
 
+    if (pQuartzScreen->displayCount == 1) {
+        if (!QuartzRandRGetCurrentModeInfo(pQuartzScreen->displayIDs[0],
+                                           &pQuartzScreen->originalMode))
+            return FALSE;
+    }
+    else {
+        pQuartzScreen->originalMode.width = pScreen->width;
+        pQuartzScreen->originalMode.height = pScreen->height;
+        pQuartzScreen->originalMode.refresh = DEFAULT_REFRESH;
+    }
+    pQuartzScreen->fakeMode = pQuartzScreen->originalMode;
+    pQuartzScreen->fakeMode.height -= aquaMenuBarHeight;
+
     pScrPriv = rrGetScrPriv(pScreen);
     pScrPriv->rrGetInfo = QuartzRandRGetInfo;
     pScrPriv->rrSetConfig = QuartzRandRSetConfig;
commit 29e9c25efb3e006b22019575fdb9ec1cc958c096
Author: Jan Hauffa <hauffa at in.tum.de>
Date:   Fri Jul 16 17:18:03 2010 +0200

    XQuartz: RandR: Implement basic RandR functionality.
    
    Querying and changing of resolution and refresh rate is supported,
    rotation is not implemented yet.
    
    Signed-off-by: Jan Hauffa <hauffa at in.tum.de>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
    (cherry picked from commit 2d411472c2915614bdeb8fdc15d19dae4621444d)

diff --git a/hw/xquartz/Makefile.am b/hw/xquartz/Makefile.am
index 96b139f..721d272 100644
--- a/hw/xquartz/Makefile.am
+++ b/hw/xquartz/Makefile.am
@@ -34,6 +34,7 @@ libXquartz_la_SOURCES = \
 	quartzCocoa.m \
 	quartzKeyboard.c \
 	quartzStartup.c \
+	quartzRandR.c \
 	threadSafety.c
 
 EXTRA_DIST = \
@@ -49,6 +50,7 @@ EXTRA_DIST = \
 	quartzAudio.h \
 	quartzCommon.h \
 	quartzKeyboard.h \
+	quartzRandR.h \
 	sanitizedCarbon.h \
 	sanitizedCocoa.h \
 	threadSafety.h
diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index eee6151..a4d7474 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -35,6 +35,7 @@
 #endif
 
 #include "quartzCommon.h"
+#include "quartzRandR.h"
 #include "inputstr.h"
 #include "quartz.h"
 #include "darwin.h"
@@ -46,7 +47,6 @@
 #include "X11Application.h"
 
 #include <X11/extensions/applewmconst.h>
-#include <X11/extensions/randr.h>
 
 // X headers
 #include "scrnintstr.h"
@@ -56,6 +56,8 @@
 #include "mi.h"
 
 // System headers
+#include <stdlib.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -64,8 +66,6 @@
 #include <rootlessCommon.h>
 #include <Xplugin.h>
 
-#define FAKE_RANDR 1
-
 // Shared global variables for Quartz modes
 int                     quartzUseSysBeep = 0;
 int                     quartzServerVisible = FALSE;
@@ -76,30 +76,6 @@ const char             *quartzOpenGLBundle = NULL;
 int                     quartzFullscreenDisableHotkeys = TRUE;
 int                     quartzOptionSendsAlt = FALSE;
 
-#if defined(RANDR) && !defined(FAKE_RANDR)
-Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
-  return FALSE;
-}
-
-Bool QuartzRandRSetConfig (ScreenPtr           pScreen,
-			       Rotation            randr,
-			       int                 rate,
-			       RRScreenSizePtr     pSize) {
-  return FALSE;
-}
-
-Bool QuartzRandRInit (ScreenPtr pScreen) {
-  rrScrPrivPtr    pScrPriv;
-    
-  if (!RRScreenInit (pScreen)) return FALSE;
-
-  pScrPriv = rrGetScrPriv(pScreen);
-  pScrPriv->rrGetInfo = QuartzRandRGetInfo;
-  pScrPriv->rrSetConfig = QuartzRandRSetConfig;
-  return TRUE;
-}
-#endif
-
 /*
 ===========================================================================
 
@@ -143,6 +119,13 @@ Bool QuartzSetupScreen(
     if (! quartzProcs->InitCursor(pScreen))
         return FALSE;
 
+#if defined(RANDR) && !defined(FAKE_RANDR)
+    if(!QuartzRandRInit(pScreen)) {
+        DEBUG_LOG("Failed to init RandR extension.\n");
+        return FALSE;
+    }
+#endif
+
     return TRUE;
 }
 
@@ -165,11 +148,6 @@ void QuartzInitOutput(
     if (!dixRegisterPrivateKey(&quartzScreenKeyRec, PRIVATE_SCREEN, 0))
 	FatalError("Failed to alloc quartz screen private.\n");
 
-#if defined(RANDR) && !defined(FAKE_RANDR)
-    if(!QuartzRandRInit(pScreen))
-        FatalError("Failed to init RandR extension.\n");
-#endif
-
     // Do display mode specific initialization
     quartzProcs->DisplayInit();
 }
@@ -191,50 +169,6 @@ void QuartzInitInput(
 }
 
 
-#ifdef FAKE_RANDR
-
-static const int padlength[4] = {0, 3, 2, 1};
-
-static void
-RREditConnectionInfo (ScreenPtr pScreen)
-{
-    xConnSetup	    *connSetup;
-    char	    *vendor;
-    xPixmapFormat   *formats;
-    xWindowRoot	    *root;
-    xDepth	    *depth;
-    xVisualType	    *visual;
-    int		    screen = 0;
-    int		    d;
-
-    connSetup = (xConnSetup *) ConnectionInfo;
-    vendor = (char *) connSetup + sizeof (xConnSetup);
-    formats = (xPixmapFormat *) ((char *) vendor +
-				 connSetup->nbytesVendor +
-				 padlength[connSetup->nbytesVendor & 3]);
-    root = (xWindowRoot *) ((char *) formats +
-			    sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
-    while (screen != pScreen->myNum)
-    {
-	depth = (xDepth *) ((char *) root + 
-			    sizeof (xWindowRoot));
-	for (d = 0; d < root->nDepths; d++)
-	{
-	    visual = (xVisualType *) ((char *) depth +
-				      sizeof (xDepth));
-	    depth = (xDepth *) ((char *) visual +
-				depth->nVisuals * sizeof (xVisualType));
-	}
-	root = (xWindowRoot *) ((char *) depth);
-	screen++;
-    }
-    root->pixWidth = pScreen->width;
-    root->pixHeight = pScreen->height;
-    root->mmWidth = pScreen->mmWidth;
-    root->mmHeight = pScreen->mmHeight;
-}
-#endif
-
 void QuartzUpdateScreens(void) {
     ScreenPtr pScreen;
     WindowPtr pRoot;
@@ -255,7 +189,7 @@ void QuartzUpdateScreens(void) {
     pScreen = screenInfo.screens[0];
     
     PseudoramiXResetScreens();
-    quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height);
+    quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height, pScreen);
     
     pScreen->x = x;
     pScreen->y = y;
@@ -446,3 +380,19 @@ void QuartzSpaceChanged(uint32_t space_id) {
     /* Do something special here, so we don't depend on quartz-wm for spaces to work... */
     DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", space_id);
 }
+
+/*
+ * QuartzCopyDisplayIDs
+ *  Associate an X11 screen with one or more CoreGraphics display IDs by copying
+ *  the list into a private array. Free the previously copied array, if present.
+ */
+void QuartzCopyDisplayIDs(ScreenPtr pScreen,
+                          int displayCount, CGDirectDisplayID *displayIDs) {
+    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+    int size = displayCount * sizeof(CGDirectDisplayID);
+
+    free(pQuartzScreen->displayIDs);
+    pQuartzScreen->displayIDs = malloc(size);
+    memcpy(pQuartzScreen->displayIDs, displayIDs, size);
+    pQuartzScreen->displayCount = displayCount;
+}
diff --git a/hw/xquartz/quartz.h b/hw/xquartz/quartz.h
index b1a3f31..1b924e7 100644
--- a/hw/xquartz/quartz.h
+++ b/hw/xquartz/quartz.h
@@ -62,7 +62,8 @@ typedef void (*ResumeScreenProc)(ScreenPtr pScreen);
 /*
  * Screen state change support
  */
-typedef void (*AddPseudoramiXScreensProc)(int *x, int *y, int *width, int *height);
+typedef void (*AddPseudoramiXScreensProc)
+    (int *x, int *y, int *width, int *height, ScreenPtr pScreen);
 typedef void (*UpdateScreenProc)(ScreenPtr pScreen);
 
 /*
diff --git a/hw/xquartz/quartzCommon.h b/hw/xquartz/quartzCommon.h
index eb761ed..d0d358b 100644
--- a/hw/xquartz/quartzCommon.h
+++ b/hw/xquartz/quartzCommon.h
@@ -51,6 +51,9 @@ typedef struct {
 #define QUARTZ_PRIV(pScreen) \
     ((QuartzScreenPtr)dixLookupPrivate(&pScreen->devPrivates, quartzScreenKey))
 
+void QuartzCopyDisplayIDs(ScreenPtr pScreen,
+                          int displayCount, CGDirectDisplayID *displayIDs);
+
 // User preferences used by Quartz modes
 extern int              quartzUseSysBeep;
 extern int              quartzFullscreenDisableHotkeys;
diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c
new file mode 100644
index 0000000..6747752
--- /dev/null
+++ b/hw/xquartz/quartzRandR.c
@@ -0,0 +1,394 @@
+/*
+ *
+ * Quartz-specific support for the XRandR extension
+ *
+ * Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons,
+ *               2010      Jan Hauffa.
+ *                 All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+#include "sanitizedCarbon.h"
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "quartzCommon.h"
+#include "quartzRandR.h"
+
+#if defined(FAKE_RANDR)
+#include "scrnintstr.h"
+#include "windowstr.h"
+#else
+#include <X11/extensions/randr.h>
+#include <randrstr.h>
+#include <IOKit/graphics/IOGraphicsTypes.h>
+#endif
+
+
+#if defined(FAKE_RANDR)
+
+static const int padlength[4] = {0, 3, 2, 1};
+
+void
+RREditConnectionInfo (ScreenPtr pScreen)
+{
+    xConnSetup	    *connSetup;
+    char	    *vendor;
+    xPixmapFormat   *formats;
+    xWindowRoot	    *root;
+    xDepth	    *depth;
+    xVisualType	    *visual;
+    int		    screen = 0;
+    int		    d;
+
+    connSetup = (xConnSetup *) ConnectionInfo;
+    vendor = (char *) connSetup + sizeof (xConnSetup);
+    formats = (xPixmapFormat *) ((char *) vendor +
+				 connSetup->nbytesVendor +
+				 padlength[connSetup->nbytesVendor & 3]);
+    root = (xWindowRoot *) ((char *) formats +
+			    sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
+    while (screen != pScreen->myNum)
+    {
+	depth = (xDepth *) ((char *) root + 
+			    sizeof (xWindowRoot));
+	for (d = 0; d < root->nDepths; d++)
+	{
+	    visual = (xVisualType *) ((char *) depth +
+				      sizeof (xDepth));
+	    depth = (xDepth *) ((char *) visual +
+				depth->nVisuals * sizeof (xVisualType));
+	}
+	root = (xWindowRoot *) ((char *) depth);
+	screen++;
+    }
+    root->pixWidth = pScreen->width;
+    root->pixHeight = pScreen->height;
+    root->mmWidth = pScreen->mmWidth;
+    root->mmHeight = pScreen->mmHeight;
+}
+
+#else  /* defined(FAKE_RANDR) */
+
+#define DEFAULT_REFRESH  60
+#define kDisplayModeUsableFlags  (kDisplayModeValidFlag | kDisplayModeSafeFlag)
+
+typedef struct {
+    size_t width, height;
+    int refresh;
+    const void *ref;
+} QuartzModeInfo, *QuartzModeInfoPtr;
+
+typedef Bool (*QuartzModeCallback)
+    (ScreenPtr, CGDirectDisplayID, QuartzModeInfoPtr, void *);
+
+
+#if defined(USE_DEPRECATED_CG_API)
+
+static long getDictLong (CFDictionaryRef dictRef, CFStringRef key) {
+    long value;
+
+    CFNumberRef numRef = (CFNumberRef) CFDictionaryGetValue(dictRef, key);
+    if (!numRef)
+        return 0;
+
+    if (!CFNumberGetValue(numRef, kCFNumberLongType, &value))
+        return 0;
+    return value;
+}
+
+static double getDictDouble (CFDictionaryRef dictRef, CFStringRef key) {
+    double value;
+
+    CFNumberRef numRef = (CFNumberRef) CFDictionaryGetValue(dictRef, key);
+    if (!numRef)
+        return 0.0;
+
+    if (!CFNumberGetValue(numRef, kCFNumberDoubleType, &value))
+        return 0.0;
+    return value;
+}
+
+static void QuartzRandRGetModeInfo (CFDictionaryRef modeRef,
+                                    QuartzModeInfoPtr pMode) {
+    pMode->width = (size_t) getDictLong(modeRef, kCGDisplayWidth);
+    pMode->height = (size_t) getDictLong(modeRef, kCGDisplayHeight);
+    pMode->refresh = (int)(getDictDouble(modeRef, kCGDisplayRefreshRate) + 0.5);
+    if (pMode->refresh == 0)
+        pMode->refresh = DEFAULT_REFRESH;
+    pMode->ref = NULL;
+}
+
+static Bool QuartzRandRGetCurrentModeInfo (CGDirectDisplayID screenId,
+                                           QuartzModeInfoPtr pMode) {
+    CFDictionaryRef curModeRef = CGDisplayCurrentMode(screenId);
+    if (!curModeRef)
+        return FALSE;
+
+    QuartzRandRGetModeInfo(curModeRef, pMode);
+    return TRUE;
+}
+
+static Bool QuartzRandRSetMode (CGDirectDisplayID screenId,
+                                QuartzModeInfoPtr pMode) {
+    CFDictionaryRef modeRef = (CFDictionaryRef) pMode->ref;
+    return (CGDisplaySwitchToMode(screenId, modeRef) != kCGErrorSuccess);
+}
+
+static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
+                                       CGDirectDisplayID screenId,
+                                       QuartzModeCallback callback,
+                                       void *data) {
+    CFDictionaryRef curModeRef, modeRef;
+    long curBpp;
+    CFArrayRef modes;
+    QuartzModeInfo modeInfo;
+    int i;
+
+    curModeRef = CGDisplayCurrentMode(screenId);
+    if (!curModeRef)
+        return FALSE;
+    curBpp = getDictLong(curModeRef, kCGDisplayBitsPerPixel);
+
+    modes = CGDisplayAvailableModes(screenId);
+    if (!modes)
+        return FALSE;
+    for (i = 0; i < CFArrayGetCount(modes); i++) {
+        modeRef = (CFDictionaryRef) CFArrayGetValueAtIndex(modes, i);
+
+        /* Skip modes that are not usable on the current display or have a
+           different pixel encoding than the current mode. */
+        if (((unsigned long) getDictLong(modeRef, kCGDisplayIOFlags) &
+             kDisplayModeUsableFlags) != kDisplayModeUsableFlags)
+            continue;
+        if (getDictLong(modeRef, kCGDisplayBitsPerPixel) != curBpp)
+            continue;
+
+        QuartzRandRGetModeInfo(modeRef, &modeInfo);
+        modeInfo.ref = modeRef;
+        if (!callback(pScreen, screenId, &modeInfo, data))
+            break;
+    }
+    return TRUE;
+}
+
+#else  /* defined(USE_DEPRECATED_CG_API) */
+
+static void QuartzRandRGetModeInfo (CGDisplayModeRef modeRef,
+                                    QuartzModeInfoPtr pMode) {
+    pMode->width = CGDisplayModeGetWidth(modeRef);
+    pMode->height = CGDisplayModeGetHeight(modeRef);
+    pMode->refresh = (int) (CGDisplayModeGetRefreshRate(modeRef) + 0.5);
+    if (pMode->refresh == 0)
+        pMode->refresh = DEFAULT_REFRESH;
+    pMode->ref = NULL;
+}
+
+static Bool QuartzRandRGetCurrentModeInfo (CGDirectDisplayID screenId,
+                                           QuartzModeInfoPtr pMode) {
+    CGDisplayModeRef curModeRef = CGDisplayCopyDisplayMode(screenId);
+    if (!curModeRef)
+        return FALSE;
+
+    QuartzRandRGetModeInfo(curModeRef, pMode);
+    CGDisplayModeRelease(curModeRef);
+    return TRUE;
+}
+
+static Bool QuartzRandRSetMode (CGDirectDisplayID screenId,
+                                QuartzModeInfoPtr pMode) {
+    CGDisplayModeRef modeRef = (CGDisplayModeRef) pMode->ref;
+    if (!modeRef)
+        return FALSE;
+
+    return (CGDisplaySetDisplayMode(screenId, modeRef, NULL) !=
+            kCGErrorSuccess);
+}
+
+static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
+                                       CGDirectDisplayID screenId,
+                                       QuartzModeCallback callback,
+                                       void *data) {
+    CGDisplayModeRef curModeRef, modeRef;
+    CFStringRef curPixelEnc, pixelEnc;
+    CFComparisonResult pixelEncEqual;
+    CFArrayRef modes;
+    QuartzModeInfo modeInfo;
+    int i;
+
+    curModeRef = CGDisplayCopyDisplayMode(screenId);
+    if (!curModeRef)
+        return FALSE;
+    curPixelEnc = CGDisplayModeCopyPixelEncoding(curModeRef);
+    CGDisplayModeRelease(curModeRef);
+
+    modes = CGDisplayCopyAllDisplayModes(screenId, NULL);
+    if (!modes) {
+        CFRelease(curPixelEnc);
+        return FALSE;
+    }
+    for (i = 0; i < CFArrayGetCount(modes); i++) {
+        modeRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
+
+        /* Skip modes that are not usable on the current display or have a
+           different pixel encoding than the current mode. */
+        if ((CGDisplayModeGetIOFlags(modeRef) & kDisplayModeUsableFlags) !=
+            kDisplayModeUsableFlags)
+            continue;
+        pixelEnc = CGDisplayModeCopyPixelEncoding(modeRef);
+        pixelEncEqual = CFStringCompare(pixelEnc, curPixelEnc, 0);
+        CFRelease(pixelEnc);
+        if (pixelEncEqual != kCFCompareEqualTo)
+            continue;
+
+        QuartzRandRGetModeInfo(modeRef, &modeInfo);
+        modeInfo.ref = modeRef;
+        if (!callback(pScreen, screenId, &modeInfo, data))
+            break;
+    }
+    CFRelease(modes);
+
+    CFRelease(curPixelEnc);
+    return TRUE;
+}
+
+#endif  /* defined(USE_DEPRECATED_CG_API) */
+
+
+static Bool QuartzRandRModesEqual (QuartzModeInfoPtr pMode1,
+                                   QuartzModeInfoPtr pMode2) {
+    if (pMode1->width != pMode2->width)
+        return FALSE;
+    if (pMode1->height != pMode2->height)
+        return FALSE;
+    if (pMode1->refresh != pMode2->refresh)
+        return FALSE;
+    return TRUE;
+}
+
+static Bool QuartzRandRGetModeCallback (ScreenPtr pScreen,
+                                        CGDirectDisplayID screenId,
+                                        QuartzModeInfoPtr pMode,
+                                        void *data) {
+    QuartzModeInfoPtr pCurMode = (QuartzModeInfoPtr) data;
+
+    RRScreenSizePtr pSize = RRRegisterSize(pScreen,
+        pMode->width, pMode->height, pScreen->mmWidth, pScreen->mmHeight);
+    if (pSize) {
+        RRRegisterRate(pScreen, pSize, pMode->refresh);
+
+        if (QuartzRandRModesEqual(pMode, pCurMode))
+            RRSetCurrentConfig(pScreen, RR_Rotate_0, pMode->refresh, pSize);
+    }
+    return TRUE;
+}
+
+static Bool QuartzRandRSetModeCallback (ScreenPtr pScreen,
+                                        CGDirectDisplayID screenId,
+                                        QuartzModeInfoPtr pMode,
+                                        void *data) {
+    QuartzModeInfoPtr pReqMode = (QuartzModeInfoPtr) data;
+
+    if (!QuartzRandRModesEqual(pMode, pReqMode))
+        return TRUE;  /* continue enumeration */
+
+    return QuartzRandRSetMode(screenId, pMode);
+}
+
+static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
+    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+    CGDirectDisplayID screenId;
+    QuartzModeInfo curMode;
+
+    *rotations = RR_Rotate_0;  /* TODO: support rotation */
+
+    if (pQuartzScreen->displayCount == 0)
+        return FALSE;
+    if (pQuartzScreen->displayCount > 1) {
+        /* RandR operations are not well-defined for an X11 screen spanning
+           multiple CG displays. Create a single entry for the current virtual
+           resolution. */
+        RRScreenSizePtr pSize = RRRegisterSize(pScreen, pScreen->width,
+            pScreen->height, pScreen->mmWidth, pScreen->mmHeight);
+        if (pSize) {
+            RRRegisterRate(pScreen, pSize, DEFAULT_REFRESH);
+            RRSetCurrentConfig(pScreen, RR_Rotate_0, DEFAULT_REFRESH, pSize);
+        }
+        return TRUE;
+    }
+    screenId = pQuartzScreen->displayIDs[0];
+
+    if (!QuartzRandRGetCurrentModeInfo(screenId, &curMode))
+        return FALSE;
+    return QuartzRandREnumerateModes(pScreen, screenId,
+        QuartzRandRGetModeCallback, &curMode);
+}
+
+static Bool QuartzRandRSetConfig (ScreenPtr           pScreen,
+			          Rotation            randr,
+			          int                 rate,
+			          RRScreenSizePtr     pSize) {
+    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+    CGDirectDisplayID screenId;
+    QuartzModeInfo reqMode, curMode;
+
+    if (pQuartzScreen->displayCount == 0)
+        return FALSE;
+    if (pQuartzScreen->displayCount > 1) {
+        /* RandR operations are not well-defined for an X11 screen spanning
+           multiple CG displays. Do not accept any configuations that differ
+           from the current configuration. */
+        return ((pSize->width == pScreen->width) &&
+                (pSize->height == pScreen->height));
+    }
+    screenId = pQuartzScreen->displayIDs[0];
+
+    reqMode.width = pSize->width;
+    reqMode.height = pSize->height;
+    reqMode.refresh = rate;
+
+    /* Do not switch modes if requested mode is equal to current mode. */
+    if (!QuartzRandRGetCurrentModeInfo(screenId, &curMode))
+        return FALSE;
+    if (QuartzRandRModesEqual(&reqMode, &curMode))
+        return TRUE;
+
+    return QuartzRandREnumerateModes(pScreen, screenId,
+        QuartzRandRSetModeCallback, &reqMode);
+}
+
+Bool QuartzRandRInit (ScreenPtr pScreen) {
+    rrScrPrivPtr    pScrPriv;
+    
+    if (!RRScreenInit (pScreen)) return FALSE;
+
+    pScrPriv = rrGetScrPriv(pScreen);
+    pScrPriv->rrGetInfo = QuartzRandRGetInfo;
+    pScrPriv->rrSetConfig = QuartzRandRSetConfig;
+    return TRUE;
+}
+
+#endif  /* defined(FAKE_RANDR) */
diff --git a/hw/xquartz/quartzRandR.h b/hw/xquartz/quartzRandR.h
new file mode 100644
index 0000000..a190205
--- /dev/null
+++ b/hw/xquartz/quartzRandR.h
@@ -0,0 +1,37 @@
+/*
+ * quartzRandR.h
+ *
+ * Copyright (c) 2010 Jan Hauffa.
+ *                 All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+/*define FAKE_RANDR 1*/
+#define USE_DEPRECATED_CG_API 1
+
+#if defined(FAKE_RANDR)
+void RREditConnectionInfo (ScreenPtr pScreen);
+#else
+Bool QuartzRandRInit (ScreenPtr pScreen);
+#endif
diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c
index 87e97d4..0e36ee1 100644
--- a/hw/xquartz/xpr/xprScreen.c
+++ b/hw/xquartz/xpr/xprScreen.c
@@ -176,7 +176,7 @@ displayScreenBounds(CGDirectDisplayID id)
  *  with PseudoramiX.
  */
 static void
-xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height)
+xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height, ScreenPtr pScreen)
 {
     CGDisplayCount i, displayCount;
     CGDirectDisplayID *displayList = NULL;
@@ -199,6 +199,7 @@ xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height)
     if(!displayList)
         FatalError("Unable to allocate memory for list of displays.\n");
     CGGetActiveDisplayList(displayCount, displayList, &displayCount);
+    QuartzCopyDisplayIDs(pScreen, displayCount, displayList);
 
     /* Get the union of all screens */
     for (i = 0; i < displayCount; i++) {
@@ -336,6 +337,7 @@ xprAddScreen(int index, ScreenPtr pScreen)
         ErrorF("Warning: noPseudoramiXExtension!\n");
         
         dpy = displayAtIndex(index);
+        QuartzCopyDisplayIDs(pScreen, 1, &dpy);
 
         frame = displayScreenBounds(dpy);
 
@@ -346,7 +348,7 @@ xprAddScreen(int index, ScreenPtr pScreen)
     }
     else
     {
-        xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height);
+        xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height, pScreen);
     }
 
     /* Passing zero width (pitch) makes miCreateScreenResources set the
commit f939ab0175e1662f5df664449cba5d72fa1dbe1c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 27 17:30:13 2010 +0100

    modes: Beware the driver switching root pixmaps
    
    Program received signal SIGSEGV, Segmentation fault.
    0x080d4a2d in xf86RandR12ScreenSetSize (pScreen=0x8dca3a0, width=800,
        height=600, mmWidth=210, mmHeight=157)
        at ../../../../hw/xfree86/modes/xf86RandR12.c:731
    731     ../../../../hw/xfree86/modes/xf86RandR12.c: No such file or directory.
            in ../../../../hw/xfree86/modes/xf86RandR12.c
    (gdb) bt full
        height=600, mmWidth=210, mmHeight=157)
        at ../../../../hw/xfree86/modes/xf86RandR12.c:731
            randrp = 0x8dcae68
            pScrn = 0x8dbeb28
            config = <value optimized out>
            pRoot = 0x8e08e30
            pScrnPix = 0xb6d12008
            ret = 1
            c = <value optimized out>
        mmWidth=210, mmHeight=157) at ../../randr/rrscreen.c:185
    No locals.
        at ../../randr/rrscreen.c:307
            pWin = 0x8e08e30
            pScreen = 0x8dca3a0
            i = <value optimized out>
            rc = 0
    ../../randr/randr.c:485
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Julien Cristau <jcristau at debian.org>
    Tested-by: Julien Cristau <jcristau at debian.org>
    Cc: Keith Packard <keithp at keithp.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit fdabcec57ae0fdc9910060609bb0848552c1db4d)

diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 043ceee..c17b5fa 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -686,7 +686,7 @@ xf86RandR12ScreenSetSize (ScreenPtr	pScreen,
     ScrnInfoPtr		pScrn = XF86SCRNINFO(pScreen);
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
     WindowPtr		pRoot = pScreen->root;
-    PixmapPtr		pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
+    PixmapPtr		pScrnPix;
     Bool		ret = FALSE;
     int                 c;
 
@@ -727,6 +727,7 @@ xf86RandR12ScreenSetSize (ScreenPtr	pScreen,
 	}
     }
 
+    pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
     pScreen->width = pScrnPix->drawable.width = width;
     pScreen->height = pScrnPix->drawable.height = height;
     randrp->mmWidth = pScreen->mmWidth = mmWidth;
commit 3ea7d271c8847a3135442ea24b8d5ff81d5e20b7
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Fri Aug 27 10:20:29 2010 -0700

    os: Return BadLength instead of disconnecting BigReq clients (#4565)
    
    If a client sends a big request that's too big (i.e. bigger than
    maxBigRequestSize << 2 bytes), the server just disconnects it.  This makes the
    client receive SIGPIPE the next time it tries to send something.
    
    The X Test Suite sends requests that are too big when the test specifies the
    TOO_LONG test type.  When the client receives SIGPIPE, XTS marks it as
    UNRESOLVED, which counts as a failure.
    
    Instead, remember how long the request is supposed to be and then return that
    size.  Dispatch() checks the length and sends BadLength to the client.  Then,
    whenever oci->ignoreBytes is nonzero, ignore the data read instead of trying to
    process it as a request.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit cf88363db0ebb42df7cc286b85d30d7898aea840)

diff --git a/os/io.c b/os/io.c
index e2df2e3..fb9f762 100644
--- a/os/io.c
+++ b/os/io.c
@@ -251,7 +251,14 @@ ReadRequestFromClient(ClientPtr client)
     need_header = FALSE;
     move_header = FALSE;
     gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
-    if (gotnow < sizeof(xReq))
+
+    if (oci->ignoreBytes > 0) {
+	if (oci->ignoreBytes > oci->size)
+	    needed = oci->size;
+	else
+	    needed = oci->ignoreBytes;
+    }
+    else if (gotnow < sizeof(xReq))
     {
 	/* We don't have an entire xReq yet.  Can't tell how big
 	 * the request will be until we get the whole xReq.
@@ -294,8 +301,13 @@ ReadRequestFromClient(ClientPtr client)
 	if (needed > maxBigRequestSize << 2)
 	{
 	    /* request is too big for us to handle */
-	    YieldControlDeath();
-	    return -1;
+	    /*
+	     * Mark the rest of it as needing to be ignored, and then return
+	     * the full size.  Dispatch() will turn it into a BadLength error.
+	     */
+	    oci->ignoreBytes = needed - gotnow;
+	    oci->lenLastReq = gotnow;
+	    return needed;
 	}
 	if ((gotnow == 0) ||
 	    ((oci->bufptr - oci->buffer + needed) > oci->size))
@@ -400,6 +412,14 @@ ReadRequestFromClient(ClientPtr client)
     }
     oci->lenLastReq = needed;
 
+    /* If there are bytes to ignore, ignore them now. */
+
+    if (oci->ignoreBytes > 0) {
+	assert(needed == oci->ignoreBytes || needed == oci->size);
+	oci->ignoreBytes -= gotnow;
+	needed = gotnow = 0;
+    }
+
     /*
      *  Check to see if client has at least one whole request in the
      *  buffer beyond the request we're returning to the caller.
@@ -1030,6 +1050,7 @@ AllocateInputBuffer(void)
     oci->bufptr = oci->buffer;
     oci->bufcnt = 0;
     oci->lenLastReq = 0;
+    oci->ignoreBytes = 0;
     return oci;
 }
 
diff --git a/os/osdep.h b/os/osdep.h
index 1d87592..3c0e78f 100644
--- a/os/osdep.h
+++ b/os/osdep.h
@@ -125,6 +125,7 @@ typedef struct _connectionInput {
     int  bufcnt;                /* count of bytes in buffer */
     int lenLastReq;
     int size;
+    unsigned int ignoreBytes;   /* bytes to ignore before the next request */
 } ConnectionInput, *ConnectionInputPtr;
 
 typedef struct _connectionOutput {


More information about the Xquartz-changes mailing list