529 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			529 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Quartz-specific support for the XRandR extension
 | 
						|
 *
 | 
						|
 * Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons,
 | 
						|
 *               2010      Jan Hauffa.
 | 
						|
 *               2010-2012 Apple Inc.
 | 
						|
 *                 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"
 | 
						|
#include "quartz.h"
 | 
						|
#include "darwin.h"
 | 
						|
 | 
						|
#include "X11Application.h"
 | 
						|
 | 
						|
#include <AvailabilityMacros.h>
 | 
						|
 | 
						|
#include <X11/extensions/randr.h>
 | 
						|
#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)
 | 
						|
 | 
						|
#define CALLBACK_SUCCESS        0
 | 
						|
#define CALLBACK_CONTINUE       1
 | 
						|
#define CALLBACK_ERROR          -1
 | 
						|
 | 
						|
typedef int (*QuartzModeCallback)
 | 
						|
    (ScreenPtr, QuartzModeInfoPtr, void *);
 | 
						|
 | 
						|
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;
 | 
						|
    pMode->pSize = NULL;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
QuartzRandRCopyCurrentModeInfo(CGDirectDisplayID screenId,
 | 
						|
                               QuartzModeInfoPtr pMode)
 | 
						|
{
 | 
						|
    CGDisplayModeRef curModeRef = CGDisplayCopyDisplayMode(screenId);
 | 
						|
    if (!curModeRef)
 | 
						|
        return FALSE;
 | 
						|
 | 
						|
    QuartzRandRGetModeInfo(curModeRef, pMode);
 | 
						|
    pMode->ref = curModeRef;
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
QuartzRandRSetCGMode(CGDirectDisplayID screenId,
 | 
						|
                     QuartzModeInfoPtr pMode)
 | 
						|
{
 | 
						|
    CGDisplayModeRef modeRef = (CGDisplayModeRef)pMode->ref;
 | 
						|
    if (!modeRef)
 | 
						|
        return FALSE;
 | 
						|
 | 
						|
    return (CGDisplaySetDisplayMode(screenId, modeRef,
 | 
						|
                                    NULL) == kCGErrorSuccess);
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
QuartzRandREnumerateModes(ScreenPtr pScreen,
 | 
						|
                          QuartzModeCallback callback,
 | 
						|
                          void *data)
 | 
						|
{
 | 
						|
    Bool retval = FALSE;
 | 
						|
    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
 | 
						|
 | 
						|
    /* Just an 800x600 fallback if we have no attached heads */
 | 
						|
    if (pQuartzScreen->displayIDs) {
 | 
						|
        CGDisplayModeRef curModeRef, modeRef;
 | 
						|
        CFStringRef curPixelEnc, pixelEnc;
 | 
						|
        CFComparisonResult pixelEncEqual;
 | 
						|
        CFArrayRef modes;
 | 
						|
        QuartzModeInfo modeInfo;
 | 
						|
        int i;
 | 
						|
        CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
 | 
						|
 | 
						|
        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++) {
 | 
						|
            int cb;
 | 
						|
            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;
 | 
						|
            cb = callback(pScreen, &modeInfo, data);
 | 
						|
            if (cb == CALLBACK_CONTINUE) {
 | 
						|
                retval = TRUE;
 | 
						|
            }
 | 
						|
            else if (cb == CALLBACK_SUCCESS) {
 | 
						|
                CFRelease(modes);
 | 
						|
                CFRelease(curPixelEnc);
 | 
						|
                return TRUE;
 | 
						|
            }
 | 
						|
            else if (cb == CALLBACK_ERROR) {
 | 
						|
                CFRelease(modes);
 | 
						|
                CFRelease(curPixelEnc);
 | 
						|
                return FALSE;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        CFRelease(modes);
 | 
						|
        CFRelease(curPixelEnc);
 | 
						|
    }
 | 
						|
 | 
						|
    switch (callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
 | 
						|
    case CALLBACK_SUCCESS:
 | 
						|
        return TRUE;
 | 
						|
 | 
						|
    case CALLBACK_ERROR:
 | 
						|
        return FALSE;
 | 
						|
 | 
						|
    case CALLBACK_CONTINUE:
 | 
						|
        retval = TRUE;
 | 
						|
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    switch (callback(pScreen, &pQuartzScreen->fullscreenMode, data)) {
 | 
						|
    case CALLBACK_SUCCESS:
 | 
						|
        return TRUE;
 | 
						|
 | 
						|
    case CALLBACK_ERROR:
 | 
						|
        return FALSE;
 | 
						|
 | 
						|
    case CALLBACK_CONTINUE:
 | 
						|
        retval = TRUE;
 | 
						|
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    return retval;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
QuartzRandRModesEqual(QuartzModeInfoPtr pMode1,
 | 
						|
                      QuartzModeInfoPtr pMode2)
 | 
						|
{
 | 
						|
    return (pMode1->width == pMode2->width) &&
 | 
						|
           (pMode1->height == pMode2->height) &&
 | 
						|
           (pMode1->refresh == pMode2->refresh);
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
QuartzRandRRegisterMode(ScreenPtr pScreen,
 | 
						|
                        QuartzModeInfoPtr pMode)
 | 
						|
{
 | 
						|
    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
 | 
						|
    Bool isCurrentMode = QuartzRandRModesEqual(&pQuartzScreen->currentMode,
 | 
						|
                                               pMode);
 | 
						|
 | 
						|
    /* 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, pMode->pSize, pMode->refresh);
 | 
						|
 | 
						|
        if (isCurrentMode)
 | 
						|
            RRSetCurrentConfig(pScreen, RR_Rotate_0, pMode->refresh,
 | 
						|
                               pMode->pSize);
 | 
						|
 | 
						|
        return TRUE;
 | 
						|
    }
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
QuartzRandRRegisterModeCallback(ScreenPtr pScreen,
 | 
						|
                                QuartzModeInfoPtr pMode,
 | 
						|
                                void *data __unused)
 | 
						|
{
 | 
						|
    if (QuartzRandRRegisterMode(pScreen, pMode)) {
 | 
						|
        return CALLBACK_CONTINUE;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        return CALLBACK_ERROR;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
QuartzRandRSetMode(ScreenPtr pScreen, QuartzModeInfoPtr pMode,
 | 
						|
                   BOOL doRegister)
 | 
						|
{
 | 
						|
    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
 | 
						|
    Bool captureDisplay =
 | 
						|
        (pMode->refresh != FAKE_REFRESH_FULLSCREEN && pMode->refresh !=
 | 
						|
    FAKE_REFRESH_ROOTLESS);
 | 
						|
    CGDirectDisplayID screenId;
 | 
						|
 | 
						|
    if (pQuartzScreen->displayIDs == NULL)
 | 
						|
        return FALSE;
 | 
						|
 | 
						|
    screenId = pQuartzScreen->displayIDs[0];
 | 
						|
    if (XQuartzShieldingWindowLevel == 0 && captureDisplay) {
 | 
						|
        if (!X11ApplicationCanEnterRandR())
 | 
						|
            return FALSE;
 | 
						|
        CGCaptureAllDisplays();
 | 
						|
        XQuartzShieldingWindowLevel = CGShieldingWindowLevel(); // 2147483630
 | 
						|
        DEBUG_LOG("Display captured.  ShieldWindowID: %u, Shield level: %d\n",
 | 
						|
                  CGShieldingWindowID(screenId), XQuartzShieldingWindowLevel);
 | 
						|
    }
 | 
						|
 | 
						|
    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;
 | 
						|
    if (pQuartzScreen->currentMode.ref)
 | 
						|
        CFRetain(pQuartzScreen->currentMode.ref);
 | 
						|
 | 
						|
    if (XQuartzShieldingWindowLevel != 0 && !captureDisplay) {
 | 
						|
        CGReleaseAllDisplays();
 | 
						|
        XQuartzShieldingWindowLevel = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
QuartzRandRSetModeCallback(ScreenPtr pScreen,
 | 
						|
                           QuartzModeInfoPtr pMode,
 | 
						|
                           void *data)
 | 
						|
{
 | 
						|
    QuartzModeInfoPtr pReqMode = (QuartzModeInfoPtr)data;
 | 
						|
 | 
						|
    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 (QuartzRandRSetMode(pScreen, pMode, FALSE))
 | 
						|
        return CALLBACK_SUCCESS;
 | 
						|
    else
 | 
						|
        return CALLBACK_ERROR;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
QuartzRandRGetInfo(ScreenPtr pScreen, Rotation *rotations)
 | 
						|
{
 | 
						|
    *rotations = RR_Rotate_0;  /* TODO: support rotation */
 | 
						|
 | 
						|
    return QuartzRandREnumerateModes(pScreen, QuartzRandRRegisterModeCallback,
 | 
						|
                                     NULL);
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
QuartzRandRSetConfig(ScreenPtr pScreen,
 | 
						|
                     Rotation randr,
 | 
						|
                     int rate,
 | 
						|
                     RRScreenSizePtr pSize)
 | 
						|
{
 | 
						|
    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
 | 
						|
    QuartzModeInfo reqMode;
 | 
						|
 | 
						|
    reqMode.width = pSize->width;
 | 
						|
    reqMode.height = pSize->height;
 | 
						|
    reqMode.refresh = rate;
 | 
						|
 | 
						|
    /* Do not switch modes if requested mode is equal to current mode. */
 | 
						|
    if (QuartzRandRModesEqual(&reqMode, &pQuartzScreen->currentMode))
 | 
						|
        return TRUE;
 | 
						|
 | 
						|
    if (QuartzRandREnumerateModes(pScreen, QuartzRandRSetModeCallback,
 | 
						|
                                  &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;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
_QuartzRandRUpdateFakeModes(ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
 | 
						|
    QuartzModeInfo activeMode;
 | 
						|
 | 
						|
    if (pQuartzScreen->displayCount > 0) {
 | 
						|
        if (!QuartzRandRCopyCurrentModeInfo(pQuartzScreen->displayIDs[0],
 | 
						|
                                            &activeMode)) {
 | 
						|
            ErrorF("Unable to determine current display mode.\n");
 | 
						|
            return FALSE;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        memset(&activeMode, 0, sizeof(activeMode));
 | 
						|
        activeMode.width = 800;
 | 
						|
        activeMode.height = 600;
 | 
						|
        activeMode.refresh = 60;
 | 
						|
    }
 | 
						|
 | 
						|
    if (pQuartzScreen->fullscreenMode.ref)
 | 
						|
        CFRelease(pQuartzScreen->fullscreenMode.ref);
 | 
						|
    if (pQuartzScreen->currentMode.ref)
 | 
						|
        CFRelease(pQuartzScreen->currentMode.ref);
 | 
						|
 | 
						|
    if (pQuartzScreen->displayCount > 1) {
 | 
						|
        activeMode.width = pScreen->width;
 | 
						|
        activeMode.height = pScreen->height;
 | 
						|
        if (XQuartzIsRootless)
 | 
						|
            activeMode.height += aquaMenuBarHeight;
 | 
						|
    }
 | 
						|
 | 
						|
    pQuartzScreen->fullscreenMode = activeMode;
 | 
						|
    pQuartzScreen->fullscreenMode.refresh = FAKE_REFRESH_FULLSCREEN;
 | 
						|
 | 
						|
    pQuartzScreen->rootlessMode = activeMode;
 | 
						|
    pQuartzScreen->rootlessMode.refresh = FAKE_REFRESH_ROOTLESS;
 | 
						|
    pQuartzScreen->rootlessMode.height -= aquaMenuBarHeight;
 | 
						|
 | 
						|
    if (XQuartzIsRootless) {
 | 
						|
        pQuartzScreen->currentMode = pQuartzScreen->rootlessMode;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        pQuartzScreen->currentMode = pQuartzScreen->fullscreenMode;
 | 
						|
    }
 | 
						|
 | 
						|
    /* This extra retain is for currentMode's copy.
 | 
						|
     * fullscreen and rootless share a retain.
 | 
						|
     */
 | 
						|
    if (pQuartzScreen->currentMode.ref)
 | 
						|
        CFRetain(pQuartzScreen->currentMode.ref);
 | 
						|
 | 
						|
    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;
 | 
						|
    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);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |