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