1 /**************************************************************
3 * Shared code for the Darwin X Server
4 * running with Quartz or the IOKit
6 **************************************************************/
8 * Copyright (c) 2001-2002 Torrey T. Lyons. All Rights Reserved.
9 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
25 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
29 * Except as contained in this notice, the name(s) of the above copyright
30 * holders shall not be used in advertising or otherwise to promote the sale,
31 * use or other dealings in this Software without prior written authorization.
33 /* $XFree86: xc/programs/Xserver/hw/darwin/darwin.c,v 1.45 2002/03/28 02:21:08 torrey Exp $ */
35 #include <CoreGraphics/CoreGraphics.h>
42 #include "scrnintstr.h"
43 #include "mibstore.h" // mi backing store implementation
44 #include "mipointer.h" // mi software cursor
45 #include "micmap.h" // mi colormap code
46 #include "fb.h" // fb framebuffer code
49 #include "xf86Version.h"
51 #include "dri-surface.h"
52 #define _APPLEDRI_SERVER_
53 #include "appledristr.h"
55 #include <sys/types.h>
57 #include <sys/syslimits.h>
64 #include <IOKit/IOKitLib.h>
65 #include <IOKit/hidsystem/IOHIDLib.h>
66 #include <IOKit/hidsystem/ev_keymap.h>
70 #include "rootless-common.h"
71 #include "pseudoramiX.h"
72 #include "X11Application.h"
74 /* Fake button press/release for scroll wheel move. */
75 #define SCROLLWHEELUPFAKE 4
76 #define SCROLLWHEELDOWNFAKE 5
78 /* X server shared global variables */
79 int darwinScreensFound = 0;
80 int darwinScreenIndex = 0;
81 int darwinFakeButtons = 1;
82 Bool darwinSwapAltMeta = FALSE;
84 /* location of X11's (0,0) point in global screen coordinates */
85 int darwinMainScreenX = 0;
86 int darwinMainScreenY = 0;
88 /* parameters read from the command line or user preferences */
89 char *darwinKeymapFile;
90 Bool darwinSyncKeymap = TRUE;
92 /* modifier masks for faking mouse buttons */
93 static int darwinFakeMouse2Mask = Mod1Mask; /* option */
94 static int darwinFakeMouse3Mask = Mod2Mask; /* command */
96 static DeviceIntPtr darwinPointer;
97 static DeviceIntPtr darwinKeyboard;
99 /* Track our view of the keyboard state. Everything we sent to dix will
100 be represented here until released. */
101 static CARD8 keysDown[DOWN_LENGTH];
104 #define SetBit(ptr,bit) \
105 do {((BYTE *) ptr)[(bit) >> 3] |= (1 << ((bit) & 7));} while (0)
107 #define ClearBit(ptr,bit) \
108 do {((BYTE *) ptr)[(bit) >> 3] &= ~(1 << ((bit) & 7));} while (0)
110 /* Common pixmap formats */
111 static PixmapFormatRec formats[] = {
112 { 1, 1, BITMAP_SCANLINE_PAD },
113 { 4, 8, BITMAP_SCANLINE_PAD },
114 { 8, 8, BITMAP_SCANLINE_PAD },
115 { 15, 16, BITMAP_SCANLINE_PAD },
116 { 16, 16, BITMAP_SCANLINE_PAD },
117 { 24, 32, BITMAP_SCANLINE_PAD },
118 { 32, 32, BITMAP_SCANLINE_PAD }
120 const int NUMFORMATS = sizeof(formats)/sizeof(formats[0]);
123 #define OSNAME " Mac OS X"
126 #define OSVENDOR " Apple"
129 #define PRE_RELEASE XF86_VERSION_SNAP
132 extern void AppleDRIExtensionInit(void);
133 extern void AppleWMExtensionInit(void);
136 DarwinPrintBanner (void)
138 ErrorF("\nXFree86 Version %d.%d.%d", XF86_VERSION_MAJOR, XF86_VERSION_MINOR,
140 #if XF86_VERSION_SNAP > 0
141 ErrorF(".%d", XF86_VERSION_SNAP);
144 #if XF86_VERSION_SNAP >= 900
145 ErrorF(" (%d.%d.0 RC %d)", XF86_VERSION_MAJOR, XF86_VERSION_MINOR + 1,
146 XF86_VERSION_SNAP - 900);
149 #ifdef XF86_CUSTOM_VERSION
150 ErrorF(" (%s)", XF86_CUSTOM_VERSION);
152 ErrorF(" / X Window System\n");
153 ErrorF("(protocol Version %d, revision %d, vendor release %d)\n",
154 X_PROTOCOL, X_PROTOCOL_REVISION, VENDOR_RELEASE );
157 /* X screensaver support. Not implemented. */
159 DarwinSaveScreen (ScreenPtr pScreen, int on)
164 /* This is a callback from dix during AddScreen() from InitOutput().
165 Initialize the screen and communicate information about it back to dix. */
167 DarwinAddScreen (int index, ScreenPtr pScreen, int argc, char **argv)
170 static int foundIndex = 0;
173 DarwinFramebufferPtr dfb;
175 /* reset index of found screens for each server generation */
179 /* allocate space for private per screen storage */
180 dfb = xalloc (sizeof (DarwinFramebufferRec));
181 SCREEN_PRIV(pScreen) = dfb;
183 /* setup hardware/mode specific details */
184 ret = QuartzAddScreen (foundIndex, pScreen);
189 /* reset the visual list */
190 miClearVisualTypes();
192 /* setup a single visual appropriate for our pixel type. Note: we use
193 TrueColor, not DirectColor */
194 if (dfb->componentCount != 1)
196 if (!miSetVisualTypes (dfb->colorBitsPerPixel, TrueColorMask,
197 dfb->bitsPerComponent, TrueColor))
199 #ifdef ENABLE_PSEUDOCOLOR
200 /* FIXME: currently we can't handle pseudocolor windows
201 inside truecolor top-level windows, so disable this. */
202 if (!miSetVisualTypes (8, PseudoColorMask, 8, PseudoColor))
208 if (!miSetVisualTypes (8, PseudoColorMask, 8, PseudoColor))
212 /* create the common 8 bit PseudoColor visual; do this last to prevent
213 it becoming the root visual. */
217 /* Machine independent screen init */
218 if (monitorResolution)
219 dpi = monitorResolution;
224 if (!fbScreenInit (pScreen, dfb->framebuffer, dfb->width,
225 dfb->height, dpi, dpi,
226 dfb->pitch/(dfb->bitsPerPixel/8), dfb->bitsPerPixel))
231 /* set the RGB order correctly for TrueColor */
232 if (dfb->bitsPerPixel > 8)
234 int bitsPerRGB = dfb->bitsPerComponent;
236 for (i = 0, visual = pScreen->visuals;
237 i < pScreen->numVisuals; i++, visual++)
239 if (visual->class == TrueColor) {
240 visual->offsetRed = bitsPerRGB * 2;
241 visual->offsetGreen = bitsPerRGB;
242 visual->offsetBlue = 0;
243 visual->redMask = ((1<<bitsPerRGB)-1) << visual->offsetRed;
244 visual->greenMask = ((1<<bitsPerRGB)-1) << visual->offsetGreen;
245 visual->blueMask = ((1<<bitsPerRGB)-1) << visual->offsetBlue;
251 if (! fbPictureInit (pScreen, 0, 0))
256 ShmRegisterFbFuncs (pScreen);
259 /* this must be initialized (why doesn't X have a default?) */
260 pScreen->SaveScreen = DarwinSaveScreen;
262 /* finish mode dependent screen setup including cursor support */
263 if (!QuartzSetupScreen (index, pScreen))
266 /* create and install the default colormap and set black / white pixels */
267 if (!miCreateDefColormap (pScreen))
270 dixScreenOrigins[index].x = dfb->x;
271 dixScreenOrigins[index].y = dfb->y;
273 ErrorF("Screen %d added: %dx%d @ (%d,%d)\n",
274 index, dfb->width, dfb->height, dfb->x, dfb->y);
279 /* Search for a file in the standard Library paths, which are (in order):
281 ~/Library/ user specific
282 /Library/ host specific
283 /Network/Library/ LAN specific
284 /System/Library/ OS specific
286 A sub-path can be specified to search in below the various Library
287 directories. Returns a new character string (owned by the caller)
288 containing the full path to the first file found. */
290 /* Library search paths */
291 static const char *libraryPathList[] = {
299 DarwinFindLibraryFile (const char *file, const char *pathext)
305 // Return the file name as is if it is already a fully qualified path.
306 if (!access(file, F_OK)) {
307 fullPath = xalloc(strlen(file)+1);
308 strcpy(fullPath, file);
312 fullPath = xalloc(PATH_MAX);
314 home = getenv("HOME");
316 snprintf(fullPath, PATH_MAX, "%s/Library/%s/%s", home, pathext, file);
317 if (!access(fullPath, F_OK))
321 while (libraryPathList[i]) {
322 snprintf(fullPath, PATH_MAX, "%s/Library/%s/%s", libraryPathList[i++],
324 if (!access(fullPath, F_OK))
332 /* Press or release the given key, specified by NX keycode. xe must already
333 have event time and mouse location filled in. pressed is KeyPress or
334 KeyRelease. keycode is NX keycode without MIN_KEYCODE adjustment. */
336 DarwinPressKeycode (xEvent *xe, int pressed, int keycode)
338 if (pressed == KeyRelease && !BitIsOn (keysDown, keycode + MIN_KEYCODE))
340 /* Don't release keys that aren't pressed. It generates extra
341 KeyPress events instead of just discarding them. */
346 if (pressed == KeyPress)
347 SetBit (keysDown, keycode + MIN_KEYCODE);
349 ClearBit (keysDown, keycode + MIN_KEYCODE);
351 xe->u.u.type = pressed;
352 xe->u.u.detail = keycode + MIN_KEYCODE;
353 (darwinKeyboard->public.processInputProc) (xe, darwinKeyboard, 1);
356 /* Ensure that X's idea of what modifiers are down matches the real
357 window server's. Do this by looking at what keys we previously sent
358 X and deciding if they need to be released/toggled yet to make FLAGS
359 become X's current modifier state. */
361 DarwinUpdateModifiers (xEvent xe, unsigned int flags)
363 static const struct {int mask; int nxkey;} pairs[] = {
364 {ShiftMask, NX_MODIFIERKEY_SHIFT},
365 {ControlMask, NX_MODIFIERKEY_CONTROL},
366 {Mod1Mask, NX_MODIFIERKEY_ALTERNATE},
367 {Mod2Mask, NX_MODIFIERKEY_COMMAND},
368 {Mod3Mask, NX_MODIFIERKEY_SECONDARYFN}
373 for (i = 0; i < (int) (sizeof (pairs) / sizeof (pairs[0])); i++)
375 keycode = DarwinModifierNXKeyToNXKeycode (pairs[i].nxkey, 0);
380 /* For each known modifier, sync up the state of the key X thinks
381 it's bound to and the real value of the flag. */
383 if ((flags & pairs[i].mask)
384 && !BitIsOn (keysDown, keycode + MIN_KEYCODE))
386 DarwinPressKeycode (&xe, KeyPress, keycode);
388 else if (!(flags & pairs[i].mask)
389 && BitIsOn (keysDown, keycode + MIN_KEYCODE))
391 DarwinPressKeycode (&xe, KeyRelease, keycode);
395 /* Do the same for Lock, but need both press and release to toggle it. */
397 if ((flags ^ lockMods) & LockMask)
399 keycode = DarwinModifierNXKeyToNXKeycode (NX_MODIFIERKEY_ALPHALOCK, 0);
403 DarwinPressKeycode (&xe, KeyPress, keycode);
404 DarwinPressKeycode (&xe, KeyRelease, keycode);
406 lockMods ^= LockMask;
411 /* Release all non-modifier keys that we think are currently pressed.
412 Usually this is done when X becomes inactive to avoid leaving keys
413 stuck down when we become active again. Modifiers are handled separately
414 in the function above. */
416 DarwinReleaseKeys (void)
418 KeyClassPtr keyc = darwinKeyboard->key;
422 memset (&xe, 0, sizeof (xe));
423 xe.u.keyButtonPointer.time = GetTimeInMillis ();
424 xe.u.keyButtonPointer.state = darwinKeyboard->key->state;
425 GetSpritePosition (&x, &y);
426 xe.u.keyButtonPointer.rootX = x;
427 xe.u.keyButtonPointer.rootY = y;
429 for (i = 0; i < DOWN_LENGTH * 8; i++)
431 if (!keyc->modifierMap[i] && BitIsOn (keysDown, i))
432 DarwinPressKeycode (&xe, KeyRelease, i - MIN_KEYCODE);
437 parseModifierString (const char *str)
439 if (strcasecmp (str, "shift") == 0)
441 else if (strcasecmp (str, "control") == 0)
443 else if (strcasecmp (str, "option") == 0)
445 else if (strcasecmp (str, "command") == 0)
447 else if (strcasecmp (str, "fn") == 0)
453 /* Parse a list of modifier names and return a corresponding modifier mask */
455 DarwinParseModifierList (const char *constmodifiers)
458 char *modifiers, *modifier, *p;
460 if (constmodifiers == NULL
461 || strlen (constmodifiers) == 0
462 || strcasecmp (constmodifiers, "none") == 0)
467 modifiers = strdup (constmodifiers);
473 modifier = strsep (&p, " ,+&|/"); /* allow lots of separators */
474 mask = parseModifierString (modifier);
478 ErrorF ("fakebuttons: Unknown modifier \"%s\"\n", modifier);
486 DarwinSetFakeButtons (const char *mod2, const char *mod3)
489 darwinFakeMouse2Mask = DarwinParseModifierList (mod2);
491 darwinFakeMouse3Mask = DarwinParseModifierList (mod3);
494 /* Read and process events from the event pipe until it is empty. */
496 ProcessInputEvents (void)
498 static int here_before = 0;
500 /* last known modifier state */
501 static unsigned int current_flags = 0;
503 /* button number and modifier mask of currently pressed fake button */
504 static int fake_button;
505 static unsigned int fake_button_mask, fake_button_modifier;
511 X11ApplicationServerReady ();
515 while (DarwinDequeueEvent (&xe))
517 unsigned int real_state;
519 real_state = xe.u.keyButtonPointer.state;
520 xe.u.keyButtonPointer.state |= fake_button_modifier;
522 /* Filter event for faked mouse button presses. */
523 if (darwinFakeButtons)
528 if (xe.u.u.detail != 1)
530 if ((xe.u.keyButtonPointer.state & darwinFakeMouse2Mask)
531 == darwinFakeMouse2Mask)
534 fake_button_modifier = Button2Mask;
535 fake_button_mask = darwinFakeMouse2Mask;
538 else if ((xe.u.keyButtonPointer.state & darwinFakeMouse3Mask)
539 == darwinFakeMouse3Mask)
542 fake_button_modifier = Button3Mask;
543 fake_button_mask = darwinFakeMouse3Mask;
549 if (fake_button != 0 && xe.u.u.detail == 1)
550 xe.u.u.detail = fake_button;
555 xe.u.keyButtonPointer.state &= ~fake_button_mask;
559 case 0: /* flags-changed */
561 if (current_flags == 0
562 && darwinSyncKeymap && darwinKeymapFile == NULL)
564 /* See if keymap has changed. */
566 static unsigned int last_seed;
567 unsigned int this_seed;
569 this_seed = DarwinSystemKeymapSeed ();
570 if (this_seed != last_seed)
572 last_seed = this_seed;
573 DarwinKeyboardReload (darwinKeyboard);
583 /* Initialize time field. */
585 xe.u.keyButtonPointer.time = GetTimeInMillis ();
587 /* Update X's idea of what modifiers are set. */
589 if (xe.u.keyButtonPointer.state != 0xffff
590 && current_flags != xe.u.keyButtonPointer.state)
592 current_flags = xe.u.keyButtonPointer.state;
593 DarwinUpdateModifiers (xe, current_flags);
603 if (!quartzServerVisible)
607 /* Sigh. Need to check that we're really over one of
608 our windows. (We need to receive pointer events while
609 not in the foreground, and the only way to do that
610 right now is to ask for _all_ pointer events..) */
613 xp_find_window (xe.u.keyButtonPointer.rootX,
614 xe.u.keyButtonPointer.rootY, 0, &wid);
619 /* Shift from global screen coordinates to coordinates
620 relative to the origin of the current screen. */
622 xe.u.keyButtonPointer.rootX -= darwinMainScreenX -
623 dixScreenOrigins[miPointerCurrentScreen()->myNum].x;
624 xe.u.keyButtonPointer.rootY -= darwinMainScreenY -
625 dixScreenOrigins[miPointerCurrentScreen()->myNum].y;
627 miPointerAbsoluteCursor (xe.u.keyButtonPointer.rootX,
628 xe.u.keyButtonPointer.rootY,
629 xe.u.keyButtonPointer.time);
634 darwinPointer->public.processInputProc (&xe, darwinPointer, 1);
639 DarwinPressKeycode (&xe, xe.u.u.type, xe.u.u.detail);
643 /* Update server's current time, since we may generate
644 events, and it's nice if the timestamps are correct. */
645 currentTime.milliseconds = GetTimeInMillis ();
647 switch (xe.u.clientMessage.u.l.type)
653 case kXquartzDeactivate:
654 DarwinReleaseKeys ();
658 if (xe.u.clientMessage.u.l.type >= kXquartzFirstEvent
659 && xe.u.clientMessage.u.l.type <= kXquartzLastEvent)
661 QuartzClientMessage (&xe);
665 ErrorF ("Unknown application defined event: %d.\n",
666 xe.u.clientMessage.u.l.longs0);
673 ErrorF("Unknown event caught: %d\n", xe.u.u.type);
677 /* Filter event for faked mouse button releases. */
678 if (fake_button != 0 && xe.u.u.type == ButtonRelease)
680 current_flags |= (real_state & fake_button_mask);
681 DarwinUpdateModifiers (xe, current_flags);
684 fake_button_modifier = 0;
685 fake_button_mask = 0;
693 DarwinEnqueuePointerEvent (xEvent *xe)
695 darwinPointer->public.processInputProc (xe, darwinPointer, 1);
698 /* Register the keyboard and mouse devices */
700 InitInput (int argc, char **argv)
704 darwinPointer = AddInputDevice(DarwinMouseProc, TRUE);
705 RegisterPointerDevice( darwinPointer );
707 darwinKeyboard = AddInputDevice(DarwinKeybdProc, TRUE);
708 RegisterKeyboardDevice( darwinKeyboard );
712 DarwinAdjustScreenOrigins (ScreenInfo *pScreenInfo)
716 /* Shift all screens so the X11 (0, 0) coordinate is at the top
717 left of the global screen coordinates.
719 Screens can be arranged so the top left isn't on any screen, so
720 instead use the top left of the leftmost screen as (0,0). This
721 may mean some screen space is in -y, but it's better that (0,0)
722 be onscreen, or else default xterms disappear. It's better that
723 -y be used than -x, because when popup menus are forced
724 "onscreen" by dumb window managers like twm, they'll shift the
725 menus down instead of left, which still looks funny but is an
726 easier target to hit. */
728 left = dixScreenOrigins[0].x;
729 top = dixScreenOrigins[0].y;
731 /* Find leftmost screen. If there's a tie, take the topmost of the two. */
732 for (i = 1; i < pScreenInfo->numScreens; i++) {
733 if (dixScreenOrigins[i].x < left ||
734 (dixScreenOrigins[i].x == left &&
735 dixScreenOrigins[i].y < top))
737 left = dixScreenOrigins[i].x;
738 top = dixScreenOrigins[i].y;
742 darwinMainScreenX = left;
743 darwinMainScreenY = top;
745 /* Shift all screens so that there is a screen whose top left
746 is at X11 (0,0) and at global screen coordinate
747 (darwinMainScreenX, darwinMainScreenY). */
749 if (darwinMainScreenX != 0 || darwinMainScreenY != 0) {
750 for (i = 0; i < pScreenInfo->numScreens; i++) {
751 dixScreenOrigins[i].x -= darwinMainScreenX;
752 dixScreenOrigins[i].y -= darwinMainScreenY;
753 ErrorF("Screen %d placed at X11 coordinate (%d,%d).\n",
754 i, dixScreenOrigins[i].x, dixScreenOrigins[i].y);
759 /* Initialize screenInfo for all actually accessible framebuffers.
761 The display mode dependent code gets called three times. The mode
762 specific InitOutput routines are expected to discover the number of
763 potentially useful screens and cache routes to them internally.
764 Inside DarwinAddScreen are two other mode specific calls. A mode
765 specific AddScreen routine is called for each screen to actually
766 initialize the screen with the ScreenPtr structure. After other
767 screen setup has been done, a mode specific SetupScreen function can
768 be called to finalize screen setup. */
771 InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
774 static unsigned long generation = 0;
776 pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
777 pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
778 pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
779 pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
781 /* List how we want common pixmap formats to be padded */
782 pScreenInfo->numPixmapFormats = NUMFORMATS;
783 for (i = 0; i < NUMFORMATS; i++)
784 pScreenInfo->formats[i] = formats[i];
786 /* Allocate private storage for each screen's Darwin specific info */
787 if (generation != serverGeneration) {
788 darwinScreenIndex = AllocateScreenPrivateIndex();
789 generation = serverGeneration;
792 /* Discover screens and do mode specific initialization */
793 QuartzInitOutput(argc, argv);
795 for (i = 0; i < darwinScreensFound; i++)
796 AddScreen( DarwinAddScreen, argc, argv );
798 DarwinAdjustScreenOrigins (pScreenInfo);
800 PseudoramiXExtensionInit (argc, argv);
801 AppleDRIExtensionInit ();
802 AppleWMExtensionInit ();
808 OsVendorFatalError (void)
810 ErrorF( " OsVendorFatalError\n" );
816 if (serverGeneration == 1)
820 /* Process device-dependent command line args. Returns 0 if argument is
821 not device dependent, otherwise Count of number of elements of argv
822 that are part of a device dependent commandline option. */
824 ddxProcessArgument (int argc, char *argv[], int i)
828 if ((numDone = QuartzProcessArgument( argc, argv, i )))
831 if ( !strcmp( argv[i], "-fakebuttons" ) ) {
832 darwinFakeButtons = TRUE;
833 ErrorF( "Faking a three button mouse\n" );
837 if ( !strcmp( argv[i], "-nofakebuttons" ) ) {
838 darwinFakeButtons = FALSE;
839 ErrorF( "Not faking a three button mouse\n" );
843 if (!strcmp( argv[i], "-fakemouse2" ) ) {
845 FatalError( "-fakemouse2 must be followed by a modifer list\n" );
847 darwinFakeMouse2Mask = DarwinParseModifierList(argv[i+1]);
851 if (!strcmp( argv[i], "-fakemouse3" ) ) {
853 FatalError( "-fakemouse3 must be followed by a modifer list\n" );
855 darwinFakeMouse3Mask = DarwinParseModifierList(argv[i+1]);
859 if ( !strcmp( argv[i], "-keymap" ) ) {
861 FatalError( "-keymap must be followed by a filename\n" );
863 darwinKeymapFile = argv[i+1];
867 if ( !strcmp( argv[i], "-nokeymap" ) ) {
868 darwinKeymapFile = NULL;
872 if ( !strcmp( argv[i], "+synckeymap" ) ) {
873 darwinSyncKeymap = TRUE;
876 if ( !strcmp( argv[i], "-synckeymap" ) ) {
877 darwinSyncKeymap = FALSE;
881 if (strcmp (argv[i], "-swapAltMeta") == 0) {
882 darwinSwapAltMeta = TRUE;
886 if (!strcmp( argv[i], "-showconfig" ) || !strcmp( argv[i], "-version" )) {
891 /* XDarwinStartup uses this argument to indicate the IOKit X server
892 should be started. Ignore it here. */
893 if ( !strcmp( argv[i], "-iokit" ) ) {
900 /* Print out correct use of device dependent commandline options.
901 Maybe the user now knows what really to do ... */
907 ErrorF("Device Dependent Usage:\n");
909 ErrorF("-depth <depth> use <depth> bits per pixel. Options: 8, 15, 24\b\n");
910 ErrorF("-fakebuttons fake a 3 button mouse with Command and Option\n");
911 ErrorF("-nofakebuttons\n");
912 ErrorF("-fakemouse2 <keys> fake middle mouse button with modifier keys\n");
913 ErrorF("-fakemouse3 <keys> fake right mouse button with modifier keys\n");
914 ErrorF(" e.g.: -fakemouse2 \"option,shift\"\n");
915 ErrorF("-keymap <file> read the keymap from <file>\n");
916 ErrorF("-nokeymap\n");
917 ErrorF("+synckeymap synchronize X keymap with system keymap\n");
918 ErrorF("-synckeymap only set X keymap on server startup\n");
919 ErrorF("-swapAltMeta swap meaning of Alt and Meta modifiers\n");
920 ErrorF("-version show server version.\n");
924 /* Device dependent cleanup. Called by dix before normal server death. */
928 ErrorF( "Quitting XDarwin...\n" );
932 /* DDX - specific abort routine. Called by AbortServer(). The attempt is
933 made to restore all original setting of the displays. Also all devices
938 ErrorF( " AbortDDX\n" );
940 /* This is needed for a abnormal server exit, since the normal exit stuff
941 MUST also be performed (i.e. the vt must be left in a defined state) */
945 extern void GlxExtensionInit();
946 extern void GlxWrapInitVisuals(void *procPtr);
947 void DarwinGlxExtensionInit (void) { GlxExtensionInit (); }
948 void DarwinGlxWrapInitVisuals (void *ptr) { GlxWrapInitVisuals (ptr); }
971 GetTimeInMillis (void)
973 extern void Microseconds ();
976 /* This doesn't involve trapping into the kernel, unlike gettimeofday. */
977 Microseconds (&usec);
979 /* Should be good enough? (-2% error) */
980 return (usec.hi << 22) | (usec.lo >> 10);