xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

darwin.c (26001B)


      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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    663 OsVendorFatalError(const char *f, va_list args)
    664 {
    665 }
    666 
    667 /*
    668  * OsVendorInit
    669  *  Initialization of Darwin OS support.
    670  */
    671 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
    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
    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
    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
    832 ddxInputThreadInit(void)
    833 {
    834 }
    835 #endif