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