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