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