14642e01fSmrg/*
24642e01fSmrg * Xplugin rootless implementation screen functions
34642e01fSmrg *
435c4bbdfSmrg * Copyright (c) 2002-2012 Apple Computer, Inc. All Rights Reserved.
54642e01fSmrg * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved.
64642e01fSmrg *
74642e01fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
84642e01fSmrg * copy of this software and associated documentation files (the "Software"),
94642e01fSmrg * to deal in the Software without restriction, including without limitation
104642e01fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
114642e01fSmrg * and/or sell copies of the Software, and to permit persons to whom the
124642e01fSmrg * Software is furnished to do so, subject to the following conditions:
134642e01fSmrg *
144642e01fSmrg * The above copyright notice and this permission notice shall be included in
154642e01fSmrg * all copies or substantial portions of the Software.
164642e01fSmrg *
174642e01fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
184642e01fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
194642e01fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
204642e01fSmrg * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
214642e01fSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
224642e01fSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
234642e01fSmrg * DEALINGS IN THE SOFTWARE.
244642e01fSmrg *
254642e01fSmrg * Except as contained in this notice, the name(s) of the above copyright
264642e01fSmrg * holders shall not be used in advertising or otherwise to promote the sale,
274642e01fSmrg * use or other dealings in this Software without prior written authorization.
284642e01fSmrg */
294642e01fSmrg
304642e01fSmrg#include "sanitizedCarbon.h"
314642e01fSmrg
324642e01fSmrg#ifdef HAVE_DIX_CONFIG_H
334642e01fSmrg#include <dix-config.h>
344642e01fSmrg#endif
354642e01fSmrg
364642e01fSmrg#include "inputstr.h"
374642e01fSmrg#include "quartz.h"
386747b715Smrg#include "quartzRandR.h"
394642e01fSmrg#include "xpr.h"
404642e01fSmrg#include "xprEvent.h"
414642e01fSmrg#include "pseudoramiX.h"
424642e01fSmrg#include "darwinEvents.h"
434642e01fSmrg#include "rootless.h"
444642e01fSmrg#include "dri.h"
454642e01fSmrg#include "globals.h"
464642e01fSmrg#include <Xplugin.h>
474642e01fSmrg#include "applewmExt.h"
484642e01fSmrg#include "micmap.h"
494642e01fSmrg
506747b715Smrg#include "rootlessCommon.h"
516747b715Smrg
524642e01fSmrg#ifdef DAMAGE
5335c4bbdfSmrg#include "damage.h"
5435c4bbdfSmrg#endif
5535c4bbdfSmrg
5635c4bbdfSmrg#include "nonsdk_extinit.h"
5735c4bbdfSmrg
584642e01fSmrg/* 10.4's deferred update makes X slower.. have to live with the tearing
5935c4bbdfSmrg * for now.. */
604642e01fSmrg#define XP_NO_DEFERRED_UPDATES 8
614642e01fSmrg
624642e01fSmrg// Name of GLX bundle for native OpenGL
634642e01fSmrgstatic const char *xprOpenGLBundle = "glxCGL.bundle";
644642e01fSmrg
654642e01fSmrg/*
664642e01fSmrg * eventHandler
674642e01fSmrg *  Callback handler for Xplugin events.
684642e01fSmrg */
6935c4bbdfSmrgstatic void
7035c4bbdfSmrgeventHandler(unsigned int type, const void *arg,
7135c4bbdfSmrg             unsigned int arg_size, void *data)
7235c4bbdfSmrg{
7335c4bbdfSmrg
744642e01fSmrg    switch (type) {
7535c4bbdfSmrg    case XP_EVENT_DISPLAY_CHANGED:
7635c4bbdfSmrg        DEBUG_LOG("XP_EVENT_DISPLAY_CHANGED\n");
7735c4bbdfSmrg        DarwinSendDDXEvent(kXquartzDisplayChanged, 0);
7835c4bbdfSmrg        break;
7935c4bbdfSmrg
8035c4bbdfSmrg    case XP_EVENT_WINDOW_STATE_CHANGED:
8135c4bbdfSmrg        if (arg_size >= sizeof(xp_window_state_event)) {
8235c4bbdfSmrg            const xp_window_state_event *ws_arg = arg;
8335c4bbdfSmrg
8435c4bbdfSmrg            DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: id=%d, state=%d\n",
8535c4bbdfSmrg                      ws_arg->id,
8635c4bbdfSmrg                      ws_arg->state);
8735c4bbdfSmrg            DarwinSendDDXEvent(kXquartzWindowState, 2,
8835c4bbdfSmrg                               ws_arg->id, ws_arg->state);
8935c4bbdfSmrg        }
9035c4bbdfSmrg        else {
9135c4bbdfSmrg            DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: ignored\n");
9235c4bbdfSmrg        }
9335c4bbdfSmrg        break;
9435c4bbdfSmrg
9535c4bbdfSmrg    case XP_EVENT_WINDOW_MOVED:
9635c4bbdfSmrg        DEBUG_LOG("XP_EVENT_WINDOW_MOVED\n");
9735c4bbdfSmrg        if (arg_size == sizeof(xp_window_id)) {
9835c4bbdfSmrg            xp_window_id id = *(xp_window_id *)arg;
9935c4bbdfSmrg            DarwinSendDDXEvent(kXquartzWindowMoved, 1, id);
10035c4bbdfSmrg        }
10135c4bbdfSmrg        break;
10235c4bbdfSmrg
10335c4bbdfSmrg    case XP_EVENT_SURFACE_DESTROYED:
10435c4bbdfSmrg        DEBUG_LOG("XP_EVENT_SURFACE_DESTROYED\n");
10535c4bbdfSmrg
10635c4bbdfSmrg    case XP_EVENT_SURFACE_CHANGED:
10735c4bbdfSmrg        DEBUG_LOG("XP_EVENT_SURFACE_CHANGED\n");
10835c4bbdfSmrg        if (arg_size == sizeof(xp_surface_id)) {
10935c4bbdfSmrg            int kind;
11035c4bbdfSmrg
11135c4bbdfSmrg            if (type == XP_EVENT_SURFACE_DESTROYED)
11235c4bbdfSmrg                kind = AppleDRISurfaceNotifyDestroyed;
11335c4bbdfSmrg            else
11435c4bbdfSmrg                kind = AppleDRISurfaceNotifyChanged;
11535c4bbdfSmrg
11635c4bbdfSmrg            DRISurfaceNotify(*(xp_surface_id *)arg, kind);
11735c4bbdfSmrg        }
11835c4bbdfSmrg        break;
11935c4bbdfSmrg
1204642e01fSmrg#ifdef XP_EVENT_SPACE_CHANGED
12135c4bbdfSmrg    case  XP_EVENT_SPACE_CHANGED:
12235c4bbdfSmrg        DEBUG_LOG("XP_EVENT_SPACE_CHANGED\n");
12335c4bbdfSmrg        if (arg_size == sizeof(uint32_t)) {
12435c4bbdfSmrg            uint32_t space_id = *(uint32_t *)arg;
12535c4bbdfSmrg            DarwinSendDDXEvent(kXquartzSpaceChanged, 1, space_id);
12635c4bbdfSmrg        }
12735c4bbdfSmrg        break;
12835c4bbdfSmrg
1294642e01fSmrg#endif
13035c4bbdfSmrg    default:
13135c4bbdfSmrg        ErrorF("Unknown XP_EVENT type (%d) in xprScreen:eventHandler\n", type);
1324642e01fSmrg    }
1334642e01fSmrg}
1344642e01fSmrg
1354642e01fSmrg/*
1364642e01fSmrg * displayAtIndex
1374642e01fSmrg *  Return the display ID for a particular display index.
1384642e01fSmrg */
1394642e01fSmrgstatic CGDirectDisplayID
1404642e01fSmrgdisplayAtIndex(int index)
1414642e01fSmrg{
1424642e01fSmrg    CGError err;
1434642e01fSmrg    CGDisplayCount cnt;
14435c4bbdfSmrg    CGDirectDisplayID dpy[index + 1];
1454642e01fSmrg
1464642e01fSmrg    err = CGGetActiveDisplayList(index + 1, dpy, &cnt);
1474642e01fSmrg    if (err == kCGErrorSuccess && cnt == index + 1)
1484642e01fSmrg        return dpy[index];
1494642e01fSmrg    else
1504642e01fSmrg        return kCGNullDirectDisplay;
1514642e01fSmrg}
1524642e01fSmrg
1534642e01fSmrg/*
1544642e01fSmrg * displayScreenBounds
1554642e01fSmrg *  Return the bounds of a particular display.
1564642e01fSmrg */
1574642e01fSmrgstatic CGRect
1584642e01fSmrgdisplayScreenBounds(CGDirectDisplayID id)
1594642e01fSmrg{
1604642e01fSmrg    CGRect frame;
1614642e01fSmrg
1624642e01fSmrg    frame = CGDisplayBounds(id);
1634642e01fSmrg
1644642e01fSmrg    DEBUG_LOG("    %dx%d @ (%d,%d).\n",
1654642e01fSmrg              (int)frame.size.width, (int)frame.size.height,
1664642e01fSmrg              (int)frame.origin.x, (int)frame.origin.y);
16735c4bbdfSmrg
16835c4bbdfSmrg    Boolean spacePerDisplay = false;
169c8548ba8Smrg    Boolean ok;
170c8548ba8Smrg    (void)CFPreferencesAppSynchronize(CFSTR("com.apple.spaces"));
171c8548ba8Smrg    spacePerDisplay = ! CFPreferencesGetAppBooleanValue(CFSTR("spans-displays"),
172c8548ba8Smrg                                                        CFSTR("com.apple.spaces"),
173c8548ba8Smrg                                                        &ok);
174c8548ba8Smrg    if (!ok)
175c8548ba8Smrg        spacePerDisplay = true;
17635c4bbdfSmrg
17735c4bbdfSmrg    /* Remove menubar to help standard X11 window managers.
17835c4bbdfSmrg     * On Mavericks and later, the menu bar is on all displays when spans-displays is false or unset.
17935c4bbdfSmrg     */
18035c4bbdfSmrg    if (XQuartzIsRootless &&
18135c4bbdfSmrg        (spacePerDisplay || (frame.origin.x == 0 && frame.origin.y == 0))) {
1824642e01fSmrg        frame.origin.y += aquaMenuBarHeight;
1834642e01fSmrg        frame.size.height -= aquaMenuBarHeight;
1844642e01fSmrg    }
1854642e01fSmrg
1864642e01fSmrg    DEBUG_LOG("    %dx%d @ (%d,%d).\n",
1874642e01fSmrg              (int)frame.size.width, (int)frame.size.height,
1884642e01fSmrg              (int)frame.origin.x, (int)frame.origin.y);
1894642e01fSmrg
1904642e01fSmrg    return frame;
1914642e01fSmrg}
1924642e01fSmrg
1934642e01fSmrg/*
1944642e01fSmrg * xprAddPseudoramiXScreens
1954642e01fSmrg *  Add a single virtual screen encompassing all the physical screens
1964642e01fSmrg *  with PseudoramiX.
1974642e01fSmrg */
1984642e01fSmrgstatic void
19935c4bbdfSmrgxprAddPseudoramiXScreens(int *x, int *y, int *width, int *height,
20035c4bbdfSmrg                         ScreenPtr pScreen)
2014642e01fSmrg{
2024642e01fSmrg    CGDisplayCount i, displayCount;
2034642e01fSmrg    CGDirectDisplayID *displayList = NULL;
2044642e01fSmrg    CGRect unionRect = CGRectNull, frame;
2054642e01fSmrg
2064642e01fSmrg    // Find all the CoreGraphics displays
2074642e01fSmrg    CGGetActiveDisplayList(0, NULL, &displayCount);
2086747b715Smrg    DEBUG_LOG("displayCount: %d\n", (int)displayCount);
2096747b715Smrg
21035c4bbdfSmrg    if (!displayCount) {
21135c4bbdfSmrg        ErrorF(
21235c4bbdfSmrg            "CoreGraphics has reported no connected displays.  Creating a stub 800x600 display.\n");
2136747b715Smrg        *x = *y = 0;
2146747b715Smrg        *width = 800;
2156747b715Smrg        *height = 600;
2166747b715Smrg        PseudoramiXAddScreen(*x, *y, *width, *height);
2179ace9065Smrg        QuartzCopyDisplayIDs(pScreen, 0, NULL);
2186747b715Smrg        return;
2196747b715Smrg    }
2206747b715Smrg
2218223e2f2Smrg    /* If the displays are captured, we are in a RandR game mode
2228223e2f2Smrg     * on the primary display, so we only want to include the first
2238223e2f2Smrg     * display.  The others are covered by the shield window.
2248223e2f2Smrg     */
2258223e2f2Smrg    if (CGDisplayIsCaptured(kCGDirectMainDisplay))
2268223e2f2Smrg        displayCount = 1;
2278223e2f2Smrg
2286747b715Smrg    displayList = malloc(displayCount * sizeof(CGDirectDisplayID));
22935c4bbdfSmrg    if (!displayList)
2306747b715Smrg        FatalError("Unable to allocate memory for list of displays.\n");
2314642e01fSmrg    CGGetActiveDisplayList(displayCount, displayList, &displayCount);
2326747b715Smrg    QuartzCopyDisplayIDs(pScreen, displayCount, displayList);
2334642e01fSmrg
2344642e01fSmrg    /* Get the union of all screens */
2354642e01fSmrg    for (i = 0; i < displayCount; i++) {
2364642e01fSmrg        CGDirectDisplayID dpy = displayList[i];
2374642e01fSmrg        frame = displayScreenBounds(dpy);
2384642e01fSmrg        unionRect = CGRectUnion(unionRect, frame);
2394642e01fSmrg    }
2404642e01fSmrg
2414642e01fSmrg    /* Use unionRect as the screen size for the X server. */
2424642e01fSmrg    *x = unionRect.origin.x;
2434642e01fSmrg    *y = unionRect.origin.y;
2444642e01fSmrg    *width = unionRect.size.width;
2454642e01fSmrg    *height = unionRect.size.height;
2464642e01fSmrg
2474642e01fSmrg    DEBUG_LOG("  screen union origin: (%d,%d) size: (%d,%d).\n",
2484642e01fSmrg              *x, *y, *width, *height);
2494642e01fSmrg
2504642e01fSmrg    /* Tell PseudoramiX about the real screens. */
25135c4bbdfSmrg    for (i = 0; i < displayCount; i++) {
2524642e01fSmrg        CGDirectDisplayID dpy = displayList[i];
2534642e01fSmrg
2544642e01fSmrg        frame = displayScreenBounds(dpy);
2554642e01fSmrg        frame.origin.x -= unionRect.origin.x;
2564642e01fSmrg        frame.origin.y -= unionRect.origin.y;
2574642e01fSmrg
2584642e01fSmrg        DEBUG_LOG("    placed at X11 coordinate (%d,%d).\n",
2594642e01fSmrg                  (int)frame.origin.x, (int)frame.origin.y);
2604642e01fSmrg
2614642e01fSmrg        PseudoramiXAddScreen(frame.origin.x, frame.origin.y,
2624642e01fSmrg                             frame.size.width, frame.size.height);
2634642e01fSmrg    }
2644642e01fSmrg
2656747b715Smrg    free(displayList);
2664642e01fSmrg}
2674642e01fSmrg
2684642e01fSmrg/*
2694642e01fSmrg * xprDisplayInit
2704642e01fSmrg *  Find number of CoreGraphics displays and initialize Xplugin.
2714642e01fSmrg */
2724642e01fSmrgstatic void
2734642e01fSmrgxprDisplayInit(void)
2744642e01fSmrg{
2754642e01fSmrg    CGDisplayCount displayCount;
2764642e01fSmrg
27735c4bbdfSmrg    TRACE();
2784642e01fSmrg
2794642e01fSmrg    CGGetActiveDisplayList(0, NULL, &displayCount);
2804642e01fSmrg
2814642e01fSmrg    /* With PseudoramiX, the X server only sees one screen; only PseudoramiX
2824642e01fSmrg       itself knows about all of the screens. */
2834642e01fSmrg
284ed6184dfSmrg    if (noPseudoramiXExtension) {
2854642e01fSmrg        darwinScreensFound = displayCount;
286ed6184dfSmrg    } else {
287ed6184dfSmrg        PseudoramiXExtensionInit();
28835c4bbdfSmrg        darwinScreensFound = 1;
289ed6184dfSmrg    }
2904642e01fSmrg
2914642e01fSmrg    if (xp_init(XP_BACKGROUND_EVENTS | XP_NO_DEFERRED_UPDATES) != Success)
2924642e01fSmrg        FatalError("Could not initialize the Xplugin library.");
2934642e01fSmrg
2944642e01fSmrg    xp_select_events(XP_EVENT_DISPLAY_CHANGED
2954642e01fSmrg                     | XP_EVENT_WINDOW_STATE_CHANGED
2964642e01fSmrg                     | XP_EVENT_WINDOW_MOVED
2974642e01fSmrg#ifdef XP_EVENT_SPACE_CHANGED
2984642e01fSmrg                     | XP_EVENT_SPACE_CHANGED
2994642e01fSmrg#endif
3004642e01fSmrg                     | XP_EVENT_SURFACE_CHANGED
3014642e01fSmrg                     | XP_EVENT_SURFACE_DESTROYED,
3024642e01fSmrg                     eventHandler, NULL);
3034642e01fSmrg
3044642e01fSmrg    AppleDRIExtensionInit();
3054642e01fSmrg    xprAppleWMInit();
3066747b715Smrg
3076747b715Smrg    XQuartzIsRootless = XQuartzRootlessDefault;
3086747b715Smrg    if (!XQuartzIsRootless)
3096747b715Smrg        RootlessHideAllWindows();
3104642e01fSmrg}
3114642e01fSmrg
3124642e01fSmrg/*
3134642e01fSmrg * xprAddScreen
3144642e01fSmrg *  Init the framebuffer and record pixmap parameters for the screen.
3154642e01fSmrg */
3164642e01fSmrgstatic Bool
3174642e01fSmrgxprAddScreen(int index, ScreenPtr pScreen)
3184642e01fSmrg{
3194642e01fSmrg    DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
3204642e01fSmrg    int depth = darwinDesiredDepth;
3214642e01fSmrg
3224642e01fSmrg    DEBUG_LOG("index=%d depth=%d\n", index, depth);
32335c4bbdfSmrg
32435c4bbdfSmrg    if (depth == -1) {
3258223e2f2Smrg        CGDisplayModeRef modeRef;
3268223e2f2Smrg        CFStringRef encStrRef;
32735c4bbdfSmrg
3288223e2f2Smrg        modeRef = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
32935c4bbdfSmrg        if (!modeRef)
3308223e2f2Smrg            goto have_depth;
3318223e2f2Smrg
3328223e2f2Smrg        encStrRef = CGDisplayModeCopyPixelEncoding(modeRef);
3338223e2f2Smrg        CFRelease(modeRef);
33435c4bbdfSmrg        if (!encStrRef)
3358223e2f2Smrg            goto have_depth;
33635c4bbdfSmrg
33735c4bbdfSmrg        if (CFStringCompare(encStrRef, CFSTR(IO32BitDirectPixels),
33835c4bbdfSmrg                            kCFCompareCaseInsensitive) ==
33935c4bbdfSmrg            kCFCompareEqualTo) {
3408223e2f2Smrg            depth = 24;
34135c4bbdfSmrg        }
34235c4bbdfSmrg        else if (CFStringCompare(encStrRef, CFSTR(IO16BitDirectPixels),
34335c4bbdfSmrg                                 kCFCompareCaseInsensitive) ==
34435c4bbdfSmrg                 kCFCompareEqualTo) {
3458223e2f2Smrg            depth = 15;
34635c4bbdfSmrg        }
34735c4bbdfSmrg        else if (CFStringCompare(encStrRef, CFSTR(IO8BitIndexedPixels),
34835c4bbdfSmrg                                 kCFCompareCaseInsensitive) ==
34935c4bbdfSmrg                 kCFCompareEqualTo) {
3508223e2f2Smrg            depth = 8;
3518223e2f2Smrg        }
3528223e2f2Smrg
3538223e2f2Smrg        CFRelease(encStrRef);
3544642e01fSmrg    }
35535c4bbdfSmrg
3568223e2f2Smrghave_depth:
35735c4bbdfSmrg    switch (depth) {
35835c4bbdfSmrg    case 8:     // pseudo-working
35935c4bbdfSmrg        dfb->visuals = PseudoColorMask;
36035c4bbdfSmrg        dfb->preferredCVC = PseudoColor;
36135c4bbdfSmrg        dfb->depth = 8;
36235c4bbdfSmrg        dfb->bitsPerRGB = 8;
36335c4bbdfSmrg        dfb->bitsPerPixel = 8;
36435c4bbdfSmrg        dfb->redMask = 0;
36535c4bbdfSmrg        dfb->greenMask = 0;
36635c4bbdfSmrg        dfb->blueMask = 0;
36735c4bbdfSmrg        break;
36835c4bbdfSmrg
36935c4bbdfSmrg#if 0
37035c4bbdfSmrg    // Removed because Mountain Lion removed support for
37135c4bbdfSmrg    // 15bit backing stores.  We can possibly re-add
37235c4bbdfSmrg    // this once libXplugin is updated to work around it.
37335c4bbdfSmrg    case 15:
37435c4bbdfSmrg        dfb->visuals = TrueColorMask;     //LARGE_VISUALS;
37535c4bbdfSmrg        dfb->preferredCVC = TrueColor;
37635c4bbdfSmrg        dfb->depth = 15;
37735c4bbdfSmrg        dfb->bitsPerRGB = 5;
37835c4bbdfSmrg        dfb->bitsPerPixel = 16;
37935c4bbdfSmrg        dfb->redMask = RM_ARGB(0, 5, 5, 5);
38035c4bbdfSmrg        dfb->greenMask = GM_ARGB(0, 5, 5, 5);
38135c4bbdfSmrg        dfb->blueMask = BM_ARGB(0, 5, 5, 5);
38235c4bbdfSmrg        break;
38335c4bbdfSmrg#endif
38435c4bbdfSmrg
38535c4bbdfSmrg    //        case 24:
38635c4bbdfSmrg    default:
38735c4bbdfSmrg        if (depth != 24)
38835c4bbdfSmrg            ErrorF(
38935c4bbdfSmrg                "Unsupported color depth requested.  Defaulting to 24bit. (depth=%d darwinDesiredDepth=%d)\n",
39035c4bbdfSmrg                depth, darwinDesiredDepth);
39135c4bbdfSmrg        dfb->visuals = TrueColorMask;     //LARGE_VISUALS;
39235c4bbdfSmrg        dfb->preferredCVC = TrueColor;
39335c4bbdfSmrg        dfb->depth = 24;
39435c4bbdfSmrg        dfb->bitsPerRGB = 8;
39535c4bbdfSmrg        dfb->bitsPerPixel = 32;
39635c4bbdfSmrg        dfb->redMask = RM_ARGB(0, 8, 8, 8);
39735c4bbdfSmrg        dfb->greenMask = GM_ARGB(0, 8, 8, 8);
39835c4bbdfSmrg        dfb->blueMask = BM_ARGB(0, 8, 8, 8);
39935c4bbdfSmrg        break;
4004642e01fSmrg    }
4014642e01fSmrg
40235c4bbdfSmrg    if (noPseudoramiXExtension) {
4034642e01fSmrg        CGDirectDisplayID dpy;
4044642e01fSmrg        CGRect frame;
4054642e01fSmrg
4066747b715Smrg        ErrorF("Warning: noPseudoramiXExtension!\n");
40735c4bbdfSmrg
4084642e01fSmrg        dpy = displayAtIndex(index);
4096747b715Smrg        QuartzCopyDisplayIDs(pScreen, 1, &dpy);
4104642e01fSmrg
4114642e01fSmrg        frame = displayScreenBounds(dpy);
4124642e01fSmrg
4134642e01fSmrg        dfb->x = frame.origin.x;
4144642e01fSmrg        dfb->y = frame.origin.y;
41535c4bbdfSmrg        dfb->width = frame.size.width;
4164642e01fSmrg        dfb->height = frame.size.height;
4174642e01fSmrg    }
41835c4bbdfSmrg    else {
41935c4bbdfSmrg        xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height,
42035c4bbdfSmrg                                 pScreen);
4214642e01fSmrg    }
4224642e01fSmrg
4234642e01fSmrg    /* Passing zero width (pitch) makes miCreateScreenResources set the
4244642e01fSmrg       screen pixmap to the framebuffer pointer, i.e. NULL. The generic
4254642e01fSmrg       rootless code takes care of making this work. */
4264642e01fSmrg    dfb->pitch = 0;
4274642e01fSmrg    dfb->framebuffer = NULL;
4284642e01fSmrg
4294642e01fSmrg    DRIScreenInit(pScreen);
4304642e01fSmrg
4314642e01fSmrg    return TRUE;
4324642e01fSmrg}
4334642e01fSmrg
4344642e01fSmrg/*
4354642e01fSmrg * xprSetupScreen
4364642e01fSmrg *  Setup the screen for rootless access.
4374642e01fSmrg */
4384642e01fSmrgstatic Bool
4394642e01fSmrgxprSetupScreen(int index, ScreenPtr pScreen)
4404642e01fSmrg{
4414642e01fSmrg#ifdef DAMAGE
4424642e01fSmrg    // The Damage extension needs to wrap underneath the
4434642e01fSmrg    // generic rootless layer, so do it now.
4444642e01fSmrg    if (!DamageSetup(pScreen))
4454642e01fSmrg        return FALSE;
4464642e01fSmrg#endif
4474642e01fSmrg
4484642e01fSmrg    // Initialize generic rootless code
4494642e01fSmrg    if (!xprInit(pScreen))
4504642e01fSmrg        return FALSE;
4514642e01fSmrg
4524642e01fSmrg    return DRIFinishScreenInit(pScreen);
4534642e01fSmrg}
4544642e01fSmrg
4554642e01fSmrg/*
4564642e01fSmrg * xprUpdateScreen
457c8548ba8Smrg *  Update screen after configuration change.
4584642e01fSmrg */
4594642e01fSmrgstatic void
4604642e01fSmrgxprUpdateScreen(ScreenPtr pScreen)
4614642e01fSmrg{
4624642e01fSmrg    rootlessGlobalOffsetX = darwinMainScreenX;
4634642e01fSmrg    rootlessGlobalOffsetY = darwinMainScreenY;
4644642e01fSmrg
4656747b715Smrg    AppleWMSetScreenOrigin(pScreen->root);
4664642e01fSmrg
4674642e01fSmrg    RootlessRepositionWindows(pScreen);
4684642e01fSmrg    RootlessUpdateScreenPixmap(pScreen);
4694642e01fSmrg}
4704642e01fSmrg
4714642e01fSmrg/*
4724642e01fSmrg * xprInitInput
4734642e01fSmrg *  Finalize xpr specific setup.
4744642e01fSmrg */
4754642e01fSmrgstatic void
4764642e01fSmrgxprInitInput(int argc, char **argv)
4774642e01fSmrg{
4784642e01fSmrg    int i;
4794642e01fSmrg
4804642e01fSmrg    rootlessGlobalOffsetX = darwinMainScreenX;
4814642e01fSmrg    rootlessGlobalOffsetY = darwinMainScreenY;
4824642e01fSmrg
4834642e01fSmrg    for (i = 0; i < screenInfo.numScreens; i++)
4846747b715Smrg        AppleWMSetScreenOrigin(screenInfo.screens[i]->root);
4854642e01fSmrg}
4864642e01fSmrg
4874642e01fSmrg/*
4884642e01fSmrg * Quartz display mode function list.
4894642e01fSmrg */
4904642e01fSmrgstatic QuartzModeProcsRec xprModeProcs = {
4914642e01fSmrg    xprDisplayInit,
4924642e01fSmrg    xprAddScreen,
4934642e01fSmrg    xprSetupScreen,
4944642e01fSmrg    xprInitInput,
4954642e01fSmrg    QuartzInitCursor,
4964642e01fSmrg    QuartzSuspendXCursor,
4974642e01fSmrg    QuartzResumeXCursor,
4984642e01fSmrg    xprAddPseudoramiXScreens,
4994642e01fSmrg    xprUpdateScreen,
5004642e01fSmrg    xprIsX11Window,
5014642e01fSmrg    xprHideWindows,
5024642e01fSmrg    RootlessFrameForWindow,
5034642e01fSmrg    TopLevelParent,
5044642e01fSmrg    DRICreateSurface,
5054642e01fSmrg    DRIDestroySurface
5064642e01fSmrg};
5074642e01fSmrg
5084642e01fSmrg/*
5094642e01fSmrg * QuartzModeBundleInit
5104642e01fSmrg *  Initialize the display mode bundle after loading.
5114642e01fSmrg */
5124642e01fSmrgBool
5134642e01fSmrgQuartzModeBundleInit(void)
5144642e01fSmrg{
5154642e01fSmrg    quartzProcs = &xprModeProcs;
5164642e01fSmrg    quartzOpenGLBundle = xprOpenGLBundle;
5174642e01fSmrg    return TRUE;
5184642e01fSmrg}
519