Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / common / xf86Init.c
CommitLineData
a09e091a
JB
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 "site.h"
55#include "mi.h"
56
57#include "compiler.h"
58
59#include "loaderProcs.h"
60#ifdef XFreeXDGA
61#include "dgaproc.h"
62#endif
63
64#define XF86_OS_PRIVS
65#include "xf86.h"
66#include "xf86Priv.h"
67#include "xf86Config.h"
68#include "xf86_OSlib.h"
69#include "xf86cmap.h"
70#include "xorgVersion.h"
71#include "xf86Build.h"
72#include "mipointer.h"
73#include <X11/extensions/XI.h>
74#include <X11/extensions/XIproto.h>
75#include "xf86DDC.h"
76#include "xf86Xinput.h"
77#include "xf86InPriv.h"
78#include "picturestr.h"
79
80#include "xf86Bus.h"
81#ifdef XSERVER_LIBPCIACCESS
82#include "xf86VGAarbiter.h"
83#endif
84#include "globals.h"
85#include "xserver-properties.h"
86
87#ifdef DPMSExtension
88#include <X11/extensions/dpmsconst.h>
89#include "dpmsproc.h"
90#endif
91#include <hotplug.h>
92
93#ifdef XF86PM
94void (*xf86OSPMClose) (void) = NULL;
95#endif
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#ifndef OSNAME
114#define OSNAME " unknown"
115#endif
116#ifndef OSVENDOR
117#define OSVENDOR ""
118#endif
119#ifndef PRE_RELEASE
120#define PRE_RELEASE XORG_VERSION_SNAP
121#endif
122
123static void
124xf86PrintBanner(void)
125{
126#if PRE_RELEASE
127 xf86ErrorFVerb(0, "\n"
128 "This is a pre-release version of the X server from "
129 XVENDORNAME ".\n" "It is not supported in any way.\n"
130 "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
131 "Select the \"xorg\" product for bugs you find in this release.\n"
132 "Before reporting bugs in pre-release versions please check the\n"
133 "latest version in the X.Org Foundation git repository.\n"
134 "See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
135#endif
136 xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
137 XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH);
138#if XORG_VERSION_SNAP > 0
139 xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
140#endif
141
142#if XORG_VERSION_SNAP >= 900
143 /* When the minor number is 99, that signifies that the we are making
144 * a release candidate for a major version. (X.0.0)
145 * When the patch number is 99, that signifies that the we are making
146 * a release candidate for a minor version. (X.Y.0)
147 * When the patch number is < 99, then we are making a release
148 * candidate for the next point release. (X.Y.Z)
149 */
150#if XORG_VERSION_MINOR >= 99
151 xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR + 1,
152 XORG_VERSION_SNAP - 900);
153#elif XORG_VERSION_PATCH == 99
154 xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
155 XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
156#else
157 xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
158 XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
159 XORG_VERSION_SNAP - 900);
160#endif
161#endif
162
163#ifdef XORG_CUSTOM_VERSION
164 xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
165#endif
166#ifndef XORG_DATE
167#define XORG_DATE "Unknown"
168#endif
169 xf86ErrorFVerb(0, "\nRelease Date: %s\n", XORG_DATE);
170 xf86ErrorFVerb(0, "X Protocol Version %d, Revision %d\n",
171 X_PROTOCOL, X_PROTOCOL_REVISION);
172 xf86ErrorFVerb(0, "Build Operating System: %s %s\n", OSNAME, OSVENDOR);
173#ifdef HAS_UTSNAME
174 {
175 struct utsname name;
176
177 /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
178 and Irix) and Single Unix Spec 3 just say that non-negative is success.
179 All agree that failure is represented by a negative number.
180 */
181 if (uname(&name) >= 0) {
182 xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
183 name.sysname, name.nodename, name.release,
184 name.version, name.machine);
185#ifdef linux
186 do {
187 char buf[80];
188 int fd = open("/proc/cmdline", O_RDONLY);
189
190 if (fd != -1) {
191 xf86ErrorFVerb(0, "Kernel command line: ");
192 memset(buf, 0, 80);
193 while (read(fd, buf, 80) > 0) {
194 xf86ErrorFVerb(0, "%.80s", buf);
195 memset(buf, 0, 80);
196 }
197 close(fd);
198 }
199 } while (0);
200#endif
201 }
202 }
203#endif
204#if defined(BUILD_DATE) && (BUILD_DATE > 19000000)
205 {
206 struct tm t;
207 char buf[100];
208
209 memset(&t, 0, sizeof(t));
210 memset(buf, 0, sizeof(buf));
211 t.tm_mday = BUILD_DATE % 100;
212 t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
213 t.tm_year = BUILD_DATE / 10000 - 1900;
214#if defined(BUILD_TIME)
215 t.tm_sec = BUILD_TIME % 100;
216 t.tm_min = (BUILD_TIME / 100) % 100;
217 t.tm_hour = (BUILD_TIME / 10000) % 100;
218 if (strftime(buf, sizeof(buf), "%d %B %Y %I:%M:%S%p", &t))
219 xf86ErrorFVerb(0, "Build Date: %s\n", buf);
220#else
221 if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
222 xf86ErrorFVerb(0, "Build Date: %s\n", buf);
223#endif
224 }
225#endif
226#if defined(BUILDERSTRING)
227 xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
228#endif
229 xf86ErrorFVerb(0, "Current version of pixman: %s\n",
230 pixman_version_string());
231 xf86ErrorFVerb(0, "\tBefore reporting problems, check "
232 "" __VENDORDWEBSUPPORT__ "\n"
233 "\tto make sure that you have the latest version.\n");
234}
235
236static void
237xf86PrintMarkers(void)
238{
239 LogPrintMarkers();
240}
241
242Bool
243xf86PrivsElevated(void)
244{
245 static Bool privsTested = FALSE;
246 static Bool privsElevated = TRUE;
247
248 if (!privsTested) {
249#if defined(WIN32)
250 privsElevated = FALSE;
251#else
252 if ((getuid() != geteuid()) || (getgid() != getegid())) {
253 privsElevated = TRUE;
254 }
255 else {
256#if defined(HAVE_ISSETUGID)
257 privsElevated = issetugid();
258#elif defined(HAVE_GETRESUID)
259 uid_t ruid, euid, suid;
260 gid_t rgid, egid, sgid;
261
262 if ((getresuid(&ruid, &euid, &suid) == 0) &&
263 (getresgid(&rgid, &egid, &sgid) == 0)) {
264 privsElevated = (euid != suid) || (egid != sgid);
265 }
266 else {
267 printf("Failed getresuid or getresgid");
268 /* Something went wrong, make defensive assumption */
269 privsElevated = TRUE;
270 }
271#else
272 if (getuid() == 0) {
273 /* running as root: uid==euid==0 */
274 privsElevated = FALSE;
275 }
276 else {
277 /*
278 * If there are saved ID's the process might still be privileged
279 * even though the above test succeeded. If issetugid() and
280 * getresgid() aren't available, test this by trying to set
281 * euid to 0.
282 */
283 unsigned int oldeuid;
284
285 oldeuid = geteuid();
286
287 if (seteuid(0) != 0) {
288 privsElevated = FALSE;
289 }
290 else {
291 if (seteuid(oldeuid) != 0) {
292 FatalError("Failed to drop privileges. Exiting\n");
293 }
294 privsElevated = TRUE;
295 }
296 }
297#endif
298 }
299#endif
300 privsTested = TRUE;
301 }
302 return privsElevated;
303}
304
305static Bool
306xf86CreateRootWindow(WindowPtr pWin)
307{
308 int ret = TRUE;
309 int err = Success;
310 ScreenPtr pScreen = pWin->drawable.pScreen;
311 RootWinPropPtr pProp;
312 CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
313 dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
314
315 DebugF("xf86CreateRootWindow(%p)\n", pWin);
316
317 if (pScreen->CreateWindow != xf86CreateRootWindow) {
318 /* Can't find hook we are hung on */
319 xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */ ,
320 "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
321 (void *) xf86CreateRootWindow,
322 (void *) pScreen->CreateWindow);
323 }
324
325 /* Unhook this function ... */
326 pScreen->CreateWindow = CreateWindow;
327 dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
328
329 /* ... and call the previous CreateWindow fuction, if any */
330 if (NULL != pScreen->CreateWindow) {
331 ret = (*pScreen->CreateWindow) (pWin);
332 }
333
334 /* Now do our stuff */
335 if (xf86RegisteredPropertiesTable != NULL) {
336 if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
337 for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
338 pProp != NULL && err == Success; pProp = pProp->next) {
339 Atom prop;
340
341 prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
342 err = dixChangeWindowProperty(serverClient, pWin,
343 prop, pProp->type,
344 pProp->format, PropModeReplace,
345 pProp->size, pProp->data, FALSE);
346 }
347
348 /* Look at err */
349 ret &= (err == Success);
350
351 }
352 else {
353 xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
354 "non-root window %p (parent %p)\n",
355 (void *) pWin, (void *) pWin->parent);
356 ret = FALSE;
357 }
358 }
359
360 DebugF("xf86CreateRootWindow() returns %d\n", ret);
361 return ret;
362}
363
364static void
365InstallSignalHandlers(void)
366{
367 /*
368 * Install signal handler for unexpected signals
369 */
370 xf86Info.caughtSignal = FALSE;
371 if (!xf86Info.notrapSignals) {
372 OsRegisterSigWrapper(xf86SigWrapper);
373 }
374 else {
375 signal(SIGSEGV, SIG_DFL);
376 signal(SIGILL, SIG_DFL);
377#ifdef SIGEMT
378 signal(SIGEMT, SIG_DFL);
379#endif
380 signal(SIGFPE, SIG_DFL);
381 signal(SIGBUS, SIG_DFL);
382 signal(SIGSYS, SIG_DFL);
383 signal(SIGXCPU, SIG_DFL);
384 signal(SIGXFSZ, SIG_DFL);
385 }
386}
387
388/*
389 * InitOutput --
390 * Initialize screenInfo for all actually accessible framebuffers.
391 * That includes vt-manager setup, querying all possible devices and
392 * collecting the pixmap formats.
393 */
394void
395InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
396{
397 int i, j, k, scr_index;
398 char **modulelist;
399 pointer *optionlist;
400 Pix24Flags screenpix24, pix24;
401 MessageType pix24From = X_DEFAULT;
402 Bool pix24Fail = FALSE;
403 Bool autoconfig = FALSE;
404 Bool sigio_blocked = FALSE;
405 Bool want_hw_access = FALSE;
406 GDevPtr configured_device;
407
408 xf86Initialising = TRUE;
409
410 config_pre_init();
411
412 if (serverGeneration == 1) {
413 if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
414 xf86ServerName++;
415 else
416 xf86ServerName = argv[0];
417
418 xf86PrintBanner();
419 xf86PrintMarkers();
420 if (xf86LogFile) {
421 time_t t;
422 const char *ct;
423
424 t = time(NULL);
425 ct = ctime(&t);
426 xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
427 xf86LogFile, ct);
428 }
429
430 /* Read and parse the config file */
431 if (!xf86DoConfigure && !xf86DoShowOptions) {
432 switch (xf86HandleConfigFile(FALSE)) {
433 case CONFIG_OK:
434 break;
435 case CONFIG_PARSE_ERROR:
436 xf86Msg(X_ERROR, "Error parsing the config file\n");
437 return;
438 case CONFIG_NOFILE:
439 autoconfig = TRUE;
440 break;
441 }
442 }
443
444 InstallSignalHandlers();
445
446 /* Initialise the loader */
447 LoaderInit();
448
449 /* Tell the loader the default module search path */
450 LoaderSetPath(xf86ModulePath);
451
452 if (xf86Info.ignoreABI) {
453 LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
454 }
455
456 if (xf86DoShowOptions)
457 DoShowOptions();
458
459 /* Do a general bus probe. This will be a PCI probe for x86 platforms */
460 xf86BusProbe();
461
462 if (xf86DoConfigure)
463 DoConfigure();
464
465 if (autoconfig) {
466 if (!xf86AutoConfig()) {
467 xf86Msg(X_ERROR, "Auto configuration failed\n");
468 return;
469 }
470 }
471
472#ifdef XF86PM
473 xf86OSPMClose = xf86OSPMOpen();
474#endif
475
476 xf86ExtensionInit();
477
478 /* Load all modules specified explicitly in the config file */
479 if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
480 xf86LoadModules(modulelist, optionlist);
481 free(modulelist);
482 free(optionlist);
483 }
484
485 /* Load all driver modules specified in the config file */
486 /* If there aren't any specified in the config file, autoconfig them */
487 /* FIXME: Does not handle multiple active screen sections, but I'm not
488 * sure if we really want to handle that case*/
489 configured_device = xf86ConfigLayout.screens->screen->device;
490 if ((!configured_device) || (!configured_device->driver)) {
491 if (!autoConfigDevice(configured_device)) {
492 xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
493 return;
494 }
495 }
496 if ((modulelist = xf86DriverlistFromConfig())) {
497 xf86LoadModules(modulelist, NULL);
498 free(modulelist);
499 }
500
501 /* Load all input driver modules specified in the config file. */
502 if ((modulelist = xf86InputDriverlistFromConfig())) {
503 xf86LoadModules(modulelist, NULL);
504 free(modulelist);
505 }
506
507 /*
508 * It is expected that xf86AddDriver()/xf86AddInputDriver will be
509 * called for each driver as it is loaded. Those functions save the
510 * module pointers for drivers.
511 * XXX Nothing keeps track of them for other modules.
512 */
513 /* XXX What do we do if not all of these could be loaded? */
514
515 /*
516 * At this point, xf86DriverList[] is all filled in with entries for
517 * each of the drivers to try and xf86NumDrivers has the number of
518 * drivers. If there are none, return now.
519 */
520
521 if (xf86NumDrivers == 0) {
522 xf86Msg(X_ERROR, "No drivers available.\n");
523 return;
524 }
525
526 /*
527 * Call each of the Identify functions and call the driverFunc to check
528 * if HW access is required. The Identify functions print out some
529 * identifying information, and anything else that might be
530 * needed at this early stage.
531 */
532
533 for (i = 0; i < xf86NumDrivers; i++) {
534 xorgHWFlags flags = HW_IO;
535
536 if (xf86DriverList[i]->Identify != NULL)
537 xf86DriverList[i]->Identify(0);
538
539 if (xf86DriverList[i]->driverFunc)
540 xf86DriverList[i]->driverFunc(NULL,
541 GET_REQUIRED_HW_INTERFACES,
542 &flags);
543
544 if (NEED_IO_ENABLED(flags))
545 want_hw_access = TRUE;
546
547 if (!(flags & HW_SKIP_CONSOLE))
548 xorgHWOpenConsole = TRUE;
549 }
550
551 if (xorgHWOpenConsole)
552 xf86OpenConsole();
553 else
554 xf86Info.dontVTSwitch = TRUE;
555
556 /* Enable full I/O access */
557 if (want_hw_access)
558 xorgHWAccess = xf86EnableIO();
559
560 if (xf86BusConfig() == FALSE)
561 return;
562
563 xf86PostProbe();
564
565 /*
566 * Sort the drivers to match the requested ording. Using a slow
567 * bubble sort.
568 */
569 for (j = 0; j < xf86NumScreens - 1; j++) {
570 for (i = 0; i < xf86NumScreens - j - 1; i++) {
571 if (xf86Screens[i + 1]->confScreen->screennum <
572 xf86Screens[i]->confScreen->screennum) {
573 ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
574
575 xf86Screens[i + 1] = xf86Screens[i];
576 xf86Screens[i] = tmpScrn;
577 }
578 }
579 }
580 /* Fix up the indexes */
581 for (i = 0; i < xf86NumScreens; i++) {
582 xf86Screens[i]->scrnIndex = i;
583 }
584
585 /*
586 * Call the driver's PreInit()'s to complete initialisation for the first
587 * generation.
588 */
589
590 for (i = 0; i < xf86NumScreens; i++) {
591 xf86VGAarbiterScrnInit(xf86Screens[i]);
592 xf86VGAarbiterLock(xf86Screens[i]);
593 if (xf86Screens[i]->PreInit &&
594 xf86Screens[i]->PreInit(xf86Screens[i], 0))
595 xf86Screens[i]->configured = TRUE;
596 xf86VGAarbiterUnlock(xf86Screens[i]);
597 }
598 for (i = 0; i < xf86NumScreens; i++)
599 if (!xf86Screens[i]->configured)
600 xf86DeleteScreen(xf86Screens[i--]);
601
602 for (i = 0; i < xf86NumGPUScreens; i++) {
603 xf86VGAarbiterScrnInit(xf86GPUScreens[i]);
604 xf86VGAarbiterLock(xf86GPUScreens[i]);
605 if (xf86GPUScreens[i]->PreInit &&
606 xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0))
607 xf86GPUScreens[i]->configured = TRUE;
608 xf86VGAarbiterUnlock(xf86GPUScreens[i]);
609 }
610 for (i = 0; i < xf86NumGPUScreens; i++)
611 if (!xf86GPUScreens[i]->configured)
612 xf86DeleteScreen(xf86GPUScreens[i--]);
613
614 /*
615 * If no screens left, return now.
616 */
617
618 if (xf86NumScreens == 0) {
619 xf86Msg(X_ERROR,
620 "Screen(s) found, but none have a usable configuration.\n");
621 return;
622 }
623
624 for (i = 0; i < xf86NumScreens; i++) {
625 if (xf86Screens[i]->name == NULL) {
626 XNFasprintf(&xf86Screens[i]->name, "screen%d", i);
627 xf86MsgVerb(X_WARNING, 0,
628 "Screen driver %d has no name set, using `%s'.\n",
629 i, xf86Screens[i]->name);
630 }
631 }
632
633 /* Remove (unload) drivers that are not required */
634 for (i = 0; i < xf86NumDrivers; i++)
635 if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
636 xf86DeleteDriver(i);
637
638 /*
639 * At this stage we know how many screens there are.
640 */
641
642 for (i = 0; i < xf86NumScreens; i++)
643 xf86InitViewport(xf86Screens[i]);
644
645 /*
646 * Collect all pixmap formats and check for conflicts at the display
647 * level. Should we die here? Or just delete the offending screens?
648 */
649 screenpix24 = Pix24DontCare;
650 for (i = 0; i < xf86NumScreens; i++) {
651 if (xf86Screens[i]->imageByteOrder !=
652 xf86Screens[0]->imageByteOrder)
653 FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
654 if (xf86Screens[i]->bitmapScanlinePad !=
655 xf86Screens[0]->bitmapScanlinePad)
656 FatalError
657 ("Inconsistent display bitmapScanlinePad. Exiting\n");
658 if (xf86Screens[i]->bitmapScanlineUnit !=
659 xf86Screens[0]->bitmapScanlineUnit)
660 FatalError
661 ("Inconsistent display bitmapScanlineUnit. Exiting\n");
662 if (xf86Screens[i]->bitmapBitOrder !=
663 xf86Screens[0]->bitmapBitOrder)
664 FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
665
666 /* Determine the depth 24 pixmap format the screens would like */
667 if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
668 if (screenpix24 == Pix24DontCare)
669 screenpix24 = xf86Screens[i]->pixmap24;
670 else if (screenpix24 != xf86Screens[i]->pixmap24)
671 FatalError
672 ("Inconsistent depth 24 pixmap format. Exiting\n");
673 }
674 }
675 /* check if screenpix24 is consistent with the config/cmdline */
676 if (xf86Info.pixmap24 != Pix24DontCare) {
677 pix24 = xf86Info.pixmap24;
678 pix24From = xf86Info.pix24From;
679 if (screenpix24 != Pix24DontCare &&
680 screenpix24 != xf86Info.pixmap24)
681 pix24Fail = TRUE;
682 }
683 else if (screenpix24 != Pix24DontCare) {
684 pix24 = screenpix24;
685 pix24From = X_PROBED;
686 }
687 else
688 pix24 = Pix24Use32;
689
690 if (pix24Fail)
691 FatalError("Screen(s) can't use the required depth 24 pixmap format"
692 " (%d). Exiting\n", PIX24TOBPP(pix24));
693
694 /* Initialise the depth 24 format */
695 for (j = 0; j < numFormats && formats[j].depth != 24; j++);
696 formats[j].bitsPerPixel = PIX24TOBPP(pix24);
697
698 /* Collect additional formats */
699 for (i = 0; i < xf86NumScreens; i++) {
700 for (j = 0; j < xf86Screens[i]->numFormats; j++) {
701 for (k = 0;; k++) {
702 if (k >= numFormats) {
703 if (k >= MAXFORMATS)
704 FatalError("Too many pixmap formats! Exiting\n");
705 formats[k] = xf86Screens[i]->formats[j];
706 numFormats++;
707 break;
708 }
709 if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
710 if ((formats[k].bitsPerPixel ==
711 xf86Screens[i]->formats[j].bitsPerPixel) &&
712 (formats[k].scanlinePad ==
713 xf86Screens[i]->formats[j].scanlinePad))
714 break;
715 FatalError("Inconsistent pixmap format for depth %d."
716 " Exiting\n", formats[k].depth);
717 }
718 }
719 }
720 }
721 formatsDone = TRUE;
722
723 if (xf86Info.vtno >= 0) {
724#define VT_ATOM_NAME "XFree86_VT"
725 Atom VTAtom = -1;
726 CARD32 *VT = NULL;
727 int ret;
728
729 /* This memory needs to stay available until the screen has been
730 initialized, and we can create the property for real.
731 */
732 if ((VT = malloc(sizeof(CARD32))) == NULL) {
733 FatalError
734 ("Unable to make VT property - out of memory. Exiting...\n");
735 }
736 *VT = xf86Info.vtno;
737
738 VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
739
740 for (i = 0, ret = Success; i < xf86NumScreens && ret == Success;
741 i++) {
742 ret =
743 xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
744 VTAtom, XA_INTEGER, 32, 1,
745 VT);
746 if (ret != Success)
747 xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
748 "Failed to register VT property\n");
749 }
750 }
751
752 if (SeatId) {
753 Atom SeatAtom;
754
755 SeatAtom =
756 MakeAtom(SEAT_ATOM_NAME, sizeof(SEAT_ATOM_NAME) - 1, TRUE);
757
758 for (i = 0; i < xf86NumScreens; i++) {
759 int ret;
760
761 ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
762 SeatAtom, XA_STRING, 8,
763 strlen(SeatId) + 1,
764 SeatId);
765 if (ret != Success) {
766 xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
767 "Failed to register seat property\n");
768 }
769 }
770 }
771
772 /* If a screen uses depth 24, show what the pixmap format is */
773 for (i = 0; i < xf86NumScreens; i++) {
774 if (xf86Screens[i]->depth == 24) {
775 xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
776 PIX24TOBPP(pix24));
777 break;
778 }
779 }
780 }
781 else {
782 /*
783 * serverGeneration != 1; some OSs have to do things here, too.
784 */
785 if (xorgHWOpenConsole)
786 xf86OpenConsole();
787
788#ifdef XF86PM
789 /*
790 should we reopen it here? We need to deal with an already opened
791 device. We could leave this to the OS layer. For now we simply
792 close it here
793 */
794 if (xf86OSPMClose)
795 xf86OSPMClose();
796 if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
797 xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
798#endif
799
800 /* Make sure full I/O access is enabled */
801 if (xorgHWAccess)
802 xf86EnableIO();
803 }
804
805 /*
806 * Use the previously collected parts to setup pScreenInfo
807 */
808
809 pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
810 pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
811 pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
812 pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
813 pScreenInfo->numPixmapFormats = numFormats;
814 for (i = 0; i < numFormats; i++)
815 pScreenInfo->formats[i] = formats[i];
816
817 /* Make sure the server's VT is active */
818
819 if (serverGeneration != 1) {
820 xf86Resetting = TRUE;
821 /* All screens are in the same state, so just check the first */
822 if (!xf86VTOwner()) {
823#ifdef HAS_USL_VTS
824 ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
825#endif
826 xf86AccessEnter();
827 OsBlockSIGIO();
828 sigio_blocked = TRUE;
829 }
830 }
831
832 for (i = 0; i < xf86NumScreens; i++)
833 if (!xf86ColormapAllocatePrivates(xf86Screens[i]))
834 FatalError("Cannot register DDX private keys");
835
836 if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0) ||
837 !dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
838 FatalError("Cannot register DDX private keys");
839
840 for (i = 0; i < xf86NumGPUScreens; i++) {
841 ScrnInfoPtr pScrn = xf86GPUScreens[i];
842 xf86VGAarbiterLock(pScrn);
843
844 /*
845 * Almost everything uses these defaults, and many of those that
846 * don't, will wrap them.
847 */
848 pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
849#ifdef XFreeXDGA
850 pScrn->SetDGAMode = xf86SetDGAMode;
851#endif
852 pScrn->DPMSSet = NULL;
853 pScrn->LoadPalette = NULL;
854 pScrn->SetOverscan = NULL;
855 pScrn->DriverFunc = NULL;
856 pScrn->pScreen = NULL;
857 scr_index = AddGPUScreen(pScrn->ScreenInit, argc, argv);
858 xf86VGAarbiterUnlock(pScrn);
859 if (scr_index == i) {
860 dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates,
861 xf86ScreenKey, xf86GPUScreens[i]);
862 pScrn->pScreen = screenInfo.gpuscreens[scr_index];
863 /* The driver should set this, but make sure it is set anyway */
864 pScrn->vtSema = TRUE;
865 } else {
866 FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index);
867 }
868 }
869
870 for (i = 0; i < xf86NumScreens; i++) {
871 xf86VGAarbiterLock(xf86Screens[i]);
872 /*
873 * Almost everything uses these defaults, and many of those that
874 * don't, will wrap them.
875 */
876 xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
877#ifdef XFreeXDGA
878 xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
879#endif
880 xf86Screens[i]->DPMSSet = NULL;
881 xf86Screens[i]->LoadPalette = NULL;
882 xf86Screens[i]->SetOverscan = NULL;
883 xf86Screens[i]->DriverFunc = NULL;
884 xf86Screens[i]->pScreen = NULL;
885 scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
886 xf86VGAarbiterUnlock(xf86Screens[i]);
887 if (scr_index == i) {
888 /*
889 * Hook in our ScrnInfoRec, and initialise some other pScreen
890 * fields.
891 */
892 dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
893 xf86ScreenKey, xf86Screens[i]);
894 xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
895 /* The driver should set this, but make sure it is set anyway */
896 xf86Screens[i]->vtSema = TRUE;
897 }
898 else {
899 /* This shouldn't normally happen */
900 FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
901 }
902
903 DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
904 i, xf86Screens[i]->pScreen);
905 DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
906 i, xf86Screens[i]->pScreen->CreateWindow);
907
908 dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
909 xf86CreateRootWindowKey,
910 xf86Screens[i]->pScreen->CreateWindow);
911 xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
912
913 if (PictureGetSubpixelOrder(xf86Screens[i]->pScreen) == SubPixelUnknown) {
914 xf86MonPtr DDC = (xf86MonPtr) (xf86Screens[i]->monitor->DDC);
915
916 PictureSetSubpixelOrder(xf86Screens[i]->pScreen,
917 DDC ?
918 (DDC->features.input_type ?
919 SubPixelHorizontalRGB : SubPixelNone) :
920 SubPixelUnknown);
921 }
922#ifdef RANDR
923 if (!xf86Info.disableRandR)
924 xf86RandRInit(screenInfo.screens[scr_index]);
925 xf86Msg(xf86Info.randRFrom, "RandR %s\n",
926 xf86Info.disableRandR ? "disabled" : "enabled");
927#endif
928 }
929
930 for (i = 0; i < xf86NumGPUScreens; i++)
931 AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);
932
933 xf86VGAarbiterWrapFunctions();
934 if (sigio_blocked)
935 OsReleaseSIGIO();
936
937 xf86InitOrigins();
938
939 xf86Resetting = FALSE;
940 xf86Initialising = FALSE;
941
942 RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr) NoopDDA, xf86Wakeup,
943 NULL);
944}
945
946/**
947 * Initialize all supported input devices present and referenced in the
948 * xorg.conf.
949 */
950void
951InitInput(int argc, char **argv)
952{
953 InputInfoPtr *pInfo;
954 DeviceIntPtr dev;
955
956 xf86Info.vtRequestsPending = FALSE;
957
958 mieqInit();
959
960 /* Initialize all configured input devices */
961 for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) {
962 (*pInfo)->options =
963 xf86AddNewOption((*pInfo)->options, "driver", (*pInfo)->driver);
964 (*pInfo)->options =
965 xf86AddNewOption((*pInfo)->options, "identifier", (*pInfo)->name);
966 /* If one fails, the others will too */
967 if (NewInputDeviceRequest((*pInfo)->options, NULL, &dev) == BadAlloc)
968 break;
969 }
970
971 config_init();
972}
973
974void
975CloseInput(void)
976{
977 config_fini();
978 mieqFini();
979}
980
981/*
982 * OsVendorInit --
983 * OS/Vendor-specific initialisations. Called from OsInit(), which
984 * is called by dix before establishing the well known sockets.
985 */
986
987void
988OsVendorInit(void)
989{
990 static Bool beenHere = FALSE;
991
992 signal(SIGCHLD, SIG_DFL); /* Need to wait for child processes */
993
994 if (!beenHere) {
995 umask(022);
996 xf86LogInit();
997 }
998
999 /* Set stderr to non-blocking. */
1000#ifndef O_NONBLOCK
1001#if defined(FNDELAY)
1002#define O_NONBLOCK FNDELAY
1003#elif defined(O_NDELAY)
1004#define O_NONBLOCK O_NDELAY
1005#endif
1006
1007#ifdef O_NONBLOCK
1008 if (!beenHere) {
1009 if (xf86PrivsElevated()) {
1010 int status;
1011
1012 status = fcntl(fileno(stderr), F_GETFL, 0);
1013 if (status != -1) {
1014 fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
1015 }
1016 }
1017 }
1018#endif
1019#endif
1020
1021 beenHere = TRUE;
1022}
1023
1024/*
1025 * ddxGiveUp --
1026 * Device dependent cleanup. Called by by dix before normal server death.
1027 * For SYSV386 we must switch the terminal back to normal mode. No error-
1028 * checking here, since there should be restored as much as possible.
1029 */
1030
1031void
1032ddxGiveUp(enum ExitCode error)
1033{
1034 int i;
1035
1036 xf86VGAarbiterFini();
1037
1038#ifdef XF86PM
1039 if (xf86OSPMClose)
1040 xf86OSPMClose();
1041 xf86OSPMClose = NULL;
1042#endif
1043
1044 for (i = 0; i < xf86NumScreens; i++) {
1045 /*
1046 * zero all access functions to
1047 * trap calls when switched away.
1048 */
1049 xf86Screens[i]->vtSema = FALSE;
1050 }
1051
1052#ifdef XFreeXDGA
1053 DGAShutdown();
1054#endif
1055
1056 if (xorgHWOpenConsole)
1057 xf86CloseConsole();
1058
1059 xf86CloseLog(error);
1060
1061 /* If an unexpected signal was caught, dump a core for debugging */
1062 if (xf86Info.caughtSignal)
1063 OsAbort();
1064}
1065
1066/*
1067 * AbortDDX --
1068 * DDX - specific abort routine. Called by AbortServer(). The attempt is
1069 * made to restore all original setting of the displays. Also all devices
1070 * are closed.
1071 */
1072
1073void
1074AbortDDX(enum ExitCode error)
1075{
1076 int i;
1077
1078 OsBlockSIGIO();
1079
1080 /*
1081 * try to restore the original video state
1082 */
1083#ifdef DPMSExtension /* Turn screens back on */
1084 if (DPMSPowerLevel != DPMSModeOn)
1085 DPMSSet(serverClient, DPMSModeOn);
1086#endif
1087 if (xf86Screens) {
1088 for (i = 0; i < xf86NumScreens; i++)
1089 if (xf86Screens[i]->vtSema) {
1090 /*
1091 * if we are aborting before ScreenInit() has finished
1092 * we might not have been wrapped yet. Therefore enable
1093 * screen explicitely.
1094 */
1095 xf86VGAarbiterLock(xf86Screens[i]);
1096 (xf86Screens[i]->LeaveVT) (xf86Screens[i]);
1097 xf86VGAarbiterUnlock(xf86Screens[i]);
1098 }
1099 }
1100
1101 xf86AccessLeave();
1102
1103 /*
1104 * This is needed for an abnormal server exit, since the normal exit stuff
1105 * MUST also be performed (i.e. the vt must be left in a defined state)
1106 */
1107 ddxGiveUp(error);
1108}
1109
1110void
1111OsVendorFatalError(const char *f, va_list args)
1112{
1113#ifdef VENDORSUPPORT
1114 ErrorFSigSafe("\nPlease refer to your Operating System Vendor support "
1115 "pages\nat %s for support on this crash.\n", VENDORSUPPORT);
1116#else
1117 ErrorFSigSafe("\nPlease consult the " XVENDORNAME " support \n\t at "
1118 __VENDORDWEBSUPPORT__ "\n for help. \n");
1119#endif
1120 if (xf86LogFile && xf86LogFileWasOpened)
1121 ErrorFSigSafe("Please also check the log file at \"%s\" for additional "
1122 "information.\n", xf86LogFile);
1123 ErrorFSigSafe("\n");
1124}
1125
1126int
1127xf86SetVerbosity(int verb)
1128{
1129 int save = xf86Verbose;
1130
1131 xf86Verbose = verb;
1132 LogSetParameter(XLOG_VERBOSITY, verb);
1133 return save;
1134}
1135
1136int
1137xf86SetLogVerbosity(int verb)
1138{
1139 int save = xf86LogVerbose;
1140
1141 xf86LogVerbose = verb;
1142 LogSetParameter(XLOG_FILE_VERBOSITY, verb);
1143 return save;
1144}
1145
1146static void
1147xf86PrintDefaultModulePath(void)
1148{
1149 ErrorF("%s\n", DEFAULT_MODULE_PATH);
1150}
1151
1152static void
1153xf86PrintDefaultLibraryPath(void)
1154{
1155 ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
1156}
1157
1158/*
1159 * ddxProcessArgument --
1160 * Process device-dependent command line args. Returns 0 if argument is
1161 * not device dependent, otherwise Count of number of elements of argv
1162 * that are part of a device dependent commandline option.
1163 *
1164 */
1165
1166/* ARGSUSED */
1167int
1168ddxProcessArgument(int argc, char **argv, int i)
1169{
1170#define CHECK_FOR_REQUIRED_ARGUMENT() \
1171 if (((i + 1) >= argc) || (!argv[i + 1])) { \
1172 ErrorF("Required argument to %s not specified\n", argv[i]); \
1173 UseMsg(); \
1174 FatalError("Required argument to %s not specified\n", argv[i]); \
1175 }
1176
1177 /* First the options that are not allowed with elevated privileges */
1178 if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
1179 if (xf86PrivsElevated()) {
1180 FatalError("The '%s' option cannot be used with "
1181 "elevated privileges.\n", argv[i]);
1182 }
1183 else if (!strcmp(argv[i], "-modulepath")) {
1184 char *mp;
1185
1186 CHECK_FOR_REQUIRED_ARGUMENT();
1187 mp = strdup(argv[i + 1]);
1188 if (!mp)
1189 FatalError("Can't allocate memory for ModulePath\n");
1190 xf86ModulePath = mp;
1191 xf86ModPathFrom = X_CMDLINE;
1192 return 2;
1193 }
1194 else if (!strcmp(argv[i], "-logfile")) {
1195 char *lf;
1196
1197 CHECK_FOR_REQUIRED_ARGUMENT();
1198 lf = strdup(argv[i + 1]);
1199 if (!lf)
1200 FatalError("Can't allocate memory for LogFile\n");
1201 xf86LogFile = lf;
1202 xf86LogFileFrom = X_CMDLINE;
1203 return 2;
1204 }
1205 }
1206 if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config")) {
1207 CHECK_FOR_REQUIRED_ARGUMENT();
1208 if (xf86PrivsElevated() && !xf86PathIsSafe(argv[i + 1])) {
1209 FatalError("\nInvalid argument for %s\n"
1210 "\tWith elevated privileges, the file specified with %s must be\n"
1211 "\ta relative path and must not contain any \"..\" elements.\n"
1212 "\tUsing default " __XCONFIGFILE__ " search path.\n\n",
1213 argv[i], argv[i]);
1214 }
1215 xf86ConfigFile = argv[i + 1];
1216 return 2;
1217 }
1218 if (!strcmp(argv[i], "-configdir")) {
1219 CHECK_FOR_REQUIRED_ARGUMENT();
1220 if (xf86PrivsElevated() && !xf86PathIsSafe(argv[i + 1])) {
1221 FatalError("\nInvalid argument for %s\n"
1222 "\tWith elevated privileges, the file specified with %s must be\n"
1223 "\ta relative path and must not contain any \"..\" elements.\n"
1224 "\tUsing default " __XCONFIGDIR__ " search path.\n\n",
1225 argv[i], argv[i]);
1226 }
1227 xf86ConfigDir = argv[i + 1];
1228 return 2;
1229 }
1230 if (!strcmp(argv[i], "-flipPixels")) {
1231 xf86FlipPixels = TRUE;
1232 return 1;
1233 }
1234#ifdef XF86VIDMODE
1235 if (!strcmp(argv[i], "-disableVidMode")) {
1236 xf86VidModeDisabled = TRUE;
1237 return 1;
1238 }
1239 if (!strcmp(argv[i], "-allowNonLocalXvidtune")) {
1240 xf86VidModeAllowNonLocal = TRUE;
1241 return 1;
1242 }
1243#endif
1244 if (!strcmp(argv[i], "-allowMouseOpenFail")) {
1245 xf86AllowMouseOpenFail = TRUE;
1246 return 1;
1247 }
1248 if (!strcmp(argv[i], "-ignoreABI")) {
1249 LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
1250 return 1;
1251 }
1252 if (!strcmp(argv[i], "-verbose")) {
1253 if (++i < argc && argv[i]) {
1254 char *end;
1255 long val;
1256
1257 val = strtol(argv[i], &end, 0);
1258 if (*end == '\0') {
1259 xf86SetVerbosity(val);
1260 return 2;
1261 }
1262 }
1263 xf86SetVerbosity(++xf86Verbose);
1264 return 1;
1265 }
1266 if (!strcmp(argv[i], "-logverbose")) {
1267 if (++i < argc && argv[i]) {
1268 char *end;
1269 long val;
1270
1271 val = strtol(argv[i], &end, 0);
1272 if (*end == '\0') {
1273 xf86SetLogVerbosity(val);
1274 return 2;
1275 }
1276 }
1277 xf86SetLogVerbosity(++xf86LogVerbose);
1278 return 1;
1279 }
1280 if (!strcmp(argv[i], "-quiet")) {
1281 xf86SetVerbosity(-1);
1282 return 1;
1283 }
1284 if (!strcmp(argv[i], "-showconfig") || !strcmp(argv[i], "-version")) {
1285 xf86PrintBanner();
1286 exit(0);
1287 }
1288 if (!strcmp(argv[i], "-showDefaultModulePath")) {
1289 xf86PrintDefaultModulePath();
1290 exit(0);
1291 }
1292 if (!strcmp(argv[i], "-showDefaultLibPath")) {
1293 xf86PrintDefaultLibraryPath();
1294 exit(0);
1295 }
1296 /* Notice the -fp flag, but allow it to pass to the dix layer */
1297 if (!strcmp(argv[i], "-fp")) {
1298 xf86fpFlag = TRUE;
1299 return 0;
1300 }
1301 /* Notice the -bs flag, but allow it to pass to the dix layer */
1302 if (!strcmp(argv[i], "-bs")) {
1303 xf86bsDisableFlag = TRUE;
1304 return 0;
1305 }
1306 /* Notice the +bs flag, but allow it to pass to the dix layer */
1307 if (!strcmp(argv[i], "+bs")) {
1308 xf86bsEnableFlag = TRUE;
1309 return 0;
1310 }
1311 /* Notice the -s flag, but allow it to pass to the dix layer */
1312 if (!strcmp(argv[i], "-s")) {
1313 xf86sFlag = TRUE;
1314 return 0;
1315 }
1316 if (!strcmp(argv[i], "-pixmap24")) {
1317 xf86Pix24 = Pix24Use24;
1318 return 1;
1319 }
1320 if (!strcmp(argv[i], "-pixmap32")) {
1321 xf86Pix24 = Pix24Use32;
1322 return 1;
1323 }
1324 if (!strcmp(argv[i], "-fbbpp")) {
1325 int bpp;
1326
1327 CHECK_FOR_REQUIRED_ARGUMENT();
1328 if (sscanf(argv[++i], "%d", &bpp) == 1) {
1329 xf86FbBpp = bpp;
1330 return 2;
1331 }
1332 else {
1333 ErrorF("Invalid fbbpp\n");
1334 return 0;
1335 }
1336 }
1337 if (!strcmp(argv[i], "-depth")) {
1338 int depth;
1339
1340 CHECK_FOR_REQUIRED_ARGUMENT();
1341 if (sscanf(argv[++i], "%d", &depth) == 1) {
1342 xf86Depth = depth;
1343 return 2;
1344 }
1345 else {
1346 ErrorF("Invalid depth\n");
1347 return 0;
1348 }
1349 }
1350 if (!strcmp(argv[i], "-weight")) {
1351 int red, green, blue;
1352
1353 CHECK_FOR_REQUIRED_ARGUMENT();
1354 if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3) {
1355 xf86Weight.red = red;
1356 xf86Weight.green = green;
1357 xf86Weight.blue = blue;
1358 return 2;
1359 }
1360 else {
1361 ErrorF("Invalid weighting\n");
1362 return 0;
1363 }
1364 }
1365 if (!strcmp(argv[i], "-gamma") || !strcmp(argv[i], "-rgamma") ||
1366 !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma")) {
1367 double gamma;
1368
1369 CHECK_FOR_REQUIRED_ARGUMENT();
1370 if (sscanf(argv[++i], "%lf", &gamma) == 1) {
1371 if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
1372 ErrorF("gamma out of range, only %.2f <= gamma_value <= %.1f"
1373 " is valid\n", GAMMA_MIN, GAMMA_MAX);
1374 return 0;
1375 }
1376 if (!strcmp(argv[i - 1], "-gamma"))
1377 xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
1378 else if (!strcmp(argv[i - 1], "-rgamma"))
1379 xf86Gamma.red = gamma;
1380 else if (!strcmp(argv[i - 1], "-ggamma"))
1381 xf86Gamma.green = gamma;
1382 else if (!strcmp(argv[i - 1], "-bgamma"))
1383 xf86Gamma.blue = gamma;
1384 return 2;
1385 }
1386 }
1387 if (!strcmp(argv[i], "-layout")) {
1388 CHECK_FOR_REQUIRED_ARGUMENT();
1389 xf86LayoutName = argv[++i];
1390 return 2;
1391 }
1392 if (!strcmp(argv[i], "-screen")) {
1393 CHECK_FOR_REQUIRED_ARGUMENT();
1394 xf86ScreenName = argv[++i];
1395 return 2;
1396 }
1397 if (!strcmp(argv[i], "-pointer")) {
1398 CHECK_FOR_REQUIRED_ARGUMENT();
1399 xf86PointerName = argv[++i];
1400 return 2;
1401 }
1402 if (!strcmp(argv[i], "-keyboard")) {
1403 CHECK_FOR_REQUIRED_ARGUMENT();
1404 xf86KeyboardName = argv[++i];
1405 return 2;
1406 }
1407 if (!strcmp(argv[i], "-nosilk")) {
1408 xf86silkenMouseDisableFlag = TRUE;
1409 return 1;
1410 }
1411#ifdef HAVE_ACPI
1412 if (!strcmp(argv[i], "-noacpi")) {
1413 xf86acpiDisableFlag = TRUE;
1414 return 1;
1415 }
1416#endif
1417 if (!strcmp(argv[i], "-configure")) {
1418 if (getuid() != 0 && geteuid() == 0) {
1419 ErrorF("The '-configure' option can only be used by root.\n");
1420 exit(1);
1421 }
1422 xf86DoConfigure = TRUE;
1423 xf86AllowMouseOpenFail = TRUE;
1424 return 1;
1425 }
1426 if (!strcmp(argv[i], "-showopts")) {
1427 if (getuid() != 0 && geteuid() == 0) {
1428 ErrorF("The '-showopts' option can only be used by root.\n");
1429 exit(1);
1430 }
1431 xf86DoShowOptions = TRUE;
1432 return 1;
1433 }
1434#ifdef XSERVER_LIBPCIACCESS
1435 if (!strcmp(argv[i], "-isolateDevice")) {
1436 CHECK_FOR_REQUIRED_ARGUMENT();
1437 if (strncmp(argv[++i], "PCI:", 4)) {
1438 FatalError("Bus types other than PCI not yet isolable\n");
1439 }
1440 xf86PciIsolateDevice(argv[i]);
1441 return 2;
1442 }
1443#endif
1444 /* Notice cmdline xkbdir, but pass to dix as well */
1445 if (!strcmp(argv[i], "-xkbdir")) {
1446 xf86xkbdirFlag = TRUE;
1447 return 0;
1448 }
1449 if (!strcmp(argv[i], "-novtswitch")) {
1450 xf86Info.autoVTSwitch = FALSE;
1451 return 1;
1452 }
1453 if (!strcmp(argv[i], "-sharevts")) {
1454 xf86Info.ShareVTs = TRUE;
1455 return 1;
1456 }
1457
1458 /* OS-specific processing */
1459 return xf86ProcessArgument(argc, argv, i);
1460}
1461
1462/*
1463 * ddxUseMsg --
1464 * Print out correct use of device dependent commandline options.
1465 * Maybe the user now knows what really to do ...
1466 */
1467
1468void
1469ddxUseMsg(void)
1470{
1471 ErrorF("\n");
1472 ErrorF("\n");
1473 ErrorF("Device Dependent Usage\n");
1474 if (!xf86PrivsElevated()) {
1475 ErrorF("-modulepath paths specify the module search path\n");
1476 ErrorF("-logfile file specify a log file name\n");
1477 ErrorF("-configure probe for devices and write an "
1478 __XCONFIGFILE__ "\n");
1479 ErrorF
1480 ("-showopts print available options for all installed drivers\n");
1481 }
1482 ErrorF
1483 ("-config file specify a configuration file, relative to the\n");
1484 ErrorF(" " __XCONFIGFILE__
1485 " search path, only root can use absolute\n");
1486 ErrorF
1487 ("-configdir dir specify a configuration directory, relative to the\n");
1488 ErrorF(" " __XCONFIGDIR__
1489 " search path, only root can use absolute\n");
1490 ErrorF("-verbose [n] verbose startup messages\n");
1491 ErrorF("-logverbose [n] verbose log messages\n");
1492 ErrorF("-quiet minimal startup messages\n");
1493 ErrorF("-pixmap24 use 24bpp pixmaps for depth 24\n");
1494 ErrorF("-pixmap32 use 32bpp pixmaps for depth 24\n");
1495 ErrorF("-fbbpp n set bpp for the framebuffer. Default: 8\n");
1496 ErrorF("-depth n set colour depth. Default: 8\n");
1497 ErrorF
1498 ("-gamma f set gamma value (0.1 < f < 10.0) Default: 1.0\n");
1499 ErrorF("-rgamma f set gamma value for red phase\n");
1500 ErrorF("-ggamma f set gamma value for green phase\n");
1501 ErrorF("-bgamma f set gamma value for blue phase\n");
1502 ErrorF
1503 ("-weight nnn set RGB weighting at 16 bpp. Default: 565\n");
1504 ErrorF("-layout name specify the ServerLayout section name\n");
1505 ErrorF("-screen name specify the Screen section name\n");
1506 ErrorF
1507 ("-keyboard name specify the core keyboard InputDevice name\n");
1508 ErrorF
1509 ("-pointer name specify the core pointer InputDevice name\n");
1510 ErrorF("-nosilk disable Silken Mouse\n");
1511 ErrorF("-flipPixels swap default black/white Pixel values\n");
1512#ifdef XF86VIDMODE
1513 ErrorF("-disableVidMode disable mode adjustments with xvidtune\n");
1514 ErrorF
1515 ("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
1516#endif
1517 ErrorF
1518 ("-allowMouseOpenFail start server even if the mouse can't be initialized\n");
1519 ErrorF("-ignoreABI make module ABI mismatches non-fatal\n");
1520#ifdef XSERVER_LIBPCIACCESS
1521 ErrorF
1522 ("-isolateDevice bus_id restrict device resets to bus_id (PCI only)\n");
1523#endif
1524 ErrorF("-version show the server version\n");
1525 ErrorF("-showDefaultModulePath show the server default module path\n");
1526 ErrorF("-showDefaultLibPath show the server default library path\n");
1527 ErrorF
1528 ("-novtswitch don't automatically switch VT at reset & exit\n");
1529 ErrorF("-sharevts share VTs with another X server\n");
1530 /* OS-specific usage */
1531 xf86UseMsg();
1532 ErrorF("\n");
1533}
1534
1535/*
1536 * xf86LoadModules iterates over a list that is being passed in.
1537 */
1538Bool
1539xf86LoadModules(char **list, pointer *optlist)
1540{
1541 int errmaj, errmin;
1542 pointer opt;
1543 int i;
1544 char *name;
1545 Bool failed = FALSE;
1546
1547 if (!list)
1548 return TRUE;
1549
1550 for (i = 0; list[i] != NULL; i++) {
1551
1552 /* Normalise the module name */
1553 name = xf86NormalizeName(list[i]);
1554
1555 /* Skip empty names */
1556 if (name == NULL || *name == '\0') {
1557 free(name);
1558 continue;
1559 }
1560
1561 /* Replace obsolete keyboard driver with kbd */
1562 if (!xf86NameCmp(name, "keyboard")) {
1563 strcpy(name, "kbd");
1564 }
1565
1566 if (optlist)
1567 opt = optlist[i];
1568 else
1569 opt = NULL;
1570
1571 if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
1572 LoaderErrorMsg(NULL, name, errmaj, errmin);
1573 failed = TRUE;
1574 }
1575 free(name);
1576 }
1577 return !failed;
1578}
1579
1580/* Pixmap format stuff */
1581
1582PixmapFormatPtr
1583xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
1584{
1585 int i;
1586 static PixmapFormatRec format; /* XXX not reentrant */
1587
1588 /*
1589 * When the formats[] list initialisation isn't complete, check the
1590 * depth 24 pixmap config/cmdline options and screen-specified formats.
1591 */
1592
1593 if (!formatsDone) {
1594 if (depth == 24) {
1595 Pix24Flags pix24 = Pix24DontCare;
1596
1597 format.depth = 24;
1598 format.scanlinePad = BITMAP_SCANLINE_PAD;
1599 if (xf86Info.pixmap24 != Pix24DontCare)
1600 pix24 = xf86Info.pixmap24;
1601 else if (pScrn->pixmap24 != Pix24DontCare)
1602 pix24 = pScrn->pixmap24;
1603 if (pix24 == Pix24Use24)
1604 format.bitsPerPixel = 24;
1605 else
1606 format.bitsPerPixel = 32;
1607 return &format;
1608 }
1609 }
1610
1611 for (i = 0; i < numFormats; i++)
1612 if (formats[i].depth == depth)
1613 break;
1614 if (i != numFormats)
1615 return &formats[i];
1616 else if (!formatsDone) {
1617 /* Check for screen-specified formats */
1618 for (i = 0; i < pScrn->numFormats; i++)
1619 if (pScrn->formats[i].depth == depth)
1620 break;
1621 if (i != pScrn->numFormats)
1622 return &pScrn->formats[i];
1623 }
1624 return NULL;
1625}
1626
1627int
1628xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
1629{
1630 PixmapFormatPtr format;
1631
1632 format = xf86GetPixFormat(pScrn, depth);
1633 if (format)
1634 return format->bitsPerPixel;
1635 else
1636 return 0;
1637}
1638
1639#ifdef DDXBEFORERESET
1640void
1641ddxBeforeReset(void)
1642{
1643}
1644#endif