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