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