quartz.c revision 9ace9065
14642e01fSmrg/*
24642e01fSmrg *
34642e01fSmrg * Quartz-specific support for the Darwin X Server
44642e01fSmrg *
54642e01fSmrg * Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons.
64642e01fSmrg *                 All Rights Reserved.
74642e01fSmrg *
84642e01fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
94642e01fSmrg * copy of this software and associated documentation files (the "Software"),
104642e01fSmrg * to deal in the Software without restriction, including without limitation
114642e01fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
124642e01fSmrg * and/or sell copies of the Software, and to permit persons to whom the
134642e01fSmrg * Software is furnished to do so, subject to the following conditions:
144642e01fSmrg *
154642e01fSmrg * The above copyright notice and this permission notice shall be included in
164642e01fSmrg * all copies or substantial portions of the Software.
174642e01fSmrg *
184642e01fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
194642e01fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
204642e01fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
214642e01fSmrg * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
224642e01fSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
234642e01fSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
244642e01fSmrg * DEALINGS IN THE SOFTWARE.
254642e01fSmrg *
264642e01fSmrg * Except as contained in this notice, the name(s) of the above copyright
274642e01fSmrg * holders shall not be used in advertising or otherwise to promote the sale,
284642e01fSmrg * use or other dealings in this Software without prior written authorization.
294642e01fSmrg */
304642e01fSmrg
314642e01fSmrg#include "sanitizedCarbon.h"
324642e01fSmrg
334642e01fSmrg#ifdef HAVE_DIX_CONFIG_H
344642e01fSmrg#include <dix-config.h>
354642e01fSmrg#endif
364642e01fSmrg
374642e01fSmrg#include "quartzCommon.h"
386747b715Smrg#include "quartzRandR.h"
394642e01fSmrg#include "inputstr.h"
404642e01fSmrg#include "quartz.h"
414642e01fSmrg#include "darwin.h"
424642e01fSmrg#include "darwinEvents.h"
434642e01fSmrg#include "pseudoramiX.h"
444642e01fSmrg#define _APPLEWM_SERVER_
454642e01fSmrg#include "applewmExt.h"
464642e01fSmrg
474642e01fSmrg#include "X11Application.h"
484642e01fSmrg
496747b715Smrg#include <X11/extensions/applewmconst.h>
504642e01fSmrg
514642e01fSmrg// X headers
524642e01fSmrg#include "scrnintstr.h"
534642e01fSmrg#include "windowstr.h"
544642e01fSmrg#include "colormapst.h"
554642e01fSmrg#include "globals.h"
564642e01fSmrg#include "mi.h"
574642e01fSmrg
584642e01fSmrg// System headers
596747b715Smrg#include <stdlib.h>
606747b715Smrg#include <string.h>
614642e01fSmrg#include <sys/types.h>
624642e01fSmrg#include <sys/stat.h>
634642e01fSmrg#include <fcntl.h>
644642e01fSmrg#include <IOKit/pwr_mgt/IOPMLib.h>
658223e2f2Smrg#include <pthread.h>
668223e2f2Smrg#include <signal.h>
674642e01fSmrg
684642e01fSmrg#include <rootlessCommon.h>
694642e01fSmrg#include <Xplugin.h>
704642e01fSmrg
716747b715SmrgDevPrivateKeyRec        quartzScreenKeyRec;
724642e01fSmrgint                     aquaMenuBarHeight = 0;
734642e01fSmrgQuartzModeProcsPtr      quartzProcs = NULL;
744642e01fSmrgconst char             *quartzOpenGLBundle = NULL;
754642e01fSmrg
766747b715SmrgBool XQuartzFullscreenDisableHotkeys = TRUE;
776747b715SmrgBool XQuartzOptionSendsAlt = FALSE;
786747b715SmrgBool XQuartzEnableKeyEquivalents = TRUE;
796747b715SmrgBool XQuartzFullscreenVisible = FALSE;
806747b715SmrgBool XQuartzRootlessDefault = TRUE;
816747b715SmrgBool XQuartzIsRootless = TRUE;
826747b715SmrgBool XQuartzServerVisible = FALSE;
836747b715SmrgBool XQuartzFullscreenMenu = FALSE;
848223e2f2Smrg
858223e2f2Smrgint32_t XQuartzShieldingWindowLevel = 0;
864642e01fSmrg
874642e01fSmrg/*
884642e01fSmrg===========================================================================
894642e01fSmrg
904642e01fSmrg Screen functions
914642e01fSmrg
924642e01fSmrg===========================================================================
934642e01fSmrg*/
944642e01fSmrg
954642e01fSmrg/*
964642e01fSmrg * QuartzAddScreen
974642e01fSmrg *  Do mode dependent initialization of each screen for Quartz.
984642e01fSmrg */
994642e01fSmrgBool QuartzAddScreen(
1004642e01fSmrg    int index,
1014642e01fSmrg    ScreenPtr pScreen)
1024642e01fSmrg{
1034642e01fSmrg    // allocate space for private per screen Quartz specific storage
1046747b715Smrg    QuartzScreenPtr displayInfo = calloc(sizeof(QuartzScreenRec), 1);
1054642e01fSmrg
1064642e01fSmrg    // QUARTZ_PRIV(pScreen) = displayInfo;
1074642e01fSmrg    dixSetPrivate(&pScreen->devPrivates, quartzScreenKey, displayInfo);
1084642e01fSmrg
1094642e01fSmrg    // do Quartz mode specific initialization
1104642e01fSmrg    return quartzProcs->AddScreen(index, pScreen);
1114642e01fSmrg}
1124642e01fSmrg
1134642e01fSmrg
1144642e01fSmrg/*
1154642e01fSmrg * QuartzSetupScreen
1164642e01fSmrg *  Finalize mode specific setup of each screen.
1174642e01fSmrg */
1184642e01fSmrgBool QuartzSetupScreen(
1194642e01fSmrg    int index,
1204642e01fSmrg    ScreenPtr pScreen)
1214642e01fSmrg{
1224642e01fSmrg    // do Quartz mode specific setup
1234642e01fSmrg    if (! quartzProcs->SetupScreen(index, pScreen))
1244642e01fSmrg        return FALSE;
1254642e01fSmrg
1264642e01fSmrg    // setup cursor support
1274642e01fSmrg    if (! quartzProcs->InitCursor(pScreen))
1284642e01fSmrg        return FALSE;
1294642e01fSmrg
1306747b715Smrg#if defined(RANDR)
1316747b715Smrg    if(!QuartzRandRInit(pScreen)) {
1326747b715Smrg        DEBUG_LOG("Failed to init RandR extension.\n");
1336747b715Smrg        return FALSE;
1346747b715Smrg    }
1356747b715Smrg#endif
1366747b715Smrg
1374642e01fSmrg    return TRUE;
1384642e01fSmrg}
1394642e01fSmrg
1404642e01fSmrg
1414642e01fSmrg/*
1424642e01fSmrg * QuartzInitOutput
1434642e01fSmrg *  Quartz display initialization.
1444642e01fSmrg */
1454642e01fSmrgvoid QuartzInitOutput(
1464642e01fSmrg    int argc,
1474642e01fSmrg    char **argv )
1484642e01fSmrg{
1498223e2f2Smrg    /* For XQuartz, we want to just use the default signal handler to work better with CrashTracer */
1508223e2f2Smrg    signal(SIGSEGV, SIG_DFL);
1518223e2f2Smrg    signal(SIGILL, SIG_DFL);
1528223e2f2Smrg#ifdef SIGEMT
1538223e2f2Smrg    signal(SIGEMT, SIG_DFL);
1548223e2f2Smrg#endif
1558223e2f2Smrg    signal(SIGFPE, SIG_DFL);
1568223e2f2Smrg#ifdef SIGBUS
1578223e2f2Smrg    signal(SIGBUS, SIG_DFL);
1588223e2f2Smrg#endif
1598223e2f2Smrg#ifdef SIGSYS
1608223e2f2Smrg    signal(SIGSYS, SIG_DFL);
1618223e2f2Smrg#endif
1628223e2f2Smrg#ifdef SIGXCPU
1638223e2f2Smrg    signal(SIGXCPU, SIG_DFL);
1648223e2f2Smrg#endif
1658223e2f2Smrg#ifdef SIGXFSZ
1668223e2f2Smrg    signal(SIGXFSZ, SIG_DFL);
1678223e2f2Smrg#endif
1688223e2f2Smrg
1694642e01fSmrg    if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler,
1704642e01fSmrg                                        QuartzWakeupHandler,
1714642e01fSmrg                                        NULL))
1724642e01fSmrg    {
1734642e01fSmrg        FatalError("Could not register block and wakeup handlers.");
1744642e01fSmrg    }
1754642e01fSmrg
1766747b715Smrg    if (!dixRegisterPrivateKey(&quartzScreenKeyRec, PRIVATE_SCREEN, 0))
1776747b715Smrg	FatalError("Failed to alloc quartz screen private.\n");
1786747b715Smrg
1794642e01fSmrg    // Do display mode specific initialization
1804642e01fSmrg    quartzProcs->DisplayInit();
1814642e01fSmrg}
1824642e01fSmrg
1834642e01fSmrg
1844642e01fSmrg/*
1854642e01fSmrg * QuartzInitInput
1864642e01fSmrg *  Inform the main thread the X server is ready to handle events.
1874642e01fSmrg */
1884642e01fSmrgvoid QuartzInitInput(
1894642e01fSmrg    int argc,
1904642e01fSmrg    char **argv )
1914642e01fSmrg{
1926747b715Smrg    X11ApplicationSetCanQuit(0);
1934642e01fSmrg    X11ApplicationServerReady();
1944642e01fSmrg    // Do final display mode specific initialization before handling events
1954642e01fSmrg    if (quartzProcs->InitInput)
1964642e01fSmrg        quartzProcs->InitInput(argc, argv);
1974642e01fSmrg}
1984642e01fSmrg
1994642e01fSmrg
2006747b715Smrgvoid QuartzUpdateScreens(void) {
2014642e01fSmrg    ScreenPtr pScreen;
2024642e01fSmrg    WindowPtr pRoot;
2034642e01fSmrg    int x, y, width, height, sx, sy;
2044642e01fSmrg    xEvent e;
2056747b715Smrg    BoxRec bounds;
2064642e01fSmrg
2074642e01fSmrg    if (noPseudoramiXExtension || screenInfo.numScreens != 1)
2084642e01fSmrg    {
2094642e01fSmrg        /* FIXME: if not using Xinerama, we have multiple screens, and
2104642e01fSmrg         to do this properly may need to add or remove screens. Which
2114642e01fSmrg         isn't possible. So don't do anything. Another reason why
2124642e01fSmrg         we default to running with Xinerama. */
2134642e01fSmrg
2144642e01fSmrg        return;
2154642e01fSmrg    }
2164642e01fSmrg
2174642e01fSmrg    pScreen = screenInfo.screens[0];
2184642e01fSmrg
2194642e01fSmrg    PseudoramiXResetScreens();
2206747b715Smrg    quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height, pScreen);
2214642e01fSmrg
2226747b715Smrg    pScreen->x = x;
2236747b715Smrg    pScreen->y = y;
2244642e01fSmrg    pScreen->mmWidth = pScreen->mmWidth * ((double) width / pScreen->width);
2254642e01fSmrg    pScreen->mmHeight = pScreen->mmHeight * ((double) height / pScreen->height);
2264642e01fSmrg    pScreen->width = width;
2274642e01fSmrg    pScreen->height = height;
2284642e01fSmrg
2294642e01fSmrg    DarwinAdjustScreenOrigins(&screenInfo);
2304642e01fSmrg
2316747b715Smrg    /* DarwinAdjustScreenOrigins or UpdateScreen may change pScreen->x/y,
2326747b715Smrg     * so use it rather than x/y
2336747b715Smrg     */
2346747b715Smrg    sx = pScreen->x + darwinMainScreenX;
2356747b715Smrg    sy = pScreen->y + darwinMainScreenY;
2364642e01fSmrg
2374642e01fSmrg    /* Adjust the root window. */
2386747b715Smrg    pRoot = pScreen->root;
2394642e01fSmrg    AppleWMSetScreenOrigin(pRoot);
2404642e01fSmrg    pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL);
2416747b715Smrg
2426747b715Smrg    /* <rdar://problem/7770779> pointer events are clipped to old display region after display reconfiguration
2436747b715Smrg     * http://xquartz.macosforge.org/trac/ticket/346
2446747b715Smrg     */
2456747b715Smrg    bounds.x1 = 0;
2466747b715Smrg    bounds.x2 = width;
2476747b715Smrg    bounds.y1 = 0;
2486747b715Smrg    bounds.y2 = height;
2496747b715Smrg    pScreen->ConstrainCursor(inputInfo.pointer, pScreen, &bounds);
2506747b715Smrg    inputInfo.pointer->spriteInfo->sprite->physLimits = bounds;
2516747b715Smrg    inputInfo.pointer->spriteInfo->sprite->hotLimits = bounds;
2526747b715Smrg
2536747b715Smrg    DEBUG_LOG("Root Window: %dx%d @ (%d, %d) darwinMainScreen (%d, %d) xy (%d, %d) dixScreenOrigins (%d, %d)\n", width, height, x - sx, y - sy, darwinMainScreenX, darwinMainScreenY, x, y, pScreen->x, pScreen->y);
2544642e01fSmrg
2554642e01fSmrg    /* Send an event for the root reconfigure */
2564642e01fSmrg    e.u.u.type = ConfigureNotify;
2574642e01fSmrg    e.u.configureNotify.window = pRoot->drawable.id;
2584642e01fSmrg    e.u.configureNotify.aboveSibling = None;
2594642e01fSmrg    e.u.configureNotify.x = x - sx;
2604642e01fSmrg    e.u.configureNotify.y = y - sy;
2614642e01fSmrg    e.u.configureNotify.width = width;
2624642e01fSmrg    e.u.configureNotify.height = height;
2634642e01fSmrg    e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
2644642e01fSmrg    e.u.configureNotify.override = pRoot->overrideRedirect;
2654642e01fSmrg    DeliverEvents(pRoot, &e, 1, NullWindow);
2664642e01fSmrg
2676747b715Smrg    quartzProcs->UpdateScreen(pScreen);
2688223e2f2Smrg
2699ace9065Smrg    /* miPaintWindow needs to be called after RootlessUpdateScreenPixmap (from xprUpdateScreen) */
2709ace9065Smrg    miPaintWindow(pRoot, &pRoot->borderClip,  PW_BACKGROUND);
2719ace9065Smrg
2728223e2f2Smrg    /* Tell RandR about the new size, so new connections get the correct info */
2738223e2f2Smrg    RRScreenSizeNotify(pScreen);
2748223e2f2Smrg}
2758223e2f2Smrg
2768223e2f2Smrgstatic void pokeActivityCallback(CFRunLoopTimerRef timer, void *info) {
2778223e2f2Smrg    UpdateSystemActivity(OverallAct);
2788223e2f2Smrg}
2798223e2f2Smrg
2808223e2f2Smrgstatic void QuartzScreenSaver(int state) {
2818223e2f2Smrg    static CFRunLoopTimerRef pokeActivityTimer = NULL;
2828223e2f2Smrg    static CFRunLoopTimerContext pokeActivityContext = { 0, NULL, NULL, NULL, NULL };
2838223e2f2Smrg    static pthread_mutex_t pokeActivityMutex = PTHREAD_MUTEX_INITIALIZER;
2848223e2f2Smrg
2858223e2f2Smrg    pthread_mutex_lock(&pokeActivityMutex);
2868223e2f2Smrg
2878223e2f2Smrg    if(state) {
2888223e2f2Smrg        if(pokeActivityTimer == NULL)
2898223e2f2Smrg            goto QuartzScreenSaverEnd;
2908223e2f2Smrg
2918223e2f2Smrg        CFRunLoopTimerInvalidate(pokeActivityTimer);
2928223e2f2Smrg        CFRelease(pokeActivityTimer);
2938223e2f2Smrg        pokeActivityTimer = NULL;
2948223e2f2Smrg    } else {
2958223e2f2Smrg        if(pokeActivityTimer != NULL)
2968223e2f2Smrg            goto QuartzScreenSaverEnd;
2978223e2f2Smrg
2988223e2f2Smrg        pokeActivityTimer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 30, 0, 0, pokeActivityCallback, &pokeActivityContext);
2998223e2f2Smrg        if(pokeActivityTimer == NULL) {
3008223e2f2Smrg            ErrorF("Unable to create pokeActivityTimer.\n");
3018223e2f2Smrg            goto QuartzScreenSaverEnd;
3028223e2f2Smrg        }
3038223e2f2Smrg
3048223e2f2Smrg        CFRunLoopAddTimer(CFRunLoopGetMain(), pokeActivityTimer, kCFRunLoopCommonModes);
3058223e2f2Smrg    }
3068223e2f2SmrgQuartzScreenSaverEnd:
3078223e2f2Smrg    pthread_mutex_unlock(&pokeActivityMutex);
3084642e01fSmrg}
3094642e01fSmrg
3106747b715Smrgvoid QuartzShowFullscreen(int state) {
3116747b715Smrg    int i;
3126747b715Smrg
3136747b715Smrg    DEBUG_LOG("QuartzShowFullscreen: state=%d\n", state);
3144642e01fSmrg
3156747b715Smrg    if(XQuartzIsRootless) {
3166747b715Smrg        ErrorF("QuartzShowFullscreen called while in rootless mode.\n");
3176747b715Smrg        return;
3186747b715Smrg    }
3194642e01fSmrg
3208223e2f2Smrg    QuartzScreenSaver(!state);
3218223e2f2Smrg
3226747b715Smrg    if(XQuartzFullscreenVisible == state)
3234642e01fSmrg        return;
3244642e01fSmrg
3256747b715Smrg    XQuartzFullscreenVisible = state;
3264642e01fSmrg
3274642e01fSmrg    xp_disable_update ();
3284642e01fSmrg
3296747b715Smrg    if (!XQuartzFullscreenVisible)
3304642e01fSmrg        RootlessHideAllWindows();
3314642e01fSmrg
3326747b715Smrg    RootlessUpdateRooted(XQuartzFullscreenVisible);
3334642e01fSmrg
3346747b715Smrg    if (XQuartzFullscreenVisible) {
3354642e01fSmrg        RootlessShowAllWindows ();
3366747b715Smrg        for (i=0; i < screenInfo.numScreens; i++) {
3376747b715Smrg            ScreenPtr pScreen = screenInfo.screens[i];
3386747b715Smrg            RootlessRepositionWindows(pScreen);
3396747b715Smrg            // JH: I don't think this is necessary, but keeping it here as a reminder
3406747b715Smrg            //RootlessUpdateScreenPixmap(pScreen);
3416747b715Smrg        }
3424642e01fSmrg    }
3434642e01fSmrg
3444642e01fSmrg    /* Somehow the menubar manages to interfere with our event stream
3454642e01fSmrg     * in fullscreen mode, even though it's not visible.
3464642e01fSmrg     */
3476747b715Smrg    X11ApplicationShowHideMenubar(!XQuartzFullscreenVisible);
3484642e01fSmrg
3494642e01fSmrg    xp_reenable_update ();
3504642e01fSmrg
3516747b715Smrg    if (XQuartzFullscreenDisableHotkeys)
3526747b715Smrg        xp_disable_hot_keys(XQuartzFullscreenVisible);
3534642e01fSmrg}
3544642e01fSmrg
3556747b715Smrgvoid QuartzSetRootless(Bool state) {
3566747b715Smrg    DEBUG_LOG("QuartzSetRootless state=%d\n", state);
3576747b715Smrg
3586747b715Smrg    if(XQuartzIsRootless == state)
3594642e01fSmrg        return;
3604642e01fSmrg
3616747b715Smrg    if(state)
3626747b715Smrg        QuartzShowFullscreen(FALSE);
3636747b715Smrg
3646747b715Smrg    XQuartzIsRootless = state;
3654642e01fSmrg
3664642e01fSmrg    xp_disable_update();
3674642e01fSmrg
3684642e01fSmrg    /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */
3694642e01fSmrg    QuartzUpdateScreens();
3704642e01fSmrg
3716747b715Smrg    if(XQuartzIsRootless) {
3724642e01fSmrg        RootlessShowAllWindows();
3736747b715Smrg    } else {
3746747b715Smrg        RootlessHideAllWindows();
3754642e01fSmrg    }
3764642e01fSmrg
3776747b715Smrg    X11ApplicationShowHideMenubar(TRUE);
3786747b715Smrg
3794642e01fSmrg    xp_reenable_update();
3806747b715Smrg
3816747b715Smrg    xp_disable_hot_keys(FALSE);
3824642e01fSmrg}
3834642e01fSmrg
3844642e01fSmrg/*
3854642e01fSmrg * QuartzShow
3864642e01fSmrg *  Show the X server on screen. Does nothing if already shown.
3874642e01fSmrg *  Calls mode specific screen resume to restore the X clip regions
3884642e01fSmrg *  (if needed) and the X server cursor state.
3894642e01fSmrg */
3906747b715Smrgvoid QuartzShow(void) {
3914642e01fSmrg    int i;
3924642e01fSmrg
3936747b715Smrg    if (XQuartzServerVisible)
3944642e01fSmrg        return;
3954642e01fSmrg
3966747b715Smrg    XQuartzServerVisible = TRUE;
3974642e01fSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
3984642e01fSmrg        if (screenInfo.screens[i]) {
3996747b715Smrg            quartzProcs->ResumeScreen(screenInfo.screens[i]);
4004642e01fSmrg        }
4014642e01fSmrg    }
4024642e01fSmrg
4036747b715Smrg    if (!XQuartzIsRootless)
4046747b715Smrg        QuartzShowFullscreen(TRUE);
4054642e01fSmrg}
4064642e01fSmrg
4074642e01fSmrg
4084642e01fSmrg/*
4094642e01fSmrg * QuartzHide
4104642e01fSmrg *  Remove the X server display from the screen. Does nothing if already
4114642e01fSmrg *  hidden. Calls mode specific screen suspend to set X clip regions to
4124642e01fSmrg *  prevent drawing (if needed) and restore the Aqua cursor.
4134642e01fSmrg */
4144642e01fSmrgvoid QuartzHide(void)
4154642e01fSmrg{
4164642e01fSmrg    int i;
4174642e01fSmrg
4186747b715Smrg    if (XQuartzServerVisible) {
4194642e01fSmrg        for (i = 0; i < screenInfo.numScreens; i++) {
4204642e01fSmrg            if (screenInfo.screens[i]) {
4214642e01fSmrg                quartzProcs->SuspendScreen(screenInfo.screens[i]);
4224642e01fSmrg            }
4234642e01fSmrg        }
4244642e01fSmrg    }
4256747b715Smrg
4266747b715Smrg    if(!XQuartzIsRootless)
4276747b715Smrg        QuartzShowFullscreen(FALSE);
4286747b715Smrg    XQuartzServerVisible = FALSE;
4294642e01fSmrg}
4304642e01fSmrg
4314642e01fSmrg
4324642e01fSmrg/*
4334642e01fSmrg * QuartzSetRootClip
4344642e01fSmrg *  Enable or disable rendering to the X screen.
4354642e01fSmrg */
4364642e01fSmrgvoid QuartzSetRootClip(
4374642e01fSmrg    BOOL enable)
4384642e01fSmrg{
4394642e01fSmrg    int i;
4404642e01fSmrg
4416747b715Smrg    if (!XQuartzServerVisible)
4424642e01fSmrg        return;
4434642e01fSmrg
4444642e01fSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
4454642e01fSmrg        if (screenInfo.screens[i]) {
4464642e01fSmrg            xf86SetRootClip(screenInfo.screens[i], enable);
4474642e01fSmrg        }
4484642e01fSmrg    }
4494642e01fSmrg}
4504642e01fSmrg
4514642e01fSmrg/*
4524642e01fSmrg * QuartzSpaceChanged
4534642e01fSmrg *  Unmap offscreen windows, map onscreen windows
4544642e01fSmrg */
4554642e01fSmrgvoid QuartzSpaceChanged(uint32_t space_id) {
4564642e01fSmrg    /* Do something special here, so we don't depend on quartz-wm for spaces to work... */
4574642e01fSmrg    DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", space_id);
4584642e01fSmrg}
4596747b715Smrg
4606747b715Smrg/*
4616747b715Smrg * QuartzCopyDisplayIDs
4626747b715Smrg *  Associate an X11 screen with one or more CoreGraphics display IDs by copying
4636747b715Smrg *  the list into a private array. Free the previously copied array, if present.
4646747b715Smrg */
4656747b715Smrgvoid QuartzCopyDisplayIDs(ScreenPtr pScreen,
4666747b715Smrg                          int displayCount, CGDirectDisplayID *displayIDs) {
4676747b715Smrg    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
4686747b715Smrg
4696747b715Smrg    free(pQuartzScreen->displayIDs);
4709ace9065Smrg    if(displayCount) {
4719ace9065Smrg        size_t size = displayCount * sizeof(CGDirectDisplayID);
4729ace9065Smrg        pQuartzScreen->displayIDs = malloc(size);
4739ace9065Smrg        memcpy(pQuartzScreen->displayIDs, displayIDs, size);
4749ace9065Smrg    } else {
4759ace9065Smrg       pQuartzScreen->displayIDs = NULL;
4769ace9065Smrg    }
4776747b715Smrg    pQuartzScreen->displayCount = displayCount;
4786747b715Smrg}
4798223e2f2Smrg
4808223e2f2Smrgvoid NSBeep(void);
4818223e2f2Smrgvoid DDXRingBell(
4828223e2f2Smrg    int volume,         // volume is % of max
4838223e2f2Smrg    int pitch,          // pitch is Hz
4848223e2f2Smrg    int duration)       // duration is milliseconds
4858223e2f2Smrg{
4868223e2f2Smrg    if (volume)
4878223e2f2Smrg        NSBeep();
4888223e2f2Smrg}
489