quartz.c revision c8548ba8
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 386747b715Smrg#include "quartzRandR.h" 394642e01fSmrg#include "inputstr.h" 404642e01fSmrg#include "quartz.h" 414642e01fSmrg#include "darwin.h" 424642e01fSmrg#include "darwinEvents.h" 434642e01fSmrg#include "pseudoramiX.h" 4435c4bbdfSmrg#include "extension.h" 4535c4bbdfSmrg#include "nonsdk_extinit.h" 4635c4bbdfSmrg#include "glx_extinit.h" 474642e01fSmrg#define _APPLEWM_SERVER_ 484642e01fSmrg#include "applewmExt.h" 494642e01fSmrg 504642e01fSmrg#include "X11Application.h" 514642e01fSmrg 526747b715Smrg#include <X11/extensions/applewmconst.h> 534642e01fSmrg 544642e01fSmrg// X headers 554642e01fSmrg#include "scrnintstr.h" 564642e01fSmrg#include "windowstr.h" 574642e01fSmrg#include "colormapst.h" 584642e01fSmrg#include "globals.h" 594642e01fSmrg#include "mi.h" 604642e01fSmrg 614642e01fSmrg// System headers 626747b715Smrg#include <stdlib.h> 636747b715Smrg#include <string.h> 644642e01fSmrg#include <sys/types.h> 654642e01fSmrg#include <sys/stat.h> 664642e01fSmrg#include <fcntl.h> 674642e01fSmrg#include <IOKit/pwr_mgt/IOPMLib.h> 6835c4bbdfSmrg#include <libkern/OSAtomic.h> 698223e2f2Smrg#include <signal.h> 704642e01fSmrg 714642e01fSmrg#include <rootlessCommon.h> 724642e01fSmrg#include <Xplugin.h> 734642e01fSmrg 74c8548ba8Smrg// These are vended by the Objective-C runtime, but they are unfortunately 75c8548ba8Smrg// not available as API in the macOS SDK. We are following suit with swift 76c8548ba8Smrg// and clang in declaring them inline here. They canot be removed or changed 77c8548ba8Smrg// in the OS without major bincompat ramifications. 78c8548ba8Smrg// 79c8548ba8Smrg// These were added in macOS 10.7. 80c8548ba8Smrgvoid * _Nonnull objc_autoreleasePoolPush(void); 81c8548ba8Smrgvoid objc_autoreleasePoolPop(void * _Nonnull context); 8235c4bbdfSmrg 8335c4bbdfSmrgDevPrivateKeyRec quartzScreenKeyRec; 8435c4bbdfSmrgint aquaMenuBarHeight = 0; 8535c4bbdfSmrgQuartzModeProcsPtr quartzProcs = NULL; 864642e01fSmrgconst char *quartzOpenGLBundle = NULL; 874642e01fSmrg 886747b715SmrgBool XQuartzFullscreenDisableHotkeys = TRUE; 896747b715SmrgBool XQuartzOptionSendsAlt = FALSE; 906747b715SmrgBool XQuartzEnableKeyEquivalents = TRUE; 916747b715SmrgBool XQuartzFullscreenVisible = FALSE; 926747b715SmrgBool XQuartzRootlessDefault = TRUE; 936747b715SmrgBool XQuartzIsRootless = TRUE; 946747b715SmrgBool XQuartzServerVisible = FALSE; 956747b715SmrgBool XQuartzFullscreenMenu = FALSE; 968223e2f2Smrg 978223e2f2Smrgint32_t XQuartzShieldingWindowLevel = 0; 984642e01fSmrg 994642e01fSmrg/* 10035c4bbdfSmrg =========================================================================== 1014642e01fSmrg 10235c4bbdfSmrg Screen functions 1034642e01fSmrg 10435c4bbdfSmrg =========================================================================== 10535c4bbdfSmrg */ 1064642e01fSmrg 1074642e01fSmrg/* 1084642e01fSmrg * QuartzAddScreen 1094642e01fSmrg * Do mode dependent initialization of each screen for Quartz. 1104642e01fSmrg */ 11135c4bbdfSmrgBool 11235c4bbdfSmrgQuartzAddScreen(int index, 11335c4bbdfSmrg ScreenPtr pScreen) 1144642e01fSmrg{ 11535c4bbdfSmrg // The clang static analyzer thinks we leak displayInfo here 11635c4bbdfSmrg#ifndef __clang_analyzer__ 1174642e01fSmrg // allocate space for private per screen Quartz specific storage 1186747b715Smrg QuartzScreenPtr displayInfo = calloc(sizeof(QuartzScreenRec), 1); 1194642e01fSmrg 1204642e01fSmrg // QUARTZ_PRIV(pScreen) = displayInfo; 1214642e01fSmrg dixSetPrivate(&pScreen->devPrivates, quartzScreenKey, displayInfo); 12235c4bbdfSmrg#endif /* __clang_analyzer__ */ 1234642e01fSmrg 1244642e01fSmrg // do Quartz mode specific initialization 1254642e01fSmrg return quartzProcs->AddScreen(index, pScreen); 1264642e01fSmrg} 1274642e01fSmrg 1284642e01fSmrg/* 1294642e01fSmrg * QuartzSetupScreen 1304642e01fSmrg * Finalize mode specific setup of each screen. 1314642e01fSmrg */ 13235c4bbdfSmrgBool 13335c4bbdfSmrgQuartzSetupScreen(int index, 13435c4bbdfSmrg ScreenPtr pScreen) 1354642e01fSmrg{ 1364642e01fSmrg // do Quartz mode specific setup 13735c4bbdfSmrg if (!quartzProcs->SetupScreen(index, pScreen)) 1384642e01fSmrg return FALSE; 1394642e01fSmrg 1404642e01fSmrg // setup cursor support 14135c4bbdfSmrg if (!quartzProcs->InitCursor(pScreen)) 1424642e01fSmrg return FALSE; 1434642e01fSmrg 1446747b715Smrg#if defined(RANDR) 14535c4bbdfSmrg if (!QuartzRandRInit(pScreen)) { 1466747b715Smrg DEBUG_LOG("Failed to init RandR extension.\n"); 1476747b715Smrg return FALSE; 1486747b715Smrg } 1496747b715Smrg#endif 1506747b715Smrg 1514642e01fSmrg return TRUE; 1524642e01fSmrg} 1534642e01fSmrg 154c8548ba8Smrg/* 155c8548ba8Smrg * QuartzBlockHandler 156c8548ba8Smrg * Clean out any autoreleased objects. 157c8548ba8Smrg */ 158c8548ba8Smrgstatic void 159c8548ba8SmrgQuartzBlockHandler(void *blockData, void *pTimeout) 160c8548ba8Smrg{ 161c8548ba8Smrg static void *poolToken = NULL; 162c8548ba8Smrg 163c8548ba8Smrg if (poolToken) { 164c8548ba8Smrg objc_autoreleasePoolPop(poolToken); 165c8548ba8Smrg } 166c8548ba8Smrg poolToken = objc_autoreleasePoolPush(); 167c8548ba8Smrg} 168c8548ba8Smrg 169c8548ba8Smrg/* 170c8548ba8Smrg * QuartzWakeupHandler 171c8548ba8Smrg */ 172c8548ba8Smrgstatic void 173c8548ba8SmrgQuartzWakeupHandler(void *blockData, int result) 174c8548ba8Smrg{ 175c8548ba8Smrg /* nothing here */ 176c8548ba8Smrg} 177c8548ba8Smrg 1784642e01fSmrg/* 1794642e01fSmrg * QuartzInitOutput 1804642e01fSmrg * Quartz display initialization. 1814642e01fSmrg */ 18235c4bbdfSmrgvoid 18335c4bbdfSmrgQuartzInitOutput(int argc, 18435c4bbdfSmrg char **argv) 1854642e01fSmrg{ 1868223e2f2Smrg /* For XQuartz, we want to just use the default signal handler to work better with CrashTracer */ 1878223e2f2Smrg signal(SIGSEGV, SIG_DFL); 1881b5d61b8Smrg signal(SIGABRT, SIG_DFL); 1898223e2f2Smrg signal(SIGILL, SIG_DFL); 1908223e2f2Smrg#ifdef SIGEMT 1918223e2f2Smrg signal(SIGEMT, SIG_DFL); 1928223e2f2Smrg#endif 1938223e2f2Smrg signal(SIGFPE, SIG_DFL); 1948223e2f2Smrg#ifdef SIGBUS 1958223e2f2Smrg signal(SIGBUS, SIG_DFL); 1968223e2f2Smrg#endif 1978223e2f2Smrg#ifdef SIGSYS 1988223e2f2Smrg signal(SIGSYS, SIG_DFL); 1998223e2f2Smrg#endif 2008223e2f2Smrg#ifdef SIGXCPU 2018223e2f2Smrg signal(SIGXCPU, SIG_DFL); 2028223e2f2Smrg#endif 2038223e2f2Smrg#ifdef SIGXFSZ 2048223e2f2Smrg signal(SIGXFSZ, SIG_DFL); 2058223e2f2Smrg#endif 2068223e2f2Smrg 2074642e01fSmrg if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler, 2084642e01fSmrg QuartzWakeupHandler, 20935c4bbdfSmrg NULL)) { 2104642e01fSmrg FatalError("Could not register block and wakeup handlers."); 2114642e01fSmrg } 2124642e01fSmrg 2136747b715Smrg if (!dixRegisterPrivateKey(&quartzScreenKeyRec, PRIVATE_SCREEN, 0)) 21435c4bbdfSmrg FatalError("Failed to alloc quartz screen private.\n"); 2156747b715Smrg 2164642e01fSmrg // Do display mode specific initialization 2174642e01fSmrg quartzProcs->DisplayInit(); 21835c4bbdfSmrg} 2194642e01fSmrg 2204642e01fSmrg/* 2214642e01fSmrg * QuartzInitInput 2224642e01fSmrg * Inform the main thread the X server is ready to handle events. 2234642e01fSmrg */ 22435c4bbdfSmrgvoid 22535c4bbdfSmrgQuartzInitInput(int argc, 22635c4bbdfSmrg char **argv) 2274642e01fSmrg{ 2286747b715Smrg X11ApplicationSetCanQuit(0); 2294642e01fSmrg X11ApplicationServerReady(); 2304642e01fSmrg // Do final display mode specific initialization before handling events 2314642e01fSmrg if (quartzProcs->InitInput) 2324642e01fSmrg quartzProcs->InitInput(argc, argv); 2334642e01fSmrg} 2344642e01fSmrg 23535c4bbdfSmrgvoid 23635c4bbdfSmrgQuartzUpdateScreens(void) 23735c4bbdfSmrg{ 2384642e01fSmrg ScreenPtr pScreen; 2394642e01fSmrg WindowPtr pRoot; 2404642e01fSmrg int x, y, width, height, sx, sy; 2414642e01fSmrg xEvent e; 2426747b715Smrg BoxRec bounds; 24335c4bbdfSmrg 24435c4bbdfSmrg if (noPseudoramiXExtension || screenInfo.numScreens != 1) { 2454642e01fSmrg /* FIXME: if not using Xinerama, we have multiple screens, and 24635c4bbdfSmrg to do this properly may need to add or remove screens. Which 24735c4bbdfSmrg isn't possible. So don't do anything. Another reason why 24835c4bbdfSmrg we default to running with Xinerama. */ 24935c4bbdfSmrg 2504642e01fSmrg return; 2514642e01fSmrg } 25235c4bbdfSmrg 2534642e01fSmrg pScreen = screenInfo.screens[0]; 25435c4bbdfSmrg 2554642e01fSmrg PseudoramiXResetScreens(); 2566747b715Smrg quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height, pScreen); 25735c4bbdfSmrg 2586747b715Smrg pScreen->x = x; 2596747b715Smrg pScreen->y = y; 26035c4bbdfSmrg pScreen->mmWidth = pScreen->mmWidth * ((double)width / pScreen->width); 26135c4bbdfSmrg pScreen->mmHeight = pScreen->mmHeight * ((double)height / pScreen->height); 2624642e01fSmrg pScreen->width = width; 2634642e01fSmrg pScreen->height = height; 26435c4bbdfSmrg 2654642e01fSmrg DarwinAdjustScreenOrigins(&screenInfo); 26635c4bbdfSmrg 2676747b715Smrg /* DarwinAdjustScreenOrigins or UpdateScreen may change pScreen->x/y, 2686747b715Smrg * so use it rather than x/y 2696747b715Smrg */ 2706747b715Smrg sx = pScreen->x + darwinMainScreenX; 2716747b715Smrg sy = pScreen->y + darwinMainScreenY; 27235c4bbdfSmrg 2734642e01fSmrg /* Adjust the root window. */ 2746747b715Smrg pRoot = pScreen->root; 2754642e01fSmrg AppleWMSetScreenOrigin(pRoot); 2764642e01fSmrg pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL); 2776747b715Smrg 2786747b715Smrg /* <rdar://problem/7770779> pointer events are clipped to old display region after display reconfiguration 2796747b715Smrg * http://xquartz.macosforge.org/trac/ticket/346 2806747b715Smrg */ 2816747b715Smrg bounds.x1 = 0; 2826747b715Smrg bounds.x2 = width; 2836747b715Smrg bounds.y1 = 0; 2846747b715Smrg bounds.y2 = height; 2856747b715Smrg pScreen->ConstrainCursor(inputInfo.pointer, pScreen, &bounds); 2866747b715Smrg inputInfo.pointer->spriteInfo->sprite->physLimits = bounds; 2876747b715Smrg inputInfo.pointer->spriteInfo->sprite->hotLimits = bounds; 2886747b715Smrg 28935c4bbdfSmrg DEBUG_LOG( 29035c4bbdfSmrg "Root Window: %dx%d @ (%d, %d) darwinMainScreen (%d, %d) xy (%d, %d) dixScreenOrigins (%d, %d)\n", 29135c4bbdfSmrg width, height, x - sx, y - sy, darwinMainScreenX, darwinMainScreenY, 29235c4bbdfSmrg x, y, 29335c4bbdfSmrg pScreen->x, pScreen->y); 2944642e01fSmrg 2954642e01fSmrg /* Send an event for the root reconfigure */ 2964642e01fSmrg e.u.u.type = ConfigureNotify; 2974642e01fSmrg e.u.configureNotify.window = pRoot->drawable.id; 2984642e01fSmrg e.u.configureNotify.aboveSibling = None; 2994642e01fSmrg e.u.configureNotify.x = x - sx; 3004642e01fSmrg e.u.configureNotify.y = y - sy; 3014642e01fSmrg e.u.configureNotify.width = width; 3024642e01fSmrg e.u.configureNotify.height = height; 3034642e01fSmrg e.u.configureNotify.borderWidth = wBorderWidth(pRoot); 3044642e01fSmrg e.u.configureNotify.override = pRoot->overrideRedirect; 3054642e01fSmrg DeliverEvents(pRoot, &e, 1, NullWindow); 3064642e01fSmrg 3076747b715Smrg quartzProcs->UpdateScreen(pScreen); 3088223e2f2Smrg 30935c4bbdfSmrg /* PaintWindow needs to be called after RootlessUpdateScreenPixmap (from xprUpdateScreen) */ 31035c4bbdfSmrg pScreen->PaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND); 3119ace9065Smrg 3128223e2f2Smrg /* Tell RandR about the new size, so new connections get the correct info */ 3138223e2f2Smrg RRScreenSizeNotify(pScreen); 3148223e2f2Smrg} 3158223e2f2Smrg 31635c4bbdfSmrgstatic void 31735c4bbdfSmrgpokeActivityCallback(CFRunLoopTimerRef timer, void *info) 31835c4bbdfSmrg{ 3198223e2f2Smrg UpdateSystemActivity(OverallAct); 3208223e2f2Smrg} 3218223e2f2Smrg 32235c4bbdfSmrgstatic void 32335c4bbdfSmrgQuartzScreenSaver(int state) 32435c4bbdfSmrg{ 3258223e2f2Smrg static CFRunLoopTimerRef pokeActivityTimer = NULL; 32635c4bbdfSmrg static CFRunLoopTimerContext pokeActivityContext = 32735c4bbdfSmrg { 0, NULL, NULL, NULL, NULL }; 32835c4bbdfSmrg static OSSpinLock pokeActivitySpinLock = OS_SPINLOCK_INIT; 3298223e2f2Smrg 33035c4bbdfSmrg OSSpinLockLock(&pokeActivitySpinLock); 33135c4bbdfSmrg 33235c4bbdfSmrg if (state) { 33335c4bbdfSmrg if (pokeActivityTimer == NULL) 3348223e2f2Smrg goto QuartzScreenSaverEnd; 3358223e2f2Smrg 3368223e2f2Smrg CFRunLoopTimerInvalidate(pokeActivityTimer); 3378223e2f2Smrg CFRelease(pokeActivityTimer); 3388223e2f2Smrg pokeActivityTimer = NULL; 33935c4bbdfSmrg } 34035c4bbdfSmrg else { 34135c4bbdfSmrg if (pokeActivityTimer != NULL) 3428223e2f2Smrg goto QuartzScreenSaverEnd; 34335c4bbdfSmrg 34435c4bbdfSmrg pokeActivityTimer = CFRunLoopTimerCreate(NULL, 34535c4bbdfSmrg CFAbsoluteTimeGetCurrent(), 34635c4bbdfSmrg 30, 0, 0, 34735c4bbdfSmrg pokeActivityCallback, 34835c4bbdfSmrg &pokeActivityContext); 34935c4bbdfSmrg if (pokeActivityTimer == NULL) { 3508223e2f2Smrg ErrorF("Unable to create pokeActivityTimer.\n"); 3518223e2f2Smrg goto QuartzScreenSaverEnd; 3528223e2f2Smrg } 3538223e2f2Smrg 35435c4bbdfSmrg CFRunLoopAddTimer( 35535c4bbdfSmrg CFRunLoopGetMain(), pokeActivityTimer, kCFRunLoopCommonModes); 3568223e2f2Smrg } 3578223e2f2SmrgQuartzScreenSaverEnd: 35835c4bbdfSmrg OSSpinLockUnlock(&pokeActivitySpinLock); 3594642e01fSmrg} 3604642e01fSmrg 36135c4bbdfSmrgvoid 36235c4bbdfSmrgQuartzShowFullscreen(int state) 36335c4bbdfSmrg{ 3646747b715Smrg int i; 36535c4bbdfSmrg 3666747b715Smrg DEBUG_LOG("QuartzShowFullscreen: state=%d\n", state); 36735c4bbdfSmrg 36835c4bbdfSmrg if (XQuartzIsRootless) { 3696747b715Smrg ErrorF("QuartzShowFullscreen called while in rootless mode.\n"); 3706747b715Smrg return; 3716747b715Smrg } 37235c4bbdfSmrg 3738223e2f2Smrg QuartzScreenSaver(!state); 37435c4bbdfSmrg 37535c4bbdfSmrg if (XQuartzFullscreenVisible == state) 3764642e01fSmrg return; 37735c4bbdfSmrg 3786747b715Smrg XQuartzFullscreenVisible = state; 37935c4bbdfSmrg 38035c4bbdfSmrg xp_disable_update(); 38135c4bbdfSmrg 3826747b715Smrg if (!XQuartzFullscreenVisible) 3834642e01fSmrg RootlessHideAllWindows(); 38435c4bbdfSmrg 3856747b715Smrg RootlessUpdateRooted(XQuartzFullscreenVisible); 38635c4bbdfSmrg 3876747b715Smrg if (XQuartzFullscreenVisible) { 38835c4bbdfSmrg RootlessShowAllWindows(); 38935c4bbdfSmrg for (i = 0; i < screenInfo.numScreens; i++) { 39035c4bbdfSmrg ScreenPtr pScreen = screenInfo.screens[i]; 3916747b715Smrg RootlessRepositionWindows(pScreen); 3926747b715Smrg // JH: I don't think this is necessary, but keeping it here as a reminder 3936747b715Smrg //RootlessUpdateScreenPixmap(pScreen); 3946747b715Smrg } 3954642e01fSmrg } 3964642e01fSmrg 3974642e01fSmrg /* Somehow the menubar manages to interfere with our event stream 39835c4bbdfSmrg * in fullscreen mode, even though it's not visible. 3994642e01fSmrg */ 4006747b715Smrg X11ApplicationShowHideMenubar(!XQuartzFullscreenVisible); 40135c4bbdfSmrg 40235c4bbdfSmrg xp_reenable_update(); 40335c4bbdfSmrg 4046747b715Smrg if (XQuartzFullscreenDisableHotkeys) 4056747b715Smrg xp_disable_hot_keys(XQuartzFullscreenVisible); 4064642e01fSmrg} 4074642e01fSmrg 40835c4bbdfSmrgvoid 40935c4bbdfSmrgQuartzSetRootless(Bool state) 41035c4bbdfSmrg{ 4116747b715Smrg DEBUG_LOG("QuartzSetRootless state=%d\n", state); 41235c4bbdfSmrg 41335c4bbdfSmrg if (XQuartzIsRootless == state) 4144642e01fSmrg return; 41535c4bbdfSmrg 41635c4bbdfSmrg if (state) 4176747b715Smrg QuartzShowFullscreen(FALSE); 41835c4bbdfSmrg 4196747b715Smrg XQuartzIsRootless = state; 4204642e01fSmrg 4214642e01fSmrg xp_disable_update(); 4224642e01fSmrg 42335c4bbdfSmrg /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */ 4244642e01fSmrg QuartzUpdateScreens(); 4254642e01fSmrg 42635c4bbdfSmrg if (XQuartzIsRootless) { 4274642e01fSmrg RootlessShowAllWindows(); 42835c4bbdfSmrg } 42935c4bbdfSmrg else { 4306747b715Smrg RootlessHideAllWindows(); 4314642e01fSmrg } 4324642e01fSmrg 4336747b715Smrg X11ApplicationShowHideMenubar(TRUE); 4346747b715Smrg 4354642e01fSmrg xp_reenable_update(); 4366747b715Smrg 4376747b715Smrg xp_disable_hot_keys(FALSE); 4384642e01fSmrg} 4394642e01fSmrg 4404642e01fSmrg/* 4414642e01fSmrg * QuartzShow 4424642e01fSmrg * Show the X server on screen. Does nothing if already shown. 4434642e01fSmrg * Calls mode specific screen resume to restore the X clip regions 4444642e01fSmrg * (if needed) and the X server cursor state. 4454642e01fSmrg */ 44635c4bbdfSmrgvoid 44735c4bbdfSmrgQuartzShow(void) 44835c4bbdfSmrg{ 4494642e01fSmrg int i; 4504642e01fSmrg 4516747b715Smrg if (XQuartzServerVisible) 4524642e01fSmrg return; 45335c4bbdfSmrg 4546747b715Smrg XQuartzServerVisible = TRUE; 4554642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 4564642e01fSmrg if (screenInfo.screens[i]) { 4576747b715Smrg quartzProcs->ResumeScreen(screenInfo.screens[i]); 4584642e01fSmrg } 4594642e01fSmrg } 46035c4bbdfSmrg 4616747b715Smrg if (!XQuartzIsRootless) 4626747b715Smrg QuartzShowFullscreen(TRUE); 4634642e01fSmrg} 4644642e01fSmrg 4654642e01fSmrg/* 4664642e01fSmrg * QuartzHide 4674642e01fSmrg * Remove the X server display from the screen. Does nothing if already 4684642e01fSmrg * hidden. Calls mode specific screen suspend to set X clip regions to 4694642e01fSmrg * prevent drawing (if needed) and restore the Aqua cursor. 4704642e01fSmrg */ 47135c4bbdfSmrgvoid 47235c4bbdfSmrgQuartzHide(void) 4734642e01fSmrg{ 4744642e01fSmrg int i; 4754642e01fSmrg 4766747b715Smrg if (XQuartzServerVisible) { 4774642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 4784642e01fSmrg if (screenInfo.screens[i]) { 4794642e01fSmrg quartzProcs->SuspendScreen(screenInfo.screens[i]); 4804642e01fSmrg } 4814642e01fSmrg } 4824642e01fSmrg } 4836747b715Smrg 48435c4bbdfSmrg if (!XQuartzIsRootless) 4856747b715Smrg QuartzShowFullscreen(FALSE); 4866747b715Smrg XQuartzServerVisible = FALSE; 4874642e01fSmrg} 4884642e01fSmrg 4894642e01fSmrg/* 4904642e01fSmrg * QuartzSetRootClip 4914642e01fSmrg * Enable or disable rendering to the X screen. 4924642e01fSmrg */ 49335c4bbdfSmrgvoid 49435c4bbdfSmrgQuartzSetRootClip(int mode) 4954642e01fSmrg{ 4964642e01fSmrg int i; 4974642e01fSmrg 4986747b715Smrg if (!XQuartzServerVisible) 4994642e01fSmrg return; 5004642e01fSmrg 5014642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 5024642e01fSmrg if (screenInfo.screens[i]) { 50335c4bbdfSmrg SetRootClip(screenInfo.screens[i], mode); 5044642e01fSmrg } 5054642e01fSmrg } 5064642e01fSmrg} 5074642e01fSmrg 50835c4bbdfSmrg/* 5094642e01fSmrg * QuartzSpaceChanged 5104642e01fSmrg * Unmap offscreen windows, map onscreen windows 5114642e01fSmrg */ 51235c4bbdfSmrgvoid 51335c4bbdfSmrgQuartzSpaceChanged(uint32_t space_id) 51435c4bbdfSmrg{ 5154642e01fSmrg /* Do something special here, so we don't depend on quartz-wm for spaces to work... */ 51635c4bbdfSmrg DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", 51735c4bbdfSmrg space_id); 5184642e01fSmrg} 5196747b715Smrg 5206747b715Smrg/* 5216747b715Smrg * QuartzCopyDisplayIDs 5226747b715Smrg * Associate an X11 screen with one or more CoreGraphics display IDs by copying 5236747b715Smrg * the list into a private array. Free the previously copied array, if present. 5246747b715Smrg */ 52535c4bbdfSmrgvoid 52635c4bbdfSmrgQuartzCopyDisplayIDs(ScreenPtr pScreen, 52735c4bbdfSmrg int displayCount, CGDirectDisplayID *displayIDs) 52835c4bbdfSmrg{ 5296747b715Smrg QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen); 5306747b715Smrg 5316747b715Smrg free(pQuartzScreen->displayIDs); 53235c4bbdfSmrg if (displayCount) { 5339ace9065Smrg size_t size = displayCount * sizeof(CGDirectDisplayID); 5349ace9065Smrg pQuartzScreen->displayIDs = malloc(size); 5359ace9065Smrg memcpy(pQuartzScreen->displayIDs, displayIDs, size); 53635c4bbdfSmrg } 53735c4bbdfSmrg else { 53835c4bbdfSmrg pQuartzScreen->displayIDs = NULL; 5399ace9065Smrg } 5406747b715Smrg pQuartzScreen->displayCount = displayCount; 5416747b715Smrg} 5428223e2f2Smrg 54335c4bbdfSmrgvoid 54435c4bbdfSmrgNSBeep(void); 54535c4bbdfSmrgvoid 54635c4bbdfSmrgDDXRingBell(int volume, // volume is % of max 54735c4bbdfSmrg int pitch, // pitch is Hz 54835c4bbdfSmrg int duration) // duration is milliseconds 5498223e2f2Smrg{ 5508223e2f2Smrg if (volume) 5518223e2f2Smrg NSBeep(); 5528223e2f2Smrg} 553