xf86Init.c revision 05b261ec
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#define NEED_EVENTS
47#include <X11/X.h>
48#include <X11/Xmd.h>
49#include <X11/Xproto.h>
50#include <X11/Xatom.h>
51#include "input.h"
52#include "servermd.h"
53#include "windowstr.h"
54#include "scrnintstr.h"
55#include "site.h"
56#include "mi.h"
57
58#include "compiler.h"
59
60#include "loaderProcs.h"
61#ifdef XFreeXDGA
62#include "dgaproc.h"
63#endif
64
65#define XF86_OS_PRIVS
66#include "xf86.h"
67#include "xf86Priv.h"
68#include "xf86Config.h"
69#include "xf86_OSlib.h"
70#include "xorgVersion.h"
71#include "xf86Date.h"
72#include "xf86Build.h"
73#include "mipointer.h"
74#ifdef XINPUT
75#include <X11/extensions/XI.h>
76#include <X11/extensions/XIproto.h>
77#else
78#include "inputstr.h"
79#endif
80#include "xf86DDC.h"
81#include "xf86Xinput.h"
82#include "xf86InPriv.h"
83#ifdef RENDER
84#include "picturestr.h"
85#endif
86
87#include "globals.h"
88
89#ifdef DPMSExtension
90#define DPMS_SERVER
91#include <X11/extensions/dpms.h>
92#include "dpmsproc.h"
93#endif
94
95
96/* forward declarations */
97
98static void xf86PrintBanner(void);
99static void xf86PrintMarkers(void);
100static void xf86PrintDefaultModulePath(void);
101static void xf86PrintDefaultLibraryPath(void);
102static void xf86RunVtInit(void);
103
104#ifdef XF86PM
105void (*xf86OSPMClose)(void) = NULL;
106#endif
107
108static char *baseModules[] = {
109	"pcidata",
110	NULL
111};
112
113/* Common pixmap formats */
114
115static PixmapFormatRec formats[MAXFORMATS] = {
116	{ 1,	1,	BITMAP_SCANLINE_PAD },
117	{ 4,	8,	BITMAP_SCANLINE_PAD },
118	{ 8,	8,	BITMAP_SCANLINE_PAD },
119	{ 15,	16,	BITMAP_SCANLINE_PAD },
120	{ 16,	16,	BITMAP_SCANLINE_PAD },
121	{ 24,	32,	BITMAP_SCANLINE_PAD },
122#ifdef RENDER
123	{ 32,	32,	BITMAP_SCANLINE_PAD },
124#endif
125};
126#ifdef RENDER
127static int numFormats = 7;
128#else
129static int numFormats = 6;
130#endif
131static Bool formatsDone = FALSE;
132
133static Bool
134xf86CreateRootWindow(WindowPtr pWin)
135{
136  int ret = TRUE;
137  int err = Success;
138  ScreenPtr pScreen = pWin->drawable.pScreen;
139  RootWinPropPtr pProp;
140  CreateWindowProcPtr CreateWindow =
141    (CreateWindowProcPtr)(pScreen->devPrivates[xf86CreateRootWindowIndex].ptr);
142
143#ifdef DEBUG
144  ErrorF("xf86CreateRootWindow(%p)\n", pWin);
145#endif
146
147  if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
148    /* Can't find hook we are hung on */
149	xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
150		  "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
151		   (void *)xf86CreateRootWindow,
152		   (void *)pScreen->CreateWindow );
153  }
154
155  /* Unhook this function ... */
156  pScreen->CreateWindow = CreateWindow;
157  pScreen->devPrivates[xf86CreateRootWindowIndex].ptr = NULL;
158
159  /* ... and call the previous CreateWindow fuction, if any */
160  if (NULL!=pScreen->CreateWindow) {
161    ret = (*pScreen->CreateWindow)(pWin);
162  }
163
164  /* Now do our stuff */
165  if (xf86RegisteredPropertiesTable != NULL) {
166    if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
167      for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
168	   pProp != NULL && err==Success;
169	   pProp = pProp->next )
170	{
171	  Atom prop;
172
173	  prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
174	  err = ChangeWindowProperty(pWin,
175				     prop, pProp->type,
176				     pProp->format, PropModeReplace,
177				     pProp->size, pProp->data,
178				     FALSE
179				     );
180	}
181
182      /* Look at err */
183      ret &= (err==Success);
184
185    } else {
186      xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
187	      "non-root window %p (parent %p)\n",
188	      (void *)pWin, (void *)pWin->parent);
189      ret = FALSE;
190    }
191  }
192
193#ifdef DEBUG
194  ErrorF("xf86CreateRootWindow() returns %d\n", ret);
195#endif
196  return (ret);
197}
198
199
200/*
201 * InitOutput --
202 *	Initialize screenInfo for all actually accessible framebuffers.
203 *      That includes vt-manager setup, querying all possible devices and
204 *      collecting the pixmap formats.
205 */
206
207static void
208PostConfigInit(void)
209{
210    /*
211     * Install signal handler for unexpected signals
212     */
213    xf86Info.caughtSignal=FALSE;
214    if (!xf86Info.notrapSignals) {
215       signal(SIGSEGV,xf86SigHandler);
216       signal(SIGILL,xf86SigHandler);
217#ifdef SIGEMT
218       signal(SIGEMT,xf86SigHandler);
219#endif
220       signal(SIGFPE,xf86SigHandler);
221#ifdef SIGBUS
222       signal(SIGBUS,xf86SigHandler);
223#endif
224#ifdef SIGSYS
225       signal(SIGSYS,xf86SigHandler);
226#endif
227#ifdef SIGXCPU
228       signal(SIGXCPU,xf86SigHandler);
229#endif
230#ifdef SIGXFSZ
231       signal(SIGXFSZ,xf86SigHandler);
232#endif
233    }
234
235#ifdef XF86PM
236    xf86OSPMClose = xf86OSPMOpen();
237#endif
238
239    /* Run an external VT Init program if specified in the config file */
240    xf86RunVtInit();
241
242    /* Do this after XF86Config is read (it's normally in OsInit()) */
243    OsInitColors();
244}
245
246void
247InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
248{
249  int                    i, j, k, scr_index;
250  static unsigned long   generation = 0;
251  char                   **modulelist;
252  pointer                *optionlist;
253  screenLayoutPtr	 layout;
254  Pix24Flags		 screenpix24, pix24;
255  MessageType		 pix24From = X_DEFAULT;
256  Bool			 pix24Fail = FALSE;
257  Bool			 autoconfig = FALSE;
258
259  xf86Initialising = TRUE;
260
261  /* Do this early? */
262  if (generation != serverGeneration) {
263      xf86ScreenIndex = AllocateScreenPrivateIndex();
264      xf86CreateRootWindowIndex = AllocateScreenPrivateIndex();
265      xf86PixmapIndex = AllocatePixmapPrivateIndex();
266      generation = serverGeneration;
267  }
268
269  if (serverGeneration == 1) {
270
271    pScreenInfo->numScreens = 0;
272
273    if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
274      xf86ServerName++;
275    else
276      xf86ServerName = argv[0];
277
278    xf86PrintBanner();
279    xf86PrintMarkers();
280    if (xf86LogFile)  {
281	time_t t;
282	const char *ct;
283	t = time(NULL);
284	ct = ctime(&t);
285	xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
286		    xf86LogFile, ct);
287    }
288
289    /* Read and parse the config file */
290    if (!xf86DoProbe && !xf86DoConfigure) {
291      switch (xf86HandleConfigFile(FALSE)) {
292      case CONFIG_OK:
293	break;
294      case CONFIG_PARSE_ERROR:
295	xf86Msg(X_ERROR, "Error parsing the config file\n");
296	return;
297      case CONFIG_NOFILE:
298	autoconfig = TRUE;
299	break;
300      }
301    }
302
303    if (!autoconfig)
304	PostConfigInit();
305
306    /* Initialise the loader */
307    LoaderInit();
308
309    /* Tell the loader the default module search path */
310    LoaderSetPath(xf86ModulePath);
311
312    if (xf86Info.ignoreABI) {
313        LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
314    }
315
316    /* Force load mandatory base modules */
317    if (!xf86LoadModules(baseModules, NULL))
318	FatalError("Unable to load required base modules, Exiting...\n");
319
320    xf86OpenConsole();
321
322    /* Do a general bus probe.  This will be a PCI probe for x86 platforms */
323    xf86BusProbe();
324
325    if (xf86DoProbe)
326	DoProbe();
327
328    if (xf86DoConfigure)
329	DoConfigure();
330
331    if (autoconfig) {
332	if (!xf86AutoConfig()) {
333	    xf86Msg(X_ERROR, "Auto configuration failed\n");
334	    return;
335	}
336	PostConfigInit();
337    }
338
339    /* Initialise the resource broker */
340    xf86ResourceBrokerInit();
341
342    /* Load all modules specified explicitly in the config file */
343    if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
344      xf86LoadModules(modulelist, optionlist);
345      xfree(modulelist);
346      xfree(optionlist);
347    }
348
349    /* Load all driver modules specified in the config file */
350    if ((modulelist = xf86DriverlistFromConfig())) {
351      xf86LoadModules(modulelist, NULL);
352      xfree(modulelist);
353    }
354
355    /* Load all input driver modules specified in the config file. */
356    if ((modulelist = xf86InputDriverlistFromConfig())) {
357      xf86LoadModules(modulelist, NULL);
358      xfree(modulelist);
359    }
360
361    /*
362     * It is expected that xf86AddDriver()/xf86AddInputDriver will be
363     * called for each driver as it is loaded.  Those functions save the
364     * module pointers for drivers.
365     * XXX Nothing keeps track of them for other modules.
366     */
367    /* XXX What do we do if not all of these could be loaded? */
368
369    /*
370     * At this point, xf86DriverList[] is all filled in with entries for
371     * each of the drivers to try and xf86NumDrivers has the number of
372     * drivers.  If there are none, return now.
373     */
374
375    if (xf86NumDrivers == 0) {
376      xf86Msg(X_ERROR, "No drivers available.\n");
377      return;
378    }
379
380    /*
381     * Call each of the Identify functions and call the driverFunc to check
382     * if HW access is required.  The Identify functions print out some
383     * identifying information, and anything else that might be
384     * needed at this early stage.
385     */
386
387    for (i = 0; i < xf86NumDrivers; i++) {
388	xorgHWFlags flags;
389      /* The Identify function is mandatory, but if it isn't there continue */
390	if (xf86DriverList[i]->Identify != NULL)
391	    xf86DriverList[i]->Identify(0);
392	else {
393	    xf86Msg(X_WARNING, "Driver `%s' has no Identify function\n",
394		  xf86DriverList[i]->driverName ? xf86DriverList[i]->driverName
395					     : "noname");
396	}
397	if (!xorgHWAccess
398	    && (!xf86DriverList[i]->driverFunc
399		|| !xf86DriverList[i]->driverFunc(NULL,
400						  GET_REQUIRED_HW_INTERFACES,
401						  &flags)
402		|| NEED_IO_ENABLED(flags)))
403	    xorgHWAccess = TRUE;
404    }
405
406    /* Enable full I/O access */
407    if (xorgHWAccess) {
408	if(!xf86EnableIO())
409	    /* oops, we have failed */
410	    xorgHWAccess = FALSE;
411    }
412
413    /*
414     * Locate bus slot that had register IO enabled at server startup
415     */
416
417    xf86AccessInit();
418    xf86FindPrimaryDevice();
419
420    /*
421     * Now call each of the Probe functions.  Each successful probe will
422     * result in an extra entry added to the xf86Screens[] list for each
423     * instance of the hardware found.
424     */
425
426    for (i = 0; i < xf86NumDrivers; i++) {
427	xorgHWFlags flags;
428	if (!xorgHWAccess) {
429	    if (!xf86DriverList[i]->driverFunc
430		|| !xf86DriverList[i]->driverFunc(NULL,
431						 GET_REQUIRED_HW_INTERFACES,
432						  &flags)
433		|| NEED_IO_ENABLED(flags))
434		continue;
435	}
436
437	if (xf86DriverList[i]->Probe != NULL)
438	    xf86DriverList[i]->Probe(xf86DriverList[i], PROBE_DEFAULT);
439	else {
440	    xf86MsgVerb(X_WARNING, 0,
441			"Driver `%s' has no Probe function (ignoring)\n",
442			xf86DriverList[i]->driverName
443			? xf86DriverList[i]->driverName : "noname");
444	}
445	xf86SetPciVideo(NULL,NONE);
446    }
447
448    /*
449     * If nothing was detected, return now.
450     */
451
452    if (xf86NumScreens == 0) {
453      xf86Msg(X_ERROR, "No devices detected.\n");
454      return;
455    }
456
457    /*
458     * Match up the screens found by the probes against those specified
459     * in the config file.  Remove the ones that won't be used.  Sort
460     * them in the order specified.
461     */
462
463    /*
464     * What is the best way to do this?
465     *
466     * For now, go through the screens allocated by the probes, and
467     * look for screen config entry which refers to the same device
468     * section as picked out by the probe.
469     *
470     */
471
472    for (i = 0; i < xf86NumScreens; i++) {
473      for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
474	   layout++) {
475	  Bool found = FALSE;
476	  for (j = 0; j < xf86Screens[i]->numEntities; j++) {
477
478	      GDevPtr dev =
479		xf86GetDevFromEntity(xf86Screens[i]->entityList[j],
480				     xf86Screens[i]->entityInstanceList[j]);
481
482	      if (dev == layout->screen->device) {
483		  /* A match has been found */
484		  xf86Screens[i]->confScreen = layout->screen;
485		  found = TRUE;
486		  break;
487	      }
488	  }
489	  if (found) break;
490      }
491      if (layout->screen == NULL) {
492	/* No match found */
493	xf86Msg(X_ERROR,
494	    "Screen %d deleted because of no matching config section.\n", i);
495        xf86DeleteScreen(i--, 0);
496      }
497    }
498
499    /*
500     * If no screens left, return now.
501     */
502
503    if (xf86NumScreens == 0) {
504      xf86Msg(X_ERROR,
505	      "Device(s) detected, but none match those in the config file.\n");
506      return;
507    }
508
509    xf86PostProbe();
510    xf86EntityInit();
511
512    /*
513     * Sort the drivers to match the requested ording.  Using a slow
514     * bubble sort.
515     */
516    for (j = 0; j < xf86NumScreens - 1; j++) {
517	for (i = 0; i < xf86NumScreens - j - 1; i++) {
518	    if (xf86Screens[i + 1]->confScreen->screennum <
519		xf86Screens[i]->confScreen->screennum) {
520		ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
521		xf86Screens[i + 1] = xf86Screens[i];
522		xf86Screens[i] = tmpScrn;
523	    }
524	}
525    }
526    /* Fix up the indexes */
527    for (i = 0; i < xf86NumScreens; i++) {
528	xf86Screens[i]->scrnIndex = i;
529    }
530
531    /*
532     * Call the driver's PreInit()'s to complete initialisation for the first
533     * generation.
534     */
535
536    for (i = 0; i < xf86NumScreens; i++) {
537	xf86EnableAccess(xf86Screens[i]);
538	if (xf86Screens[i]->PreInit &&
539	    xf86Screens[i]->PreInit(xf86Screens[i], 0))
540	    xf86Screens[i]->configured = TRUE;
541    }
542    for (i = 0; i < xf86NumScreens; i++)
543	if (!xf86Screens[i]->configured)
544	    xf86DeleteScreen(i--, 0);
545
546    /*
547     * If no screens left, return now.
548     */
549
550    if (xf86NumScreens == 0) {
551      xf86Msg(X_ERROR,
552	      "Screen(s) found, but none have a usable configuration.\n");
553      return;
554    }
555
556    /* This could be moved into a separate function */
557
558    /*
559     * Check that all screens have initialised the mandatory function
560     * entry points.  Delete those which have not.
561     */
562
563#define WARN_SCREEN(func) \
564    xf86Msg(X_ERROR, "Driver `%s' has no %s function, deleting.\n", \
565	   xf86Screens[i]->name, (warned++, func))
566
567    for (i = 0; i < xf86NumScreens; i++) {
568      int warned = 0;
569      if (xf86Screens[i]->name == NULL) {
570	xf86Screens[i]->name = xnfalloc(strlen("screen") + 1 + 1);
571	if (i < 10)
572	  sprintf(xf86Screens[i]->name, "screen%c", i + '0');
573	else
574	  sprintf(xf86Screens[i]->name, "screen%c", i - 10 + 'A');
575	xf86MsgVerb(X_WARNING, 0,
576		    "Screen driver %d has no name set, using `%s'.\n",
577		    i, xf86Screens[i]->name);
578      }
579      if (xf86Screens[i]->ScreenInit == NULL)
580	WARN_SCREEN("ScreenInit");
581      if (xf86Screens[i]->EnterVT == NULL)
582	WARN_SCREEN("EnterVT");
583      if (xf86Screens[i]->LeaveVT == NULL)
584	WARN_SCREEN("LeaveVT");
585      if (warned)
586	xf86DeleteScreen(i--, 0);
587    }
588
589    /*
590     * If no screens left, return now.
591     */
592
593    if (xf86NumScreens == 0) {
594      xf86Msg(X_ERROR, "Screen(s) found, but drivers were unusable.\n");
595      return;
596    }
597
598    /* XXX Should this be before or after loading dependent modules? */
599    if (xf86ProbeOnly)
600    {
601      OsCleanup(TRUE);
602      AbortDDX();
603      fflush(stderr);
604      exit(0);
605    }
606
607    /* Remove (unload) drivers that are not required */
608    for (i = 0; i < xf86NumDrivers; i++)
609	if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
610	    xf86DeleteDriver(i);
611
612    /*
613     * At this stage we know how many screens there are.
614     */
615
616    for (i = 0; i < xf86NumScreens; i++)
617      xf86InitViewport(xf86Screens[i]);
618
619    /*
620     * Collect all pixmap formats and check for conflicts at the display
621     * level.  Should we die here?  Or just delete the offending screens?
622     * Also, should this be done for -probeonly?
623     */
624    screenpix24 = Pix24DontCare;
625    for (i = 0; i < xf86NumScreens; i++) {
626	if (xf86Screens[i]->imageByteOrder !=
627	    xf86Screens[0]->imageByteOrder)
628	    FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
629	if (xf86Screens[i]->bitmapScanlinePad !=
630	    xf86Screens[0]->bitmapScanlinePad)
631	    FatalError("Inconsistent display bitmapScanlinePad.  Exiting\n");
632	if (xf86Screens[i]->bitmapScanlineUnit !=
633	    xf86Screens[0]->bitmapScanlineUnit)
634	    FatalError("Inconsistent display bitmapScanlineUnit.  Exiting\n");
635	if (xf86Screens[i]->bitmapBitOrder !=
636	    xf86Screens[0]->bitmapBitOrder)
637	    FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
638
639	/* Determine the depth 24 pixmap format the screens would like */
640	if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
641	    if (screenpix24 == Pix24DontCare)
642		screenpix24 = xf86Screens[i]->pixmap24;
643	    else if (screenpix24 != xf86Screens[i]->pixmap24)
644		FatalError("Inconsistent depth 24 pixmap format.  Exiting\n");
645	}
646    }
647    /* check if screenpix24 is consistent with the config/cmdline */
648    if (xf86Info.pixmap24 != Pix24DontCare) {
649	pix24 = xf86Info.pixmap24;
650	pix24From = xf86Info.pix24From;
651	if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
652	    pix24Fail = TRUE;
653    } else if (screenpix24 != Pix24DontCare) {
654	pix24 = screenpix24;
655	pix24From = X_PROBED;
656    } else
657	pix24 = Pix24Use32;
658
659    if (pix24Fail)
660	FatalError("Screen(s) can't use the required depth 24 pixmap format"
661		   " (%d).  Exiting\n", PIX24TOBPP(pix24));
662
663    /* Initialise the depth 24 format */
664    for (j = 0; j < numFormats && formats[j].depth != 24; j++)
665	;
666    formats[j].bitsPerPixel = PIX24TOBPP(pix24);
667
668    /* Collect additional formats */
669    for (i = 0; i < xf86NumScreens; i++) {
670	for (j = 0; j < xf86Screens[i]->numFormats; j++) {
671	    for (k = 0; ; k++) {
672		if (k >= numFormats) {
673		    if (k >= MAXFORMATS)
674			FatalError("Too many pixmap formats!  Exiting\n");
675		    formats[k] = xf86Screens[i]->formats[j];
676		    numFormats++;
677		    break;
678		}
679		if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
680		    if ((formats[k].bitsPerPixel ==
681			 xf86Screens[i]->formats[j].bitsPerPixel) &&
682		        (formats[k].scanlinePad ==
683			 xf86Screens[i]->formats[j].scanlinePad))
684			break;
685		    FatalError("Inconsistent pixmap format for depth %d."
686			       "  Exiting\n", formats[k].depth);
687		}
688	    }
689	}
690    }
691    formatsDone = TRUE;
692
693    if (xf86Info.vtno >= 0 ) {
694#define VT_ATOM_NAME         "XFree86_VT"
695      Atom VTAtom=-1;
696      CARD32  *VT = NULL;
697      int  ret;
698
699      /* This memory needs to stay available until the screen has been
700	 initialized, and we can create the property for real.
701      */
702      if ( (VT = xalloc(sizeof(CARD32)))==NULL ) {
703	FatalError("Unable to make VT property - out of memory. Exiting...\n");
704      }
705      *VT = xf86Info.vtno;
706
707      VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
708
709      for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
710	ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
711					     VTAtom, XA_INTEGER, 32,
712					     1, VT );
713	if (ret != Success)
714	  xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
715		     "Failed to register VT property\n");
716      }
717    }
718
719    /* If a screen uses depth 24, show what the pixmap format is */
720    for (i = 0; i < xf86NumScreens; i++) {
721	if (xf86Screens[i]->depth == 24) {
722	    xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
723		    PIX24TOBPP(pix24));
724	    break;
725	}
726    }
727
728#ifdef XKB
729    xf86InitXkb();
730#endif
731    /* set up the proper access funcs */
732    xf86PostPreInit();
733
734    AddCallback(&ServerGrabCallback, xf86GrabServerCallback, NULL);
735
736  } else {
737    /*
738     * serverGeneration != 1; some OSs have to do things here, too.
739     */
740    xf86OpenConsole();
741
742#ifdef XF86PM
743    /*
744      should we reopen it here? We need to deal with an already opened
745      device. We could leave this to the OS layer. For now we simply
746      close it here
747    */
748    if (xf86OSPMClose)
749        xf86OSPMClose();
750    if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
751	xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
752#endif
753
754    /* Make sure full I/O access is enabled */
755    if (xorgHWAccess)
756	xf86EnableIO();
757  }
758
759#if 0
760  /*
761   * Install signal handler for unexpected signals
762   */
763  xf86Info.caughtSignal=FALSE;
764  if (!xf86Info.notrapSignals)
765  {
766     signal(SIGSEGV,xf86SigHandler);
767     signal(SIGILL,xf86SigHandler);
768#ifdef SIGEMT
769     signal(SIGEMT,xf86SigHandler);
770#endif
771     signal(SIGFPE,xf86SigHandler);
772#ifdef SIGBUS
773     signal(SIGBUS,xf86SigHandler);
774#endif
775#ifdef SIGSYS
776     signal(SIGSYS,xf86SigHandler);
777#endif
778#ifdef SIGXCPU
779     signal(SIGXCPU,xf86SigHandler);
780#endif
781#ifdef SIGXFSZ
782     signal(SIGXFSZ,xf86SigHandler);
783#endif
784  }
785#endif
786
787  /*
788   * Use the previously collected parts to setup pScreenInfo
789   */
790
791  pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
792  pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
793  pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
794  pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
795  pScreenInfo->numPixmapFormats = numFormats;
796  for (i = 0; i < numFormats; i++)
797    pScreenInfo->formats[i] = formats[i];
798
799  /* Make sure the server's VT is active */
800
801  if (serverGeneration != 1) {
802    xf86Resetting = TRUE;
803    /* All screens are in the same state, so just check the first */
804    if (!xf86Screens[0]->vtSema) {
805#ifdef HAS_USL_VTS
806      ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
807#endif
808      xf86AccessEnter();
809      xf86EnterServerState(SETUP);
810    }
811  }
812#ifdef SCO325
813  else {
814    /*
815     * Under SCO we must ack that we got the console at startup,
816     * I think this is the safest way to assure it.
817     */
818    static int once = 1;
819    if (once) {
820      once = 0;
821      if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
822        xf86Msg(X_WARNING, "VT_ACKACQ failed");
823    }
824  }
825#endif /* SCO325 */
826
827  for (i = 0; i < xf86NumScreens; i++) {
828   	xf86EnableAccess(xf86Screens[i]);
829	/*
830	 * Almost everything uses these defaults, and many of those that
831	 * don't, will wrap them.
832	 */
833	xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
834	xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
835	xf86Screens[i]->DPMSSet = NULL;
836	xf86Screens[i]->LoadPalette = NULL;
837	xf86Screens[i]->SetOverscan = NULL;
838	xf86Screens[i]->DriverFunc = NULL;
839	xf86Screens[i]->pScreen = NULL;
840	scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
841      if (scr_index == i) {
842	/*
843	 * Hook in our ScrnInfoRec, and initialise some other pScreen
844	 * fields.
845	 */
846	screenInfo.screens[scr_index]->devPrivates[xf86ScreenIndex].ptr
847	  = (pointer)xf86Screens[i];
848	xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
849	/* The driver should set this, but make sure it is set anyway */
850	xf86Screens[i]->vtSema = TRUE;
851      } else {
852	/* This shouldn't normally happen */
853	FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
854      }
855
856#ifdef DEBUG
857      ErrorF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
858	     i, xf86Screens[i]->pScreen );
859      ErrorF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
860	     i, xf86Screens[i]->pScreen->CreateWindow );
861#endif
862
863      screenInfo.screens[scr_index]->devPrivates[xf86CreateRootWindowIndex].ptr
864	= (void*)(xf86Screens[i]->pScreen->CreateWindow);
865      xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
866
867#ifdef RENDER
868    if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
869    {
870	xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
871	PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
872				 DDC ?
873				 (DDC->features.input_type ?
874				  SubPixelHorizontalRGB : SubPixelNone) :
875				 SubPixelUnknown);
876    }
877#endif
878#ifdef RANDR
879    if (!xf86Info.disableRandR)
880	xf86RandRInit (screenInfo.screens[scr_index]);
881    xf86Msg(xf86Info.randRFrom, "RandR %s\n",
882	    xf86Info.disableRandR ? "disabled" : "enabled");
883#endif
884  }
885
886  xf86PostScreenInit();
887
888  xf86InitOrigins();
889
890  xf86Resetting = FALSE;
891  xf86Initialising = FALSE;
892
893  RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
894				 NULL);
895}
896
897/*
898 * InitInput --
899 *      Initialize all supported input devices.
900 */
901
902void
903InitInput(argc, argv)
904     int     	  argc;
905     char    	  **argv;
906{
907    IDevPtr* pDev;
908    InputDriverPtr pDrv;
909    InputInfoPtr pInfo;
910
911    xf86Info.vtRequestsPending = FALSE;
912    xf86Info.inputPending = FALSE;
913
914    if (serverGeneration == 1) {
915	/* Call the PreInit function for each input device instance. */
916	for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
917	    /* Replace obsolete keyboard driver with kbd */
918	    if (!xf86NameCmp((*pDev)->driver, "keyboard")) {
919		xf86MsgVerb(X_WARNING, 0,
920			    "*** WARNING the legacy keyboard driver \"%s\" has been removed\n",
921			    (*pDev)->driver);
922		xf86MsgVerb(X_WARNING, 0,
923			    "*** Using the new \"kbd\" driver for \"%s\".\n",
924			    (*pDev)->identifier);
925		strcpy((*pDev)->driver, "kbd");
926            }
927
928	    if ((pDrv = xf86LookupInputDriver((*pDev)->driver)) == NULL) {
929		xf86Msg(X_ERROR, "No Input driver matching `%s'\n", (*pDev)->driver);
930		/* XXX For now, just continue. */
931		continue;
932	    }
933	    if (!pDrv->PreInit) {
934		xf86MsgVerb(X_WARNING, 0,
935		    "Input driver `%s' has no PreInit function (ignoring)\n",
936		    pDrv->driverName);
937		continue;
938	    }
939	    pInfo = pDrv->PreInit(pDrv, *pDev, 0);
940	    if (!pInfo) {
941		xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n",
942			(*pDev)->identifier);
943		continue;
944	    } else if (!(pInfo->flags & XI86_CONFIGURED)) {
945		xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n",
946			(*pDev)->identifier);
947		xf86DeleteInput(pInfo, 0);
948		continue;
949	    }
950	}
951    }
952
953    /* Initialise all input devices. */
954    pInfo = xf86InputDevs;
955    while (pInfo) {
956        xf86Msg(X_INFO, "evaluating device (%s)\n", pInfo->name);
957	xf86ActivateDevice(pInfo);
958	pInfo = pInfo->next;
959    }
960
961    mieqInit();
962}
963
964#ifndef SET_STDERR_NONBLOCKING
965#define SET_STDERR_NONBLOCKING 1
966#endif
967
968/*
969 * OsVendorInit --
970 *      OS/Vendor-specific initialisations.  Called from OsInit(), which
971 *      is called by dix before establishing the well known sockets.
972 */
973
974void
975OsVendorInit()
976{
977  static Bool beenHere = FALSE;
978
979  xf86WrapperInit();
980
981#ifdef SIGCHLD
982  signal(SIGCHLD, SIG_DFL);	/* Need to wait for child processes */
983#endif
984  OsDelayInitColors = TRUE;
985#ifndef BUILTIN_FONTS
986  loadableFonts = TRUE;
987#endif
988
989  if (!beenHere)
990    xf86LogInit();
991
992#if SET_STDERR_NONBLOCKING
993        /* Set stderr to non-blocking. */
994#ifndef O_NONBLOCK
995#if defined(FNDELAY)
996#define O_NONBLOCK FNDELAY
997#elif defined(O_NDELAY)
998#define O_NONBLOCK O_NDELAY
999#endif
1000#endif
1001
1002#ifdef O_NONBLOCK
1003  if (!beenHere) {
1004    if (geteuid() == 0 && getuid() != geteuid())
1005    {
1006      int status;
1007
1008      status = fcntl(fileno(stderr), F_GETFL, 0);
1009      if (status != -1) {
1010	fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
1011      }
1012    }
1013  }
1014#endif
1015#endif
1016
1017  beenHere = TRUE;
1018}
1019
1020/*
1021 * ddxGiveUp --
1022 *      Device dependent cleanup. Called by by dix before normal server death.
1023 *      For SYSV386 we must switch the terminal back to normal mode. No error-
1024 *      checking here, since there should be restored as much as possible.
1025 */
1026
1027void
1028ddxGiveUp()
1029{
1030    int i;
1031
1032#ifdef XF86PM
1033    if (xf86OSPMClose)
1034	xf86OSPMClose();
1035    xf86OSPMClose = NULL;
1036#endif
1037
1038    xf86AccessLeaveState();
1039
1040    for (i = 0; i < xf86NumScreens; i++) {
1041	/*
1042	 * zero all access functions to
1043	 * trap calls when switched away.
1044	 */
1045	xf86Screens[i]->vtSema = FALSE;
1046	xf86Screens[i]->access = NULL;
1047	xf86Screens[i]->busAccess = NULL;
1048    }
1049
1050#ifdef USE_XF86_SERVERLOCK
1051    xf86UnlockServer();
1052#endif
1053#ifdef XFreeXDGA
1054    DGAShutdown();
1055#endif
1056
1057    xf86CloseConsole();
1058
1059    xf86CloseLog();
1060
1061    /* If an unexpected signal was caught, dump a core for debugging */
1062    if (xf86Info.caughtSignal)
1063	abort();
1064}
1065
1066
1067
1068/*
1069 * AbortDDX --
1070 *      DDX - specific abort routine.  Called by AbortServer(). The attempt is
1071 *      made to restore all original setting of the displays. Also all devices
1072 *      are closed.
1073 */
1074
1075void
1076AbortDDX()
1077{
1078  int i;
1079
1080  /*
1081   * try to restore the original video state
1082   */
1083#ifdef HAS_USL_VTS
1084  /* Need the sleep when starting X from within another X session */
1085  sleep(1);
1086#endif
1087#ifdef DPMSExtension /* Turn screens back on */
1088  if (DPMSPowerLevel != DPMSModeOn)
1089      DPMSSet(DPMSModeOn);
1090#endif
1091  if (xf86Screens) {
1092      if (xf86Screens[0]->vtSema)
1093	  xf86EnterServerState(SETUP);
1094      for (i = 0; i < xf86NumScreens; i++)
1095	  if (xf86Screens[i]->vtSema) {
1096	      /*
1097	       * if we are aborting before ScreenInit() has finished
1098	       * we might not have been wrapped yet. Therefore enable
1099	       * screen explicitely.
1100	       */
1101	      xf86EnableAccess(xf86Screens[i]);
1102	      (xf86Screens[i]->LeaveVT)(i, 0);
1103	  }
1104  }
1105
1106  xf86AccessLeave();
1107
1108  /*
1109   * This is needed for an abnormal server exit, since the normal exit stuff
1110   * MUST also be performed (i.e. the vt must be left in a defined state)
1111   */
1112  ddxGiveUp();
1113}
1114
1115void
1116OsVendorFatalError()
1117{
1118#ifdef VENDORSUPPORT
1119    ErrorF("\nPlease refer to your Operating System Vendor support pages\n"
1120	   "at %s for support on this crash.\n",VENDORSUPPORT);
1121#else
1122    ErrorF("\nPlease consult the "XVENDORNAME" support \n"
1123	   "\t at "__VENDORDWEBSUPPORT__"\n for help. \n");
1124#endif
1125    if (xf86LogFile && xf86LogFileWasOpened)
1126	ErrorF("Please also check the log file at \"%s\" for additional "
1127              "information.\n", xf86LogFile);
1128    ErrorF("\n");
1129}
1130
1131int
1132xf86SetVerbosity(int verb)
1133{
1134    int save = xf86Verbose;
1135
1136    xf86Verbose = verb;
1137    LogSetParameter(XLOG_VERBOSITY, verb);
1138    return save;
1139}
1140
1141int
1142xf86SetLogVerbosity(int verb)
1143{
1144    int save = xf86LogVerbose;
1145
1146    xf86LogVerbose = verb;
1147    LogSetParameter(XLOG_FILE_VERBOSITY, verb);
1148    return save;
1149}
1150
1151/*
1152 * ddxProcessArgument --
1153 *	Process device-dependent command line args. Returns 0 if argument is
1154 *      not device dependent, otherwise Count of number of elements of argv
1155 *      that are part of a device dependent commandline option.
1156 *
1157 */
1158
1159
1160
1161/* ARGSUSED */
1162int
1163ddxProcessArgument(int argc, char **argv, int i)
1164{
1165  /*
1166   * Note: can't use xalloc/xfree here because OsInit() hasn't been called
1167   * yet.  Use malloc/free instead.
1168   */
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 only allowed for root */
1178  if (getuid() == 0 || geteuid() != 0)
1179  {
1180    if (!strcmp(argv[i], "-modulepath"))
1181    {
1182      char *mp;
1183      CHECK_FOR_REQUIRED_ARGUMENT();
1184      mp = malloc(strlen(argv[i + 1]) + 1);
1185      if (!mp)
1186	FatalError("Can't allocate memory for ModulePath\n");
1187      strcpy(mp, argv[i + 1]);
1188      xf86ModulePath = mp;
1189      xf86ModPathFrom = X_CMDLINE;
1190      return 2;
1191    }
1192    else if (!strcmp(argv[i], "-logfile"))
1193    {
1194      char *lf;
1195      CHECK_FOR_REQUIRED_ARGUMENT();
1196      lf = malloc(strlen(argv[i + 1]) + 1);
1197      if (!lf)
1198	FatalError("Can't allocate memory for LogFile\n");
1199      strcpy(lf, argv[i + 1]);
1200      xf86LogFile = lf;
1201      xf86LogFileFrom = X_CMDLINE;
1202      return 2;
1203    }
1204  } else if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
1205    FatalError("The '%s' option can only be used by root.\n", argv[i]);
1206  }
1207  if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
1208  {
1209    CHECK_FOR_REQUIRED_ARGUMENT();
1210    if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
1211      FatalError("\nInvalid argument for %s\n"
1212	  "\tFor non-root users, the file specified with %s must be\n"
1213	  "\ta relative path and must not contain any \"..\" elements.\n"
1214	  "\tUsing default "__XCONFIGFILE__" search path.\n\n",
1215	  argv[i], argv[i]);
1216    }
1217    xf86ConfigFile = argv[i + 1];
1218    return 2;
1219  }
1220  if (!strcmp(argv[i],"-showunresolved"))
1221  {
1222    xf86ShowUnresolved = TRUE;
1223    return 1;
1224  }
1225  if (!strcmp(argv[i],"-probeonly"))
1226  {
1227    xf86ProbeOnly = TRUE;
1228    return 1;
1229  }
1230  if (!strcmp(argv[i],"-flipPixels"))
1231  {
1232    xf86FlipPixels = TRUE;
1233    return 1;
1234  }
1235#ifdef XF86VIDMODE
1236  if (!strcmp(argv[i],"-disableVidMode"))
1237  {
1238    xf86VidModeDisabled = TRUE;
1239    return 1;
1240  }
1241  if (!strcmp(argv[i],"-allowNonLocalXvidtune"))
1242  {
1243    xf86VidModeAllowNonLocal = TRUE;
1244    return 1;
1245  }
1246#endif
1247#ifdef XF86MISC
1248  if (!strcmp(argv[i],"-disableModInDev"))
1249  {
1250    xf86MiscModInDevDisabled = TRUE;
1251    return 1;
1252  }
1253  if (!strcmp(argv[i],"-allowNonLocalModInDev"))
1254  {
1255    xf86MiscModInDevAllowNonLocal = TRUE;
1256    return 1;
1257  }
1258#endif
1259  if (!strcmp(argv[i],"-allowMouseOpenFail"))
1260  {
1261    xf86AllowMouseOpenFail = TRUE;
1262    return 1;
1263  }
1264  if (!strcmp(argv[i],"-bestRefresh"))
1265  {
1266    xf86BestRefresh = TRUE;
1267    return 1;
1268  }
1269  if (!strcmp(argv[i],"-ignoreABI"))
1270  {
1271    LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
1272    return 1;
1273  }
1274  if (!strcmp(argv[i],"-verbose"))
1275  {
1276    if (++i < argc && argv[i])
1277    {
1278      char *end;
1279      long val;
1280      val = strtol(argv[i], &end, 0);
1281      if (*end == '\0')
1282      {
1283	xf86SetVerbosity(val);
1284	return 2;
1285      }
1286    }
1287    xf86SetVerbosity(++xf86Verbose);
1288    return 1;
1289  }
1290  if (!strcmp(argv[i],"-logverbose"))
1291  {
1292    if (++i < argc && argv[i])
1293    {
1294      char *end;
1295      long val;
1296      val = strtol(argv[i], &end, 0);
1297      if (*end == '\0')
1298      {
1299	xf86SetLogVerbosity(val);
1300	return 2;
1301      }
1302    }
1303    xf86SetLogVerbosity(++xf86LogVerbose);
1304    return 1;
1305  }
1306  if (!strcmp(argv[i],"-quiet"))
1307  {
1308    xf86SetVerbosity(0);
1309    return 1;
1310  }
1311  if (!strcmp(argv[i],"-showconfig") || !strcmp(argv[i],"-version"))
1312  {
1313    xf86PrintBanner();
1314    exit(0);
1315  }
1316  if (!strcmp(argv[i],"-showDefaultModulePath"))
1317  {
1318    xf86PrintDefaultModulePath();
1319    exit(0);
1320  }
1321  if (!strcmp(argv[i],"-showDefaultLibPath"))
1322  {
1323    xf86PrintDefaultLibraryPath();
1324    exit(0);
1325  }
1326  /* Notice the -fp flag, but allow it to pass to the dix layer */
1327  if (!strcmp(argv[i], "-fp"))
1328  {
1329    xf86fpFlag = TRUE;
1330    return 0;
1331  }
1332  /* Notice the -co flag, but allow it to pass to the dix layer */
1333  if (!strcmp(argv[i], "-co"))
1334  {
1335    xf86coFlag = TRUE;
1336    return 0;
1337  }
1338  /* Notice the -bs flag, but allow it to pass to the dix layer */
1339  if (!strcmp(argv[i], "-bs"))
1340  {
1341    xf86bsDisableFlag = TRUE;
1342    return 0;
1343  }
1344  /* Notice the +bs flag, but allow it to pass to the dix layer */
1345  if (!strcmp(argv[i], "+bs"))
1346  {
1347    xf86bsEnableFlag = TRUE;
1348    return 0;
1349  }
1350  /* Notice the -s flag, but allow it to pass to the dix layer */
1351  if (!strcmp(argv[i], "-s"))
1352  {
1353    xf86sFlag = TRUE;
1354    return 0;
1355  }
1356  if (!strcmp(argv[i], "-bpp"))
1357  {
1358    ErrorF("The -bpp option is no longer supported.\n"
1359	"\tUse -depth to set the color depth, and use -fbbpp if you really\n"
1360	"\tneed to force a non-default framebuffer (hardware) pixel format.\n");
1361    if (++i >= argc)
1362      return 1;
1363    return 2;
1364  }
1365  if (!strcmp(argv[i], "-pixmap24"))
1366  {
1367    xf86Pix24 = Pix24Use24;
1368    return 1;
1369  }
1370  if (!strcmp(argv[i], "-pixmap32"))
1371  {
1372    xf86Pix24 = Pix24Use32;
1373    return 1;
1374  }
1375  if (!strcmp(argv[i], "-fbbpp"))
1376  {
1377    int bpp;
1378    CHECK_FOR_REQUIRED_ARGUMENT();
1379    if (sscanf(argv[++i], "%d", &bpp) == 1)
1380    {
1381      xf86FbBpp = bpp;
1382      return 2;
1383    }
1384    else
1385    {
1386      ErrorF("Invalid fbbpp\n");
1387      return 0;
1388    }
1389  }
1390  if (!strcmp(argv[i], "-depth"))
1391  {
1392    int depth;
1393    CHECK_FOR_REQUIRED_ARGUMENT();
1394    if (sscanf(argv[++i], "%d", &depth) == 1)
1395    {
1396      xf86Depth = depth;
1397      return 2;
1398    }
1399    else
1400    {
1401      ErrorF("Invalid depth\n");
1402      return 0;
1403    }
1404  }
1405  if (!strcmp(argv[i], "-weight"))
1406  {
1407    int red, green, blue;
1408    CHECK_FOR_REQUIRED_ARGUMENT();
1409    if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3)
1410    {
1411      xf86Weight.red = red;
1412      xf86Weight.green = green;
1413      xf86Weight.blue = blue;
1414      return 2;
1415    }
1416    else
1417    {
1418      ErrorF("Invalid weighting\n");
1419      return 0;
1420    }
1421  }
1422  if (!strcmp(argv[i], "-gamma")  || !strcmp(argv[i], "-rgamma") ||
1423      !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma"))
1424  {
1425    double gamma;
1426    CHECK_FOR_REQUIRED_ARGUMENT();
1427    if (sscanf(argv[++i], "%lf", &gamma) == 1) {
1428       if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
1429	  ErrorF("gamma out of range, only  %.2f <= gamma_value <= %.1f"
1430		 " is valid\n", GAMMA_MIN, GAMMA_MAX);
1431	  return 0;
1432       }
1433       if (!strcmp(argv[i-1], "-gamma"))
1434	  xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
1435       else if (!strcmp(argv[i-1], "-rgamma")) xf86Gamma.red = gamma;
1436       else if (!strcmp(argv[i-1], "-ggamma")) xf86Gamma.green = gamma;
1437       else if (!strcmp(argv[i-1], "-bgamma")) xf86Gamma.blue = gamma;
1438       return 2;
1439    }
1440  }
1441  if (!strcmp(argv[i], "-layout"))
1442  {
1443    CHECK_FOR_REQUIRED_ARGUMENT();
1444    xf86LayoutName = argv[++i];
1445    return 2;
1446  }
1447  if (!strcmp(argv[i], "-screen"))
1448  {
1449    CHECK_FOR_REQUIRED_ARGUMENT();
1450    xf86ScreenName = argv[++i];
1451    return 2;
1452  }
1453  if (!strcmp(argv[i], "-pointer"))
1454  {
1455    CHECK_FOR_REQUIRED_ARGUMENT();
1456    xf86PointerName = argv[++i];
1457    return 2;
1458  }
1459  if (!strcmp(argv[i], "-keyboard"))
1460  {
1461    CHECK_FOR_REQUIRED_ARGUMENT();
1462    xf86KeyboardName = argv[++i];
1463    return 2;
1464  }
1465  if (!strcmp(argv[i], "-nosilk"))
1466  {
1467    xf86silkenMouseDisableFlag = TRUE;
1468    return 1;
1469  }
1470#ifdef HAVE_ACPI
1471  if (!strcmp(argv[i], "-noacpi"))
1472  {
1473    xf86acpiDisableFlag = TRUE;
1474    return 1;
1475  }
1476#endif
1477  if (!strcmp(argv[i], "-scanpci"))
1478  {
1479    DoScanPci(argc, argv, i);
1480  }
1481  if (!strcmp(argv[i], "-probe"))
1482  {
1483    xf86DoProbe = TRUE;
1484    return 1;
1485  }
1486  if (!strcmp(argv[i], "-configure"))
1487  {
1488    if (getuid() != 0 && geteuid() == 0) {
1489	ErrorF("The '-configure' option can only be used by root.\n");
1490	exit(1);
1491    }
1492    xf86DoConfigure = TRUE;
1493    xf86AllowMouseOpenFail = TRUE;
1494    return 1;
1495  }
1496  if (!strcmp(argv[i], "-isolateDevice"))
1497  {
1498    int bus, device, func;
1499    CHECK_FOR_REQUIRED_ARGUMENT();
1500    if (strncmp(argv[++i], "PCI:", 4)) {
1501       FatalError("Bus types other than PCI not yet isolable\n");
1502    }
1503    if (sscanf(argv[i], "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
1504       xf86IsolateDevice.bus = bus;
1505       xf86IsolateDevice.device = device;
1506       xf86IsolateDevice.func = func;
1507       return 2;
1508    } else {
1509       FatalError("Invalid isolated device specification\n");
1510    }
1511  }
1512  /* OS-specific processing */
1513  return xf86ProcessArgument(argc, argv, i);
1514}
1515
1516/* ddxInitGlobals - called by |InitGlobals| from os/util.c */
1517void ddxInitGlobals(void)
1518{
1519}
1520
1521/*
1522 * ddxUseMsg --
1523 *	Print out correct use of device dependent commandline options.
1524 *      Maybe the user now knows what really to do ...
1525 */
1526
1527void
1528ddxUseMsg()
1529{
1530  ErrorF("\n");
1531  ErrorF("\n");
1532  ErrorF("Device Dependent Usage\n");
1533  if (getuid() == 0 || geteuid() != 0)
1534  {
1535    ErrorF("-modulepath paths      specify the module search path\n");
1536    ErrorF("-logfile file          specify a log file name\n");
1537    ErrorF("-configure             probe for devices and write an "__XCONFIGFILE__"\n");
1538  }
1539  ErrorF("-config file           specify a configuration file, relative to the\n");
1540  ErrorF("                       "__XCONFIGFILE__" search path, only root can use absolute\n");
1541  ErrorF("-probeonly             probe for devices, then exit\n");
1542  ErrorF("-scanpci               execute the scanpci module and exit\n");
1543  ErrorF("-verbose [n]           verbose startup messages\n");
1544  ErrorF("-logverbose [n]        verbose log messages\n");
1545  ErrorF("-quiet                 minimal startup messages\n");
1546  ErrorF("-pixmap24              use 24bpp pixmaps for depth 24\n");
1547  ErrorF("-pixmap32              use 32bpp pixmaps for depth 24\n");
1548  ErrorF("-fbbpp n               set bpp for the framebuffer. Default: 8\n");
1549  ErrorF("-depth n               set colour depth. Default: 8\n");
1550  ErrorF("-gamma f               set gamma value (0.1 < f < 10.0) Default: 1.0\n");
1551  ErrorF("-rgamma f              set gamma value for red phase\n");
1552  ErrorF("-ggamma f              set gamma value for green phase\n");
1553  ErrorF("-bgamma f              set gamma value for blue phase\n");
1554  ErrorF("-weight nnn            set RGB weighting at 16 bpp.  Default: 565\n");
1555  ErrorF("-layout name           specify the ServerLayout section name\n");
1556  ErrorF("-screen name           specify the Screen section name\n");
1557  ErrorF("-keyboard name         specify the core keyboard InputDevice name\n");
1558  ErrorF("-pointer name          specify the core pointer InputDevice name\n");
1559  ErrorF("-nosilk                disable Silken Mouse\n");
1560  ErrorF("-flipPixels            swap default black/white Pixel values\n");
1561#ifdef XF86VIDMODE
1562  ErrorF("-disableVidMode        disable mode adjustments with xvidtune\n");
1563  ErrorF("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
1564#endif
1565#ifdef XF86MISC
1566  ErrorF("-disableModInDev       disable dynamic modification of input device settings\n");
1567  ErrorF("-allowNonLocalModInDev allow changes to keyboard and mouse settings\n");
1568  ErrorF("                       from non-local clients\n");
1569  ErrorF("-allowMouseOpenFail    start server even if the mouse can't be initialized\n");
1570#endif
1571  ErrorF("-bestRefresh           choose modes with the best refresh rate\n");
1572  ErrorF("-ignoreABI             make module ABI mismatches non-fatal\n");
1573  ErrorF("-isolateDevice bus_id  restrict device resets to bus_id (PCI only)\n");
1574  ErrorF("-version               show the server version\n");
1575  ErrorF("-showDefaultModulePath show the server default module path\n");
1576  ErrorF("-showDefaultLibPath    show the server default library path\n");
1577  /* OS-specific usage */
1578  xf86UseMsg();
1579  ErrorF("\n");
1580}
1581
1582
1583#ifndef OSNAME
1584#define OSNAME " unknown"
1585#endif
1586#ifndef OSVENDOR
1587#define OSVENDOR ""
1588#endif
1589#ifndef PRE_RELEASE
1590#define PRE_RELEASE XORG_VERSION_SNAP
1591#endif
1592
1593static void
1594xf86PrintBanner()
1595{
1596#if PRE_RELEASE
1597  ErrorF("\n"
1598    "This is a pre-release version of the X server from " XVENDORNAME ".\n"
1599    "It is not supported in any way.\n"
1600    "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
1601    "Select the \"xorg\" product for bugs you find in this release.\n"
1602    "Before reporting bugs in pre-release versions please check the\n"
1603    "latest version in the X.Org Foundation git repository.\n"
1604    "See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
1605#endif
1606  ErrorF("\nX.Org X Server %d.%d.%d",
1607	 XORG_VERSION_MAJOR,
1608	 XORG_VERSION_MINOR,
1609	 XORG_VERSION_PATCH);
1610#if XORG_VERSION_SNAP > 0
1611  ErrorF(".%d", XORG_VERSION_SNAP);
1612#endif
1613
1614#if XORG_VERSION_SNAP >= 900
1615  /* When the minor number is 99, that signifies that the we are making
1616   * a release candidate for a major version.  (X.0.0)
1617   * When the patch number is 99, that signifies that the we are making
1618   * a release candidate for a minor version.  (X.Y.0)
1619   * When the patch number is < 99, then we are making a release
1620   * candidate for the next point release.  (X.Y.Z)
1621   */
1622#if XORG_VERSION_MINOR >= 99
1623  ErrorF(" (%d.0.0 RC %d)", XORG_VERSION_MAJOR+1, XORG_VERSION_SNAP - 900);
1624#elif XORG_VERSION_PATCH == 99
1625  ErrorF(" (%d.%d.0 RC %d)", XORG_VERSION_MAJOR, XORG_VERSION_MINOR + 1,
1626				XORG_VERSION_SNAP - 900);
1627#else
1628  ErrorF(" (%d.%d.%d RC %d)", XORG_VERSION_MAJOR, XORG_VERSION_MINOR,
1629 			 XORG_VERSION_PATCH + 1, XORG_VERSION_SNAP - 900);
1630#endif
1631#endif
1632
1633#ifdef XORG_CUSTOM_VERSION
1634  ErrorF(" (%s)", XORG_CUSTOM_VERSION);
1635#endif
1636#ifndef XORG_DATE
1637#define XORG_DATE XF86_DATE
1638#endif
1639  ErrorF("\nRelease Date: %s\n", XORG_DATE);
1640  ErrorF("X Protocol Version %d, Revision %d\n",
1641         X_PROTOCOL, X_PROTOCOL_REVISION);
1642  ErrorF("Build Operating System: %s %s\n", OSNAME, OSVENDOR);
1643#ifdef HAS_UTSNAME
1644  {
1645    struct utsname name;
1646
1647    /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
1648       and Irix) and Single Unix Spec 3 just say that non-negative is success.
1649       All agree that failure is represented by a negative number.
1650     */
1651    if (uname(&name) >= 0) {
1652      ErrorF("Current Operating System: %s %s %s %s %s\n",
1653	name.sysname, name.nodename, name.release, name.version, name.machine);
1654    }
1655  }
1656#endif
1657#if defined(BUILD_DATE) && (BUILD_DATE > 19000000)
1658  {
1659    struct tm t;
1660    char buf[100];
1661
1662    bzero(&t, sizeof(t));
1663    bzero(buf, sizeof(buf));
1664    t.tm_mday = BUILD_DATE % 100;
1665    t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
1666    t.tm_year = BUILD_DATE / 10000 - 1900;
1667#if defined(BUILD_TIME)
1668    t.tm_sec = BUILD_TIME % 100;
1669    t.tm_min = (BUILD_TIME / 100) % 100;
1670    t.tm_hour = (BUILD_TIME / 10000) % 100;
1671    if (strftime(buf, sizeof(buf), "%d %B %Y  %I:%M:%S%p", &t))
1672       ErrorF("Build Date: %s\n", buf);
1673#else
1674    if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
1675       ErrorF("Build Date: %s\n", buf);
1676#endif
1677  }
1678#endif
1679#if defined(CLOG_DATE) && (CLOG_DATE > 19000000)
1680  {
1681    struct tm t;
1682    char buf[100];
1683
1684    bzero(&t, sizeof(t));
1685    bzero(buf, sizeof(buf));
1686    t.tm_mday = CLOG_DATE % 100;
1687    t.tm_mon = (CLOG_DATE / 100) % 100 - 1;
1688    t.tm_year = CLOG_DATE / 10000 - 1900;
1689    if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
1690       ErrorF("Changelog Date: %s\n", buf);
1691  }
1692#endif
1693#if defined(BUILDERSTRING)
1694  ErrorF("%s \n",BUILDERSTRING);
1695#endif
1696  ErrorF("\tBefore reporting problems, check "__VENDORDWEBSUPPORT__"\n"
1697	 "\tto make sure that you have the latest version.\n");
1698  ErrorF("Module Loader present\n");
1699}
1700
1701static void
1702xf86PrintMarkers()
1703{
1704  LogPrintMarkers();
1705}
1706
1707static void
1708xf86PrintDefaultModulePath(void)
1709{
1710  ErrorF("%s\n", DEFAULT_MODULE_PATH);
1711}
1712
1713static void
1714xf86PrintDefaultLibraryPath(void)
1715{
1716  ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
1717}
1718
1719static void
1720xf86RunVtInit(void)
1721{
1722    int i;
1723
1724    /*
1725     * If VTInit was set, run that program with consoleFd as stdin and stdout
1726     */
1727
1728    if (xf86Info.vtinit) {
1729      switch(fork()) {
1730      case -1:
1731          FatalError("xf86RunVtInit: fork failed (%s)\n", strerror(errno));
1732          break;
1733      case 0:  /* child */
1734	  if (setuid(getuid()) == -1) {
1735	      xf86Msg(X_ERROR, "xf86RunVtInit: setuid failed (%s)\n",
1736			 strerror(errno));
1737	      exit(255);
1738	  }
1739          /* set stdin, stdout to the consoleFd */
1740          for (i = 0; i < 2; i++) {
1741            if (xf86Info.consoleFd != i) {
1742              close(i);
1743              dup(xf86Info.consoleFd);
1744            }
1745          }
1746          execl("/bin/sh", "sh", "-c", xf86Info.vtinit, (void *)NULL);
1747          xf86Msg(X_WARNING, "exec of /bin/sh failed for VTInit (%s)\n",
1748                 strerror(errno));
1749          exit(255);
1750          break;
1751      default:  /* parent */
1752          wait(NULL);
1753      }
1754    }
1755}
1756
1757/*
1758 * xf86LoadModules iterates over a list that is being passed in.
1759 */
1760Bool
1761xf86LoadModules(char **list, pointer *optlist)
1762{
1763    int errmaj, errmin;
1764    pointer opt;
1765    int i;
1766    char *name;
1767    Bool failed = FALSE;
1768
1769    if (!list)
1770	return TRUE;
1771
1772    for (i = 0; list[i] != NULL; i++) {
1773
1774	/* Normalise the module name */
1775	name = xf86NormalizeName(list[i]);
1776
1777	/* Skip empty names */
1778	if (name == NULL || *name == '\0')
1779	    continue;
1780
1781	/* Replace obsolete keyboard driver with kbd */
1782	if (!xf86NameCmp(name, "keyboard")) {
1783	    strcpy(name, "kbd");
1784	}
1785
1786	if (optlist)
1787	    opt = optlist[i];
1788	else
1789	    opt = NULL;
1790
1791        if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
1792	    LoaderErrorMsg(NULL, name, errmaj, errmin);
1793	    failed = TRUE;
1794	}
1795	xfree(name);
1796    }
1797    return !failed;
1798}
1799
1800/* Pixmap format stuff */
1801
1802_X_EXPORT PixmapFormatPtr
1803xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
1804{
1805    int i;
1806    static PixmapFormatRec format;	/* XXX not reentrant */
1807
1808    /*
1809     * When the formats[] list initialisation isn't complete, check the
1810     * depth 24 pixmap config/cmdline options and screen-specified formats.
1811     */
1812
1813    if (!formatsDone) {
1814	if (depth == 24) {
1815	    Pix24Flags pix24 = Pix24DontCare;
1816
1817	    format.depth = 24;
1818	    format.scanlinePad = BITMAP_SCANLINE_PAD;
1819	    if (xf86Info.pixmap24 != Pix24DontCare)
1820		pix24 = xf86Info.pixmap24;
1821	    else if (pScrn->pixmap24 != Pix24DontCare)
1822		pix24 = pScrn->pixmap24;
1823	    if (pix24 == Pix24Use24)
1824		format.bitsPerPixel = 24;
1825	    else
1826		format.bitsPerPixel = 32;
1827	    return &format;
1828	}
1829    }
1830
1831    for (i = 0; i < numFormats; i++)
1832	if (formats[i].depth == depth)
1833	   break;
1834    if (i != numFormats)
1835	return &formats[i];
1836    else if (!formatsDone) {
1837	/* Check for screen-specified formats */
1838	for (i = 0; i < pScrn->numFormats; i++)
1839	    if (pScrn->formats[i].depth == depth)
1840		break;
1841	if (i != pScrn->numFormats)
1842	    return &pScrn->formats[i];
1843    }
1844    return NULL;
1845}
1846
1847_X_EXPORT int
1848xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
1849{
1850    PixmapFormatPtr format;
1851
1852
1853    format = xf86GetPixFormat(pScrn, depth);
1854    if (format)
1855	return format->bitsPerPixel;
1856    else
1857	return 0;
1858}
1859
1860