xref: /OK3568_Linux_fs/external/xserver/hw/xquartz/xpr/xprScreen.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Xplugin rootless implementation screen functions
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (c) 2002-2012 Apple Computer, Inc. All Rights Reserved.
5*4882a593Smuzhiyun  * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
8*4882a593Smuzhiyun  * copy of this software and associated documentation files (the "Software"),
9*4882a593Smuzhiyun  * to deal in the Software without restriction, including without limitation
10*4882a593Smuzhiyun  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11*4882a593Smuzhiyun  * and/or sell copies of the Software, and to permit persons to whom the
12*4882a593Smuzhiyun  * Software is furnished to do so, subject to the following conditions:
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * The above copyright notice and this permission notice shall be included in
15*4882a593Smuzhiyun  * all copies or substantial portions of the Software.
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*4882a593Smuzhiyun  * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
21*4882a593Smuzhiyun  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22*4882a593Smuzhiyun  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23*4882a593Smuzhiyun  * DEALINGS IN THE SOFTWARE.
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * Except as contained in this notice, the name(s) of the above copyright
26*4882a593Smuzhiyun  * holders shall not be used in advertising or otherwise to promote the sale,
27*4882a593Smuzhiyun  * use or other dealings in this Software without prior written authorization.
28*4882a593Smuzhiyun  */
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #include "sanitizedCarbon.h"
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
33*4882a593Smuzhiyun #include <dix-config.h>
34*4882a593Smuzhiyun #endif
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #include "inputstr.h"
37*4882a593Smuzhiyun #include "quartz.h"
38*4882a593Smuzhiyun #include "quartzRandR.h"
39*4882a593Smuzhiyun #include "xpr.h"
40*4882a593Smuzhiyun #include "xprEvent.h"
41*4882a593Smuzhiyun #include "pseudoramiX.h"
42*4882a593Smuzhiyun #include "darwinEvents.h"
43*4882a593Smuzhiyun #include "rootless.h"
44*4882a593Smuzhiyun #include "dri.h"
45*4882a593Smuzhiyun #include "globals.h"
46*4882a593Smuzhiyun #include <Xplugin.h>
47*4882a593Smuzhiyun #include "applewmExt.h"
48*4882a593Smuzhiyun #include "micmap.h"
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #include "rootlessCommon.h"
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun #ifdef DAMAGE
53*4882a593Smuzhiyun #include "damage.h"
54*4882a593Smuzhiyun #endif
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun #include "nonsdk_extinit.h"
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /* 10.4's deferred update makes X slower.. have to live with the tearing
59*4882a593Smuzhiyun  * for now.. */
60*4882a593Smuzhiyun #define XP_NO_DEFERRED_UPDATES 8
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun // Name of GLX bundle for native OpenGL
63*4882a593Smuzhiyun static const char *xprOpenGLBundle = "glxCGL.bundle";
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun /*
66*4882a593Smuzhiyun  * eventHandler
67*4882a593Smuzhiyun  *  Callback handler for Xplugin events.
68*4882a593Smuzhiyun  */
69*4882a593Smuzhiyun static void
eventHandler(unsigned int type,const void * arg,unsigned int arg_size,void * data)70*4882a593Smuzhiyun eventHandler(unsigned int type, const void *arg,
71*4882a593Smuzhiyun              unsigned int arg_size, void *data)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun     switch (type) {
75*4882a593Smuzhiyun     case XP_EVENT_DISPLAY_CHANGED:
76*4882a593Smuzhiyun         DEBUG_LOG("XP_EVENT_DISPLAY_CHANGED\n");
77*4882a593Smuzhiyun         DarwinSendDDXEvent(kXquartzDisplayChanged, 0);
78*4882a593Smuzhiyun         break;
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun     case XP_EVENT_WINDOW_STATE_CHANGED:
81*4882a593Smuzhiyun         if (arg_size >= sizeof(xp_window_state_event)) {
82*4882a593Smuzhiyun             const xp_window_state_event *ws_arg = arg;
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun             DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: id=%d, state=%d\n",
85*4882a593Smuzhiyun                       ws_arg->id,
86*4882a593Smuzhiyun                       ws_arg->state);
87*4882a593Smuzhiyun             DarwinSendDDXEvent(kXquartzWindowState, 2,
88*4882a593Smuzhiyun                                ws_arg->id, ws_arg->state);
89*4882a593Smuzhiyun         }
90*4882a593Smuzhiyun         else {
91*4882a593Smuzhiyun             DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: ignored\n");
92*4882a593Smuzhiyun         }
93*4882a593Smuzhiyun         break;
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun     case XP_EVENT_WINDOW_MOVED:
96*4882a593Smuzhiyun         DEBUG_LOG("XP_EVENT_WINDOW_MOVED\n");
97*4882a593Smuzhiyun         if (arg_size == sizeof(xp_window_id)) {
98*4882a593Smuzhiyun             xp_window_id id = *(xp_window_id *)arg;
99*4882a593Smuzhiyun             DarwinSendDDXEvent(kXquartzWindowMoved, 1, id);
100*4882a593Smuzhiyun         }
101*4882a593Smuzhiyun         break;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun     case XP_EVENT_SURFACE_DESTROYED:
104*4882a593Smuzhiyun         DEBUG_LOG("XP_EVENT_SURFACE_DESTROYED\n");
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun     case XP_EVENT_SURFACE_CHANGED:
107*4882a593Smuzhiyun         DEBUG_LOG("XP_EVENT_SURFACE_CHANGED\n");
108*4882a593Smuzhiyun         if (arg_size == sizeof(xp_surface_id)) {
109*4882a593Smuzhiyun             int kind;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun             if (type == XP_EVENT_SURFACE_DESTROYED)
112*4882a593Smuzhiyun                 kind = AppleDRISurfaceNotifyDestroyed;
113*4882a593Smuzhiyun             else
114*4882a593Smuzhiyun                 kind = AppleDRISurfaceNotifyChanged;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun             DRISurfaceNotify(*(xp_surface_id *)arg, kind);
117*4882a593Smuzhiyun         }
118*4882a593Smuzhiyun         break;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun #ifdef XP_EVENT_SPACE_CHANGED
121*4882a593Smuzhiyun     case  XP_EVENT_SPACE_CHANGED:
122*4882a593Smuzhiyun         DEBUG_LOG("XP_EVENT_SPACE_CHANGED\n");
123*4882a593Smuzhiyun         if (arg_size == sizeof(uint32_t)) {
124*4882a593Smuzhiyun             uint32_t space_id = *(uint32_t *)arg;
125*4882a593Smuzhiyun             DarwinSendDDXEvent(kXquartzSpaceChanged, 1, space_id);
126*4882a593Smuzhiyun         }
127*4882a593Smuzhiyun         break;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun #endif
130*4882a593Smuzhiyun     default:
131*4882a593Smuzhiyun         ErrorF("Unknown XP_EVENT type (%d) in xprScreen:eventHandler\n", type);
132*4882a593Smuzhiyun     }
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun /*
136*4882a593Smuzhiyun  * displayAtIndex
137*4882a593Smuzhiyun  *  Return the display ID for a particular display index.
138*4882a593Smuzhiyun  */
139*4882a593Smuzhiyun static CGDirectDisplayID
displayAtIndex(int index)140*4882a593Smuzhiyun displayAtIndex(int index)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun     CGError err;
143*4882a593Smuzhiyun     CGDisplayCount cnt;
144*4882a593Smuzhiyun     CGDirectDisplayID dpy[index + 1];
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun     err = CGGetActiveDisplayList(index + 1, dpy, &cnt);
147*4882a593Smuzhiyun     if (err == kCGErrorSuccess && cnt == index + 1)
148*4882a593Smuzhiyun         return dpy[index];
149*4882a593Smuzhiyun     else
150*4882a593Smuzhiyun         return kCGNullDirectDisplay;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun /*
154*4882a593Smuzhiyun  * displayScreenBounds
155*4882a593Smuzhiyun  *  Return the bounds of a particular display.
156*4882a593Smuzhiyun  */
157*4882a593Smuzhiyun static CGRect
displayScreenBounds(CGDirectDisplayID id)158*4882a593Smuzhiyun displayScreenBounds(CGDirectDisplayID id)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun     CGRect frame;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun     frame = CGDisplayBounds(id);
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun     DEBUG_LOG("    %dx%d @ (%d,%d).\n",
165*4882a593Smuzhiyun               (int)frame.size.width, (int)frame.size.height,
166*4882a593Smuzhiyun               (int)frame.origin.x, (int)frame.origin.y);
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun     Boolean spacePerDisplay = false;
169*4882a593Smuzhiyun     Boolean ok;
170*4882a593Smuzhiyun     (void)CFPreferencesAppSynchronize(CFSTR("com.apple.spaces"));
171*4882a593Smuzhiyun     spacePerDisplay = ! CFPreferencesGetAppBooleanValue(CFSTR("spans-displays"),
172*4882a593Smuzhiyun                                                         CFSTR("com.apple.spaces"),
173*4882a593Smuzhiyun                                                         &ok);
174*4882a593Smuzhiyun     if (!ok)
175*4882a593Smuzhiyun         spacePerDisplay = true;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun     /* Remove menubar to help standard X11 window managers.
178*4882a593Smuzhiyun      * On Mavericks and later, the menu bar is on all displays when spans-displays is false or unset.
179*4882a593Smuzhiyun      */
180*4882a593Smuzhiyun     if (XQuartzIsRootless &&
181*4882a593Smuzhiyun         (spacePerDisplay || (frame.origin.x == 0 && frame.origin.y == 0))) {
182*4882a593Smuzhiyun         frame.origin.y += aquaMenuBarHeight;
183*4882a593Smuzhiyun         frame.size.height -= aquaMenuBarHeight;
184*4882a593Smuzhiyun     }
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun     DEBUG_LOG("    %dx%d @ (%d,%d).\n",
187*4882a593Smuzhiyun               (int)frame.size.width, (int)frame.size.height,
188*4882a593Smuzhiyun               (int)frame.origin.x, (int)frame.origin.y);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun     return frame;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun /*
194*4882a593Smuzhiyun  * xprAddPseudoramiXScreens
195*4882a593Smuzhiyun  *  Add a single virtual screen encompassing all the physical screens
196*4882a593Smuzhiyun  *  with PseudoramiX.
197*4882a593Smuzhiyun  */
198*4882a593Smuzhiyun static void
xprAddPseudoramiXScreens(int * x,int * y,int * width,int * height,ScreenPtr pScreen)199*4882a593Smuzhiyun xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height,
200*4882a593Smuzhiyun                          ScreenPtr pScreen)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun     CGDisplayCount i, displayCount;
203*4882a593Smuzhiyun     CGDirectDisplayID *displayList = NULL;
204*4882a593Smuzhiyun     CGRect unionRect = CGRectNull, frame;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun     // Find all the CoreGraphics displays
207*4882a593Smuzhiyun     CGGetActiveDisplayList(0, NULL, &displayCount);
208*4882a593Smuzhiyun     DEBUG_LOG("displayCount: %d\n", (int)displayCount);
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun     if (!displayCount) {
211*4882a593Smuzhiyun         ErrorF(
212*4882a593Smuzhiyun             "CoreGraphics has reported no connected displays.  Creating a stub 800x600 display.\n");
213*4882a593Smuzhiyun         *x = *y = 0;
214*4882a593Smuzhiyun         *width = 800;
215*4882a593Smuzhiyun         *height = 600;
216*4882a593Smuzhiyun         PseudoramiXAddScreen(*x, *y, *width, *height);
217*4882a593Smuzhiyun         QuartzCopyDisplayIDs(pScreen, 0, NULL);
218*4882a593Smuzhiyun         return;
219*4882a593Smuzhiyun     }
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun     /* If the displays are captured, we are in a RandR game mode
222*4882a593Smuzhiyun      * on the primary display, so we only want to include the first
223*4882a593Smuzhiyun      * display.  The others are covered by the shield window.
224*4882a593Smuzhiyun      */
225*4882a593Smuzhiyun     if (CGDisplayIsCaptured(kCGDirectMainDisplay))
226*4882a593Smuzhiyun         displayCount = 1;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun     displayList = malloc(displayCount * sizeof(CGDirectDisplayID));
229*4882a593Smuzhiyun     if (!displayList)
230*4882a593Smuzhiyun         FatalError("Unable to allocate memory for list of displays.\n");
231*4882a593Smuzhiyun     CGGetActiveDisplayList(displayCount, displayList, &displayCount);
232*4882a593Smuzhiyun     QuartzCopyDisplayIDs(pScreen, displayCount, displayList);
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun     /* Get the union of all screens */
235*4882a593Smuzhiyun     for (i = 0; i < displayCount; i++) {
236*4882a593Smuzhiyun         CGDirectDisplayID dpy = displayList[i];
237*4882a593Smuzhiyun         frame = displayScreenBounds(dpy);
238*4882a593Smuzhiyun         unionRect = CGRectUnion(unionRect, frame);
239*4882a593Smuzhiyun     }
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun     /* Use unionRect as the screen size for the X server. */
242*4882a593Smuzhiyun     *x = unionRect.origin.x;
243*4882a593Smuzhiyun     *y = unionRect.origin.y;
244*4882a593Smuzhiyun     *width = unionRect.size.width;
245*4882a593Smuzhiyun     *height = unionRect.size.height;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun     DEBUG_LOG("  screen union origin: (%d,%d) size: (%d,%d).\n",
248*4882a593Smuzhiyun               *x, *y, *width, *height);
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun     /* Tell PseudoramiX about the real screens. */
251*4882a593Smuzhiyun     for (i = 0; i < displayCount; i++) {
252*4882a593Smuzhiyun         CGDirectDisplayID dpy = displayList[i];
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun         frame = displayScreenBounds(dpy);
255*4882a593Smuzhiyun         frame.origin.x -= unionRect.origin.x;
256*4882a593Smuzhiyun         frame.origin.y -= unionRect.origin.y;
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun         DEBUG_LOG("    placed at X11 coordinate (%d,%d).\n",
259*4882a593Smuzhiyun                   (int)frame.origin.x, (int)frame.origin.y);
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun         PseudoramiXAddScreen(frame.origin.x, frame.origin.y,
262*4882a593Smuzhiyun                              frame.size.width, frame.size.height);
263*4882a593Smuzhiyun     }
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun     free(displayList);
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun /*
269*4882a593Smuzhiyun  * xprDisplayInit
270*4882a593Smuzhiyun  *  Find number of CoreGraphics displays and initialize Xplugin.
271*4882a593Smuzhiyun  */
272*4882a593Smuzhiyun static void
xprDisplayInit(void)273*4882a593Smuzhiyun xprDisplayInit(void)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun     CGDisplayCount displayCount;
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun     TRACE();
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun     CGGetActiveDisplayList(0, NULL, &displayCount);
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun     /* With PseudoramiX, the X server only sees one screen; only PseudoramiX
282*4882a593Smuzhiyun        itself knows about all of the screens. */
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun     if (noPseudoramiXExtension)
285*4882a593Smuzhiyun         darwinScreensFound = displayCount;
286*4882a593Smuzhiyun     else
287*4882a593Smuzhiyun         darwinScreensFound = 1;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun     if (xp_init(XP_BACKGROUND_EVENTS | XP_NO_DEFERRED_UPDATES) != Success)
290*4882a593Smuzhiyun         FatalError("Could not initialize the Xplugin library.");
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun     xp_select_events(XP_EVENT_DISPLAY_CHANGED
293*4882a593Smuzhiyun                      | XP_EVENT_WINDOW_STATE_CHANGED
294*4882a593Smuzhiyun                      | XP_EVENT_WINDOW_MOVED
295*4882a593Smuzhiyun #ifdef XP_EVENT_SPACE_CHANGED
296*4882a593Smuzhiyun                      | XP_EVENT_SPACE_CHANGED
297*4882a593Smuzhiyun #endif
298*4882a593Smuzhiyun                      | XP_EVENT_SURFACE_CHANGED
299*4882a593Smuzhiyun                      | XP_EVENT_SURFACE_DESTROYED,
300*4882a593Smuzhiyun                      eventHandler, NULL);
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun     AppleDRIExtensionInit();
303*4882a593Smuzhiyun     xprAppleWMInit();
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun     XQuartzIsRootless = XQuartzRootlessDefault;
306*4882a593Smuzhiyun     if (!XQuartzIsRootless)
307*4882a593Smuzhiyun         RootlessHideAllWindows();
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun /*
311*4882a593Smuzhiyun  * xprAddScreen
312*4882a593Smuzhiyun  *  Init the framebuffer and record pixmap parameters for the screen.
313*4882a593Smuzhiyun  */
314*4882a593Smuzhiyun static Bool
xprAddScreen(int index,ScreenPtr pScreen)315*4882a593Smuzhiyun xprAddScreen(int index, ScreenPtr pScreen)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun     DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
318*4882a593Smuzhiyun     int depth = darwinDesiredDepth;
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun     DEBUG_LOG("index=%d depth=%d\n", index, depth);
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun     if (depth == -1) {
323*4882a593Smuzhiyun         CGDisplayModeRef modeRef;
324*4882a593Smuzhiyun         CFStringRef encStrRef;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun         modeRef = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
327*4882a593Smuzhiyun         if (!modeRef)
328*4882a593Smuzhiyun             goto have_depth;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun         encStrRef = CGDisplayModeCopyPixelEncoding(modeRef);
331*4882a593Smuzhiyun         CFRelease(modeRef);
332*4882a593Smuzhiyun         if (!encStrRef)
333*4882a593Smuzhiyun             goto have_depth;
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun         if (CFStringCompare(encStrRef, CFSTR(IO32BitDirectPixels),
336*4882a593Smuzhiyun                             kCFCompareCaseInsensitive) ==
337*4882a593Smuzhiyun             kCFCompareEqualTo) {
338*4882a593Smuzhiyun             depth = 24;
339*4882a593Smuzhiyun         }
340*4882a593Smuzhiyun         else if (CFStringCompare(encStrRef, CFSTR(IO16BitDirectPixels),
341*4882a593Smuzhiyun                                  kCFCompareCaseInsensitive) ==
342*4882a593Smuzhiyun                  kCFCompareEqualTo) {
343*4882a593Smuzhiyun             depth = 15;
344*4882a593Smuzhiyun         }
345*4882a593Smuzhiyun         else if (CFStringCompare(encStrRef, CFSTR(IO8BitIndexedPixels),
346*4882a593Smuzhiyun                                  kCFCompareCaseInsensitive) ==
347*4882a593Smuzhiyun                  kCFCompareEqualTo) {
348*4882a593Smuzhiyun             depth = 8;
349*4882a593Smuzhiyun         }
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun         CFRelease(encStrRef);
352*4882a593Smuzhiyun     }
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun have_depth:
355*4882a593Smuzhiyun     switch (depth) {
356*4882a593Smuzhiyun     case 8:     // pseudo-working
357*4882a593Smuzhiyun         dfb->visuals = PseudoColorMask;
358*4882a593Smuzhiyun         dfb->preferredCVC = PseudoColor;
359*4882a593Smuzhiyun         dfb->depth = 8;
360*4882a593Smuzhiyun         dfb->bitsPerRGB = 8;
361*4882a593Smuzhiyun         dfb->bitsPerPixel = 8;
362*4882a593Smuzhiyun         dfb->redMask = 0;
363*4882a593Smuzhiyun         dfb->greenMask = 0;
364*4882a593Smuzhiyun         dfb->blueMask = 0;
365*4882a593Smuzhiyun         break;
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun #if 0
368*4882a593Smuzhiyun     // Removed because Mountain Lion removed support for
369*4882a593Smuzhiyun     // 15bit backing stores.  We can possibly re-add
370*4882a593Smuzhiyun     // this once libXplugin is updated to work around it.
371*4882a593Smuzhiyun     case 15:
372*4882a593Smuzhiyun         dfb->visuals = TrueColorMask;     //LARGE_VISUALS;
373*4882a593Smuzhiyun         dfb->preferredCVC = TrueColor;
374*4882a593Smuzhiyun         dfb->depth = 15;
375*4882a593Smuzhiyun         dfb->bitsPerRGB = 5;
376*4882a593Smuzhiyun         dfb->bitsPerPixel = 16;
377*4882a593Smuzhiyun         dfb->redMask = RM_ARGB(0, 5, 5, 5);
378*4882a593Smuzhiyun         dfb->greenMask = GM_ARGB(0, 5, 5, 5);
379*4882a593Smuzhiyun         dfb->blueMask = BM_ARGB(0, 5, 5, 5);
380*4882a593Smuzhiyun         break;
381*4882a593Smuzhiyun #endif
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun     //        case 24:
384*4882a593Smuzhiyun     default:
385*4882a593Smuzhiyun         if (depth != 24)
386*4882a593Smuzhiyun             ErrorF(
387*4882a593Smuzhiyun                 "Unsupported color depth requested.  Defaulting to 24bit. (depth=%d darwinDesiredDepth=%d)\n",
388*4882a593Smuzhiyun                 depth, darwinDesiredDepth);
389*4882a593Smuzhiyun         dfb->visuals = TrueColorMask;     //LARGE_VISUALS;
390*4882a593Smuzhiyun         dfb->preferredCVC = TrueColor;
391*4882a593Smuzhiyun         dfb->depth = 24;
392*4882a593Smuzhiyun         dfb->bitsPerRGB = 8;
393*4882a593Smuzhiyun         dfb->bitsPerPixel = 32;
394*4882a593Smuzhiyun         dfb->redMask = RM_ARGB(0, 8, 8, 8);
395*4882a593Smuzhiyun         dfb->greenMask = GM_ARGB(0, 8, 8, 8);
396*4882a593Smuzhiyun         dfb->blueMask = BM_ARGB(0, 8, 8, 8);
397*4882a593Smuzhiyun         break;
398*4882a593Smuzhiyun     }
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun     if (noPseudoramiXExtension) {
401*4882a593Smuzhiyun         CGDirectDisplayID dpy;
402*4882a593Smuzhiyun         CGRect frame;
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun         ErrorF("Warning: noPseudoramiXExtension!\n");
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun         dpy = displayAtIndex(index);
407*4882a593Smuzhiyun         QuartzCopyDisplayIDs(pScreen, 1, &dpy);
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun         frame = displayScreenBounds(dpy);
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun         dfb->x = frame.origin.x;
412*4882a593Smuzhiyun         dfb->y = frame.origin.y;
413*4882a593Smuzhiyun         dfb->width = frame.size.width;
414*4882a593Smuzhiyun         dfb->height = frame.size.height;
415*4882a593Smuzhiyun     }
416*4882a593Smuzhiyun     else {
417*4882a593Smuzhiyun         xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height,
418*4882a593Smuzhiyun                                  pScreen);
419*4882a593Smuzhiyun     }
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun     /* Passing zero width (pitch) makes miCreateScreenResources set the
422*4882a593Smuzhiyun        screen pixmap to the framebuffer pointer, i.e. NULL. The generic
423*4882a593Smuzhiyun        rootless code takes care of making this work. */
424*4882a593Smuzhiyun     dfb->pitch = 0;
425*4882a593Smuzhiyun     dfb->framebuffer = NULL;
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun     DRIScreenInit(pScreen);
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun     return TRUE;
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun /*
433*4882a593Smuzhiyun  * xprSetupScreen
434*4882a593Smuzhiyun  *  Setup the screen for rootless access.
435*4882a593Smuzhiyun  */
436*4882a593Smuzhiyun static Bool
xprSetupScreen(int index,ScreenPtr pScreen)437*4882a593Smuzhiyun xprSetupScreen(int index, ScreenPtr pScreen)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun #ifdef DAMAGE
440*4882a593Smuzhiyun     // The Damage extension needs to wrap underneath the
441*4882a593Smuzhiyun     // generic rootless layer, so do it now.
442*4882a593Smuzhiyun     if (!DamageSetup(pScreen))
443*4882a593Smuzhiyun         return FALSE;
444*4882a593Smuzhiyun #endif
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun     // Initialize generic rootless code
447*4882a593Smuzhiyun     if (!xprInit(pScreen))
448*4882a593Smuzhiyun         return FALSE;
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun     return DRIFinishScreenInit(pScreen);
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun /*
454*4882a593Smuzhiyun  * xprUpdateScreen
455*4882a593Smuzhiyun  *  Update screen after configuration change.
456*4882a593Smuzhiyun  */
457*4882a593Smuzhiyun static void
xprUpdateScreen(ScreenPtr pScreen)458*4882a593Smuzhiyun xprUpdateScreen(ScreenPtr pScreen)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun     rootlessGlobalOffsetX = darwinMainScreenX;
461*4882a593Smuzhiyun     rootlessGlobalOffsetY = darwinMainScreenY;
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun     AppleWMSetScreenOrigin(pScreen->root);
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun     RootlessRepositionWindows(pScreen);
466*4882a593Smuzhiyun     RootlessUpdateScreenPixmap(pScreen);
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun /*
470*4882a593Smuzhiyun  * xprInitInput
471*4882a593Smuzhiyun  *  Finalize xpr specific setup.
472*4882a593Smuzhiyun  */
473*4882a593Smuzhiyun static void
xprInitInput(int argc,char ** argv)474*4882a593Smuzhiyun xprInitInput(int argc, char **argv)
475*4882a593Smuzhiyun {
476*4882a593Smuzhiyun     int i;
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun     rootlessGlobalOffsetX = darwinMainScreenX;
479*4882a593Smuzhiyun     rootlessGlobalOffsetY = darwinMainScreenY;
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun     for (i = 0; i < screenInfo.numScreens; i++)
482*4882a593Smuzhiyun         AppleWMSetScreenOrigin(screenInfo.screens[i]->root);
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun /*
486*4882a593Smuzhiyun  * Quartz display mode function list.
487*4882a593Smuzhiyun  */
488*4882a593Smuzhiyun static QuartzModeProcsRec xprModeProcs = {
489*4882a593Smuzhiyun     xprDisplayInit,
490*4882a593Smuzhiyun     xprAddScreen,
491*4882a593Smuzhiyun     xprSetupScreen,
492*4882a593Smuzhiyun     xprInitInput,
493*4882a593Smuzhiyun     QuartzInitCursor,
494*4882a593Smuzhiyun     QuartzSuspendXCursor,
495*4882a593Smuzhiyun     QuartzResumeXCursor,
496*4882a593Smuzhiyun     xprAddPseudoramiXScreens,
497*4882a593Smuzhiyun     xprUpdateScreen,
498*4882a593Smuzhiyun     xprIsX11Window,
499*4882a593Smuzhiyun     xprHideWindows,
500*4882a593Smuzhiyun     RootlessFrameForWindow,
501*4882a593Smuzhiyun     TopLevelParent,
502*4882a593Smuzhiyun     DRICreateSurface,
503*4882a593Smuzhiyun     DRIDestroySurface
504*4882a593Smuzhiyun };
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun /*
507*4882a593Smuzhiyun  * QuartzModeBundleInit
508*4882a593Smuzhiyun  *  Initialize the display mode bundle after loading.
509*4882a593Smuzhiyun  */
510*4882a593Smuzhiyun Bool
QuartzModeBundleInit(void)511*4882a593Smuzhiyun QuartzModeBundleInit(void)
512*4882a593Smuzhiyun {
513*4882a593Smuzhiyun     quartzProcs = &xprModeProcs;
514*4882a593Smuzhiyun     quartzOpenGLBundle = xprOpenGLBundle;
515*4882a593Smuzhiyun     return TRUE;
516*4882a593Smuzhiyun }
517