xf86Init.c revision ed6184df
1/* 2 * Loosely based on code bearing the following copyright: 3 * 4 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. 5 */ 6/* 7 * Copyright (c) 1992-2003 by The XFree86 Project, Inc. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included in 17 * all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 * OTHER DEALINGS IN THE SOFTWARE. 26 * 27 * Except as contained in this notice, the name of the copyright holder(s) 28 * and author(s) shall not be used in advertising or otherwise to promote 29 * the sale, use or other dealings in this Software without prior written 30 * authorization from the copyright holder(s) and author(s). 31 */ 32 33#ifdef HAVE_XORG_CONFIG_H 34#include <xorg-config.h> 35#endif 36 37#include <stdlib.h> 38#include <errno.h> 39 40#undef HAS_UTSNAME 41#if !defined(WIN32) 42#define HAS_UTSNAME 1 43#include <sys/utsname.h> 44#endif 45 46#include <X11/X.h> 47#include <X11/Xmd.h> 48#include <X11/Xproto.h> 49#include <X11/Xatom.h> 50#include "input.h" 51#include "servermd.h" 52#include "windowstr.h" 53#include "scrnintstr.h" 54#include "mi.h" 55#include "dbus-core.h" 56#include "systemd-logind.h" 57 58#include "loaderProcs.h" 59 60#define XF86_OS_PRIVS 61#include "xf86.h" 62#include "xf86Priv.h" 63#include "xf86Config.h" 64#include "xf86_OSlib.h" 65#include "xf86cmap.h" 66#include "xorgVersion.h" 67#include "mipointer.h" 68#include <X11/extensions/XI.h> 69#include <X11/extensions/XIproto.h> 70#include "xf86Extensions.h" 71#include "xf86DDC.h" 72#include "xf86Xinput.h" 73#include "xf86InPriv.h" 74#include "xf86Crtc.h" 75#include "picturestr.h" 76#include "randrstr.h" 77#include "xf86Bus.h" 78#ifdef XSERVER_LIBPCIACCESS 79#include "xf86VGAarbiter.h" 80#endif 81#include "globals.h" 82#include "xserver-properties.h" 83 84#ifdef DPMSExtension 85#include <X11/extensions/dpmsconst.h> 86#include "dpmsproc.h" 87#endif 88 89#ifdef __linux__ 90#include <linux/major.h> 91#include <sys/sysmacros.h> 92#endif 93#include <hotplug.h> 94 95void (*xf86OSPMClose) (void) = NULL; 96static Bool xorgHWOpenConsole = FALSE; 97 98/* Common pixmap formats */ 99 100static PixmapFormatRec formats[MAXFORMATS] = { 101 {1, 1, BITMAP_SCANLINE_PAD}, 102 {4, 8, BITMAP_SCANLINE_PAD}, 103 {8, 8, BITMAP_SCANLINE_PAD}, 104 {15, 16, BITMAP_SCANLINE_PAD}, 105 {16, 16, BITMAP_SCANLINE_PAD}, 106 {24, 32, BITMAP_SCANLINE_PAD}, 107 {32, 32, BITMAP_SCANLINE_PAD}, 108}; 109 110static int numFormats = 7; 111static Bool formatsDone = FALSE; 112 113 114static void 115xf86PrintBanner(void) 116{ 117 xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d", 118 XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH); 119#if XORG_VERSION_SNAP > 0 120 xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP); 121#endif 122 123#if XORG_VERSION_SNAP >= 900 124 /* When the minor number is 99, that signifies that the we are making 125 * a release candidate for a major version. (X.0.0) 126 * When the patch number is 99, that signifies that the we are making 127 * a release candidate for a minor version. (X.Y.0) 128 * When the patch number is < 99, then we are making a release 129 * candidate for the next point release. (X.Y.Z) 130 */ 131#if XORG_VERSION_MINOR >= 99 132 xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR + 1, 133 XORG_VERSION_SNAP - 900); 134#elif XORG_VERSION_PATCH == 99 135 xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR, 136 XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900); 137#else 138 xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR, 139 XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1, 140 XORG_VERSION_SNAP - 900); 141#endif 142#endif 143 144#ifdef XORG_CUSTOM_VERSION 145 xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION); 146#endif 147 xf86ErrorFVerb(0, "\nX Protocol Version %d, Revision %d\n", 148 X_PROTOCOL, X_PROTOCOL_REVISION); 149#ifdef HAS_UTSNAME 150 { 151 struct utsname name; 152 153 /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX, 154 and Irix) and Single Unix Spec 3 just say that non-negative is success. 155 All agree that failure is represented by a negative number. 156 */ 157 if (uname(&name) >= 0) { 158 xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n", 159 name.sysname, name.nodename, name.release, 160 name.version, name.machine); 161#ifdef __linux__ 162 do { 163 char buf[80]; 164 int fd = open("/proc/cmdline", O_RDONLY); 165 166 if (fd != -1) { 167 xf86ErrorFVerb(0, "Kernel command line: "); 168 memset(buf, 0, 80); 169 while (read(fd, buf, 80) > 0) { 170 xf86ErrorFVerb(0, "%.80s", buf); 171 memset(buf, 0, 80); 172 } 173 close(fd); 174 } 175 } while (0); 176#endif 177 } 178 } 179#endif 180#if defined(BUILDERSTRING) 181 xf86ErrorFVerb(0, "%s \n", BUILDERSTRING); 182#endif 183 xf86ErrorFVerb(0, "Current version of pixman: %s\n", 184 pixman_version_string()); 185 xf86ErrorFVerb(0, "\tBefore reporting problems, check " 186 "" __VENDORDWEBSUPPORT__ "\n" 187 "\tto make sure that you have the latest version.\n"); 188} 189 190Bool 191xf86PrivsElevated(void) 192{ 193 return PrivsElevated(); 194} 195 196Bool 197xf86HasTTYs(void) 198{ 199#ifdef __linux__ 200 struct stat tty0devAttributes; 201 return (stat("/dev/tty0", &tty0devAttributes) == 0 && major(tty0devAttributes.st_rdev) == TTY_MAJOR); 202#else 203 return TRUE; 204#endif 205} 206 207static void 208xf86AutoConfigOutputDevices(void) 209{ 210 int i; 211 212 if (!xf86Info.autoBindGPU) 213 return; 214 215 for (i = 0; i < xf86NumGPUScreens; i++) { 216 int scrnum = xf86GPUScreens[i]->confScreen->screennum; 217 RRProviderAutoConfigGpuScreen(xf86ScrnToScreen(xf86GPUScreens[i]), 218 xf86ScrnToScreen(xf86Screens[scrnum])); 219 } 220} 221 222static void 223AddSeatId(CallbackListPtr *pcbl, void *data, void *screen) 224{ 225 ScreenPtr pScreen = screen; 226 Atom SeatAtom = MakeAtom(SEAT_ATOM_NAME, sizeof(SEAT_ATOM_NAME) - 1, TRUE); 227 int err; 228 229 err = dixChangeWindowProperty(serverClient, pScreen->root, SeatAtom, 230 XA_STRING, 8, PropModeReplace, 231 strlen(data) + 1, data, FALSE); 232 233 if (err != Success) 234 xf86DrvMsg(pScreen->myNum, X_WARNING, 235 "Failed to register seat property\n"); 236} 237 238static void 239AddVTAtoms(CallbackListPtr *pcbl, void *data, void *screen) 240{ 241#define VT_ATOM_NAME "XFree86_VT" 242 int err, HasVT = 1; 243 ScreenPtr pScreen = screen; 244 Atom VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE); 245 Atom HasVTAtom = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1, 246 TRUE); 247 248 err = dixChangeWindowProperty(serverClient, pScreen->root, VTAtom, 249 XA_INTEGER, 32, PropModeReplace, 1, 250 &xf86Info.vtno, FALSE); 251 252 err |= dixChangeWindowProperty(serverClient, pScreen->root, HasVTAtom, 253 XA_INTEGER, 32, PropModeReplace, 1, 254 &HasVT, FALSE); 255 256 if (err != Success) 257 xf86DrvMsg(pScreen->myNum, X_WARNING, 258 "Failed to register VT properties\n"); 259} 260 261static Bool 262xf86ScreenInit(ScreenPtr pScreen, int argc, char **argv) 263{ 264 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 265 266 pScrn->pScreen = pScreen; 267 return pScrn->ScreenInit (pScreen, argc, argv); 268} 269 270static void 271xf86EnsureRANDR(ScreenPtr pScreen) 272{ 273#ifdef RANDR 274 if (!dixPrivateKeyRegistered(rrPrivKey) || 275 !rrGetScrPriv(pScreen)) 276 xf86RandRInit(pScreen); 277#endif 278} 279 280/* 281 * InitOutput -- 282 * Initialize screenInfo for all actually accessible framebuffers. 283 * That includes vt-manager setup, querying all possible devices and 284 * collecting the pixmap formats. 285 */ 286void 287InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) 288{ 289 int i, j, k, scr_index; 290 const char **modulelist; 291 void **optionlist; 292 Bool autoconfig = FALSE; 293 Bool sigio_blocked = FALSE; 294 Bool want_hw_access = FALSE; 295 GDevPtr configured_device; 296 297 xf86Initialising = TRUE; 298 299 config_pre_init(); 300 301 if (serverGeneration == 1) { 302 xf86PrintBanner(); 303 LogPrintMarkers(); 304 if (xf86LogFile) { 305 time_t t; 306 const char *ct; 307 308 t = time(NULL); 309 ct = ctime(&t); 310 xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s", 311 xf86LogFile, ct); 312 } 313 314 /* Read and parse the config file */ 315 if (!xf86DoConfigure && !xf86DoShowOptions) { 316 switch (xf86HandleConfigFile(FALSE)) { 317 case CONFIG_OK: 318 break; 319 case CONFIG_PARSE_ERROR: 320 xf86Msg(X_ERROR, "Error parsing the config file\n"); 321 return; 322 case CONFIG_NOFILE: 323 autoconfig = TRUE; 324 break; 325 } 326 } 327 328 /* Initialise the loader */ 329 LoaderInit(); 330 331 /* Tell the loader the default module search path */ 332 LoaderSetPath(xf86ModulePath); 333 334 if (xf86Info.ignoreABI) { 335 LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL); 336 } 337 338 if (xf86DoShowOptions) 339 DoShowOptions(); 340 341 dbus_core_init(); 342 systemd_logind_init(); 343 344 /* Do a general bus probe. This will be a PCI probe for x86 platforms */ 345 xf86BusProbe(); 346 347 if (xf86DoConfigure) 348 DoConfigure(); 349 350 if (autoconfig) { 351 if (!xf86AutoConfig()) { 352 xf86Msg(X_ERROR, "Auto configuration failed\n"); 353 return; 354 } 355 } 356 357 xf86OSPMClose = xf86OSPMOpen(); 358 359 xf86ExtensionInit(); 360 361 /* Load all modules specified explicitly in the config file */ 362 if ((modulelist = xf86ModulelistFromConfig(&optionlist))) { 363 xf86LoadModules(modulelist, optionlist); 364 free(modulelist); 365 free(optionlist); 366 } 367 368 /* Load all driver modules specified in the config file */ 369 /* If there aren't any specified in the config file, autoconfig them */ 370 /* FIXME: Does not handle multiple active screen sections, but I'm not 371 * sure if we really want to handle that case*/ 372 configured_device = xf86ConfigLayout.screens->screen->device; 373 if ((!configured_device) || (!configured_device->driver)) { 374 if (!autoConfigDevice(configured_device)) { 375 xf86Msg(X_ERROR, "Automatic driver configuration failed\n"); 376 return; 377 } 378 } 379 if ((modulelist = xf86DriverlistFromConfig())) { 380 xf86LoadModules(modulelist, NULL); 381 free(modulelist); 382 } 383 384 /* Load all input driver modules specified in the config file. */ 385 if ((modulelist = xf86InputDriverlistFromConfig())) { 386 xf86LoadModules(modulelist, NULL); 387 free(modulelist); 388 } 389 390 /* 391 * It is expected that xf86AddDriver()/xf86AddInputDriver will be 392 * called for each driver as it is loaded. Those functions save the 393 * module pointers for drivers. 394 * XXX Nothing keeps track of them for other modules. 395 */ 396 /* XXX What do we do if not all of these could be loaded? */ 397 398 /* 399 * At this point, xf86DriverList[] is all filled in with entries for 400 * each of the drivers to try and xf86NumDrivers has the number of 401 * drivers. If there are none, return now. 402 */ 403 404 if (xf86NumDrivers == 0) { 405 xf86Msg(X_ERROR, "No drivers available.\n"); 406 return; 407 } 408 409 /* 410 * Call each of the Identify functions and call the driverFunc to check 411 * if HW access is required. The Identify functions print out some 412 * identifying information, and anything else that might be 413 * needed at this early stage. 414 */ 415 416 for (i = 0; i < xf86NumDrivers; i++) { 417 xorgHWFlags flags = HW_IO; 418 419 if (xf86DriverList[i]->Identify != NULL) 420 xf86DriverList[i]->Identify(0); 421 422 if (xf86DriverList[i]->driverFunc) 423 xf86DriverList[i]->driverFunc(NULL, 424 GET_REQUIRED_HW_INTERFACES, 425 &flags); 426 427 if (NEED_IO_ENABLED(flags)) 428 want_hw_access = TRUE; 429 430 /* Non-seat0 X servers should not open console */ 431 if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0() && xf86HasTTYs()) 432 xorgHWOpenConsole = TRUE; 433 } 434 435 if (xorgHWOpenConsole) 436 xf86OpenConsole(); 437 else 438 xf86Info.dontVTSwitch = TRUE; 439 440 /* Enable full I/O access */ 441 if (want_hw_access) 442 xorgHWAccess = xf86EnableIO(); 443 444 if (xf86BusConfig() == FALSE) 445 return; 446 447 xf86PostProbe(); 448 449 /* 450 * Sort the drivers to match the requested ording. Using a slow 451 * bubble sort. 452 */ 453 for (j = 0; j < xf86NumScreens - 1; j++) { 454 for (i = 0; i < xf86NumScreens - j - 1; i++) { 455 if (xf86Screens[i + 1]->confScreen->screennum < 456 xf86Screens[i]->confScreen->screennum) { 457 ScrnInfoPtr tmpScrn = xf86Screens[i + 1]; 458 459 xf86Screens[i + 1] = xf86Screens[i]; 460 xf86Screens[i] = tmpScrn; 461 } 462 } 463 } 464 /* Fix up the indexes */ 465 for (i = 0; i < xf86NumScreens; i++) { 466 xf86Screens[i]->scrnIndex = i; 467 } 468 469 /* 470 * Call the driver's PreInit()'s to complete initialisation for the first 471 * generation. 472 */ 473 474 for (i = 0; i < xf86NumScreens; i++) { 475 xf86VGAarbiterScrnInit(xf86Screens[i]); 476 xf86VGAarbiterLock(xf86Screens[i]); 477 if (xf86Screens[i]->PreInit && 478 xf86Screens[i]->PreInit(xf86Screens[i], 0)) 479 xf86Screens[i]->configured = TRUE; 480 xf86VGAarbiterUnlock(xf86Screens[i]); 481 } 482 for (i = 0; i < xf86NumScreens; i++) 483 if (!xf86Screens[i]->configured) 484 xf86DeleteScreen(xf86Screens[i--]); 485 486 for (i = 0; i < xf86NumGPUScreens; i++) { 487 xf86VGAarbiterScrnInit(xf86GPUScreens[i]); 488 xf86VGAarbiterLock(xf86GPUScreens[i]); 489 if (xf86GPUScreens[i]->PreInit && 490 xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0)) 491 xf86GPUScreens[i]->configured = TRUE; 492 xf86VGAarbiterUnlock(xf86GPUScreens[i]); 493 } 494 for (i = 0; i < xf86NumGPUScreens; i++) 495 if (!xf86GPUScreens[i]->configured) 496 xf86DeleteScreen(xf86GPUScreens[i--]); 497 498 /* 499 * If no screens left, return now. 500 */ 501 502 if (xf86NumScreens == 0) { 503 xf86Msg(X_ERROR, 504 "Screen(s) found, but none have a usable configuration.\n"); 505 return; 506 } 507 508 /* Remove (unload) drivers that are not required */ 509 for (i = 0; i < xf86NumDrivers; i++) 510 if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0) 511 xf86DeleteDriver(i); 512 513 /* 514 * At this stage we know how many screens there are. 515 */ 516 517 for (i = 0; i < xf86NumScreens; i++) 518 xf86InitViewport(xf86Screens[i]); 519 520 /* 521 * Collect all pixmap formats and check for conflicts at the display 522 * level. Should we die here? Or just delete the offending screens? 523 */ 524 for (i = 0; i < xf86NumScreens; i++) { 525 if (xf86Screens[i]->imageByteOrder != 526 xf86Screens[0]->imageByteOrder) 527 FatalError("Inconsistent display bitmapBitOrder. Exiting\n"); 528 if (xf86Screens[i]->bitmapScanlinePad != 529 xf86Screens[0]->bitmapScanlinePad) 530 FatalError 531 ("Inconsistent display bitmapScanlinePad. Exiting\n"); 532 if (xf86Screens[i]->bitmapScanlineUnit != 533 xf86Screens[0]->bitmapScanlineUnit) 534 FatalError 535 ("Inconsistent display bitmapScanlineUnit. Exiting\n"); 536 if (xf86Screens[i]->bitmapBitOrder != 537 xf86Screens[0]->bitmapBitOrder) 538 FatalError("Inconsistent display bitmapBitOrder. Exiting\n"); 539 } 540 541 /* Collect additional formats */ 542 for (i = 0; i < xf86NumScreens; i++) { 543 for (j = 0; j < xf86Screens[i]->numFormats; j++) { 544 for (k = 0;; k++) { 545 if (k >= numFormats) { 546 if (k >= MAXFORMATS) 547 FatalError("Too many pixmap formats! Exiting\n"); 548 formats[k] = xf86Screens[i]->formats[j]; 549 numFormats++; 550 break; 551 } 552 if (formats[k].depth == xf86Screens[i]->formats[j].depth) { 553 if ((formats[k].bitsPerPixel == 554 xf86Screens[i]->formats[j].bitsPerPixel) && 555 (formats[k].scanlinePad == 556 xf86Screens[i]->formats[j].scanlinePad)) 557 break; 558 FatalError("Inconsistent pixmap format for depth %d." 559 " Exiting\n", formats[k].depth); 560 } 561 } 562 } 563 } 564 formatsDone = TRUE; 565 } 566 else { 567 /* 568 * serverGeneration != 1; some OSs have to do things here, too. 569 */ 570 if (xorgHWOpenConsole) 571 xf86OpenConsole(); 572 573 /* 574 should we reopen it here? We need to deal with an already opened 575 device. We could leave this to the OS layer. For now we simply 576 close it here 577 */ 578 if (xf86OSPMClose) 579 xf86OSPMClose(); 580 if ((xf86OSPMClose = xf86OSPMOpen()) != NULL) 581 xf86MsgVerb(X_INFO, 3, "APM registered successfully\n"); 582 583 /* Make sure full I/O access is enabled */ 584 if (xorgHWAccess) 585 xf86EnableIO(); 586 } 587 588 if (xf86Info.vtno >= 0) 589 AddCallback(&RootWindowFinalizeCallback, AddVTAtoms, NULL); 590 591 if (SeatId) 592 AddCallback(&RootWindowFinalizeCallback, AddSeatId, SeatId); 593 594 /* 595 * Use the previously collected parts to setup pScreenInfo 596 */ 597 598 pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder; 599 pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad; 600 pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit; 601 pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder; 602 pScreenInfo->numPixmapFormats = numFormats; 603 for (i = 0; i < numFormats; i++) 604 pScreenInfo->formats[i] = formats[i]; 605 606 /* Make sure the server's VT is active */ 607 608 if (serverGeneration != 1) { 609 xf86Resetting = TRUE; 610 /* All screens are in the same state, so just check the first */ 611 if (!xf86VTOwner()) { 612#ifdef HAS_USL_VTS 613 ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ); 614#endif 615 input_lock(); 616 sigio_blocked = TRUE; 617 } 618 } 619 620 for (i = 0; i < xf86NumScreens; i++) 621 if (!xf86ColormapAllocatePrivates(xf86Screens[i])) 622 FatalError("Cannot register DDX private keys"); 623 624 if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0)) 625 FatalError("Cannot register DDX private keys"); 626 627 for (i = 0; i < xf86NumScreens; i++) { 628 xf86VGAarbiterLock(xf86Screens[i]); 629 /* 630 * Almost everything uses these defaults, and many of those that 631 * don't, will wrap them. 632 */ 633 xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess; 634#ifdef XFreeXDGA 635 xf86Screens[i]->SetDGAMode = xf86SetDGAMode; 636#endif 637 scr_index = AddScreen(xf86ScreenInit, argc, argv); 638 xf86VGAarbiterUnlock(xf86Screens[i]); 639 if (scr_index == i) { 640 /* 641 * Hook in our ScrnInfoRec, and initialise some other pScreen 642 * fields. 643 */ 644 dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates, 645 xf86ScreenKey, xf86Screens[i]); 646 xf86Screens[i]->pScreen = screenInfo.screens[scr_index]; 647 /* The driver should set this, but make sure it is set anyway */ 648 xf86Screens[i]->vtSema = TRUE; 649 } 650 else { 651 /* This shouldn't normally happen */ 652 FatalError("AddScreen/ScreenInit failed for driver %d\n", i); 653 } 654 655 if (PictureGetSubpixelOrder(xf86Screens[i]->pScreen) == SubPixelUnknown) { 656 xf86MonPtr DDC = (xf86MonPtr) (xf86Screens[i]->monitor->DDC); 657 658 PictureSetSubpixelOrder(xf86Screens[i]->pScreen, 659 DDC ? 660 (DDC->features.input_type ? 661 SubPixelHorizontalRGB : SubPixelNone) : 662 SubPixelUnknown); 663 } 664 665 /* 666 * If the driver hasn't set up its own RANDR support, install the 667 * fallback support. 668 */ 669 xf86EnsureRANDR(xf86Screens[i]->pScreen); 670 } 671 672 for (i = 0; i < xf86NumGPUScreens; i++) { 673 ScrnInfoPtr pScrn = xf86GPUScreens[i]; 674 xf86VGAarbiterLock(pScrn); 675 676 /* 677 * Almost everything uses these defaults, and many of those that 678 * don't, will wrap them. 679 */ 680 pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess; 681#ifdef XFreeXDGA 682 pScrn->SetDGAMode = xf86SetDGAMode; 683#endif 684 scr_index = AddGPUScreen(xf86ScreenInit, argc, argv); 685 xf86VGAarbiterUnlock(pScrn); 686 if (scr_index == i) { 687 dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates, 688 xf86ScreenKey, xf86GPUScreens[i]); 689 pScrn->pScreen = screenInfo.gpuscreens[scr_index]; 690 /* The driver should set this, but make sure it is set anyway */ 691 pScrn->vtSema = TRUE; 692 } else { 693 FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index); 694 } 695 } 696 697 for (i = 0; i < xf86NumGPUScreens; i++) { 698 int scrnum = xf86GPUScreens[i]->confScreen->screennum; 699 AttachUnboundGPU(xf86Screens[scrnum]->pScreen, xf86GPUScreens[i]->pScreen); 700 } 701 702 xf86AutoConfigOutputDevices(); 703 704 xf86VGAarbiterWrapFunctions(); 705 if (sigio_blocked) 706 input_unlock(); 707 708 xf86InitOrigins(); 709 710 xf86Resetting = FALSE; 711 xf86Initialising = FALSE; 712 713 RegisterBlockAndWakeupHandlers((ServerBlockHandlerProcPtr) NoopDDA, xf86Wakeup, 714 NULL); 715} 716 717/** 718 * Initialize all supported input devices present and referenced in the 719 * xorg.conf. 720 */ 721void 722InitInput(int argc, char **argv) 723{ 724 InputInfoPtr *pInfo; 725 DeviceIntPtr dev; 726 727 xf86Info.vtRequestsPending = FALSE; 728 729 /* Enable threaded input */ 730 InputThreadPreInit(); 731 732 mieqInit(); 733 734 /* Initialize all configured input devices */ 735 for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) { 736 (*pInfo)->options = 737 xf86AddNewOption((*pInfo)->options, "driver", (*pInfo)->driver); 738 (*pInfo)->options = 739 xf86AddNewOption((*pInfo)->options, "identifier", (*pInfo)->name); 740 /* If one fails, the others will too */ 741 if (NewInputDeviceRequest((*pInfo)->options, NULL, &dev) == BadAlloc) 742 break; 743 } 744 745 config_init(); 746} 747 748void 749CloseInput(void) 750{ 751 config_fini(); 752 mieqFini(); 753} 754 755/* 756 * OsVendorInit -- 757 * OS/Vendor-specific initialisations. Called from OsInit(), which 758 * is called by dix before establishing the well known sockets. 759 */ 760 761void 762OsVendorInit(void) 763{ 764 static Bool beenHere = FALSE; 765 766 OsSignal(SIGCHLD, SIG_DFL); /* Need to wait for child processes */ 767 768 if (!beenHere) { 769 umask(022); 770 xf86LogInit(); 771 } 772 773 /* Set stderr to non-blocking. */ 774#ifndef O_NONBLOCK 775#if defined(FNDELAY) 776#define O_NONBLOCK FNDELAY 777#elif defined(O_NDELAY) 778#define O_NONBLOCK O_NDELAY 779#endif 780 781#ifdef O_NONBLOCK 782 if (!beenHere) { 783 if (PrivsElevated()) { 784 int status; 785 786 status = fcntl(fileno(stderr), F_GETFL, 0); 787 if (status != -1) { 788 fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK); 789 } 790 } 791 } 792#endif 793#endif 794 795 beenHere = TRUE; 796} 797 798/* 799 * ddxGiveUp -- 800 * Device dependent cleanup. Called by by dix before normal server death. 801 * For SYSV386 we must switch the terminal back to normal mode. No error- 802 * checking here, since there should be restored as much as possible. 803 */ 804 805void 806ddxGiveUp(enum ExitCode error) 807{ 808 int i; 809 810 if (error == EXIT_ERR_ABORT) { 811 input_lock(); 812 813 /* try to restore the original video state */ 814#ifdef DPMSExtension /* Turn screens back on */ 815 if (DPMSPowerLevel != DPMSModeOn) 816 DPMSSet(serverClient, DPMSModeOn); 817#endif 818 if (xf86Screens) { 819 for (i = 0; i < xf86NumScreens; i++) 820 if (xf86Screens[i]->vtSema) { 821 /* 822 * if we are aborting before ScreenInit() has finished we 823 * might not have been wrapped yet. Therefore enable screen 824 * explicitly. 825 */ 826 xf86VGAarbiterLock(xf86Screens[i]); 827 (xf86Screens[i]->LeaveVT) (xf86Screens[i]); 828 xf86VGAarbiterUnlock(xf86Screens[i]); 829 } 830 } 831 } 832 833 xf86VGAarbiterFini(); 834 835 if (xf86OSPMClose) 836 xf86OSPMClose(); 837 xf86OSPMClose = NULL; 838 839 for (i = 0; i < xf86NumScreens; i++) { 840 /* 841 * zero all access functions to 842 * trap calls when switched away. 843 */ 844 xf86Screens[i]->vtSema = FALSE; 845 } 846 847 if (xorgHWOpenConsole) 848 xf86CloseConsole(); 849 850 systemd_logind_fini(); 851 dbus_core_fini(); 852 853 xf86CloseLog(error); 854} 855 856void 857OsVendorFatalError(const char *f, va_list args) 858{ 859#ifdef VENDORSUPPORT 860 ErrorFSigSafe("\nPlease refer to your Operating System Vendor support " 861 "pages\nat %s for support on this crash.\n", VENDORSUPPORT); 862#else 863 ErrorFSigSafe("\nPlease consult the " XVENDORNAME " support \n\t at " 864 __VENDORDWEBSUPPORT__ "\n for help. \n"); 865#endif 866 if (xf86LogFile && xf86LogFileWasOpened) 867 ErrorFSigSafe("Please also check the log file at \"%s\" for additional " 868 "information.\n", xf86LogFile); 869 ErrorFSigSafe("\n"); 870} 871 872int 873xf86SetVerbosity(int verb) 874{ 875 int save = xf86Verbose; 876 877 xf86Verbose = verb; 878 LogSetParameter(XLOG_VERBOSITY, verb); 879 return save; 880} 881 882int 883xf86SetLogVerbosity(int verb) 884{ 885 int save = xf86LogVerbose; 886 887 xf86LogVerbose = verb; 888 LogSetParameter(XLOG_FILE_VERBOSITY, verb); 889 return save; 890} 891 892static void 893xf86PrintDefaultModulePath(void) 894{ 895 ErrorF("%s\n", DEFAULT_MODULE_PATH); 896} 897 898static void 899xf86PrintDefaultLibraryPath(void) 900{ 901 ErrorF("%s\n", DEFAULT_LIBRARY_PATH); 902} 903 904static void 905xf86CheckPrivs(const char *option, const char *arg) 906{ 907 if (PrivsElevated() && !xf86PathIsSafe(arg)) { 908 FatalError("\nInvalid argument for %s - \"%s\"\n" 909 "\tWith elevated privileges %s must specify a relative path\n" 910 "\twithout any \"..\" elements.\n\n", option, arg, option); 911 } 912} 913 914/* 915 * ddxProcessArgument -- 916 * Process device-dependent command line args. Returns 0 if argument is 917 * not device dependent, otherwise Count of number of elements of argv 918 * that are part of a device dependent commandline option. 919 * 920 */ 921 922/* ARGSUSED */ 923int 924ddxProcessArgument(int argc, char **argv, int i) 925{ 926 /* First the options that are not allowed with elevated privileges */ 927 if (!strcmp(argv[i], "-modulepath")) { 928 CHECK_FOR_REQUIRED_ARGUMENTS(1); 929 if (xf86PrivsElevated()) 930 FatalError("\nInvalid argument -modulepath " 931 "with elevated privileges\n"); 932 xf86ModulePath = argv[i + 1]; 933 xf86ModPathFrom = X_CMDLINE; 934 return 2; 935 } 936 if (!strcmp(argv[i], "-logfile")) { 937 CHECK_FOR_REQUIRED_ARGUMENTS(1); 938 if (xf86PrivsElevated()) 939 FatalError("\nInvalid argument -logfile " 940 "with elevated privileges\n"); 941 xf86LogFile = argv[i + 1]; 942 xf86LogFileFrom = X_CMDLINE; 943 return 2; 944 } 945 if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config")) { 946 CHECK_FOR_REQUIRED_ARGUMENTS(1); 947 xf86CheckPrivs(argv[i], argv[i + 1]); 948 xf86ConfigFile = argv[i + 1]; 949 return 2; 950 } 951 if (!strcmp(argv[i], "-configdir")) { 952 CHECK_FOR_REQUIRED_ARGUMENTS(1); 953 xf86CheckPrivs(argv[i], argv[i + 1]); 954 xf86ConfigDir = argv[i + 1]; 955 return 2; 956 } 957#ifdef XF86VIDMODE 958 if (!strcmp(argv[i], "-disableVidMode")) { 959 xf86VidModeDisabled = TRUE; 960 return 1; 961 } 962 if (!strcmp(argv[i], "-allowNonLocalXvidtune")) { 963 xf86VidModeAllowNonLocal = TRUE; 964 return 1; 965 } 966#endif 967 if (!strcmp(argv[i], "-allowMouseOpenFail")) { 968 xf86AllowMouseOpenFail = TRUE; 969 return 1; 970 } 971 if (!strcmp(argv[i], "-ignoreABI")) { 972 LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL); 973 return 1; 974 } 975 if (!strcmp(argv[i], "-verbose")) { 976 if (++i < argc && argv[i]) { 977 char *end; 978 long val; 979 980 val = strtol(argv[i], &end, 0); 981 if (*end == '\0') { 982 xf86SetVerbosity(val); 983 return 2; 984 } 985 } 986 xf86SetVerbosity(++xf86Verbose); 987 return 1; 988 } 989 if (!strcmp(argv[i], "-logverbose")) { 990 if (++i < argc && argv[i]) { 991 char *end; 992 long val; 993 994 val = strtol(argv[i], &end, 0); 995 if (*end == '\0') { 996 xf86SetLogVerbosity(val); 997 return 2; 998 } 999 } 1000 xf86SetLogVerbosity(++xf86LogVerbose); 1001 return 1; 1002 } 1003 if (!strcmp(argv[i], "-quiet")) { 1004 xf86SetVerbosity(-1); 1005 return 1; 1006 } 1007 if (!strcmp(argv[i], "-showconfig") || !strcmp(argv[i], "-version")) { 1008 xf86PrintBanner(); 1009 exit(0); 1010 } 1011 if (!strcmp(argv[i], "-showDefaultModulePath")) { 1012 xf86PrintDefaultModulePath(); 1013 exit(0); 1014 } 1015 if (!strcmp(argv[i], "-showDefaultLibPath")) { 1016 xf86PrintDefaultLibraryPath(); 1017 exit(0); 1018 } 1019 /* Notice the -fp flag, but allow it to pass to the dix layer */ 1020 if (!strcmp(argv[i], "-fp")) { 1021 xf86fpFlag = TRUE; 1022 return 0; 1023 } 1024 /* Notice the -bs flag, but allow it to pass to the dix layer */ 1025 if (!strcmp(argv[i], "-bs")) { 1026 xf86bsDisableFlag = TRUE; 1027 return 0; 1028 } 1029 /* Notice the +bs flag, but allow it to pass to the dix layer */ 1030 if (!strcmp(argv[i], "+bs")) { 1031 xf86bsEnableFlag = TRUE; 1032 return 0; 1033 } 1034 /* Notice the -s flag, but allow it to pass to the dix layer */ 1035 if (!strcmp(argv[i], "-s")) { 1036 xf86sFlag = TRUE; 1037 return 0; 1038 } 1039 if (!strcmp(argv[i], "-pixmap32") || !strcmp(argv[i], "-pixmap24")) { 1040 /* silently accept */ 1041 return 1; 1042 } 1043 if (!strcmp(argv[i], "-fbbpp")) { 1044 int bpp; 1045 1046 CHECK_FOR_REQUIRED_ARGUMENTS(1); 1047 if (sscanf(argv[++i], "%d", &bpp) == 1) { 1048 xf86FbBpp = bpp; 1049 return 2; 1050 } 1051 else { 1052 ErrorF("Invalid fbbpp\n"); 1053 return 0; 1054 } 1055 } 1056 if (!strcmp(argv[i], "-depth")) { 1057 int depth; 1058 1059 CHECK_FOR_REQUIRED_ARGUMENTS(1); 1060 if (sscanf(argv[++i], "%d", &depth) == 1) { 1061 xf86Depth = depth; 1062 return 2; 1063 } 1064 else { 1065 ErrorF("Invalid depth\n"); 1066 return 0; 1067 } 1068 } 1069 if (!strcmp(argv[i], "-weight")) { 1070 int red, green, blue; 1071 1072 CHECK_FOR_REQUIRED_ARGUMENTS(1); 1073 if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3) { 1074 xf86Weight.red = red; 1075 xf86Weight.green = green; 1076 xf86Weight.blue = blue; 1077 return 2; 1078 } 1079 else { 1080 ErrorF("Invalid weighting\n"); 1081 return 0; 1082 } 1083 } 1084 if (!strcmp(argv[i], "-gamma") || !strcmp(argv[i], "-rgamma") || 1085 !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma")) { 1086 double gamma; 1087 1088 CHECK_FOR_REQUIRED_ARGUMENTS(1); 1089 if (sscanf(argv[++i], "%lf", &gamma) == 1) { 1090 if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) { 1091 ErrorF("gamma out of range, only %.2f <= gamma_value <= %.1f" 1092 " is valid\n", GAMMA_MIN, GAMMA_MAX); 1093 return 0; 1094 } 1095 if (!strcmp(argv[i - 1], "-gamma")) 1096 xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma; 1097 else if (!strcmp(argv[i - 1], "-rgamma")) 1098 xf86Gamma.red = gamma; 1099 else if (!strcmp(argv[i - 1], "-ggamma")) 1100 xf86Gamma.green = gamma; 1101 else if (!strcmp(argv[i - 1], "-bgamma")) 1102 xf86Gamma.blue = gamma; 1103 return 2; 1104 } 1105 } 1106 if (!strcmp(argv[i], "-layout")) { 1107 CHECK_FOR_REQUIRED_ARGUMENTS(1); 1108 xf86LayoutName = argv[++i]; 1109 return 2; 1110 } 1111 if (!strcmp(argv[i], "-screen")) { 1112 CHECK_FOR_REQUIRED_ARGUMENTS(1); 1113 xf86ScreenName = argv[++i]; 1114 return 2; 1115 } 1116 if (!strcmp(argv[i], "-pointer")) { 1117 CHECK_FOR_REQUIRED_ARGUMENTS(1); 1118 xf86PointerName = argv[++i]; 1119 return 2; 1120 } 1121 if (!strcmp(argv[i], "-keyboard")) { 1122 CHECK_FOR_REQUIRED_ARGUMENTS(1); 1123 xf86KeyboardName = argv[++i]; 1124 return 2; 1125 } 1126 if (!strcmp(argv[i], "-nosilk")) { 1127 xf86silkenMouseDisableFlag = TRUE; 1128 return 1; 1129 } 1130#ifdef HAVE_ACPI 1131 if (!strcmp(argv[i], "-noacpi")) { 1132 xf86acpiDisableFlag = TRUE; 1133 return 1; 1134 } 1135#endif 1136 if (!strcmp(argv[i], "-configure")) { 1137 if (getuid() != 0 && geteuid() == 0) { 1138 ErrorF("The '-configure' option can only be used by root.\n"); 1139 exit(1); 1140 } 1141 xf86DoConfigure = TRUE; 1142 xf86AllowMouseOpenFail = TRUE; 1143 return 1; 1144 } 1145 if (!strcmp(argv[i], "-showopts")) { 1146 if (getuid() != 0 && geteuid() == 0) { 1147 ErrorF("The '-showopts' option can only be used by root.\n"); 1148 exit(1); 1149 } 1150 xf86DoShowOptions = TRUE; 1151 return 1; 1152 } 1153#ifdef XSERVER_LIBPCIACCESS 1154 if (!strcmp(argv[i], "-isolateDevice")) { 1155 CHECK_FOR_REQUIRED_ARGUMENTS(1); 1156 if (strncmp(argv[++i], "PCI:", 4)) { 1157 FatalError("Bus types other than PCI not yet isolable\n"); 1158 } 1159 xf86PciIsolateDevice(argv[i]); 1160 return 2; 1161 } 1162#endif 1163 /* Notice cmdline xkbdir, but pass to dix as well */ 1164 if (!strcmp(argv[i], "-xkbdir")) { 1165 xf86xkbdirFlag = TRUE; 1166 return 0; 1167 } 1168 if (!strcmp(argv[i], "-novtswitch")) { 1169 xf86Info.autoVTSwitch = FALSE; 1170 return 1; 1171 } 1172 if (!strcmp(argv[i], "-sharevts")) { 1173 xf86Info.ShareVTs = TRUE; 1174 return 1; 1175 } 1176 if (!strcmp(argv[i], "-iglx") || !strcmp(argv[i], "+iglx")) { 1177 xf86Info.iglxFrom = X_CMDLINE; 1178 return 0; 1179 } 1180 if (!strcmp(argv[i], "-noautoBindGPU")) { 1181 xf86AutoBindGPUDisabled = TRUE; 1182 return 1; 1183 } 1184 1185 /* OS-specific processing */ 1186 return xf86ProcessArgument(argc, argv, i); 1187} 1188 1189/* 1190 * ddxUseMsg -- 1191 * Print out correct use of device dependent commandline options. 1192 * Maybe the user now knows what really to do ... 1193 */ 1194 1195void 1196ddxUseMsg(void) 1197{ 1198 ErrorF("\n"); 1199 ErrorF("\n"); 1200 ErrorF("Device Dependent Usage\n"); 1201 if (!PrivsElevated()) { 1202 ErrorF("-modulepath paths specify the module search path\n"); 1203 ErrorF("-logfile file specify a log file name\n"); 1204 ErrorF("-configure probe for devices and write an " 1205 XCONFIGFILE "\n"); 1206 ErrorF 1207 ("-showopts print available options for all installed drivers\n"); 1208 } 1209 ErrorF 1210 ("-config file specify a configuration file, relative to the\n"); 1211 ErrorF(" " XCONFIGFILE 1212 " search path, only root can use absolute\n"); 1213 ErrorF 1214 ("-configdir dir specify a configuration directory, relative to the\n"); 1215 ErrorF(" " XCONFIGDIR 1216 " search path, only root can use absolute\n"); 1217 ErrorF("-verbose [n] verbose startup messages\n"); 1218 ErrorF("-logverbose [n] verbose log messages\n"); 1219 ErrorF("-quiet minimal startup messages\n"); 1220 ErrorF("-fbbpp n set bpp for the framebuffer. Default: 8\n"); 1221 ErrorF("-depth n set colour depth. Default: 8\n"); 1222 ErrorF 1223 ("-gamma f set gamma value (0.1 < f < 10.0) Default: 1.0\n"); 1224 ErrorF("-rgamma f set gamma value for red phase\n"); 1225 ErrorF("-ggamma f set gamma value for green phase\n"); 1226 ErrorF("-bgamma f set gamma value for blue phase\n"); 1227 ErrorF 1228 ("-weight nnn set RGB weighting at 16 bpp. Default: 565\n"); 1229 ErrorF("-layout name specify the ServerLayout section name\n"); 1230 ErrorF("-screen name specify the Screen section name\n"); 1231 ErrorF 1232 ("-keyboard name specify the core keyboard InputDevice name\n"); 1233 ErrorF 1234 ("-pointer name specify the core pointer InputDevice name\n"); 1235 ErrorF("-nosilk disable Silken Mouse\n"); 1236#ifdef XF86VIDMODE 1237 ErrorF("-disableVidMode disable mode adjustments with xvidtune\n"); 1238 ErrorF 1239 ("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n"); 1240#endif 1241 ErrorF 1242 ("-allowMouseOpenFail start server even if the mouse can't be initialized\n"); 1243 ErrorF("-ignoreABI make module ABI mismatches non-fatal\n"); 1244#ifdef XSERVER_LIBPCIACCESS 1245 ErrorF 1246 ("-isolateDevice bus_id restrict device resets to bus_id (PCI only)\n"); 1247#endif 1248 ErrorF("-version show the server version\n"); 1249 ErrorF("-showDefaultModulePath show the server default module path\n"); 1250 ErrorF("-showDefaultLibPath show the server default library path\n"); 1251 ErrorF 1252 ("-novtswitch don't automatically switch VT at reset & exit\n"); 1253 ErrorF("-sharevts share VTs with another X server\n"); 1254 /* OS-specific usage */ 1255 xf86UseMsg(); 1256 ErrorF("\n"); 1257} 1258 1259/* 1260 * xf86LoadModules iterates over a list that is being passed in. 1261 */ 1262Bool 1263xf86LoadModules(const char **list, void **optlist) 1264{ 1265 int errmaj; 1266 void *opt; 1267 int i; 1268 char *name; 1269 Bool failed = FALSE; 1270 1271 if (!list) 1272 return TRUE; 1273 1274 for (i = 0; list[i] != NULL; i++) { 1275 1276 /* Normalise the module name */ 1277 name = xf86NormalizeName(list[i]); 1278 1279 /* Skip empty names */ 1280 if (name == NULL || *name == '\0') { 1281 free(name); 1282 continue; 1283 } 1284 1285 /* Replace obsolete keyboard driver with kbd */ 1286 if (!xf86NameCmp(name, "keyboard")) { 1287 strcpy(name, "kbd"); 1288 } 1289 1290 if (optlist) 1291 opt = optlist[i]; 1292 else 1293 opt = NULL; 1294 1295 if (!LoadModule(name, opt, NULL, &errmaj)) { 1296 LoaderErrorMsg(NULL, name, errmaj, 0); 1297 failed = TRUE; 1298 } 1299 free(name); 1300 } 1301 return !failed; 1302} 1303 1304/* Pixmap format stuff */ 1305 1306PixmapFormatPtr 1307xf86GetPixFormat(ScrnInfoPtr pScrn, int depth) 1308{ 1309 int i; 1310 1311 for (i = 0; i < numFormats; i++) 1312 if (formats[i].depth == depth) 1313 break; 1314 if (i != numFormats) 1315 return &formats[i]; 1316 else if (!formatsDone) { 1317 /* Check for screen-specified formats */ 1318 for (i = 0; i < pScrn->numFormats; i++) 1319 if (pScrn->formats[i].depth == depth) 1320 break; 1321 if (i != pScrn->numFormats) 1322 return &pScrn->formats[i]; 1323 } 1324 return NULL; 1325} 1326 1327int 1328xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth) 1329{ 1330 PixmapFormatPtr format; 1331 1332 format = xf86GetPixFormat(pScrn, depth); 1333 if (format) 1334 return format->bitsPerPixel; 1335 else 1336 return 0; 1337} 1338 1339#ifdef DDXBEFORERESET 1340void 1341ddxBeforeReset(void) 1342{ 1343} 1344#endif 1345 1346#if INPUTTHREAD 1347/** This function is called in Xserver/os/inputthread.c when starting 1348 the input thread. */ 1349void 1350ddxInputThreadInit(void) 1351{ 1352 xf86OSInputThreadInit(); 1353} 1354#endif 1355