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 88dc61d50dSmrg/* These are initialized by X11Application with default values set in NSUserDefaults+XQuartzDefaults */ 89dc61d50dSmrgBool XQuartzFullscreenDisableHotkeys; 90dc61d50dSmrgBool XQuartzOptionSendsAlt; 91dc61d50dSmrgBool XQuartzEnableKeyEquivalents; 92dc61d50dSmrgBool XQuartzFullscreenMenu; 93dc61d50dSmrgBool XQuartzRootlessDefault; 94dc61d50dSmrg 956747b715SmrgBool XQuartzFullscreenVisible = FALSE; 966747b715SmrgBool XQuartzIsRootless = TRUE; 976747b715SmrgBool XQuartzServerVisible = FALSE; 988223e2f2Smrg 998223e2f2Smrgint32_t XQuartzShieldingWindowLevel = 0; 1004642e01fSmrg 1014642e01fSmrg/* 10235c4bbdfSmrg =========================================================================== 1034642e01fSmrg 10435c4bbdfSmrg Screen functions 1054642e01fSmrg 10635c4bbdfSmrg =========================================================================== 10735c4bbdfSmrg */ 1084642e01fSmrg 1094642e01fSmrg/* 1104642e01fSmrg * QuartzAddScreen 1114642e01fSmrg * Do mode dependent initialization of each screen for Quartz. 1124642e01fSmrg */ 11335c4bbdfSmrgBool 11435c4bbdfSmrgQuartzAddScreen(int index, 11535c4bbdfSmrg ScreenPtr pScreen) 1164642e01fSmrg{ 11735c4bbdfSmrg // The clang static analyzer thinks we leak displayInfo here 11835c4bbdfSmrg#ifndef __clang_analyzer__ 1194642e01fSmrg // allocate space for private per screen Quartz specific storage 1206747b715Smrg QuartzScreenPtr displayInfo = calloc(sizeof(QuartzScreenRec), 1); 1214642e01fSmrg 1224642e01fSmrg // QUARTZ_PRIV(pScreen) = displayInfo; 1234642e01fSmrg dixSetPrivate(&pScreen->devPrivates, quartzScreenKey, displayInfo); 12435c4bbdfSmrg#endif /* __clang_analyzer__ */ 1254642e01fSmrg 1264642e01fSmrg // do Quartz mode specific initialization 1274642e01fSmrg return quartzProcs->AddScreen(index, pScreen); 1284642e01fSmrg} 1294642e01fSmrg 1304642e01fSmrg/* 1314642e01fSmrg * QuartzSetupScreen 1324642e01fSmrg * Finalize mode specific setup of each screen. 1334642e01fSmrg */ 13435c4bbdfSmrgBool 13535c4bbdfSmrgQuartzSetupScreen(int index, 13635c4bbdfSmrg ScreenPtr pScreen) 1374642e01fSmrg{ 1384642e01fSmrg // do Quartz mode specific setup 13935c4bbdfSmrg if (!quartzProcs->SetupScreen(index, pScreen)) 1404642e01fSmrg return FALSE; 1414642e01fSmrg 1424642e01fSmrg // setup cursor support 14335c4bbdfSmrg if (!quartzProcs->InitCursor(pScreen)) 1444642e01fSmrg return FALSE; 1454642e01fSmrg 1466747b715Smrg#if defined(RANDR) 14735c4bbdfSmrg if (!QuartzRandRInit(pScreen)) { 1486747b715Smrg DEBUG_LOG("Failed to init RandR extension.\n"); 1496747b715Smrg return FALSE; 1506747b715Smrg } 1516747b715Smrg#endif 1526747b715Smrg 1534642e01fSmrg return TRUE; 1544642e01fSmrg} 1554642e01fSmrg 156c8548ba8Smrg/* 157c8548ba8Smrg * QuartzBlockHandler 158c8548ba8Smrg * Clean out any autoreleased objects. 159c8548ba8Smrg */ 160c8548ba8Smrgstatic void 161c8548ba8SmrgQuartzBlockHandler(void *blockData, void *pTimeout) 162c8548ba8Smrg{ 163c8548ba8Smrg static void *poolToken = NULL; 164c8548ba8Smrg 165c8548ba8Smrg if (poolToken) { 166c8548ba8Smrg objc_autoreleasePoolPop(poolToken); 167c8548ba8Smrg } 168c8548ba8Smrg poolToken = objc_autoreleasePoolPush(); 169c8548ba8Smrg} 170c8548ba8Smrg 171c8548ba8Smrg/* 172c8548ba8Smrg * QuartzWakeupHandler 173c8548ba8Smrg */ 174c8548ba8Smrgstatic void 175c8548ba8SmrgQuartzWakeupHandler(void *blockData, int result) 176c8548ba8Smrg{ 177c8548ba8Smrg /* nothing here */ 178c8548ba8Smrg} 179c8548ba8Smrg 1804642e01fSmrg/* 1814642e01fSmrg * QuartzInitOutput 1824642e01fSmrg * Quartz display initialization. 1834642e01fSmrg */ 18435c4bbdfSmrgvoid 18535c4bbdfSmrgQuartzInitOutput(int argc, 18635c4bbdfSmrg char **argv) 1874642e01fSmrg{ 1888223e2f2Smrg /* For XQuartz, we want to just use the default signal handler to work better with CrashTracer */ 1898223e2f2Smrg signal(SIGSEGV, SIG_DFL); 1901b5d61b8Smrg signal(SIGABRT, SIG_DFL); 1918223e2f2Smrg signal(SIGILL, SIG_DFL); 1928223e2f2Smrg#ifdef SIGEMT 1938223e2f2Smrg signal(SIGEMT, SIG_DFL); 1948223e2f2Smrg#endif 1958223e2f2Smrg signal(SIGFPE, SIG_DFL); 1968223e2f2Smrg#ifdef SIGBUS 1978223e2f2Smrg signal(SIGBUS, SIG_DFL); 1988223e2f2Smrg#endif 1998223e2f2Smrg#ifdef SIGSYS 2008223e2f2Smrg signal(SIGSYS, SIG_DFL); 2018223e2f2Smrg#endif 2028223e2f2Smrg#ifdef SIGXCPU 2038223e2f2Smrg signal(SIGXCPU, SIG_DFL); 2048223e2f2Smrg#endif 2058223e2f2Smrg#ifdef SIGXFSZ 2068223e2f2Smrg signal(SIGXFSZ, SIG_DFL); 2078223e2f2Smrg#endif 2088223e2f2Smrg 2094642e01fSmrg if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler, 2104642e01fSmrg QuartzWakeupHandler, 21135c4bbdfSmrg NULL)) { 2124642e01fSmrg FatalError("Could not register block and wakeup handlers."); 2134642e01fSmrg } 2144642e01fSmrg 2156747b715Smrg if (!dixRegisterPrivateKey(&quartzScreenKeyRec, PRIVATE_SCREEN, 0)) 21635c4bbdfSmrg FatalError("Failed to alloc quartz screen private.\n"); 2176747b715Smrg 2184642e01fSmrg // Do display mode specific initialization 2194642e01fSmrg quartzProcs->DisplayInit(); 22035c4bbdfSmrg} 2214642e01fSmrg 2224642e01fSmrg/* 2234642e01fSmrg * QuartzInitInput 2244642e01fSmrg * Inform the main thread the X server is ready to handle events. 2254642e01fSmrg */ 22635c4bbdfSmrgvoid 22735c4bbdfSmrgQuartzInitInput(int argc, 22835c4bbdfSmrg char **argv) 2294642e01fSmrg{ 2306747b715Smrg X11ApplicationSetCanQuit(0); 2314642e01fSmrg X11ApplicationServerReady(); 2324642e01fSmrg // Do final display mode specific initialization before handling events 2334642e01fSmrg if (quartzProcs->InitInput) 2344642e01fSmrg quartzProcs->InitInput(argc, argv); 2354642e01fSmrg} 2364642e01fSmrg 23735c4bbdfSmrgvoid 23835c4bbdfSmrgQuartzUpdateScreens(void) 23935c4bbdfSmrg{ 2404642e01fSmrg ScreenPtr pScreen; 2414642e01fSmrg WindowPtr pRoot; 2424642e01fSmrg int x, y, width, height, sx, sy; 2434642e01fSmrg xEvent e; 2446747b715Smrg BoxRec bounds; 24535c4bbdfSmrg 24635c4bbdfSmrg if (noPseudoramiXExtension || screenInfo.numScreens != 1) { 2474642e01fSmrg /* FIXME: if not using Xinerama, we have multiple screens, and 24835c4bbdfSmrg to do this properly may need to add or remove screens. Which 24935c4bbdfSmrg isn't possible. So don't do anything. Another reason why 25035c4bbdfSmrg we default to running with Xinerama. */ 25135c4bbdfSmrg 2524642e01fSmrg return; 2534642e01fSmrg } 25435c4bbdfSmrg 2554642e01fSmrg pScreen = screenInfo.screens[0]; 25635c4bbdfSmrg 2574642e01fSmrg PseudoramiXResetScreens(); 2586747b715Smrg quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height, pScreen); 25935c4bbdfSmrg 2606747b715Smrg pScreen->x = x; 2616747b715Smrg pScreen->y = y; 26235c4bbdfSmrg pScreen->mmWidth = pScreen->mmWidth * ((double)width / pScreen->width); 26335c4bbdfSmrg pScreen->mmHeight = pScreen->mmHeight * ((double)height / pScreen->height); 2644642e01fSmrg pScreen->width = width; 2654642e01fSmrg pScreen->height = height; 26635c4bbdfSmrg 2674642e01fSmrg DarwinAdjustScreenOrigins(&screenInfo); 26835c4bbdfSmrg 2696747b715Smrg /* DarwinAdjustScreenOrigins or UpdateScreen may change pScreen->x/y, 2706747b715Smrg * so use it rather than x/y 2716747b715Smrg */ 2726747b715Smrg sx = pScreen->x + darwinMainScreenX; 2736747b715Smrg sy = pScreen->y + darwinMainScreenY; 27435c4bbdfSmrg 2754642e01fSmrg /* Adjust the root window. */ 2766747b715Smrg pRoot = pScreen->root; 2774642e01fSmrg AppleWMSetScreenOrigin(pRoot); 2784642e01fSmrg pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL); 2796747b715Smrg 2806747b715Smrg /* <rdar://problem/7770779> pointer events are clipped to old display region after display reconfiguration 2816747b715Smrg * http://xquartz.macosforge.org/trac/ticket/346 2826747b715Smrg */ 2836747b715Smrg bounds.x1 = 0; 2846747b715Smrg bounds.x2 = width; 2856747b715Smrg bounds.y1 = 0; 2866747b715Smrg bounds.y2 = height; 2876747b715Smrg pScreen->ConstrainCursor(inputInfo.pointer, pScreen, &bounds); 2886747b715Smrg inputInfo.pointer->spriteInfo->sprite->physLimits = bounds; 2896747b715Smrg inputInfo.pointer->spriteInfo->sprite->hotLimits = bounds; 2906747b715Smrg 29135c4bbdfSmrg DEBUG_LOG( 29235c4bbdfSmrg "Root Window: %dx%d @ (%d, %d) darwinMainScreen (%d, %d) xy (%d, %d) dixScreenOrigins (%d, %d)\n", 29335c4bbdfSmrg width, height, x - sx, y - sy, darwinMainScreenX, darwinMainScreenY, 29435c4bbdfSmrg x, y, 29535c4bbdfSmrg pScreen->x, pScreen->y); 2964642e01fSmrg 2974642e01fSmrg /* Send an event for the root reconfigure */ 2984642e01fSmrg e.u.u.type = ConfigureNotify; 2994642e01fSmrg e.u.configureNotify.window = pRoot->drawable.id; 3004642e01fSmrg e.u.configureNotify.aboveSibling = None; 3014642e01fSmrg e.u.configureNotify.x = x - sx; 3024642e01fSmrg e.u.configureNotify.y = y - sy; 3034642e01fSmrg e.u.configureNotify.width = width; 3044642e01fSmrg e.u.configureNotify.height = height; 3054642e01fSmrg e.u.configureNotify.borderWidth = wBorderWidth(pRoot); 3064642e01fSmrg e.u.configureNotify.override = pRoot->overrideRedirect; 3074642e01fSmrg DeliverEvents(pRoot, &e, 1, NullWindow); 3084642e01fSmrg 3096747b715Smrg quartzProcs->UpdateScreen(pScreen); 3108223e2f2Smrg 31135c4bbdfSmrg /* PaintWindow needs to be called after RootlessUpdateScreenPixmap (from xprUpdateScreen) */ 31235c4bbdfSmrg pScreen->PaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND); 3139ace9065Smrg 3148223e2f2Smrg /* Tell RandR about the new size, so new connections get the correct info */ 3158223e2f2Smrg RRScreenSizeNotify(pScreen); 3168223e2f2Smrg} 3178223e2f2Smrg 31835c4bbdfSmrgstatic void 31935c4bbdfSmrgpokeActivityCallback(CFRunLoopTimerRef timer, void *info) 32035c4bbdfSmrg{ 3218223e2f2Smrg UpdateSystemActivity(OverallAct); 3228223e2f2Smrg} 3238223e2f2Smrg 32435c4bbdfSmrgstatic void 32535c4bbdfSmrgQuartzScreenSaver(int state) 32635c4bbdfSmrg{ 3278223e2f2Smrg static CFRunLoopTimerRef pokeActivityTimer = NULL; 32835c4bbdfSmrg static CFRunLoopTimerContext pokeActivityContext = 32935c4bbdfSmrg { 0, NULL, NULL, NULL, NULL }; 33035c4bbdfSmrg static OSSpinLock pokeActivitySpinLock = OS_SPINLOCK_INIT; 3318223e2f2Smrg 33235c4bbdfSmrg OSSpinLockLock(&pokeActivitySpinLock); 33335c4bbdfSmrg 33435c4bbdfSmrg if (state) { 33535c4bbdfSmrg if (pokeActivityTimer == NULL) 3368223e2f2Smrg goto QuartzScreenSaverEnd; 3378223e2f2Smrg 3388223e2f2Smrg CFRunLoopTimerInvalidate(pokeActivityTimer); 3398223e2f2Smrg CFRelease(pokeActivityTimer); 3408223e2f2Smrg pokeActivityTimer = NULL; 34135c4bbdfSmrg } 34235c4bbdfSmrg else { 34335c4bbdfSmrg if (pokeActivityTimer != NULL) 3448223e2f2Smrg goto QuartzScreenSaverEnd; 34535c4bbdfSmrg 34635c4bbdfSmrg pokeActivityTimer = CFRunLoopTimerCreate(NULL, 34735c4bbdfSmrg CFAbsoluteTimeGetCurrent(), 34835c4bbdfSmrg 30, 0, 0, 34935c4bbdfSmrg pokeActivityCallback, 35035c4bbdfSmrg &pokeActivityContext); 35135c4bbdfSmrg if (pokeActivityTimer == NULL) { 3528223e2f2Smrg ErrorF("Unable to create pokeActivityTimer.\n"); 3538223e2f2Smrg goto QuartzScreenSaverEnd; 3548223e2f2Smrg } 3558223e2f2Smrg 35635c4bbdfSmrg CFRunLoopAddTimer( 35735c4bbdfSmrg CFRunLoopGetMain(), pokeActivityTimer, kCFRunLoopCommonModes); 3588223e2f2Smrg } 3598223e2f2SmrgQuartzScreenSaverEnd: 36035c4bbdfSmrg OSSpinLockUnlock(&pokeActivitySpinLock); 3614642e01fSmrg} 3624642e01fSmrg 36335c4bbdfSmrgvoid 36435c4bbdfSmrgQuartzShowFullscreen(int state) 36535c4bbdfSmrg{ 3666747b715Smrg int i; 36735c4bbdfSmrg 3686747b715Smrg DEBUG_LOG("QuartzShowFullscreen: state=%d\n", state); 36935c4bbdfSmrg 37035c4bbdfSmrg if (XQuartzIsRootless) { 3716747b715Smrg ErrorF("QuartzShowFullscreen called while in rootless mode.\n"); 3726747b715Smrg return; 3736747b715Smrg } 37435c4bbdfSmrg 3758223e2f2Smrg QuartzScreenSaver(!state); 37635c4bbdfSmrg 37735c4bbdfSmrg if (XQuartzFullscreenVisible == state) 3784642e01fSmrg return; 37935c4bbdfSmrg 3806747b715Smrg XQuartzFullscreenVisible = state; 38135c4bbdfSmrg 38235c4bbdfSmrg xp_disable_update(); 38335c4bbdfSmrg 3846747b715Smrg if (!XQuartzFullscreenVisible) 3854642e01fSmrg RootlessHideAllWindows(); 38635c4bbdfSmrg 3876747b715Smrg RootlessUpdateRooted(XQuartzFullscreenVisible); 38835c4bbdfSmrg 3896747b715Smrg if (XQuartzFullscreenVisible) { 39035c4bbdfSmrg RootlessShowAllWindows(); 39135c4bbdfSmrg for (i = 0; i < screenInfo.numScreens; i++) { 39235c4bbdfSmrg ScreenPtr pScreen = screenInfo.screens[i]; 3936747b715Smrg RootlessRepositionWindows(pScreen); 3946747b715Smrg // JH: I don't think this is necessary, but keeping it here as a reminder 3956747b715Smrg //RootlessUpdateScreenPixmap(pScreen); 3966747b715Smrg } 3974642e01fSmrg } 3984642e01fSmrg 3994642e01fSmrg /* Somehow the menubar manages to interfere with our event stream 40035c4bbdfSmrg * in fullscreen mode, even though it's not visible. 4014642e01fSmrg */ 4026747b715Smrg X11ApplicationShowHideMenubar(!XQuartzFullscreenVisible); 40335c4bbdfSmrg 40435c4bbdfSmrg xp_reenable_update(); 40535c4bbdfSmrg 4066747b715Smrg if (XQuartzFullscreenDisableHotkeys) 4076747b715Smrg xp_disable_hot_keys(XQuartzFullscreenVisible); 4084642e01fSmrg} 4094642e01fSmrg 41035c4bbdfSmrgvoid 41135c4bbdfSmrgQuartzSetRootless(Bool state) 41235c4bbdfSmrg{ 4136747b715Smrg DEBUG_LOG("QuartzSetRootless state=%d\n", state); 41435c4bbdfSmrg 41535c4bbdfSmrg if (XQuartzIsRootless == state) 4164642e01fSmrg return; 41735c4bbdfSmrg 41835c4bbdfSmrg if (state) 4196747b715Smrg QuartzShowFullscreen(FALSE); 42035c4bbdfSmrg 4216747b715Smrg XQuartzIsRootless = state; 4224642e01fSmrg 4234642e01fSmrg xp_disable_update(); 4244642e01fSmrg 42535c4bbdfSmrg /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */ 4264642e01fSmrg QuartzUpdateScreens(); 4274642e01fSmrg 42835c4bbdfSmrg if (XQuartzIsRootless) { 4294642e01fSmrg RootlessShowAllWindows(); 43035c4bbdfSmrg } 43135c4bbdfSmrg else { 4326747b715Smrg RootlessHideAllWindows(); 4334642e01fSmrg } 4344642e01fSmrg 4356747b715Smrg X11ApplicationShowHideMenubar(TRUE); 4366747b715Smrg 4374642e01fSmrg xp_reenable_update(); 4386747b715Smrg 4396747b715Smrg xp_disable_hot_keys(FALSE); 4404642e01fSmrg} 4414642e01fSmrg 4424642e01fSmrg/* 4434642e01fSmrg * QuartzShow 4444642e01fSmrg * Show the X server on screen. Does nothing if already shown. 4454642e01fSmrg * Calls mode specific screen resume to restore the X clip regions 4464642e01fSmrg * (if needed) and the X server cursor state. 4474642e01fSmrg */ 44835c4bbdfSmrgvoid 44935c4bbdfSmrgQuartzShow(void) 45035c4bbdfSmrg{ 4514642e01fSmrg int i; 4524642e01fSmrg 4536747b715Smrg if (XQuartzServerVisible) 4544642e01fSmrg return; 45535c4bbdfSmrg 4566747b715Smrg XQuartzServerVisible = TRUE; 4574642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 4584642e01fSmrg if (screenInfo.screens[i]) { 4596747b715Smrg quartzProcs->ResumeScreen(screenInfo.screens[i]); 4604642e01fSmrg } 4614642e01fSmrg } 46235c4bbdfSmrg 4636747b715Smrg if (!XQuartzIsRootless) 4646747b715Smrg QuartzShowFullscreen(TRUE); 4654642e01fSmrg} 4664642e01fSmrg 4674642e01fSmrg/* 4684642e01fSmrg * QuartzHide 4694642e01fSmrg * Remove the X server display from the screen. Does nothing if already 4704642e01fSmrg * hidden. Calls mode specific screen suspend to set X clip regions to 4714642e01fSmrg * prevent drawing (if needed) and restore the Aqua cursor. 4724642e01fSmrg */ 47335c4bbdfSmrgvoid 47435c4bbdfSmrgQuartzHide(void) 4754642e01fSmrg{ 4764642e01fSmrg int i; 4774642e01fSmrg 4786747b715Smrg if (XQuartzServerVisible) { 4794642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 4804642e01fSmrg if (screenInfo.screens[i]) { 4814642e01fSmrg quartzProcs->SuspendScreen(screenInfo.screens[i]); 4824642e01fSmrg } 4834642e01fSmrg } 4844642e01fSmrg } 4856747b715Smrg 48635c4bbdfSmrg if (!XQuartzIsRootless) 4876747b715Smrg QuartzShowFullscreen(FALSE); 4886747b715Smrg XQuartzServerVisible = FALSE; 4894642e01fSmrg} 4904642e01fSmrg 4914642e01fSmrg/* 4924642e01fSmrg * QuartzSetRootClip 4934642e01fSmrg * Enable or disable rendering to the X screen. 4944642e01fSmrg */ 49535c4bbdfSmrgvoid 49635c4bbdfSmrgQuartzSetRootClip(int mode) 4974642e01fSmrg{ 4984642e01fSmrg int i; 4994642e01fSmrg 5006747b715Smrg if (!XQuartzServerVisible) 5014642e01fSmrg return; 5024642e01fSmrg 5034642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 5044642e01fSmrg if (screenInfo.screens[i]) { 50535c4bbdfSmrg SetRootClip(screenInfo.screens[i], mode); 5064642e01fSmrg } 5074642e01fSmrg } 5084642e01fSmrg} 5094642e01fSmrg 51035c4bbdfSmrg/* 5114642e01fSmrg * QuartzSpaceChanged 5124642e01fSmrg * Unmap offscreen windows, map onscreen windows 5134642e01fSmrg */ 51435c4bbdfSmrgvoid 51535c4bbdfSmrgQuartzSpaceChanged(uint32_t space_id) 51635c4bbdfSmrg{ 5174642e01fSmrg /* Do something special here, so we don't depend on quartz-wm for spaces to work... */ 51835c4bbdfSmrg DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", 51935c4bbdfSmrg space_id); 5204642e01fSmrg} 5216747b715Smrg 5226747b715Smrg/* 5236747b715Smrg * QuartzCopyDisplayIDs 5246747b715Smrg * Associate an X11 screen with one or more CoreGraphics display IDs by copying 5256747b715Smrg * the list into a private array. Free the previously copied array, if present. 5266747b715Smrg */ 52735c4bbdfSmrgvoid 52835c4bbdfSmrgQuartzCopyDisplayIDs(ScreenPtr pScreen, 52935c4bbdfSmrg int displayCount, CGDirectDisplayID *displayIDs) 53035c4bbdfSmrg{ 5316747b715Smrg QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen); 5326747b715Smrg 5336747b715Smrg free(pQuartzScreen->displayIDs); 53435c4bbdfSmrg if (displayCount) { 5359ace9065Smrg size_t size = displayCount * sizeof(CGDirectDisplayID); 5369ace9065Smrg pQuartzScreen->displayIDs = malloc(size); 5379ace9065Smrg memcpy(pQuartzScreen->displayIDs, displayIDs, size); 53835c4bbdfSmrg } 53935c4bbdfSmrg else { 54035c4bbdfSmrg pQuartzScreen->displayIDs = NULL; 5419ace9065Smrg } 5426747b715Smrg pQuartzScreen->displayCount = displayCount; 5436747b715Smrg} 5448223e2f2Smrg 54535c4bbdfSmrgvoid 54635c4bbdfSmrgNSBeep(void); 54735c4bbdfSmrgvoid 54835c4bbdfSmrgDDXRingBell(int volume, // volume is % of max 54935c4bbdfSmrg int pitch, // pitch is Hz 55035c4bbdfSmrg int duration) // duration is milliseconds 5518223e2f2Smrg{ 5528223e2f2Smrg if (volume) 5538223e2f2Smrg NSBeep(); 5548223e2f2Smrg} 555