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

Jeremy Huddleston jeremyhu at freedesktop.org
Fri Aug 20 23:28:24 PDT 2010


Rebased ref, commits from common ancestor:
commit 1f03dfb10cd9afab052d38cd9de8311dd4bd9166
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 d07081c5a6d32446f4ef86b25af5ac62683f7595
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 895a7f9364d3a1c786cdfd6843fe913ff1d66579
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>

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 7534267..586d299 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;
@@ -129,8 +129,9 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
     int i;
     BOOL retval = FALSE;
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+    CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
 
-    switch(callback(pScreen, screenId, &pQuartzScreen->rootlessMode, data)) {
+    switch(callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
         case CALLBACK_SUCCESS:
             return TRUE;
         case CALLBACK_ERROR:
@@ -140,7 +141,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
             break;
     }
 
-    switch(callback(pScreen, screenId, &pQuartzScreen->fullscreenMode, data)) {
+    switch(callback(pScreen, &pQuartzScreen->fullscreenMode, data)) {
         case CALLBACK_SUCCESS:
             return TRUE;
         case CALLBACK_ERROR:
@@ -172,7 +173,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
 
         QuartzRandRGetModeInfo(modeRef, &modeInfo);
         modeInfo.ref = modeRef;
-        cb = callback(pScreen, screenId, &modeInfo, data);
+        cb = callback(pScreen, &modeInfo, data);
         if (cb == CALLBACK_SUCCESS)
             break;
         if (cb == CALLBACK_ERROR) {
@@ -193,6 +194,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 +208,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 +218,6 @@ static Bool QuartzRandRSetMode (CGDirectDisplayID screenId,
 }
 
 static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
-                                       CGDirectDisplayID screenId,
                                        QuartzModeCallback callback,
                                        void *data) {
     CGDisplayModeRef curModeRef, modeRef;
@@ -228,8 +229,9 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
     Bool retval = TRUE;
 
     QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+    CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
 
-    switch(callback(pScreen, screenId, &pQuartzScreen->rootlessMode, data)) {
+    switch(callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
         case CALLBACK_SUCCESS:
             return TRUE;
         case CALLBACK_ERROR:
@@ -239,7 +241,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
             break;
     }
 
-    switch(callback(pScreen, screenId, &pQuartzScreen->fullscreenMode, data)) {
+    switch(callback(pScreen, &pQuartzScreen->fullscreenMode, data)) {
         case CALLBACK_SUCCESS:
             return TRUE;
         case CALLBACK_ERROR:
@@ -277,7 +279,7 @@ static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
 
         QuartzRandRGetModeInfo(modeRef, &modeInfo);
         modeInfo.ref = modeRef;
-        cb = callback(pScreen, screenId, &modeInfo, data);
+        cb = callback(pScreen, &modeInfo, data);
         if (cb == CALLBACK_SUCCESS)
             break;
 		if (cb == CALLBACK_ERROR) {
@@ -306,14 +308,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 +324,6 @@ static Bool QuartzRandRRegisterMode (ScreenPtr pScreen,
 }
 
 static int QuartzRandRRegisterModeCallback (ScreenPtr pScreen,
-                                        CGDirectDisplayID screenId,
                                         QuartzModeInfoPtr pMode,
                                         void *data __unused) {
     if(QuartzRandRRegisterMode(pScreen, pMode)) {
@@ -331,40 +333,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 +396,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 +404,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 +494,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 d51bce565e9b789694176c2150ec698b9528e194
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>

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 9b84fa1..7534267 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 e2ea1fd96edb14dd89e4e03759c93907776d84fd
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>

diff --git a/hw/xquartz/quartzRandR.c b/hw/xquartz/quartzRandR.c
index 65dce22..9b84fa1 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 = 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 = 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;
+    }
 
     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
@@ -144,10 +172,15 @@ 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;
+        }
     }
-    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 275cd394f507afc0d4a1cde81dc89e2eb3979ece
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>

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

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

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 6137fbd27c0afe950cd87cc205d5a0d8a47e361b
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>

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 4bf1f56d775b46099169f5218c12114a46c8c136
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>

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 968d3549f84cd1f529328c4cd8d968c189d6d646
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sun Aug 15 20:07:28 2010 -0700

    rootless: Remove ROOTLESS_WORKAROUND
    
    This was already removed for XWin (20701522be803fe47e921fcf059dadf64c7f287d)
    with no reported side effects.  XQuartz seems to be behaving ok without it as
    well.  While this possibly brings back bug #1168, we don't have any reproduction
    steps for that issue, and if it crops up again, we should fix it a real way
    rather than this hokey workaround which doesn't even work for COMPOSITE.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/configure.ac b/configure.ac
index 9884fa7..95f7a76 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1926,7 +1926,7 @@ if test "x$XQUARTZ" = xyes; then
 
 	AC_CHECK_LIB([Xplugin],[xp_init],[:])
 
-	CFLAGS="${CFLAGS} -DROOTLESS_WORKAROUND -DROOTLESS_SAFEALPHA -DNO_ALLOCA"
+	CFLAGS="${CFLAGS} -DROOTLESS_SAFEALPHA -DNO_ALLOCA"
 
 	PKG_CHECK_MODULES(XPBPROXY, $APPLEWMPROTO $LIBAPPLEWM xfixes x11)
 
diff --git a/miext/damage/damage.c b/miext/damage/damage.c
index 1cf0513..e0e96f2 100644
--- a/miext/damage/damage.c
+++ b/miext/damage/damage.c
@@ -89,11 +89,7 @@ getDrawableDamageRef (DrawablePtr pDrawable)
 	ScreenPtr   pScreen = pDrawable->pScreen;
 
 	pPixmap = 0;
-	if (pScreen->GetWindowPixmap
-#ifdef ROOTLESS_WORKAROUND
-	    && ((WindowPtr)pDrawable)->viewable
-#endif
-	    )
+	if (pScreen->GetWindowPixmap)
 	    pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable);
 
 	if (!pPixmap)
commit 79ee78de9de49d0cab03401662baa476a18e53b8
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Aug 20 17:32:27 2010 -0700

    xserver 1.9.0
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 1f4eb34..9884fa7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,8 +26,8 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([xorg-server], 1.8.99.906, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2010-08-12"
+AC_INIT([xorg-server], 1.9.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2010-08-20"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
commit 3e56efcfb63677cd8574e1e435e61d96f79ea536
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Aug 20 10:01:48 2010 -0700

    fb: make isClipped always reject negative coordinates (bug 11503)
    
    A window with either dimension > 32767 can be positioned such that
    coordinates > 32767 are visible on the screen. Attempts to draw to
    those pixels will generate coordinates wrapped around to negative
    values.
    
    The optimized clipping macro, 'isClipped', in fbbits.h, computes
    clipping in window space rather than screen space using int16 values,
    and so it too has coordinates wrapped around to negative values and
    hence ends up accepting the wrapped drawing coordinates.
    
    Two possible fixes for this problem
    
     1) Detect wrapped region coordinates and clip those to 32767.
     2) Detect negative incoming coordinates and reject those
    
    This patch takes the second approach as it is much shorter, simply
    detecting when either X or Y incoming coordinate is negative, which
    can never be 'within' any drawable.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/fb/fbbits.h b/fb/fbbits.h
index 8bf1a02..2dec84b 100644
--- a/fb/fbbits.h
+++ b/fb/fbbits.h
@@ -25,7 +25,7 @@
  * underlying datatypes instead of masks
  */
 
-#define isClipped(c,ul,lr)  ((((c) - (ul)) | ((lr) - (c))) & 0x80008000)
+#define isClipped(c,ul,lr)  (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
 
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
commit 951605b4660290044fb238bcf1d6d9e498567e8c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Aug 20 13:51:04 2010 +0100

    edid: Adjust rounding of max_clock
    
    A simple hack to accommodate various EDID who have detailed modes that
    exceed the EDID's max pixel clock. The pixel clock is only defined in
    units of 10MHz and often appears as the maximum pixel code of the
    detailed modes, rounded to the nearest 10MHz. Adjusting the max_clock to
    include an extra 5MHz prevents the parser from rejecting the detailed
    modes.
    
    The kernel uses the same fuzz and by including it in X we can use the
    same modes in X as for the console.
    
    Fixes:
    
      Bug 23833 - X uses different refresh rate to that set by kernel module
      https://bugs.freedesktop.org/show_bug.cgi?id=23833
    
    In the future, we will want to try harder to keep the KMS modes but at
    the same time we need to apply the restrictions as specified by the
    user's configuration, and need to fill in modes for fullscreen games on
    fixed-mode panels.
    
    Reported-and-tested-by: Fabio Pedretti <fabio.ped at libero.it>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Alex Deucher <alexdeucher at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
index acb7efa..46958f7 100644
--- a/hw/xfree86/ddc/interpret_edid.c
+++ b/hw/xfree86/ddc/interpret_edid.c
@@ -552,7 +552,7 @@ get_monitor_ranges(Uchar *c, struct monitor_ranges *r)
     r->max_h = MAX_H;
     r->max_clock = 0;
     if(MAX_CLOCK != 0xff) /* is specified? */
-	r->max_clock = MAX_CLOCK * 10;
+	r->max_clock = MAX_CLOCK * 10 + 5;
     if (HAVE_2ND_GTF) {
 	r->gtf_2nd_f = F_2ND_GTF;
 	r->gtf_2nd_c = C_2ND_GTF;
commit 7e581780603d6b15291d032efdeeca77f969e0ba
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 24 12:24:58 2010 +0100

    glx: Prevent NULL context deref in __glXGetDrawable() (bug 29184)
    
    During a SwapBuffers request, we may end up querying an unknown drawable
    outside of an active context, and so need to report this error prior to
    attempting to dereference the NULL context.
    
    Also fixes:
    
      [Bug 29184] glXSwapBuffers with no GLX context crashes X.
      https://bugs.freedesktop.org/show_bug.cgi?id=29184
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Kristian Høgsberg <krh at bitplanet.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 9e5b213..8d13c15 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -491,6 +491,13 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
 	return pGlxDraw;
     }
 
+    /* No active context and an unknown drawable, bail. */
+    if (glxc == NULL) {
+	    client->errorValue = drawId;
+	    *error = BadMatch;
+	    return NULL;
+    }
+
     /* The drawId wasn't a GLX drawable.  Make sure it's a window and
      * create a GLXWindow for it.  Check that the drawable screen
      * matches the context screen and that the context fbconfig is
commit 5725849a1b427cd4a72b84e57f211edb35838718
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Jun 28 18:08:50 2010 -0400

    render: Bounds check for nglyphs in ProcRenderAddGlyphs (#28801)
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/render/render.c b/render/render.c
index ef233e4..00241f9 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1077,6 +1077,14 @@ ProcRenderAddGlyphs (ClientPtr client)
     gi = (xGlyphInfo *) (gids + nglyphs);
     bits = (CARD8 *) (gi + nglyphs);
     remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
+
+    /* protect against bad nglyphs */
+    if (gi < stuff || gi > ((CARD32 *)stuff + client->req_len) ||
+        bits < stuff || bits > ((CARD32 *)stuff + client->req_len)) {
+        err = BadLength;
+        goto bail;
+    }
+
     for (i = 0; i < nglyphs; i++)
     {
 	size_t padded_width;


More information about the Xquartz-changes mailing list