xref: /OK3568_Linux_fs/external/xserver/hw/xquartz/darwin.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /**************************************************************
2  *
3  * Xquartz initialization code
4  *
5  * Copyright (c) 2007-2012 Apple Inc.
6  * Copyright (c) 2001-2004 Torrey T. Lyons. All Rights Reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21  * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
22  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  *
26  * Except as contained in this notice, the name(s) of the above copyright
27  * holders shall not be used in advertising or otherwise to promote the sale,
28  * use or other dealings in this Software without prior written authorization.
29  */
30 
31 #ifdef HAVE_DIX_CONFIG_H
32 #include <dix-config.h>
33 #endif
34 
35 #include <X11/X.h>
36 #include <X11/Xproto.h>
37 #include "os.h"
38 #include "servermd.h"
39 #include "inputstr.h"
40 #include "scrnintstr.h"
41 #include "mipointer.h"          // mi software cursor
42 #include "micmap.h"             // mi colormap code
43 #include "fb.h"                 // fb framebuffer code
44 #include "site.h"
45 #include "globals.h"
46 #include "dix.h"
47 #include "xkbsrv.h"
48 
49 #include <X11/extensions/XI.h>
50 #include <X11/extensions/XIproto.h>
51 #include "exevents.h"
52 #include "extinit.h"
53 #include "glx_extinit.h"
54 #include "xserver-properties.h"
55 
56 #include <sys/types.h>
57 #include <sys/time.h>
58 #include <sys/stat.h>
59 #include <sys/syslimits.h>
60 #include <stdio.h>
61 #include <fcntl.h>
62 #include <unistd.h>
63 #include <stdarg.h>
64 
65 #define HAS_UTSNAME 1
66 #include <sys/utsname.h>
67 
68 #define NO_CFPLUGIN
69 #include <IOKit/hidsystem/IOHIDLib.h>
70 
71 #ifdef MITSHM
72 #include "shmint.h"
73 #endif
74 
75 #include "darwin.h"
76 #include "darwinEvents.h"
77 #include "quartzKeyboard.h"
78 #include "quartz.h"
79 
80 #include "X11Application.h"
81 
82 aslclient aslc;
83 
84 void
xq_asl_log(int level,const char * subsystem,const char * file,const char * function,int line,const char * fmt,...)85 xq_asl_log(int level, const char *subsystem, const char *file,
86            const char *function, int line, const char *fmt,
87            ...)
88 {
89     va_list args;
90     aslmsg msg = asl_new(ASL_TYPE_MSG);
91 
92     if (msg) {
93         char *_line;
94 
95         asl_set(msg, "File", file);
96         asl_set(msg, "Function", function);
97         asprintf(&_line, "%d", line);
98         if (_line) {
99             asl_set(msg, "Line", _line);
100             free(_line);
101         }
102         if (subsystem)
103             asl_set(msg, "Subsystem", subsystem);
104     }
105 
106     va_start(args, fmt);
107     asl_vlog(aslc, msg, level, fmt, args);
108     va_end(args);
109 
110     if (msg)
111         asl_free(msg);
112 }
113 
114 /*
115  * X server shared global variables
116  */
117 int darwinScreensFound = 0;
118 DevPrivateKeyRec darwinScreenKeyRec;
119 io_connect_t darwinParamConnect = 0;
120 int darwinEventReadFD = -1;
121 int darwinEventWriteFD = -1;
122 // int                     darwinMouseAccelChange = 1;
123 int darwinFakeButtons = 0;
124 
125 // location of X11's (0,0) point in global screen coordinates
126 int darwinMainScreenX = 0;
127 int darwinMainScreenY = 0;
128 
129 // parameters read from the command line or user preferences
130 int darwinDesiredDepth = -1;
131 int darwinSyncKeymap = FALSE;
132 
133 // modifier masks for faking mouse buttons - ANY of these bits trigger it  (not all)
134 #ifdef NX_DEVICELCMDKEYMASK
135 int darwinFakeMouse2Mask = NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK;
136 int darwinFakeMouse3Mask = NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK;
137 #else
138 int darwinFakeMouse2Mask = NX_ALTERNATEMASK;
139 int darwinFakeMouse3Mask = NX_COMMANDMASK;
140 #endif
141 
142 // Modifier mask for overriding event delivery to appkit (might be useful to set this to rcommand for input menu
143 unsigned int darwinAppKitModMask = 0;            // Any of these bits
144 
145 // Modifier mask for items in the Window menu (0 and -1 cause shortcuts to be disabled)
146 unsigned int windowItemModMask = NX_COMMANDMASK;
147 
148 // devices
149 DeviceIntPtr darwinKeyboard = NULL;
150 DeviceIntPtr darwinPointer = NULL;
151 DeviceIntPtr darwinTabletStylus = NULL;
152 DeviceIntPtr darwinTabletCursor = NULL;
153 DeviceIntPtr darwinTabletEraser = NULL;
154 
155 // Common pixmap formats
156 static PixmapFormatRec formats[] = {
157     { 1,  1,  BITMAP_SCANLINE_PAD    },
158     { 4,  8,  BITMAP_SCANLINE_PAD    },
159     { 8,  8,  BITMAP_SCANLINE_PAD    },
160     { 15, 16, BITMAP_SCANLINE_PAD    },
161     { 16, 16, BITMAP_SCANLINE_PAD    },
162     { 24, 32, BITMAP_SCANLINE_PAD    },
163     { 32, 32, BITMAP_SCANLINE_PAD    }
164 };
165 
166 void
DarwinPrintBanner(void)167 DarwinPrintBanner(void)
168 {
169     ErrorF("Xquartz starting:\n");
170     ErrorF("X.Org X Server %s\n", XSERVER_VERSION);
171     ErrorF("Build Date: %s\n", BUILD_DATE);
172 }
173 
174 /*
175  * DarwinSaveScreen
176  *  X screensaver support. Not implemented.
177  */
178 static Bool
DarwinSaveScreen(ScreenPtr pScreen,int on)179 DarwinSaveScreen(ScreenPtr pScreen, int on)
180 {
181     // FIXME
182     if (on == SCREEN_SAVER_FORCER) {}
183     else if (on == SCREEN_SAVER_ON) {}
184     else {}
185     return TRUE;
186 }
187 
188 /*
189  * DarwinScreenInit
190  *  This is a callback from dix during AddScreen() from InitOutput().
191  *  Initialize the screen and communicate information about it back to dix.
192  */
193 static Bool
DarwinScreenInit(ScreenPtr pScreen,int argc,char ** argv)194 DarwinScreenInit(ScreenPtr pScreen, int argc, char **argv)
195 {
196     int dpi;
197     static int foundIndex = 0;
198     Bool ret;
199     DarwinFramebufferPtr dfb;
200 
201     if (!dixRegisterPrivateKey(&darwinScreenKeyRec, PRIVATE_SCREEN, 0))
202         return FALSE;
203 
204     // reset index of found screens for each server generation
205     if (pScreen->myNum == 0) {
206         foundIndex = 0;
207 
208         // reset the visual list
209         miClearVisualTypes();
210     }
211 
212     // allocate space for private per screen storage
213     dfb = malloc(sizeof(DarwinFramebufferRec));
214 
215     // SCREEN_PRIV(pScreen) = dfb;
216     dixSetPrivate(&pScreen->devPrivates, darwinScreenKey, dfb);
217 
218     // setup hardware/mode specific details
219     ret = QuartzAddScreen(foundIndex, pScreen);
220     foundIndex++;
221     if (!ret)
222         return FALSE;
223 
224     // setup a single visual appropriate for our pixel type
225     if (!miSetVisualTypesAndMasks(dfb->depth, dfb->visuals, dfb->bitsPerRGB,
226                                   dfb->preferredCVC, dfb->redMask,
227                                   dfb->greenMask, dfb->blueMask)) {
228         return FALSE;
229     }
230 
231     // TODO: Make PseudoColor visuals not suck in TrueColor mode
232     // if(dfb->depth > 8)
233     //    miSetVisualTypesAndMasks(8, PseudoColorMask, 8, PseudoColor, 0, 0, 0);
234     //
235     // TODO: Re-add support for 15bit
236     // if (dfb->depth > 15)
237     //    miSetVisualTypesAndMasks(15, TrueColorMask, 5, TrueColor,
238     //                             RM_ARGB(0, 5, 5, 5), GM_ARGB(0, 5, 5,
239     //                                                          5),
240     //                             BM_ARGB(0, 5, 5, 5));
241     if (dfb->depth > 24)
242         miSetVisualTypesAndMasks(24, TrueColorMask, 8, TrueColor,
243                                  RM_ARGB(0, 8, 8, 8), GM_ARGB(0, 8, 8,
244                                                               8),
245                                  BM_ARGB(0, 8, 8, 8));
246 
247     miSetPixmapDepths();
248 
249     // machine independent screen init
250     // setup _Screen structure in pScreen
251     if (monitorResolution)
252         dpi = monitorResolution;
253     else
254         dpi = 96;
255 
256     // initialize fb
257     if (!fbScreenInit(pScreen,
258                       dfb->framebuffer,                  // pointer to screen bitmap
259                       dfb->width, dfb->height,           // screen size in pixels
260                       dpi, dpi,                          // dots per inch
261                       dfb->pitch / (dfb->bitsPerPixel / 8), // pixel width of framebuffer
262                       dfb->bitsPerPixel)) {              // bits per pixel for screen
263         return FALSE;
264     }
265 
266     if (!fbPictureInit(pScreen, 0, 0)) {
267         return FALSE;
268     }
269 
270 #ifdef MITSHM
271     ShmRegisterFbFuncs(pScreen);
272 #endif
273 
274     // this must be initialized (why doesn't X have a default?)
275     pScreen->SaveScreen = DarwinSaveScreen;
276 
277     // finish mode dependent screen setup including cursor support
278     if (!QuartzSetupScreen(pScreen->myNum, pScreen)) {
279         return FALSE;
280     }
281 
282     // create and install the default colormap and
283     // set pScreen->blackPixel / pScreen->white
284     if (!miCreateDefColormap(pScreen)) {
285         return FALSE;
286     }
287 
288     pScreen->x = dfb->x;
289     pScreen->y = dfb->y;
290 
291     /*    ErrorF("Screen %d added: %dx%d @ (%d,%d)\n",
292        index, dfb->width, dfb->height, dfb->x, dfb->y); */
293 
294     return TRUE;
295 }
296 
297 /*
298    =============================================================================
299 
300    mouse and keyboard callbacks
301 
302    =============================================================================
303  */
304 
305 static void
DarwinInputHandlerNotify(int fd __unused,int ready __unused,void * data __unused)306 DarwinInputHandlerNotify(int fd __unused, int ready __unused, void *data __unused)
307 {
308 }
309 
310 /*
311  * DarwinMouseProc: Handle the initialization, etc. of a mouse
312  */
313 static int
DarwinMouseProc(DeviceIntPtr pPointer,int what)314 DarwinMouseProc(DeviceIntPtr pPointer, int what)
315 {
316 #define NBUTTONS 3
317 #define NAXES    6
318     // 3 buttons: left, middle, right
319     CARD8 map[NBUTTONS + 1] = { 0, 1, 2, 3};
320     Atom btn_labels[NBUTTONS] = { 0 };
321     Atom axes_labels[NAXES] = { 0 };
322 
323     switch (what) {
324     case DEVICE_INIT:
325         pPointer->public.on = FALSE;
326 
327         btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
328         btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
329         btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
330 
331         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
332         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
333         axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
334         axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
335         axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL);
336         axes_labels[5] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL);
337 
338         // Set button map.
339         InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS,
340                                 btn_labels,
341                                 (PtrCtrlProcPtr)NoopDDA,
342                                 GetMotionHistorySize(), NAXES,
343                                 axes_labels);
344         InitValuatorAxisStruct(pPointer, 0, axes_labels[0],
345                                NO_AXIS_LIMITS, NO_AXIS_LIMITS,
346                                0, 0, 0, Absolute);
347         InitValuatorAxisStruct(pPointer, 1, axes_labels[1],
348                                NO_AXIS_LIMITS, NO_AXIS_LIMITS,
349                                0, 0, 0, Absolute);
350         InitValuatorAxisStruct(pPointer, 2, axes_labels[2],
351                                NO_AXIS_LIMITS, NO_AXIS_LIMITS,
352                                1, 0, 1, Relative);
353         InitValuatorAxisStruct(pPointer, 3, axes_labels[3],
354                                NO_AXIS_LIMITS, NO_AXIS_LIMITS,
355                                1, 0, 1, Relative);
356         InitValuatorAxisStruct(pPointer, 4, axes_labels[4],
357                                NO_AXIS_LIMITS, NO_AXIS_LIMITS,
358                                1, 0, 1, Relative);
359         InitValuatorAxisStruct(pPointer, 5, axes_labels[5],
360                                NO_AXIS_LIMITS, NO_AXIS_LIMITS,
361                                1, 0, 1, Relative);
362 
363         SetScrollValuator(pPointer, 4, SCROLL_TYPE_VERTICAL, -1.0, SCROLL_FLAG_PREFERRED);
364         SetScrollValuator(pPointer, 5, SCROLL_TYPE_HORIZONTAL, -1.0, SCROLL_FLAG_NONE);
365         break;
366 
367     case DEVICE_ON:
368         pPointer->public.on = TRUE;
369         SetNotifyFd(darwinEventReadFD, DarwinInputHandlerNotify, X_NOTIFY_READ, NULL);
370         return Success;
371 
372     case DEVICE_CLOSE:
373     case DEVICE_OFF:
374         pPointer->public.on = FALSE;
375         RemoveNotifyFd(darwinEventReadFD);
376         return Success;
377     }
378 
379     return Success;
380 #undef NBUTTONS
381 #undef NAXES
382 }
383 
384 static int
DarwinTabletProc(DeviceIntPtr pPointer,int what)385 DarwinTabletProc(DeviceIntPtr pPointer, int what)
386 {
387 #define NBUTTONS 3
388 #define NAXES    5
389     CARD8 map[NBUTTONS + 1] = { 0, 1, 2, 3 };
390     Atom btn_labels[NBUTTONS] = { 0 };
391     Atom axes_labels[NAXES] = { 0 };
392 
393     switch (what) {
394     case DEVICE_INIT:
395         pPointer->public.on = FALSE;
396 
397         btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
398         btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
399         btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
400 
401         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
402         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
403         axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
404         axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X);
405         axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y);
406 
407         // Set button map.
408         InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS,
409                                 btn_labels,
410                                 (PtrCtrlProcPtr)NoopDDA,
411                                 GetMotionHistorySize(), NAXES,
412                                 axes_labels);
413         InitProximityClassDeviceStruct(pPointer);
414 
415         InitValuatorAxisStruct(pPointer, 0, axes_labels[0],
416                                0, XQUARTZ_VALUATOR_LIMIT,
417                                1, 0, 1, Absolute);
418         InitValuatorAxisStruct(pPointer, 1, axes_labels[1],
419                                0, XQUARTZ_VALUATOR_LIMIT,
420                                1, 0, 1, Absolute);
421         InitValuatorAxisStruct(pPointer, 2, axes_labels[2],
422                                0, XQUARTZ_VALUATOR_LIMIT,
423                                1, 0, 1, Absolute);
424         InitValuatorAxisStruct(pPointer, 3, axes_labels[3],
425                                -XQUARTZ_VALUATOR_LIMIT,
426                                XQUARTZ_VALUATOR_LIMIT,
427                                1, 0, 1, Absolute);
428         InitValuatorAxisStruct(pPointer, 4, axes_labels[4],
429                                -XQUARTZ_VALUATOR_LIMIT,
430                                XQUARTZ_VALUATOR_LIMIT,
431                                1, 0, 1, Absolute);
432 
433         //          pPointer->use = IsXExtensionDevice;
434         break;
435 
436     case DEVICE_ON:
437         pPointer->public.on = TRUE;
438         SetNotifyFd(darwinEventReadFD, DarwinInputHandlerNotify, X_NOTIFY_READ, NULL);
439         return Success;
440 
441     case DEVICE_CLOSE:
442     case DEVICE_OFF:
443         pPointer->public.on = FALSE;
444         RemoveNotifyFd(darwinEventReadFD);
445         return Success;
446     }
447     return Success;
448 #undef NBUTTONS
449 #undef NAXES
450 }
451 
452 /*
453  * DarwinKeybdProc
454  *  Callback from X
455  */
456 static int
DarwinKeybdProc(DeviceIntPtr pDev,int onoff)457 DarwinKeybdProc(DeviceIntPtr pDev, int onoff)
458 {
459     switch (onoff) {
460     case DEVICE_INIT:
461         DarwinKeyboardInit(pDev);
462         break;
463 
464     case DEVICE_ON:
465         pDev->public.on = TRUE;
466         SetNotifyFd(darwinEventReadFD, DarwinInputHandlerNotify, X_NOTIFY_READ, NULL);
467         break;
468 
469     case DEVICE_OFF:
470         pDev->public.on = FALSE;
471         RemoveNotifyFd(darwinEventReadFD);
472         break;
473 
474     case DEVICE_CLOSE:
475         break;
476     }
477 
478     return Success;
479 }
480 
481 /*
482    ===========================================================================
483 
484    Utility routines
485 
486    ===========================================================================
487  */
488 
489 /*
490  * DarwinParseModifierList
491  *  Parse a list of modifier names and return a corresponding modifier mask
492  */
493 int
DarwinParseModifierList(const char * constmodifiers,int separatelr)494 DarwinParseModifierList(const char *constmodifiers, int separatelr)
495 {
496     int result = 0;
497 
498     if (constmodifiers) {
499         char *modifiers = strdup(constmodifiers);
500         char *modifier;
501         int nxkey;
502         char *p = modifiers;
503 
504         while (p) {
505             modifier = strsep(&p, " ,+&|/"); // allow lots of separators
506             nxkey = DarwinModifierStringToNXMask(modifier, separatelr);
507             if (nxkey)
508                 result |= nxkey;
509             else
510                 ErrorF("fakebuttons: Unknown modifier \"%s\"\n", modifier);
511         }
512         free(modifiers);
513     }
514     return result;
515 }
516 
517 /*
518    ===========================================================================
519 
520    Functions needed to link against device independent X
521 
522    ===========================================================================
523  */
524 
525 /*
526  * InitInput
527  *  Register the keyboard and mouse devices
528  */
529 void
InitInput(int argc,char ** argv)530 InitInput(int argc, char **argv)
531 {
532     XkbRMLVOSet rmlvo = {
533         .rules   = "base", .model         = "empty", .layout = "empty",
534         .variant = NULL,   .options       = NULL
535     };
536 
537     /* We need to really have rules... or something... */
538     XkbSetRulesDflts(&rmlvo);
539 
540     assert(Success == AllocDevicePair(serverClient, "xquartz virtual",
541                                       &darwinPointer, &darwinKeyboard,
542                                       DarwinMouseProc, DarwinKeybdProc, FALSE));
543 
544     /* here's the snippet from the current gdk sources:
545        if (!strcmp (tmp_name, "pointer"))
546        gdkdev->info.source = GDK_SOURCE_MOUSE;
547        else if (!strcmp (tmp_name, "wacom") ||
548        !strcmp (tmp_name, "pen"))
549        gdkdev->info.source = GDK_SOURCE_PEN;
550        else if (!strcmp (tmp_name, "eraser"))
551        gdkdev->info.source = GDK_SOURCE_ERASER;
552        else if (!strcmp (tmp_name, "cursor"))
553        gdkdev->info.source = GDK_SOURCE_CURSOR;
554        else
555        gdkdev->info.source = GDK_SOURCE_PEN;
556      */
557 
558     darwinTabletStylus = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
559     assert(darwinTabletStylus);
560     darwinTabletStylus->name = strdup("pen");
561 
562     darwinTabletCursor = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
563     assert(darwinTabletCursor);
564     darwinTabletCursor->name = strdup("cursor");
565 
566     darwinTabletEraser = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
567     assert(darwinTabletEraser);
568     darwinTabletEraser->name = strdup("eraser");
569 
570     DarwinEQInit();
571 
572     QuartzInitInput(argc, argv);
573 }
574 
575 void
CloseInput(void)576 CloseInput(void)
577 {
578     DarwinEQFini();
579 }
580 
581 /*
582  * DarwinAdjustScreenOrigins
583  *  Shift all screens so the X11 (0, 0) coordinate is at the top
584  *  left of the global screen coordinates.
585  *
586  *  Screens can be arranged so the top left isn't on any screen, so
587  *  instead use the top left of the leftmost screen as (0,0). This
588  *  may mean some screen space is in -y, but it's better that (0,0)
589  *  be onscreen, or else default xterms disappear. It's better that
590  *  -y be used than -x, because when popup menus are forced
591  *  "onscreen" by dumb window managers like twm, they'll shift the
592  *  menus down instead of left, which still looks funny but is an
593  *  easier target to hit.
594  */
595 void
DarwinAdjustScreenOrigins(ScreenInfo * pScreenInfo)596 DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo)
597 {
598     int i, left, top;
599 
600     left = pScreenInfo->screens[0]->x;
601     top = pScreenInfo->screens[0]->y;
602 
603     /* Find leftmost screen. If there's a tie, take the topmost of the two. */
604     for (i = 1; i < pScreenInfo->numScreens; i++) {
605         if (pScreenInfo->screens[i]->x < left ||
606             (pScreenInfo->screens[i]->x == left &&
607              pScreenInfo->screens[i]->y < top)) {
608             left = pScreenInfo->screens[i]->x;
609             top = pScreenInfo->screens[i]->y;
610         }
611     }
612 
613     darwinMainScreenX = left;
614     darwinMainScreenY = top;
615 
616     DEBUG_LOG("top = %d, left=%d\n", top, left);
617 
618     /* Shift all screens so that there is a screen whose top left
619      * is at X11 (0,0) and at global screen coordinate
620      * (darwinMainScreenX, darwinMainScreenY).
621      */
622 
623     if (darwinMainScreenX != 0 || darwinMainScreenY != 0) {
624         for (i = 0; i < pScreenInfo->numScreens; i++) {
625             pScreenInfo->screens[i]->x -= darwinMainScreenX;
626             pScreenInfo->screens[i]->y -= darwinMainScreenY;
627             DEBUG_LOG("Screen %d placed at X11 coordinate (%d,%d).\n",
628                       i, pScreenInfo->screens[i]->x,
629                       pScreenInfo->screens[i]->y);
630         }
631     }
632 
633     /* Update screenInfo.x/y */
634     update_desktop_dimensions();
635 }
636 
637 /*
638  * InitOutput
639  *  Initialize screenInfo for all actually accessible framebuffers.
640  *
641  *  The display mode dependent code gets called three times. The mode
642  *  specific InitOutput routines are expected to discover the number
643  *  of potentially useful screens and cache routes to them internally.
644  *  Inside DarwinScreenInit are two other mode specific calls.
645  *  A mode specific AddScreen routine is called for each screen to
646  *  actually initialize the screen with the ScreenPtr structure.
647  *  After other screen setup has been done, a mode specific
648  *  SetupScreen function can be called to finalize screen setup.
649  */
650 void
InitOutput(ScreenInfo * pScreenInfo,int argc,char ** argv)651 InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
652 {
653     int i;
654 
655     pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
656     pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
657     pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
658     pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
659 
660     // List how we want common pixmap formats to be padded
661     pScreenInfo->numPixmapFormats = ARRAY_SIZE(formats);
662     for (i = 0; i < ARRAY_SIZE(formats); i++)
663         pScreenInfo->formats[i] = formats[i];
664 
665     // Discover screens and do mode specific initialization
666     QuartzInitOutput(argc, argv);
667 
668     // Add screens
669     for (i = 0; i < darwinScreensFound; i++) {
670         AddScreen(DarwinScreenInit, argc, argv);
671     }
672 
673     xorgGlxCreateVendor();
674 
675     DarwinAdjustScreenOrigins(pScreenInfo);
676 }
677 
678 /*
679  * OsVendorFatalError
680  */
681 void
OsVendorFatalError(const char * f,va_list args)682 OsVendorFatalError(const char *f, va_list args)
683 {
684 }
685 
686 /*
687  * OsVendorInit
688  *  Initialization of Darwin OS support.
689  */
690 void
OsVendorInit(void)691 OsVendorInit(void)
692 {
693     if (serverGeneration == 1) {
694         char *lf;
695         char *home = getenv("HOME");
696         assert(home);
697         assert(0 < asprintf(&lf, "%s/Library/Logs/X11", home));
698 
699         /* Ignore errors.  If EEXIST, we don't care.  If anything else,
700          * LogInit will handle it for us.
701          */
702         (void)mkdir(lf, S_IRWXU | S_IRWXG | S_IRWXO);
703         free(lf);
704 
705         assert(0 <
706                asprintf(&lf, "%s/Library/Logs/X11/%s.log", home,
707                         bundle_id_prefix));
708         LogInit(lf, ".old");
709         free(lf);
710 
711         DarwinPrintBanner();
712     }
713 }
714 
715 /*
716  * ddxProcessArgument
717  *  Process device-dependent command line args. Returns 0 if argument is
718  *  not device dependent, otherwise Count of number of elements of argv
719  *  that are part of a device dependent commandline option.
720  */
721 int
ddxProcessArgument(int argc,char * argv[],int i)722 ddxProcessArgument(int argc, char *argv[], int i)
723 {
724     //    if ( !strcmp( argv[i], "-fullscreen" ) ) {
725     //        ErrorF( "Running full screen in parallel with Mac OS X Quartz window server.\n" );
726     //        return 1;
727     //    }
728 
729     //    if ( !strcmp( argv[i], "-rootless" ) ) {
730     //        ErrorF( "Running rootless inside Mac OS X window server.\n" );
731     //        return 1;
732     //    }
733 
734     // This command line arg is passed when launched from the Aqua GUI.
735     if (!strncmp(argv[i], "-psn_", 5)) {
736         return 1;
737     }
738 
739     if (!strcmp(argv[i], "-fakebuttons")) {
740         darwinFakeButtons = TRUE;
741         ErrorF("Faking a three button mouse\n");
742         return 1;
743     }
744 
745     if (!strcmp(argv[i], "-nofakebuttons")) {
746         darwinFakeButtons = FALSE;
747         ErrorF("Not faking a three button mouse\n");
748         return 1;
749     }
750 
751     if (!strcmp(argv[i], "-fakemouse2")) {
752         if (i == argc - 1) {
753             FatalError("-fakemouse2 must be followed by a modifier list\n");
754         }
755         if (!strcasecmp(argv[i + 1], "none") || !strcmp(argv[i + 1], ""))
756             darwinFakeMouse2Mask = 0;
757         else
758             darwinFakeMouse2Mask = DarwinParseModifierList(argv[i + 1], 1);
759         ErrorF("Modifier mask to fake mouse button 2 = 0x%x\n",
760                darwinFakeMouse2Mask);
761         return 2;
762     }
763 
764     if (!strcmp(argv[i], "-fakemouse3")) {
765         if (i == argc - 1) {
766             FatalError("-fakemouse3 must be followed by a modifier list\n");
767         }
768         if (!strcasecmp(argv[i + 1], "none") || !strcmp(argv[i + 1], ""))
769             darwinFakeMouse3Mask = 0;
770         else
771             darwinFakeMouse3Mask = DarwinParseModifierList(argv[i + 1], 1);
772         ErrorF("Modifier mask to fake mouse button 3 = 0x%x\n",
773                darwinFakeMouse3Mask);
774         return 2;
775     }
776 
777     if (!strcmp(argv[i], "+synckeymap")) {
778         darwinSyncKeymap = TRUE;
779         return 1;
780     }
781 
782     if (!strcmp(argv[i], "-synckeymap")) {
783         darwinSyncKeymap = FALSE;
784         return 1;
785     }
786 
787     if (!strcmp(argv[i], "-depth")) {
788         if (i == argc - 1) {
789             FatalError("-depth must be followed by a number\n");
790         }
791         darwinDesiredDepth = atoi(argv[i + 1]);
792         if (darwinDesiredDepth != -1 &&
793             darwinDesiredDepth != 8 &&
794             darwinDesiredDepth != 15 &&
795             darwinDesiredDepth != 24) {
796             FatalError("Unsupported pixel depth. Use 8, 15, or 24 bits\n");
797         }
798 
799         ErrorF("Attempting to use pixel depth of %i\n", darwinDesiredDepth);
800         return 2;
801     }
802 
803     if (!strcmp(argv[i], "-showconfig") || !strcmp(argv[i], "-version")) {
804         DarwinPrintBanner();
805         exit(0);
806     }
807 
808     return 0;
809 }
810 
811 /*
812  * ddxUseMsg --
813  *  Print out correct use of device dependent commandline options.
814  *  Maybe the user now knows what really to do ...
815  */
816 void
ddxUseMsg(void)817 ddxUseMsg(void)
818 {
819     ErrorF("\n");
820     ErrorF("\n");
821     ErrorF("Device Dependent Usage:\n");
822     ErrorF("\n");
823     ErrorF("-depth <8,15,24> : use this bit depth.\n");
824     ErrorF(
825         "-fakebuttons : fake a three button mouse with Command and Option keys.\n");
826     ErrorF("-nofakebuttons : don't fake a three button mouse.\n");
827     ErrorF(
828         "-fakemouse2 <modifiers> : fake middle mouse button with modifier keys.\n");
829     ErrorF(
830         "-fakemouse3 <modifiers> : fake right mouse button with modifier keys.\n");
831     ErrorF(
832         "  ex: -fakemouse2 \"option,shift\" = option-shift-click is middle button.\n");
833     ErrorF("-version : show the server version.\n");
834     ErrorF("\n");
835 }
836 
837 /*
838  * ddxGiveUp --
839  *      Device dependent cleanup. Called by dix before normal server death.
840  */
841 void
ddxGiveUp(enum ExitCode error)842 ddxGiveUp(enum ExitCode error)
843 {
844     LogClose(error);
845 }
846 
847 /*
848  * AbortDDX --
849  *      DDX - specific abort routine.  Called by AbortServer(). The attempt is
850  *      made to restore all original setting of the displays. Also all devices
851  *      are closed.
852  */
853 _X_NORETURN
854 void
AbortDDX(enum ExitCode error)855 AbortDDX(enum ExitCode error)
856 {
857     ErrorF("   AbortDDX\n");
858     OsAbort();
859 }
860 
861 #if INPUTTHREAD
862 /** This function is called in Xserver/os/inputthread.c when starting
863     the input thread. */
864 void
ddxInputThreadInit(void)865 ddxInputThreadInit(void)
866 {
867 }
868 #endif
869