quartz.c revision 35c4bbdf
14642e01fSmrg/*
24642e01fSmrg *
34642e01fSmrg * Quartz-specific support for the Darwin X Server
44642e01fSmrg *
535c4bbdfSmrg * Copyright (c) 2002-2012 Apple Inc. All rights reserved.
64642e01fSmrg * Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons.
74642e01fSmrg *                 All Rights Reserved.
84642e01fSmrg *
94642e01fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
104642e01fSmrg * copy of this software and associated documentation files (the "Software"),
114642e01fSmrg * to deal in the Software without restriction, including without limitation
124642e01fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
134642e01fSmrg * and/or sell copies of the Software, and to permit persons to whom the
144642e01fSmrg * Software is furnished to do so, subject to the following conditions:
154642e01fSmrg *
164642e01fSmrg * The above copyright notice and this permission notice shall be included in
174642e01fSmrg * all copies or substantial portions of the Software.
184642e01fSmrg *
194642e01fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
204642e01fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
214642e01fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
224642e01fSmrg * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
234642e01fSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
244642e01fSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
254642e01fSmrg * DEALINGS IN THE SOFTWARE.
264642e01fSmrg *
274642e01fSmrg * Except as contained in this notice, the name(s) of the above copyright
284642e01fSmrg * holders shall not be used in advertising or otherwise to promote the sale,
294642e01fSmrg * use or other dealings in this Software without prior written authorization.
304642e01fSmrg */
314642e01fSmrg
324642e01fSmrg#include "sanitizedCarbon.h"
334642e01fSmrg
344642e01fSmrg#ifdef HAVE_DIX_CONFIG_H
354642e01fSmrg#include <dix-config.h>
364642e01fSmrg#endif
374642e01fSmrg
384642e01fSmrg#include "quartzCommon.h"
396747b715Smrg#include "quartzRandR.h"
404642e01fSmrg#include "inputstr.h"
414642e01fSmrg#include "quartz.h"
424642e01fSmrg#include "darwin.h"
434642e01fSmrg#include "darwinEvents.h"
444642e01fSmrg#include "pseudoramiX.h"
4535c4bbdfSmrg#include "extension.h"
4635c4bbdfSmrg#include "nonsdk_extinit.h"
4735c4bbdfSmrg#include "glx_extinit.h"
484642e01fSmrg#define _APPLEWM_SERVER_
494642e01fSmrg#include "applewmExt.h"
504642e01fSmrg
514642e01fSmrg#include "X11Application.h"
524642e01fSmrg
536747b715Smrg#include <X11/extensions/applewmconst.h>
544642e01fSmrg
554642e01fSmrg// X headers
564642e01fSmrg#include "scrnintstr.h"
574642e01fSmrg#include "windowstr.h"
584642e01fSmrg#include "colormapst.h"
594642e01fSmrg#include "globals.h"
604642e01fSmrg#include "mi.h"
614642e01fSmrg
624642e01fSmrg// System headers
636747b715Smrg#include <stdlib.h>
646747b715Smrg#include <string.h>
654642e01fSmrg#include <sys/types.h>
664642e01fSmrg#include <sys/stat.h>
674642e01fSmrg#include <fcntl.h>
684642e01fSmrg#include <IOKit/pwr_mgt/IOPMLib.h>
6935c4bbdfSmrg#include <libkern/OSAtomic.h>
708223e2f2Smrg#include <signal.h>
714642e01fSmrg
724642e01fSmrg#include <rootlessCommon.h>
734642e01fSmrg#include <Xplugin.h>
744642e01fSmrg
7535c4bbdfSmrg/* Work around a bug on Leopard's headers */
7635c4bbdfSmrg#if defined (__LP64__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 && MAC_OS_X_VERSION_MAX_ALLOWED < 1060
7735c4bbdfSmrgextern OSErr UpdateSystemActivity(UInt8 activity);
7835c4bbdfSmrg#define OverallAct 0
7935c4bbdfSmrg#endif
8035c4bbdfSmrg
8135c4bbdfSmrgDevPrivateKeyRec quartzScreenKeyRec;
8235c4bbdfSmrgint aquaMenuBarHeight = 0;
8335c4bbdfSmrgQuartzModeProcsPtr quartzProcs = NULL;
844642e01fSmrgconst char             *quartzOpenGLBundle = NULL;
854642e01fSmrg
866747b715SmrgBool XQuartzFullscreenDisableHotkeys = TRUE;
876747b715SmrgBool XQuartzOptionSendsAlt = FALSE;
886747b715SmrgBool XQuartzEnableKeyEquivalents = TRUE;
896747b715SmrgBool XQuartzFullscreenVisible = FALSE;
906747b715SmrgBool XQuartzRootlessDefault = TRUE;
916747b715SmrgBool XQuartzIsRootless = TRUE;
926747b715SmrgBool XQuartzServerVisible = FALSE;
936747b715SmrgBool XQuartzFullscreenMenu = FALSE;
948223e2f2Smrg
958223e2f2Smrgint32_t XQuartzShieldingWindowLevel = 0;
964642e01fSmrg
974642e01fSmrg/*
9835c4bbdfSmrg   ===========================================================================
994642e01fSmrg
10035c4bbdfSmrg   Screen functions
1014642e01fSmrg
10235c4bbdfSmrg   ===========================================================================
10335c4bbdfSmrg */
1044642e01fSmrg
1054642e01fSmrg/*
1064642e01fSmrg * QuartzAddScreen
1074642e01fSmrg *  Do mode dependent initialization of each screen for Quartz.
1084642e01fSmrg */
10935c4bbdfSmrgBool
11035c4bbdfSmrgQuartzAddScreen(int index,
11135c4bbdfSmrg                ScreenPtr pScreen)
1124642e01fSmrg{
11335c4bbdfSmrg    // The clang static analyzer thinks we leak displayInfo here
11435c4bbdfSmrg#ifndef __clang_analyzer__
1154642e01fSmrg    // allocate space for private per screen Quartz specific storage
1166747b715Smrg    QuartzScreenPtr displayInfo = calloc(sizeof(QuartzScreenRec), 1);
1174642e01fSmrg
1184642e01fSmrg    // QUARTZ_PRIV(pScreen) = displayInfo;
1194642e01fSmrg    dixSetPrivate(&pScreen->devPrivates, quartzScreenKey, displayInfo);
12035c4bbdfSmrg#endif /* __clang_analyzer__ */
1214642e01fSmrg
1224642e01fSmrg    // do Quartz mode specific initialization
1234642e01fSmrg    return quartzProcs->AddScreen(index, pScreen);
1244642e01fSmrg}
1254642e01fSmrg
1264642e01fSmrg/*
1274642e01fSmrg * QuartzSetupScreen
1284642e01fSmrg *  Finalize mode specific setup of each screen.
1294642e01fSmrg */
13035c4bbdfSmrgBool
13135c4bbdfSmrgQuartzSetupScreen(int index,
13235c4bbdfSmrg                  ScreenPtr pScreen)
1334642e01fSmrg{
1344642e01fSmrg    // do Quartz mode specific setup
13535c4bbdfSmrg    if (!quartzProcs->SetupScreen(index, pScreen))
1364642e01fSmrg        return FALSE;
1374642e01fSmrg
1384642e01fSmrg    // setup cursor support
13935c4bbdfSmrg    if (!quartzProcs->InitCursor(pScreen))
1404642e01fSmrg        return FALSE;
1414642e01fSmrg
1426747b715Smrg#if defined(RANDR)
14335c4bbdfSmrg    if (!QuartzRandRInit(pScreen)) {
1446747b715Smrg        DEBUG_LOG("Failed to init RandR extension.\n");
1456747b715Smrg        return FALSE;
1466747b715Smrg    }
1476747b715Smrg#endif
1486747b715Smrg
1494642e01fSmrg    return TRUE;
1504642e01fSmrg}
1514642e01fSmrg
15235c4bbdfSmrgstatic const ExtensionModule quartzExtensions[] = {
15335c4bbdfSmrg    /* PseudoramiX needs to be done before RandR, so
15435c4bbdfSmrg     * it is in miinitext.c until it can be reordered.
15535c4bbdfSmrg     * { PseudoramiXExtensionInit, "PseudoramiX", &noPseudoramiXExtension },
15635c4bbdfSmrg     */
15735c4bbdfSmrg#ifdef GLXEXT
15835c4bbdfSmrg    {GlxExtensionInit, "GLX", &noGlxExtension},
15935c4bbdfSmrg#endif
16035c4bbdfSmrg};
16135c4bbdfSmrg
16235c4bbdfSmrg/*
16335c4bbdfSmrg * QuartzExtensionInit
16435c4bbdfSmrg * Initialises XQuartz-specific extensions.
16535c4bbdfSmrg */
16635c4bbdfSmrgstatic void QuartzExtensionInit(void)
16735c4bbdfSmrg{
16835c4bbdfSmrg    LoadExtensionList(quartzExtensions, ARRAY_SIZE(quartzExtensions), TRUE);
16935c4bbdfSmrg}
1704642e01fSmrg
1714642e01fSmrg/*
1724642e01fSmrg * QuartzInitOutput
1734642e01fSmrg *  Quartz display initialization.
1744642e01fSmrg */
17535c4bbdfSmrgvoid
17635c4bbdfSmrgQuartzInitOutput(int argc,
17735c4bbdfSmrg                 char **argv)
1784642e01fSmrg{
1798223e2f2Smrg    /* For XQuartz, we want to just use the default signal handler to work better with CrashTracer */
1808223e2f2Smrg    signal(SIGSEGV, SIG_DFL);
1818223e2f2Smrg    signal(SIGILL, SIG_DFL);
1828223e2f2Smrg#ifdef SIGEMT
1838223e2f2Smrg    signal(SIGEMT, SIG_DFL);
1848223e2f2Smrg#endif
1858223e2f2Smrg    signal(SIGFPE, SIG_DFL);
1868223e2f2Smrg#ifdef SIGBUS
1878223e2f2Smrg    signal(SIGBUS, SIG_DFL);
1888223e2f2Smrg#endif
1898223e2f2Smrg#ifdef SIGSYS
1908223e2f2Smrg    signal(SIGSYS, SIG_DFL);
1918223e2f2Smrg#endif
1928223e2f2Smrg#ifdef SIGXCPU
1938223e2f2Smrg    signal(SIGXCPU, SIG_DFL);
1948223e2f2Smrg#endif
1958223e2f2Smrg#ifdef SIGXFSZ
1968223e2f2Smrg    signal(SIGXFSZ, SIG_DFL);
1978223e2f2Smrg#endif
1988223e2f2Smrg
1994642e01fSmrg    if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler,
2004642e01fSmrg                                        QuartzWakeupHandler,
20135c4bbdfSmrg                                        NULL)) {
2024642e01fSmrg        FatalError("Could not register block and wakeup handlers.");
2034642e01fSmrg    }
2044642e01fSmrg
2056747b715Smrg    if (!dixRegisterPrivateKey(&quartzScreenKeyRec, PRIVATE_SCREEN, 0))
20635c4bbdfSmrg        FatalError("Failed to alloc quartz screen private.\n");
2076747b715Smrg
2084642e01fSmrg    // Do display mode specific initialization
2094642e01fSmrg    quartzProcs->DisplayInit();
2104642e01fSmrg
21135c4bbdfSmrg    QuartzExtensionInit();
21235c4bbdfSmrg}
2134642e01fSmrg
2144642e01fSmrg/*
2154642e01fSmrg * QuartzInitInput
2164642e01fSmrg *  Inform the main thread the X server is ready to handle events.
2174642e01fSmrg */
21835c4bbdfSmrgvoid
21935c4bbdfSmrgQuartzInitInput(int argc,
22035c4bbdfSmrg                char **argv)
2214642e01fSmrg{
2226747b715Smrg    X11ApplicationSetCanQuit(0);
2234642e01fSmrg    X11ApplicationServerReady();
2244642e01fSmrg    // Do final display mode specific initialization before handling events
2254642e01fSmrg    if (quartzProcs->InitInput)
2264642e01fSmrg        quartzProcs->InitInput(argc, argv);
2274642e01fSmrg}
2284642e01fSmrg
22935c4bbdfSmrgvoid
23035c4bbdfSmrgQuartzUpdateScreens(void)
23135c4bbdfSmrg{
2324642e01fSmrg    ScreenPtr pScreen;
2334642e01fSmrg    WindowPtr pRoot;
2344642e01fSmrg    int x, y, width, height, sx, sy;
2354642e01fSmrg    xEvent e;
2366747b715Smrg    BoxRec bounds;
23735c4bbdfSmrg
23835c4bbdfSmrg    if (noPseudoramiXExtension || screenInfo.numScreens != 1) {
2394642e01fSmrg        /* FIXME: if not using Xinerama, we have multiple screens, and
24035c4bbdfSmrg           to do this properly may need to add or remove screens. Which
24135c4bbdfSmrg           isn't possible. So don't do anything. Another reason why
24235c4bbdfSmrg           we default to running with Xinerama. */
24335c4bbdfSmrg
2444642e01fSmrg        return;
2454642e01fSmrg    }
24635c4bbdfSmrg
2474642e01fSmrg    pScreen = screenInfo.screens[0];
24835c4bbdfSmrg
2494642e01fSmrg    PseudoramiXResetScreens();
2506747b715Smrg    quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height, pScreen);
25135c4bbdfSmrg
2526747b715Smrg    pScreen->x = x;
2536747b715Smrg    pScreen->y = y;
25435c4bbdfSmrg    pScreen->mmWidth = pScreen->mmWidth * ((double)width / pScreen->width);
25535c4bbdfSmrg    pScreen->mmHeight = pScreen->mmHeight * ((double)height / pScreen->height);
2564642e01fSmrg    pScreen->width = width;
2574642e01fSmrg    pScreen->height = height;
25835c4bbdfSmrg
2594642e01fSmrg    DarwinAdjustScreenOrigins(&screenInfo);
26035c4bbdfSmrg
2616747b715Smrg    /* DarwinAdjustScreenOrigins or UpdateScreen may change pScreen->x/y,
2626747b715Smrg     * so use it rather than x/y
2636747b715Smrg     */
2646747b715Smrg    sx = pScreen->x + darwinMainScreenX;
2656747b715Smrg    sy = pScreen->y + darwinMainScreenY;
26635c4bbdfSmrg
2674642e01fSmrg    /* Adjust the root window. */
2686747b715Smrg    pRoot = pScreen->root;
2694642e01fSmrg    AppleWMSetScreenOrigin(pRoot);
2704642e01fSmrg    pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL);
2716747b715Smrg
2726747b715Smrg    /* <rdar://problem/7770779> pointer events are clipped to old display region after display reconfiguration
2736747b715Smrg     * http://xquartz.macosforge.org/trac/ticket/346
2746747b715Smrg     */
2756747b715Smrg    bounds.x1 = 0;
2766747b715Smrg    bounds.x2 = width;
2776747b715Smrg    bounds.y1 = 0;
2786747b715Smrg    bounds.y2 = height;
2796747b715Smrg    pScreen->ConstrainCursor(inputInfo.pointer, pScreen, &bounds);
2806747b715Smrg    inputInfo.pointer->spriteInfo->sprite->physLimits = bounds;
2816747b715Smrg    inputInfo.pointer->spriteInfo->sprite->hotLimits = bounds;
2826747b715Smrg
28335c4bbdfSmrg    DEBUG_LOG(
28435c4bbdfSmrg        "Root Window: %dx%d @ (%d, %d) darwinMainScreen (%d, %d) xy (%d, %d) dixScreenOrigins (%d, %d)\n",
28535c4bbdfSmrg        width, height, x - sx, y - sy, darwinMainScreenX, darwinMainScreenY,
28635c4bbdfSmrg        x, y,
28735c4bbdfSmrg        pScreen->x, pScreen->y);
2884642e01fSmrg
2894642e01fSmrg    /* Send an event for the root reconfigure */
2904642e01fSmrg    e.u.u.type = ConfigureNotify;
2914642e01fSmrg    e.u.configureNotify.window = pRoot->drawable.id;
2924642e01fSmrg    e.u.configureNotify.aboveSibling = None;
2934642e01fSmrg    e.u.configureNotify.x = x - sx;
2944642e01fSmrg    e.u.configureNotify.y = y - sy;
2954642e01fSmrg    e.u.configureNotify.width = width;
2964642e01fSmrg    e.u.configureNotify.height = height;
2974642e01fSmrg    e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
2984642e01fSmrg    e.u.configureNotify.override = pRoot->overrideRedirect;
2994642e01fSmrg    DeliverEvents(pRoot, &e, 1, NullWindow);
3004642e01fSmrg
3016747b715Smrg    quartzProcs->UpdateScreen(pScreen);
3028223e2f2Smrg
30335c4bbdfSmrg    /* PaintWindow needs to be called after RootlessUpdateScreenPixmap (from xprUpdateScreen) */
30435c4bbdfSmrg    pScreen->PaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND);
3059ace9065Smrg
3068223e2f2Smrg    /* Tell RandR about the new size, so new connections get the correct info */
3078223e2f2Smrg    RRScreenSizeNotify(pScreen);
3088223e2f2Smrg}
3098223e2f2Smrg
31035c4bbdfSmrgstatic void
31135c4bbdfSmrgpokeActivityCallback(CFRunLoopTimerRef timer, void *info)
31235c4bbdfSmrg{
3138223e2f2Smrg    UpdateSystemActivity(OverallAct);
3148223e2f2Smrg}
3158223e2f2Smrg
31635c4bbdfSmrgstatic void
31735c4bbdfSmrgQuartzScreenSaver(int state)
31835c4bbdfSmrg{
3198223e2f2Smrg    static CFRunLoopTimerRef pokeActivityTimer = NULL;
32035c4bbdfSmrg    static CFRunLoopTimerContext pokeActivityContext =
32135c4bbdfSmrg    { 0, NULL, NULL, NULL, NULL };
32235c4bbdfSmrg    static OSSpinLock pokeActivitySpinLock = OS_SPINLOCK_INIT;
3238223e2f2Smrg
32435c4bbdfSmrg    OSSpinLockLock(&pokeActivitySpinLock);
32535c4bbdfSmrg
32635c4bbdfSmrg    if (state) {
32735c4bbdfSmrg        if (pokeActivityTimer == NULL)
3288223e2f2Smrg            goto QuartzScreenSaverEnd;
3298223e2f2Smrg
3308223e2f2Smrg        CFRunLoopTimerInvalidate(pokeActivityTimer);
3318223e2f2Smrg        CFRelease(pokeActivityTimer);
3328223e2f2Smrg        pokeActivityTimer = NULL;
33335c4bbdfSmrg    }
33435c4bbdfSmrg    else {
33535c4bbdfSmrg        if (pokeActivityTimer != NULL)
3368223e2f2Smrg            goto QuartzScreenSaverEnd;
33735c4bbdfSmrg
33835c4bbdfSmrg        pokeActivityTimer = CFRunLoopTimerCreate(NULL,
33935c4bbdfSmrg                                                 CFAbsoluteTimeGetCurrent(),
34035c4bbdfSmrg                                                 30, 0, 0,
34135c4bbdfSmrg                                                 pokeActivityCallback,
34235c4bbdfSmrg                                                 &pokeActivityContext);
34335c4bbdfSmrg        if (pokeActivityTimer == NULL) {
3448223e2f2Smrg            ErrorF("Unable to create pokeActivityTimer.\n");
3458223e2f2Smrg            goto QuartzScreenSaverEnd;
3468223e2f2Smrg        }
3478223e2f2Smrg
34835c4bbdfSmrg        CFRunLoopAddTimer(
34935c4bbdfSmrg            CFRunLoopGetMain(), pokeActivityTimer, kCFRunLoopCommonModes);
3508223e2f2Smrg    }
3518223e2f2SmrgQuartzScreenSaverEnd:
35235c4bbdfSmrg    OSSpinLockUnlock(&pokeActivitySpinLock);
3534642e01fSmrg}
3544642e01fSmrg
35535c4bbdfSmrgvoid
35635c4bbdfSmrgQuartzShowFullscreen(int state)
35735c4bbdfSmrg{
3586747b715Smrg    int i;
35935c4bbdfSmrg
3606747b715Smrg    DEBUG_LOG("QuartzShowFullscreen: state=%d\n", state);
36135c4bbdfSmrg
36235c4bbdfSmrg    if (XQuartzIsRootless) {
3636747b715Smrg        ErrorF("QuartzShowFullscreen called while in rootless mode.\n");
3646747b715Smrg        return;
3656747b715Smrg    }
36635c4bbdfSmrg
3678223e2f2Smrg    QuartzScreenSaver(!state);
36835c4bbdfSmrg
36935c4bbdfSmrg    if (XQuartzFullscreenVisible == state)
3704642e01fSmrg        return;
37135c4bbdfSmrg
3726747b715Smrg    XQuartzFullscreenVisible = state;
37335c4bbdfSmrg
37435c4bbdfSmrg    xp_disable_update();
37535c4bbdfSmrg
3766747b715Smrg    if (!XQuartzFullscreenVisible)
3774642e01fSmrg        RootlessHideAllWindows();
37835c4bbdfSmrg
3796747b715Smrg    RootlessUpdateRooted(XQuartzFullscreenVisible);
38035c4bbdfSmrg
3816747b715Smrg    if (XQuartzFullscreenVisible) {
38235c4bbdfSmrg        RootlessShowAllWindows();
38335c4bbdfSmrg        for (i = 0; i < screenInfo.numScreens; i++) {
38435c4bbdfSmrg            ScreenPtr pScreen = screenInfo.screens[i];
3856747b715Smrg            RootlessRepositionWindows(pScreen);
3866747b715Smrg            // JH: I don't think this is necessary, but keeping it here as a reminder
3876747b715Smrg            //RootlessUpdateScreenPixmap(pScreen);
3886747b715Smrg        }
3894642e01fSmrg    }
3904642e01fSmrg
3914642e01fSmrg    /* Somehow the menubar manages to interfere with our event stream
39235c4bbdfSmrg     * in fullscreen mode, even though it's not visible.
3934642e01fSmrg     */
3946747b715Smrg    X11ApplicationShowHideMenubar(!XQuartzFullscreenVisible);
39535c4bbdfSmrg
39635c4bbdfSmrg    xp_reenable_update();
39735c4bbdfSmrg
3986747b715Smrg    if (XQuartzFullscreenDisableHotkeys)
3996747b715Smrg        xp_disable_hot_keys(XQuartzFullscreenVisible);
4004642e01fSmrg}
4014642e01fSmrg
40235c4bbdfSmrgvoid
40335c4bbdfSmrgQuartzSetRootless(Bool state)
40435c4bbdfSmrg{
4056747b715Smrg    DEBUG_LOG("QuartzSetRootless state=%d\n", state);
40635c4bbdfSmrg
40735c4bbdfSmrg    if (XQuartzIsRootless == state)
4084642e01fSmrg        return;
40935c4bbdfSmrg
41035c4bbdfSmrg    if (state)
4116747b715Smrg        QuartzShowFullscreen(FALSE);
41235c4bbdfSmrg
4136747b715Smrg    XQuartzIsRootless = state;
4144642e01fSmrg
4154642e01fSmrg    xp_disable_update();
4164642e01fSmrg
41735c4bbdfSmrg    /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */
4184642e01fSmrg    QuartzUpdateScreens();
4194642e01fSmrg
42035c4bbdfSmrg    if (XQuartzIsRootless) {
4214642e01fSmrg        RootlessShowAllWindows();
42235c4bbdfSmrg    }
42335c4bbdfSmrg    else {
4246747b715Smrg        RootlessHideAllWindows();
4254642e01fSmrg    }
4264642e01fSmrg
4276747b715Smrg    X11ApplicationShowHideMenubar(TRUE);
4286747b715Smrg
4294642e01fSmrg    xp_reenable_update();
4306747b715Smrg
4316747b715Smrg    xp_disable_hot_keys(FALSE);
4324642e01fSmrg}
4334642e01fSmrg
4344642e01fSmrg/*
4354642e01fSmrg * QuartzShow
4364642e01fSmrg *  Show the X server on screen. Does nothing if already shown.
4374642e01fSmrg *  Calls mode specific screen resume to restore the X clip regions
4384642e01fSmrg *  (if needed) and the X server cursor state.
4394642e01fSmrg */
44035c4bbdfSmrgvoid
44135c4bbdfSmrgQuartzShow(void)
44235c4bbdfSmrg{
4434642e01fSmrg    int i;
4444642e01fSmrg
4456747b715Smrg    if (XQuartzServerVisible)
4464642e01fSmrg        return;
44735c4bbdfSmrg
4486747b715Smrg    XQuartzServerVisible = TRUE;
4494642e01fSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
4504642e01fSmrg        if (screenInfo.screens[i]) {
4516747b715Smrg            quartzProcs->ResumeScreen(screenInfo.screens[i]);
4524642e01fSmrg        }
4534642e01fSmrg    }
45435c4bbdfSmrg
4556747b715Smrg    if (!XQuartzIsRootless)
4566747b715Smrg        QuartzShowFullscreen(TRUE);
4574642e01fSmrg}
4584642e01fSmrg
4594642e01fSmrg/*
4604642e01fSmrg * QuartzHide
4614642e01fSmrg *  Remove the X server display from the screen. Does nothing if already
4624642e01fSmrg *  hidden. Calls mode specific screen suspend to set X clip regions to
4634642e01fSmrg *  prevent drawing (if needed) and restore the Aqua cursor.
4644642e01fSmrg */
46535c4bbdfSmrgvoid
46635c4bbdfSmrgQuartzHide(void)
4674642e01fSmrg{
4684642e01fSmrg    int i;
4694642e01fSmrg
4706747b715Smrg    if (XQuartzServerVisible) {
4714642e01fSmrg        for (i = 0; i < screenInfo.numScreens; i++) {
4724642e01fSmrg            if (screenInfo.screens[i]) {
4734642e01fSmrg                quartzProcs->SuspendScreen(screenInfo.screens[i]);
4744642e01fSmrg            }
4754642e01fSmrg        }
4764642e01fSmrg    }
4776747b715Smrg
47835c4bbdfSmrg    if (!XQuartzIsRootless)
4796747b715Smrg        QuartzShowFullscreen(FALSE);
4806747b715Smrg    XQuartzServerVisible = FALSE;
4814642e01fSmrg}
4824642e01fSmrg
4834642e01fSmrg/*
4844642e01fSmrg * QuartzSetRootClip
4854642e01fSmrg *  Enable or disable rendering to the X screen.
4864642e01fSmrg */
48735c4bbdfSmrgvoid
48835c4bbdfSmrgQuartzSetRootClip(int mode)
4894642e01fSmrg{
4904642e01fSmrg    int i;
4914642e01fSmrg
4926747b715Smrg    if (!XQuartzServerVisible)
4934642e01fSmrg        return;
4944642e01fSmrg
4954642e01fSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
4964642e01fSmrg        if (screenInfo.screens[i]) {
49735c4bbdfSmrg            SetRootClip(screenInfo.screens[i], mode);
4984642e01fSmrg        }
4994642e01fSmrg    }
5004642e01fSmrg}
5014642e01fSmrg
50235c4bbdfSmrg/*
5034642e01fSmrg * QuartzSpaceChanged
5044642e01fSmrg *  Unmap offscreen windows, map onscreen windows
5054642e01fSmrg */
50635c4bbdfSmrgvoid
50735c4bbdfSmrgQuartzSpaceChanged(uint32_t space_id)
50835c4bbdfSmrg{
5094642e01fSmrg    /* Do something special here, so we don't depend on quartz-wm for spaces to work... */
51035c4bbdfSmrg    DEBUG_LOG("Space Changed (%u) ... do something interesting...\n",
51135c4bbdfSmrg              space_id);
5124642e01fSmrg}
5136747b715Smrg
5146747b715Smrg/*
5156747b715Smrg * QuartzCopyDisplayIDs
5166747b715Smrg *  Associate an X11 screen with one or more CoreGraphics display IDs by copying
5176747b715Smrg *  the list into a private array. Free the previously copied array, if present.
5186747b715Smrg */
51935c4bbdfSmrgvoid
52035c4bbdfSmrgQuartzCopyDisplayIDs(ScreenPtr pScreen,
52135c4bbdfSmrg                     int displayCount, CGDirectDisplayID *displayIDs)
52235c4bbdfSmrg{
5236747b715Smrg    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
5246747b715Smrg
5256747b715Smrg    free(pQuartzScreen->displayIDs);
52635c4bbdfSmrg    if (displayCount) {
5279ace9065Smrg        size_t size = displayCount * sizeof(CGDirectDisplayID);
5289ace9065Smrg        pQuartzScreen->displayIDs = malloc(size);
5299ace9065Smrg        memcpy(pQuartzScreen->displayIDs, displayIDs, size);
53035c4bbdfSmrg    }
53135c4bbdfSmrg    else {
53235c4bbdfSmrg        pQuartzScreen->displayIDs = NULL;
5339ace9065Smrg    }
5346747b715Smrg    pQuartzScreen->displayCount = displayCount;
5356747b715Smrg}
5368223e2f2Smrg
53735c4bbdfSmrgvoid
53835c4bbdfSmrgNSBeep(void);
53935c4bbdfSmrgvoid
54035c4bbdfSmrgDDXRingBell(int volume,              // volume is % of max
54135c4bbdfSmrg            int pitch,               // pitch is Hz
54235c4bbdfSmrg            int duration)            // duration is milliseconds
5438223e2f2Smrg{
5448223e2f2Smrg    if (volume)
5458223e2f2Smrg        NSBeep();
5468223e2f2Smrg}
547