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