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