1706f2543Smrg/*
2706f2543Smrg * Loosely based on code bearing the following copyright:
3706f2543Smrg *
4706f2543Smrg *   Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
5706f2543Smrg */
6706f2543Smrg/*
7706f2543Smrg * Copyright (c) 1992-2003 by The XFree86 Project, Inc.
8706f2543Smrg *
9706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
10706f2543Smrg * copy of this software and associated documentation files (the "Software"),
11706f2543Smrg * to deal in the Software without restriction, including without limitation
12706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
14706f2543Smrg * Software is furnished to do so, subject to the following conditions:
15706f2543Smrg *
16706f2543Smrg * The above copyright notice and this permission notice shall be included in
17706f2543Smrg * all copies or substantial portions of the Software.
18706f2543Smrg *
19706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22706f2543Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
23706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25706f2543Smrg * OTHER DEALINGS IN THE SOFTWARE.
26706f2543Smrg *
27706f2543Smrg * Except as contained in this notice, the name of the copyright holder(s)
28706f2543Smrg * and author(s) shall not be used in advertising or otherwise to promote
29706f2543Smrg * the sale, use or other dealings in this Software without prior written
30706f2543Smrg * authorization from the copyright holder(s) and author(s).
31706f2543Smrg */
32706f2543Smrg
33706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
34706f2543Smrg#include <xorg-config.h>
35706f2543Smrg#endif
36706f2543Smrg
37706f2543Smrg#include <stdlib.h>
38706f2543Smrg#include <errno.h>
39706f2543Smrg
40706f2543Smrg#undef HAS_UTSNAME
41706f2543Smrg#if !defined(WIN32)
42706f2543Smrg#define HAS_UTSNAME 1
43706f2543Smrg#include <sys/utsname.h>
44706f2543Smrg#endif
45706f2543Smrg
46706f2543Smrg#include <X11/X.h>
47706f2543Smrg#include <X11/Xmd.h>
48706f2543Smrg#include <X11/Xproto.h>
49706f2543Smrg#include <X11/Xatom.h>
50706f2543Smrg#include "input.h"
51706f2543Smrg#include "servermd.h"
52706f2543Smrg#include "windowstr.h"
53706f2543Smrg#include "scrnintstr.h"
54706f2543Smrg#include "site.h"
55706f2543Smrg#include "mi.h"
56706f2543Smrg
57706f2543Smrg#include "compiler.h"
58706f2543Smrg
59706f2543Smrg#include "loaderProcs.h"
60706f2543Smrg#ifdef XFreeXDGA
61706f2543Smrg#include "dgaproc.h"
62706f2543Smrg#endif
63706f2543Smrg
64706f2543Smrg#define XF86_OS_PRIVS
65706f2543Smrg#include "xf86.h"
66706f2543Smrg#include "xf86Priv.h"
67706f2543Smrg#include "xf86Config.h"
68706f2543Smrg#include "xf86_OSlib.h"
69706f2543Smrg#include "xf86cmap.h"
70706f2543Smrg#include "xorgVersion.h"
71706f2543Smrg#include "xf86Build.h"
72706f2543Smrg#include "mipointer.h"
73706f2543Smrg#include <X11/extensions/XI.h>
74706f2543Smrg#include <X11/extensions/XIproto.h>
75706f2543Smrg#include "xf86DDC.h"
76706f2543Smrg#include "xf86Xinput.h"
77706f2543Smrg#include "xf86InPriv.h"
78706f2543Smrg#include "picturestr.h"
79706f2543Smrg
80706f2543Smrg#include "xf86Bus.h"
81706f2543Smrg#include "xf86VGAarbiter.h"
82706f2543Smrg#include "globals.h"
83706f2543Smrg
84706f2543Smrg#ifdef DPMSExtension
85706f2543Smrg#include <X11/extensions/dpmsconst.h>
86706f2543Smrg#include "dpmsproc.h"
87706f2543Smrg#endif
88706f2543Smrg#include <hotplug.h>
89706f2543Smrg
90706f2543Smrg
91706f2543Smrg#ifdef XF86PM
92706f2543Smrgvoid (*xf86OSPMClose)(void) = NULL;
93706f2543Smrg#endif
94706f2543Smrgstatic Bool xorgHWOpenConsole = FALSE;
95706f2543Smrg
96706f2543Smrg/* Common pixmap formats */
97706f2543Smrg
98706f2543Smrgstatic PixmapFormatRec formats[MAXFORMATS] = {
99706f2543Smrg	{ 1,	1,	BITMAP_SCANLINE_PAD },
100706f2543Smrg	{ 4,	8,	BITMAP_SCANLINE_PAD },
101706f2543Smrg	{ 8,	8,	BITMAP_SCANLINE_PAD },
102706f2543Smrg	{ 15,	16,	BITMAP_SCANLINE_PAD },
103706f2543Smrg	{ 16,	16,	BITMAP_SCANLINE_PAD },
104706f2543Smrg	{ 24,	32,	BITMAP_SCANLINE_PAD },
105706f2543Smrg	{ 32,	32,	BITMAP_SCANLINE_PAD },
106706f2543Smrg};
107706f2543Smrgstatic int numFormats = 7;
108706f2543Smrgstatic Bool formatsDone = FALSE;
109706f2543Smrg
110706f2543Smrg#ifndef OSNAME
111706f2543Smrg#define OSNAME " unknown"
112706f2543Smrg#endif
113706f2543Smrg#ifndef OSVENDOR
114706f2543Smrg#define OSVENDOR ""
115706f2543Smrg#endif
116706f2543Smrg#ifndef PRE_RELEASE
117706f2543Smrg#define PRE_RELEASE XORG_VERSION_SNAP
118706f2543Smrg#endif
119706f2543Smrg
120706f2543Smrgstatic void
121706f2543Smrgxf86PrintBanner(void)
122706f2543Smrg{
123706f2543Smrg#if PRE_RELEASE
124706f2543Smrg  xf86ErrorFVerb(0, "\n"
125706f2543Smrg    "This is a pre-release version of the X server from " XVENDORNAME ".\n"
126706f2543Smrg    "It is not supported in any way.\n"
127706f2543Smrg    "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
128706f2543Smrg    "Select the \"xorg\" product for bugs you find in this release.\n"
129706f2543Smrg    "Before reporting bugs in pre-release versions please check the\n"
130706f2543Smrg    "latest version in the X.Org Foundation git repository.\n"
131706f2543Smrg    "See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
132706f2543Smrg#endif
133706f2543Smrg  xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
134706f2543Smrg	 XORG_VERSION_MAJOR,
135706f2543Smrg	 XORG_VERSION_MINOR,
136706f2543Smrg	 XORG_VERSION_PATCH);
137706f2543Smrg#if XORG_VERSION_SNAP > 0
138706f2543Smrg  xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
139706f2543Smrg#endif
140706f2543Smrg
141706f2543Smrg#if XORG_VERSION_SNAP >= 900
142706f2543Smrg  /* When the minor number is 99, that signifies that the we are making
143706f2543Smrg   * a release candidate for a major version.  (X.0.0)
144706f2543Smrg   * When the patch number is 99, that signifies that the we are making
145706f2543Smrg   * a release candidate for a minor version.  (X.Y.0)
146706f2543Smrg   * When the patch number is < 99, then we are making a release
147706f2543Smrg   * candidate for the next point release.  (X.Y.Z)
148706f2543Smrg   */
149706f2543Smrg#if XORG_VERSION_MINOR >= 99
150706f2543Smrg  xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR+1,
151706f2543Smrg                 XORG_VERSION_SNAP - 900);
152706f2543Smrg#elif XORG_VERSION_PATCH == 99
153706f2543Smrg  xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
154706f2543Smrg                 XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
155706f2543Smrg#else
156706f2543Smrg  xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
157706f2543Smrg                 XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
158706f2543Smrg                 XORG_VERSION_SNAP - 900);
159706f2543Smrg#endif
160706f2543Smrg#endif
161706f2543Smrg
162706f2543Smrg#ifdef XORG_CUSTOM_VERSION
163706f2543Smrg  xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
164706f2543Smrg#endif
165706f2543Smrg#ifndef XORG_DATE
166706f2543Smrg# define XORG_DATE "Unknown"
167706f2543Smrg#endif
168706f2543Smrg  xf86ErrorFVerb(0, "\nRelease Date: %s\n", XORG_DATE);
169706f2543Smrg  xf86ErrorFVerb(0, "X Protocol Version %d, Revision %d\n",
170706f2543Smrg         X_PROTOCOL, X_PROTOCOL_REVISION);
171706f2543Smrg  xf86ErrorFVerb(0, "Build Operating System: %s %s\n", OSNAME, OSVENDOR);
172706f2543Smrg#ifdef HAS_UTSNAME
173706f2543Smrg  {
174706f2543Smrg    struct utsname name;
175706f2543Smrg
176706f2543Smrg    /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
177706f2543Smrg       and Irix) and Single Unix Spec 3 just say that non-negative is success.
178706f2543Smrg       All agree that failure is represented by a negative number.
179706f2543Smrg     */
180706f2543Smrg    if (uname(&name) >= 0) {
181706f2543Smrg      xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
182706f2543Smrg	name.sysname, name.nodename, name.release, name.version, name.machine);
183706f2543Smrg#ifdef linux
184706f2543Smrg      do {
185706f2543Smrg	  char buf[80];
186706f2543Smrg	  int fd = open("/proc/cmdline", O_RDONLY);
187706f2543Smrg	  if (fd != -1) {
188706f2543Smrg	    xf86ErrorFVerb(0, "Kernel command line: ");
189706f2543Smrg	    memset(buf, 0, 80);
190706f2543Smrg	    while (read(fd, buf, 80) > 0) {
191706f2543Smrg		xf86ErrorFVerb(0, "%.80s", buf);
192706f2543Smrg		memset(buf, 0, 80);
193706f2543Smrg	    }
194706f2543Smrg	    close(fd);
195706f2543Smrg	  }
196706f2543Smrg      } while (0);
197706f2543Smrg#endif
198706f2543Smrg    }
199706f2543Smrg  }
200706f2543Smrg#endif
201706f2543Smrg#if defined(BUILD_DATE) && (BUILD_DATE > 19000000)
202706f2543Smrg  {
203706f2543Smrg    struct tm t;
204706f2543Smrg    char buf[100];
205706f2543Smrg
206706f2543Smrg    memset(&t, 0, sizeof(t));
207706f2543Smrg    memset(buf, 0, sizeof(buf));
208706f2543Smrg    t.tm_mday = BUILD_DATE % 100;
209706f2543Smrg    t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
210706f2543Smrg    t.tm_year = BUILD_DATE / 10000 - 1900;
211706f2543Smrg#if defined(BUILD_TIME)
212706f2543Smrg    t.tm_sec = BUILD_TIME % 100;
213706f2543Smrg    t.tm_min = (BUILD_TIME / 100) % 100;
214706f2543Smrg    t.tm_hour = (BUILD_TIME / 10000) % 100;
215706f2543Smrg    if (strftime(buf, sizeof(buf), "%d %B %Y  %I:%M:%S%p", &t))
216706f2543Smrg       xf86ErrorFVerb(0, "Build Date: %s\n", buf);
217706f2543Smrg#else
218706f2543Smrg    if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
219706f2543Smrg       xf86ErrorFVerb(0, "Build Date: %s\n", buf);
220706f2543Smrg#endif
221706f2543Smrg  }
222706f2543Smrg#endif
223706f2543Smrg#if defined(BUILDERSTRING)
224706f2543Smrg  xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
225706f2543Smrg#endif
226706f2543Smrg  xf86ErrorFVerb(0, "Current version of pixman: %s\n",
227706f2543Smrg                 pixman_version_string());
228706f2543Smrg  xf86ErrorFVerb(0, "\tBefore reporting problems, check "
229706f2543Smrg                 ""__VENDORDWEBSUPPORT__"\n"
230706f2543Smrg                 "\tto make sure that you have the latest version.\n");
231706f2543Smrg}
232706f2543Smrg
233706f2543Smrgstatic void
234706f2543Smrgxf86PrintMarkers(void)
235706f2543Smrg{
236706f2543Smrg  LogPrintMarkers();
237706f2543Smrg}
238706f2543Smrg
239706f2543Smrgstatic Bool
240706f2543Smrgxf86CreateRootWindow(WindowPtr pWin)
241706f2543Smrg{
242706f2543Smrg  int ret = TRUE;
243706f2543Smrg  int err = Success;
244706f2543Smrg  ScreenPtr pScreen = pWin->drawable.pScreen;
245706f2543Smrg  RootWinPropPtr pProp;
246706f2543Smrg  CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
247706f2543Smrg      dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
248706f2543Smrg
249706f2543Smrg  DebugF("xf86CreateRootWindow(%p)\n", pWin);
250706f2543Smrg
251706f2543Smrg  if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
252706f2543Smrg    /* Can't find hook we are hung on */
253706f2543Smrg	xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
254706f2543Smrg		  "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
255706f2543Smrg		   (void *)xf86CreateRootWindow,
256706f2543Smrg		   (void *)pScreen->CreateWindow );
257706f2543Smrg  }
258706f2543Smrg
259706f2543Smrg  /* Unhook this function ... */
260706f2543Smrg  pScreen->CreateWindow = CreateWindow;
261706f2543Smrg  dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
262706f2543Smrg
263706f2543Smrg  /* ... and call the previous CreateWindow fuction, if any */
264706f2543Smrg  if (NULL!=pScreen->CreateWindow) {
265706f2543Smrg    ret = (*pScreen->CreateWindow)(pWin);
266706f2543Smrg  }
267706f2543Smrg
268706f2543Smrg  /* Now do our stuff */
269706f2543Smrg  if (xf86RegisteredPropertiesTable != NULL) {
270706f2543Smrg    if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
271706f2543Smrg      for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
272706f2543Smrg	   pProp != NULL && err==Success;
273706f2543Smrg	   pProp = pProp->next )
274706f2543Smrg	{
275706f2543Smrg	  Atom prop;
276706f2543Smrg
277706f2543Smrg	  prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
278706f2543Smrg	  err = dixChangeWindowProperty(serverClient, pWin,
279706f2543Smrg					prop, pProp->type,
280706f2543Smrg					pProp->format, PropModeReplace,
281706f2543Smrg					pProp->size, pProp->data,
282706f2543Smrg					FALSE);
283706f2543Smrg	}
284706f2543Smrg
285706f2543Smrg      /* Look at err */
286706f2543Smrg      ret &= (err==Success);
287706f2543Smrg
288706f2543Smrg    } else {
289706f2543Smrg      xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
290706f2543Smrg	      "non-root window %p (parent %p)\n",
291706f2543Smrg	      (void *)pWin, (void *)pWin->parent);
292706f2543Smrg      ret = FALSE;
293706f2543Smrg    }
294706f2543Smrg  }
295706f2543Smrg
296706f2543Smrg  DebugF("xf86CreateRootWindow() returns %d\n", ret);
297706f2543Smrg  return ret;
298706f2543Smrg}
299706f2543Smrg
300706f2543Smrg
301706f2543Smrgstatic void
302706f2543SmrgInstallSignalHandlers(void)
303706f2543Smrg{
304706f2543Smrg    /*
305706f2543Smrg     * Install signal handler for unexpected signals
306706f2543Smrg     */
307706f2543Smrg    xf86Info.caughtSignal=FALSE;
308706f2543Smrg    if (!xf86Info.notrapSignals) {
309706f2543Smrg	OsRegisterSigWrapper(xf86SigWrapper);
310706f2543Smrg    } else {
311706f2543Smrg	signal(SIGSEGV, SIG_DFL);
312706f2543Smrg	signal(SIGILL, SIG_DFL);
313706f2543Smrg#ifdef SIGEMT
314706f2543Smrg	signal(SIGEMT, SIG_DFL);
315706f2543Smrg#endif
316706f2543Smrg	signal(SIGFPE, SIG_DFL);
317706f2543Smrg	signal(SIGBUS, SIG_DFL);
318706f2543Smrg	signal(SIGSYS, SIG_DFL);
319706f2543Smrg	signal(SIGXCPU, SIG_DFL);
320706f2543Smrg	signal(SIGXFSZ, SIG_DFL);
321706f2543Smrg    }
322706f2543Smrg}
323706f2543Smrg
324706f2543Smrg/*
325706f2543Smrg * InitOutput --
326706f2543Smrg *	Initialize screenInfo for all actually accessible framebuffers.
327706f2543Smrg *      That includes vt-manager setup, querying all possible devices and
328706f2543Smrg *      collecting the pixmap formats.
329706f2543Smrg */
330706f2543Smrgvoid
331706f2543SmrgInitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
332706f2543Smrg{
333706f2543Smrg  int                    i, j, k, scr_index, was_blocked = 0;
334706f2543Smrg  char                   **modulelist;
335706f2543Smrg  pointer                *optionlist;
336706f2543Smrg  Pix24Flags		 screenpix24, pix24;
337706f2543Smrg  MessageType		 pix24From = X_DEFAULT;
338706f2543Smrg  Bool			 pix24Fail = FALSE;
339706f2543Smrg  Bool			 autoconfig = FALSE;
340706f2543Smrg  GDevPtr		 configured_device;
341706f2543Smrg
342706f2543Smrg  xf86Initialising = TRUE;
343706f2543Smrg
344706f2543Smrg  if (serverGeneration == 1) {
345706f2543Smrg    if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
346706f2543Smrg      xf86ServerName++;
347706f2543Smrg    else
348706f2543Smrg      xf86ServerName = argv[0];
349706f2543Smrg
350706f2543Smrg	xf86PrintBanner();
351706f2543Smrg	xf86PrintMarkers();
352706f2543Smrg	if (xf86LogFile)  {
353706f2543Smrg	    time_t t;
354706f2543Smrg	    const char *ct;
355706f2543Smrg	    t = time(NULL);
356706f2543Smrg	    ct = ctime(&t);
357706f2543Smrg	    xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
358706f2543Smrg			xf86LogFile, ct);
359706f2543Smrg	}
360706f2543Smrg
361706f2543Smrg    /* Read and parse the config file */
362706f2543Smrg    if (!xf86DoConfigure && !xf86DoShowOptions) {
363706f2543Smrg      switch (xf86HandleConfigFile(FALSE)) {
364706f2543Smrg      case CONFIG_OK:
365706f2543Smrg	break;
366706f2543Smrg      case CONFIG_PARSE_ERROR:
367706f2543Smrg	xf86Msg(X_ERROR, "Error parsing the config file\n");
368706f2543Smrg	return;
369706f2543Smrg      case CONFIG_NOFILE:
370706f2543Smrg	autoconfig = TRUE;
371706f2543Smrg	break;
372706f2543Smrg      }
373706f2543Smrg    }
374706f2543Smrg
375706f2543Smrg    InstallSignalHandlers();
376706f2543Smrg
377706f2543Smrg    /* Initialise the loader */
378706f2543Smrg    LoaderInit();
379706f2543Smrg
380706f2543Smrg    /* Tell the loader the default module search path */
381706f2543Smrg    LoaderSetPath(xf86ModulePath);
382706f2543Smrg
383706f2543Smrg    if (xf86Info.ignoreABI) {
384706f2543Smrg        LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
385706f2543Smrg    }
386706f2543Smrg
387706f2543Smrg    if (xf86DoShowOptions)
388706f2543Smrg        DoShowOptions();
389706f2543Smrg
390706f2543Smrg    /* Do a general bus probe.  This will be a PCI probe for x86 platforms */
391706f2543Smrg    xf86BusProbe();
392706f2543Smrg
393706f2543Smrg    if (xf86DoConfigure)
394706f2543Smrg	DoConfigure();
395706f2543Smrg
396706f2543Smrg    if (autoconfig) {
397706f2543Smrg	if (!xf86AutoConfig()) {
398706f2543Smrg	    xf86Msg(X_ERROR, "Auto configuration failed\n");
399706f2543Smrg	    return;
400706f2543Smrg	}
401706f2543Smrg    }
402706f2543Smrg
403706f2543Smrg#ifdef XF86PM
404706f2543Smrg    xf86OSPMClose = xf86OSPMOpen();
405706f2543Smrg#endif
406706f2543Smrg
407706f2543Smrg    /* Load all modules specified explicitly in the config file */
408706f2543Smrg    if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
409706f2543Smrg      xf86LoadModules(modulelist, optionlist);
410706f2543Smrg      free(modulelist);
411706f2543Smrg      free(optionlist);
412706f2543Smrg    }
413706f2543Smrg
414706f2543Smrg    /* Load all driver modules specified in the config file */
415706f2543Smrg    /* If there aren't any specified in the config file, autoconfig them */
416706f2543Smrg    /* FIXME: Does not handle multiple active screen sections, but I'm not
417706f2543Smrg     * sure if we really want to handle that case*/
418706f2543Smrg    configured_device = xf86ConfigLayout.screens->screen->device;
419706f2543Smrg    if ((!configured_device) || (!configured_device->driver)) {
420706f2543Smrg        if (!autoConfigDevice(configured_device)) {
421706f2543Smrg            xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
422706f2543Smrg            return ;
423706f2543Smrg        }
424706f2543Smrg    }
425706f2543Smrg    if ((modulelist = xf86DriverlistFromConfig())) {
426706f2543Smrg      xf86LoadModules(modulelist, NULL);
427706f2543Smrg      free(modulelist);
428706f2543Smrg    }
429706f2543Smrg
430706f2543Smrg    /* Load all input driver modules specified in the config file. */
431706f2543Smrg    if ((modulelist = xf86InputDriverlistFromConfig())) {
432706f2543Smrg      xf86LoadModules(modulelist, NULL);
433706f2543Smrg      free(modulelist);
434706f2543Smrg    }
435706f2543Smrg
436706f2543Smrg    /*
437706f2543Smrg     * It is expected that xf86AddDriver()/xf86AddInputDriver will be
438706f2543Smrg     * called for each driver as it is loaded.  Those functions save the
439706f2543Smrg     * module pointers for drivers.
440706f2543Smrg     * XXX Nothing keeps track of them for other modules.
441706f2543Smrg     */
442706f2543Smrg    /* XXX What do we do if not all of these could be loaded? */
443706f2543Smrg
444706f2543Smrg    /*
445706f2543Smrg     * At this point, xf86DriverList[] is all filled in with entries for
446706f2543Smrg     * each of the drivers to try and xf86NumDrivers has the number of
447706f2543Smrg     * drivers.  If there are none, return now.
448706f2543Smrg     */
449706f2543Smrg
450706f2543Smrg    if (xf86NumDrivers == 0) {
451706f2543Smrg      xf86Msg(X_ERROR, "No drivers available.\n");
452706f2543Smrg      return;
453706f2543Smrg    }
454706f2543Smrg
455706f2543Smrg    /*
456706f2543Smrg     * Call each of the Identify functions and call the driverFunc to check
457706f2543Smrg     * if HW access is required.  The Identify functions print out some
458706f2543Smrg     * identifying information, and anything else that might be
459706f2543Smrg     * needed at this early stage.
460706f2543Smrg     */
461706f2543Smrg
462706f2543Smrg    for (i = 0; i < xf86NumDrivers; i++) {
463706f2543Smrg	if (xf86DriverList[i]->Identify != NULL)
464706f2543Smrg	    xf86DriverList[i]->Identify(0);
465706f2543Smrg
466706f2543Smrg	if (!xorgHWAccess || !xorgHWOpenConsole) {
467706f2543Smrg	    xorgHWFlags flags;
468706f2543Smrg	    if(!xf86DriverList[i]->driverFunc
469706f2543Smrg		|| !xf86DriverList[i]->driverFunc(NULL,
470706f2543Smrg						  GET_REQUIRED_HW_INTERFACES,
471706f2543Smrg						  &flags))
472706f2543Smrg		flags = HW_IO;
473706f2543Smrg
474706f2543Smrg	    if(NEED_IO_ENABLED(flags))
475706f2543Smrg		xorgHWAccess = TRUE;
476706f2543Smrg	    if(!(flags & HW_SKIP_CONSOLE))
477706f2543Smrg		xorgHWOpenConsole = TRUE;
478706f2543Smrg	}
479706f2543Smrg    }
480706f2543Smrg
481706f2543Smrg    if (xorgHWOpenConsole)
482706f2543Smrg	xf86OpenConsole();
483706f2543Smrg    else
484706f2543Smrg	xf86Info.dontVTSwitch = TRUE;
485706f2543Smrg
486706f2543Smrg    if (xf86BusConfig() == FALSE)
487706f2543Smrg        return;
488706f2543Smrg
489706f2543Smrg    xf86PostProbe();
490706f2543Smrg
491706f2543Smrg    /*
492706f2543Smrg     * Sort the drivers to match the requested ording.  Using a slow
493706f2543Smrg     * bubble sort.
494706f2543Smrg     */
495706f2543Smrg    for (j = 0; j < xf86NumScreens - 1; j++) {
496706f2543Smrg	for (i = 0; i < xf86NumScreens - j - 1; i++) {
497706f2543Smrg	    if (xf86Screens[i + 1]->confScreen->screennum <
498706f2543Smrg		xf86Screens[i]->confScreen->screennum) {
499706f2543Smrg		ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
500706f2543Smrg		xf86Screens[i + 1] = xf86Screens[i];
501706f2543Smrg		xf86Screens[i] = tmpScrn;
502706f2543Smrg	    }
503706f2543Smrg	}
504706f2543Smrg    }
505706f2543Smrg    /* Fix up the indexes */
506706f2543Smrg    for (i = 0; i < xf86NumScreens; i++) {
507706f2543Smrg	xf86Screens[i]->scrnIndex = i;
508706f2543Smrg    }
509706f2543Smrg
510706f2543Smrg    /*
511706f2543Smrg     * Call the driver's PreInit()'s to complete initialisation for the first
512706f2543Smrg     * generation.
513706f2543Smrg     */
514706f2543Smrg
515706f2543Smrg    for (i = 0; i < xf86NumScreens; i++) {
516706f2543Smrg	xf86VGAarbiterScrnInit(xf86Screens[i]);
517706f2543Smrg	xf86VGAarbiterLock(xf86Screens[i]);
518706f2543Smrg	if (xf86Screens[i]->PreInit &&
519706f2543Smrg	    xf86Screens[i]->PreInit(xf86Screens[i], 0))
520706f2543Smrg	    xf86Screens[i]->configured = TRUE;
521706f2543Smrg	xf86VGAarbiterUnlock(xf86Screens[i]);
522706f2543Smrg    }
523706f2543Smrg    for (i = 0; i < xf86NumScreens; i++)
524706f2543Smrg	if (!xf86Screens[i]->configured)
525706f2543Smrg	    xf86DeleteScreen(i--, 0);
526706f2543Smrg
527706f2543Smrg    /*
528706f2543Smrg     * If no screens left, return now.
529706f2543Smrg     */
530706f2543Smrg
531706f2543Smrg    if (xf86NumScreens == 0) {
532706f2543Smrg      xf86Msg(X_ERROR,
533706f2543Smrg	      "Screen(s) found, but none have a usable configuration.\n");
534706f2543Smrg      return;
535706f2543Smrg    }
536706f2543Smrg
537706f2543Smrg    for (i = 0; i < xf86NumScreens; i++) {
538706f2543Smrg      if (xf86Screens[i]->name == NULL) {
539706f2543Smrg	XNFasprintf(&xf86Screens[i]->name, "screen%d", i);
540706f2543Smrg	xf86MsgVerb(X_WARNING, 0,
541706f2543Smrg		    "Screen driver %d has no name set, using `%s'.\n",
542706f2543Smrg		    i, xf86Screens[i]->name);
543706f2543Smrg      }
544706f2543Smrg    }
545706f2543Smrg
546706f2543Smrg    /* Remove (unload) drivers that are not required */
547706f2543Smrg    for (i = 0; i < xf86NumDrivers; i++)
548706f2543Smrg	if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
549706f2543Smrg	    xf86DeleteDriver(i);
550706f2543Smrg
551706f2543Smrg    /*
552706f2543Smrg     * At this stage we know how many screens there are.
553706f2543Smrg     */
554706f2543Smrg
555706f2543Smrg    for (i = 0; i < xf86NumScreens; i++)
556706f2543Smrg      xf86InitViewport(xf86Screens[i]);
557706f2543Smrg
558706f2543Smrg    /*
559706f2543Smrg     * Collect all pixmap formats and check for conflicts at the display
560706f2543Smrg     * level.  Should we die here?  Or just delete the offending screens?
561706f2543Smrg     */
562706f2543Smrg    screenpix24 = Pix24DontCare;
563706f2543Smrg    for (i = 0; i < xf86NumScreens; i++) {
564706f2543Smrg	if (xf86Screens[i]->imageByteOrder !=
565706f2543Smrg	    xf86Screens[0]->imageByteOrder)
566706f2543Smrg	    FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
567706f2543Smrg	if (xf86Screens[i]->bitmapScanlinePad !=
568706f2543Smrg	    xf86Screens[0]->bitmapScanlinePad)
569706f2543Smrg	    FatalError("Inconsistent display bitmapScanlinePad.  Exiting\n");
570706f2543Smrg	if (xf86Screens[i]->bitmapScanlineUnit !=
571706f2543Smrg	    xf86Screens[0]->bitmapScanlineUnit)
572706f2543Smrg	    FatalError("Inconsistent display bitmapScanlineUnit.  Exiting\n");
573706f2543Smrg	if (xf86Screens[i]->bitmapBitOrder !=
574706f2543Smrg	    xf86Screens[0]->bitmapBitOrder)
575706f2543Smrg	    FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
576706f2543Smrg
577706f2543Smrg	/* Determine the depth 24 pixmap format the screens would like */
578706f2543Smrg	if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
579706f2543Smrg	    if (screenpix24 == Pix24DontCare)
580706f2543Smrg		screenpix24 = xf86Screens[i]->pixmap24;
581706f2543Smrg	    else if (screenpix24 != xf86Screens[i]->pixmap24)
582706f2543Smrg		FatalError("Inconsistent depth 24 pixmap format.  Exiting\n");
583706f2543Smrg	}
584706f2543Smrg    }
585706f2543Smrg    /* check if screenpix24 is consistent with the config/cmdline */
586706f2543Smrg    if (xf86Info.pixmap24 != Pix24DontCare) {
587706f2543Smrg	pix24 = xf86Info.pixmap24;
588706f2543Smrg	pix24From = xf86Info.pix24From;
589706f2543Smrg	if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
590706f2543Smrg	    pix24Fail = TRUE;
591706f2543Smrg    } else if (screenpix24 != Pix24DontCare) {
592706f2543Smrg	pix24 = screenpix24;
593706f2543Smrg	pix24From = X_PROBED;
594706f2543Smrg    } else
595706f2543Smrg	pix24 = Pix24Use32;
596706f2543Smrg
597706f2543Smrg    if (pix24Fail)
598706f2543Smrg	FatalError("Screen(s) can't use the required depth 24 pixmap format"
599706f2543Smrg		   " (%d).  Exiting\n", PIX24TOBPP(pix24));
600706f2543Smrg
601706f2543Smrg    /* Initialise the depth 24 format */
602706f2543Smrg    for (j = 0; j < numFormats && formats[j].depth != 24; j++)
603706f2543Smrg	;
604706f2543Smrg    formats[j].bitsPerPixel = PIX24TOBPP(pix24);
605706f2543Smrg
606706f2543Smrg    /* Collect additional formats */
607706f2543Smrg    for (i = 0; i < xf86NumScreens; i++) {
608706f2543Smrg	for (j = 0; j < xf86Screens[i]->numFormats; j++) {
609706f2543Smrg	    for (k = 0; ; k++) {
610706f2543Smrg		if (k >= numFormats) {
611706f2543Smrg		    if (k >= MAXFORMATS)
612706f2543Smrg			FatalError("Too many pixmap formats!  Exiting\n");
613706f2543Smrg		    formats[k] = xf86Screens[i]->formats[j];
614706f2543Smrg		    numFormats++;
615706f2543Smrg		    break;
616706f2543Smrg		}
617706f2543Smrg		if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
618706f2543Smrg		    if ((formats[k].bitsPerPixel ==
619706f2543Smrg			 xf86Screens[i]->formats[j].bitsPerPixel) &&
620706f2543Smrg		        (formats[k].scanlinePad ==
621706f2543Smrg			 xf86Screens[i]->formats[j].scanlinePad))
622706f2543Smrg			break;
623706f2543Smrg		    FatalError("Inconsistent pixmap format for depth %d."
624706f2543Smrg			       "  Exiting\n", formats[k].depth);
625706f2543Smrg		}
626706f2543Smrg	    }
627706f2543Smrg	}
628706f2543Smrg    }
629706f2543Smrg    formatsDone = TRUE;
630706f2543Smrg
631706f2543Smrg    if (xf86Info.vtno >= 0 ) {
632706f2543Smrg#define VT_ATOM_NAME         "XFree86_VT"
633706f2543Smrg      Atom VTAtom=-1;
634706f2543Smrg      CARD32  *VT = NULL;
635706f2543Smrg      int  ret;
636706f2543Smrg
637706f2543Smrg      /* This memory needs to stay available until the screen has been
638706f2543Smrg	 initialized, and we can create the property for real.
639706f2543Smrg      */
640706f2543Smrg      if ( (VT = malloc(sizeof(CARD32)))==NULL ) {
641706f2543Smrg	FatalError("Unable to make VT property - out of memory. Exiting...\n");
642706f2543Smrg      }
643706f2543Smrg      *VT = xf86Info.vtno;
644706f2543Smrg
645706f2543Smrg      VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
646706f2543Smrg
647706f2543Smrg      for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
648706f2543Smrg	ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
649706f2543Smrg					     VTAtom, XA_INTEGER, 32,
650706f2543Smrg					     1, VT );
651706f2543Smrg	if (ret != Success)
652706f2543Smrg	  xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
653706f2543Smrg		     "Failed to register VT property\n");
654706f2543Smrg      }
655706f2543Smrg    }
656706f2543Smrg
657706f2543Smrg    /* If a screen uses depth 24, show what the pixmap format is */
658706f2543Smrg    for (i = 0; i < xf86NumScreens; i++) {
659706f2543Smrg	if (xf86Screens[i]->depth == 24) {
660706f2543Smrg	    xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
661706f2543Smrg		    PIX24TOBPP(pix24));
662706f2543Smrg	    break;
663706f2543Smrg	}
664706f2543Smrg    }
665706f2543Smrg  } else {
666706f2543Smrg    /*
667706f2543Smrg     * serverGeneration != 1; some OSs have to do things here, too.
668706f2543Smrg     */
669706f2543Smrg    if (xorgHWOpenConsole)
670706f2543Smrg	xf86OpenConsole();
671706f2543Smrg
672706f2543Smrg#ifdef XF86PM
673706f2543Smrg    /*
674706f2543Smrg      should we reopen it here? We need to deal with an already opened
675706f2543Smrg      device. We could leave this to the OS layer. For now we simply
676706f2543Smrg      close it here
677706f2543Smrg    */
678706f2543Smrg    if (xf86OSPMClose)
679706f2543Smrg        xf86OSPMClose();
680706f2543Smrg    if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
681706f2543Smrg	xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
682706f2543Smrg#endif
683706f2543Smrg
684706f2543Smrg    /* Make sure full I/O access is enabled */
685706f2543Smrg    if (xorgHWAccess)
686706f2543Smrg	xf86EnableIO();
687706f2543Smrg  }
688706f2543Smrg
689706f2543Smrg  /*
690706f2543Smrg   * Use the previously collected parts to setup pScreenInfo
691706f2543Smrg   */
692706f2543Smrg
693706f2543Smrg  pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
694706f2543Smrg  pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
695706f2543Smrg  pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
696706f2543Smrg  pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
697706f2543Smrg  pScreenInfo->numPixmapFormats = numFormats;
698706f2543Smrg  for (i = 0; i < numFormats; i++)
699706f2543Smrg    pScreenInfo->formats[i] = formats[i];
700706f2543Smrg
701706f2543Smrg  /* Make sure the server's VT is active */
702706f2543Smrg
703706f2543Smrg  if (serverGeneration != 1) {
704706f2543Smrg    xf86Resetting = TRUE;
705706f2543Smrg    /* All screens are in the same state, so just check the first */
706706f2543Smrg    if (!xf86Screens[0]->vtSema) {
707706f2543Smrg#ifdef HAS_USL_VTS
708706f2543Smrg      ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
709706f2543Smrg#endif
710706f2543Smrg      xf86AccessEnter();
711706f2543Smrg      was_blocked = xf86BlockSIGIO();
712706f2543Smrg    }
713706f2543Smrg  }
714706f2543Smrg
715706f2543Smrg  for (i = 0; i < xf86NumScreens; i++)
716706f2543Smrg      if (!xf86ColormapAllocatePrivates(xf86Screens[i]))
717706f2543Smrg	  FatalError("Cannot register DDX private keys");
718706f2543Smrg
719706f2543Smrg  if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0) ||
720706f2543Smrg      !dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
721706f2543Smrg      FatalError("Cannot register DDX private keys");
722706f2543Smrg
723706f2543Smrg  for (i = 0; i < xf86NumScreens; i++) {
724706f2543Smrg	xf86VGAarbiterLock(xf86Screens[i]);
725706f2543Smrg	/*
726706f2543Smrg	 * Almost everything uses these defaults, and many of those that
727706f2543Smrg	 * don't, will wrap them.
728706f2543Smrg	 */
729706f2543Smrg	xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
730706f2543Smrg#ifdef XFreeXDGA
731706f2543Smrg	xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
732706f2543Smrg#endif
733706f2543Smrg	xf86Screens[i]->DPMSSet = NULL;
734706f2543Smrg	xf86Screens[i]->LoadPalette = NULL;
735706f2543Smrg	xf86Screens[i]->SetOverscan = NULL;
736706f2543Smrg	xf86Screens[i]->DriverFunc = NULL;
737706f2543Smrg	xf86Screens[i]->pScreen = NULL;
738706f2543Smrg	scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
739706f2543Smrg	xf86VGAarbiterUnlock(xf86Screens[i]);
740706f2543Smrg      if (scr_index == i) {
741706f2543Smrg	/*
742706f2543Smrg	 * Hook in our ScrnInfoRec, and initialise some other pScreen
743706f2543Smrg	 * fields.
744706f2543Smrg	 */
745706f2543Smrg	dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
746706f2543Smrg		      xf86ScreenKey, xf86Screens[i]);
747706f2543Smrg	xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
748706f2543Smrg	/* The driver should set this, but make sure it is set anyway */
749706f2543Smrg	xf86Screens[i]->vtSema = TRUE;
750706f2543Smrg      } else {
751706f2543Smrg	/* This shouldn't normally happen */
752706f2543Smrg	FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
753706f2543Smrg      }
754706f2543Smrg
755706f2543Smrg      DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
756706f2543Smrg	     i, xf86Screens[i]->pScreen );
757706f2543Smrg      DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
758706f2543Smrg	     i, xf86Screens[i]->pScreen->CreateWindow );
759706f2543Smrg
760706f2543Smrg      dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
761706f2543Smrg		    xf86CreateRootWindowKey,
762706f2543Smrg		    xf86Screens[i]->pScreen->CreateWindow);
763706f2543Smrg      xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
764706f2543Smrg
765706f2543Smrg    if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
766706f2543Smrg    {
767706f2543Smrg	xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
768706f2543Smrg	PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
769706f2543Smrg				 DDC ?
770706f2543Smrg				 (DDC->features.input_type ?
771706f2543Smrg				  SubPixelHorizontalRGB : SubPixelNone) :
772706f2543Smrg				 SubPixelUnknown);
773706f2543Smrg    }
774706f2543Smrg#ifdef RANDR
775706f2543Smrg    if (!xf86Info.disableRandR)
776706f2543Smrg	xf86RandRInit (screenInfo.screens[scr_index]);
777706f2543Smrg    xf86Msg(xf86Info.randRFrom, "RandR %s\n",
778706f2543Smrg	    xf86Info.disableRandR ? "disabled" : "enabled");
779706f2543Smrg#endif
780706f2543Smrg  }
781706f2543Smrg
782706f2543Smrg  xf86VGAarbiterWrapFunctions();
783706f2543Smrg  xf86UnblockSIGIO(was_blocked);
784706f2543Smrg
785706f2543Smrg  xf86InitOrigins();
786706f2543Smrg
787706f2543Smrg  xf86Resetting = FALSE;
788706f2543Smrg  xf86Initialising = FALSE;
789706f2543Smrg
790706f2543Smrg  RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
791706f2543Smrg				 NULL);
792706f2543Smrg}
793706f2543Smrg
794706f2543Smrgstatic InputInfoPtr
795706f2543SmrgduplicateDevice(InputInfoPtr pInfo)
796706f2543Smrg{
797706f2543Smrg    InputInfoPtr dup = calloc(1, sizeof(InputInfoRec));
798706f2543Smrg    if (dup) {
799706f2543Smrg        dup->name = strdup(pInfo->name);
800706f2543Smrg        dup->driver = strdup(pInfo->driver);
801706f2543Smrg        dup->options = xf86OptionListDuplicate(pInfo->options);
802706f2543Smrg        /* type_name is a const string */
803706f2543Smrg        dup->type_name = pInfo->type_name;
804706f2543Smrg        dup->fd = -1;
805706f2543Smrg    }
806706f2543Smrg    return dup;
807706f2543Smrg}
808706f2543Smrg
809706f2543Smrg/*
810706f2543Smrg * InitInput --
811706f2543Smrg *      Initialize all supported input devices.
812706f2543Smrg */
813706f2543Smrg
814706f2543Smrgvoid
815706f2543SmrgInitInput(int argc, char **argv)
816706f2543Smrg{
817706f2543Smrg    InputInfoPtr* pInfo;
818706f2543Smrg    DeviceIntPtr dev;
819706f2543Smrg
820706f2543Smrg    xf86Info.vtRequestsPending = FALSE;
821706f2543Smrg
822706f2543Smrg    mieqInit();
823706f2543Smrg
824706f2543Smrg    GetEventList(&xf86Events);
825706f2543Smrg
826706f2543Smrg    /* Initialize all configured input devices */
827706f2543Smrg    for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) {
828706f2543Smrg        InputInfoPtr dup;
829706f2543Smrg        /* Replace obsolete keyboard driver with kbd */
830706f2543Smrg        if (!xf86NameCmp((*pInfo)->driver, "keyboard")) {
831706f2543Smrg            strcpy((*pInfo)->driver, "kbd");
832706f2543Smrg        }
833706f2543Smrg
834706f2543Smrg        /* Data passed into xf86NewInputDevice will be freed on shutdown.
835706f2543Smrg         * Duplicate from xf86ConfigLayout.inputs, otherwise we don't have any
836706f2543Smrg         * xorg.conf input devices in the second generation
837706f2543Smrg         */
838706f2543Smrg        dup = duplicateDevice(*pInfo);
839706f2543Smrg
840706f2543Smrg        /* If one fails, the others will too */
841706f2543Smrg        if (xf86NewInputDevice(dup, &dev, TRUE) == BadAlloc)
842706f2543Smrg            break;
843706f2543Smrg    }
844706f2543Smrg
845706f2543Smrg    config_init();
846706f2543Smrg}
847706f2543Smrg
848706f2543Smrgvoid
849706f2543SmrgCloseInput (void)
850706f2543Smrg{
851706f2543Smrg    config_fini();
852706f2543Smrg}
853706f2543Smrg
854706f2543Smrg/*
855706f2543Smrg * OsVendorInit --
856706f2543Smrg *      OS/Vendor-specific initialisations.  Called from OsInit(), which
857706f2543Smrg *      is called by dix before establishing the well known sockets.
858706f2543Smrg */
859706f2543Smrg
860706f2543Smrgvoid
861706f2543SmrgOsVendorInit(void)
862706f2543Smrg{
863706f2543Smrg  static Bool beenHere = FALSE;
864706f2543Smrg
865706f2543Smrg  signal(SIGCHLD, SIG_DFL);	/* Need to wait for child processes */
866706f2543Smrg
867706f2543Smrg  if (!beenHere) {
868706f2543Smrg    umask(022);
869706f2543Smrg    xf86LogInit();
870706f2543Smrg  }
871706f2543Smrg
872706f2543Smrg        /* Set stderr to non-blocking. */
873706f2543Smrg#ifndef O_NONBLOCK
874706f2543Smrg#if defined(FNDELAY)
875706f2543Smrg#define O_NONBLOCK FNDELAY
876706f2543Smrg#elif defined(O_NDELAY)
877706f2543Smrg#define O_NONBLOCK O_NDELAY
878706f2543Smrg#endif
879706f2543Smrg
880706f2543Smrg#ifdef O_NONBLOCK
881706f2543Smrg  if (!beenHere) {
882706f2543Smrg    if (geteuid() == 0 && getuid() != geteuid())
883706f2543Smrg    {
884706f2543Smrg      int status;
885706f2543Smrg
886706f2543Smrg      status = fcntl(fileno(stderr), F_GETFL, 0);
887706f2543Smrg      if (status != -1) {
888706f2543Smrg	fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
889706f2543Smrg      }
890706f2543Smrg    }
891706f2543Smrg  }
892706f2543Smrg#endif
893706f2543Smrg#endif
894706f2543Smrg
895706f2543Smrg  beenHere = TRUE;
896706f2543Smrg}
897706f2543Smrg
898706f2543Smrg/*
899706f2543Smrg * ddxGiveUp --
900706f2543Smrg *      Device dependent cleanup. Called by by dix before normal server death.
901706f2543Smrg *      For SYSV386 we must switch the terminal back to normal mode. No error-
902706f2543Smrg *      checking here, since there should be restored as much as possible.
903706f2543Smrg */
904706f2543Smrg
905706f2543Smrgvoid
906706f2543SmrgddxGiveUp(void)
907706f2543Smrg{
908706f2543Smrg    int i;
909706f2543Smrg
910706f2543Smrg    xf86VGAarbiterFini();
911706f2543Smrg
912706f2543Smrg#ifdef XF86PM
913706f2543Smrg    if (xf86OSPMClose)
914706f2543Smrg	xf86OSPMClose();
915706f2543Smrg    xf86OSPMClose = NULL;
916706f2543Smrg#endif
917706f2543Smrg
918706f2543Smrg    for (i = 0; i < xf86NumScreens; i++) {
919706f2543Smrg	/*
920706f2543Smrg	 * zero all access functions to
921706f2543Smrg	 * trap calls when switched away.
922706f2543Smrg	 */
923706f2543Smrg	xf86Screens[i]->vtSema = FALSE;
924706f2543Smrg    }
925706f2543Smrg
926706f2543Smrg#ifdef XFreeXDGA
927706f2543Smrg    DGAShutdown();
928706f2543Smrg#endif
929706f2543Smrg
930706f2543Smrg    if (xorgHWOpenConsole)
931706f2543Smrg	xf86CloseConsole();
932706f2543Smrg
933706f2543Smrg    xf86CloseLog();
934706f2543Smrg
935706f2543Smrg    /* If an unexpected signal was caught, dump a core for debugging */
936706f2543Smrg    if (xf86Info.caughtSignal)
937706f2543Smrg	OsAbort();
938706f2543Smrg}
939706f2543Smrg
940706f2543Smrg
941706f2543Smrg
942706f2543Smrg/*
943706f2543Smrg * AbortDDX --
944706f2543Smrg *      DDX - specific abort routine.  Called by AbortServer(). The attempt is
945706f2543Smrg *      made to restore all original setting of the displays. Also all devices
946706f2543Smrg *      are closed.
947706f2543Smrg */
948706f2543Smrg
949706f2543Smrgvoid
950706f2543SmrgAbortDDX(void)
951706f2543Smrg{
952706f2543Smrg  int i;
953706f2543Smrg
954706f2543Smrg  xf86BlockSIGIO();
955706f2543Smrg
956706f2543Smrg  /*
957706f2543Smrg   * try to restore the original video state
958706f2543Smrg   */
959706f2543Smrg#ifdef DPMSExtension /* Turn screens back on */
960706f2543Smrg  if (DPMSPowerLevel != DPMSModeOn)
961706f2543Smrg      DPMSSet(serverClient, DPMSModeOn);
962706f2543Smrg#endif
963706f2543Smrg  if (xf86Screens) {
964706f2543Smrg      for (i = 0; i < xf86NumScreens; i++)
965706f2543Smrg	  if (xf86Screens[i]->vtSema) {
966706f2543Smrg	      /*
967706f2543Smrg	       * if we are aborting before ScreenInit() has finished
968706f2543Smrg	       * we might not have been wrapped yet. Therefore enable
969706f2543Smrg	       * screen explicitely.
970706f2543Smrg	       */
971706f2543Smrg	      xf86VGAarbiterLock(xf86Screens[i]);
972706f2543Smrg	      (xf86Screens[i]->LeaveVT)(i, 0);
973706f2543Smrg	      xf86VGAarbiterUnlock(xf86Screens[i]);
974706f2543Smrg	  }
975706f2543Smrg  }
976706f2543Smrg
977706f2543Smrg  xf86AccessLeave();
978706f2543Smrg
979706f2543Smrg  /*
980706f2543Smrg   * This is needed for an abnormal server exit, since the normal exit stuff
981706f2543Smrg   * MUST also be performed (i.e. the vt must be left in a defined state)
982706f2543Smrg   */
983706f2543Smrg  ddxGiveUp();
984706f2543Smrg}
985706f2543Smrg
986706f2543Smrgvoid
987706f2543SmrgOsVendorFatalError(void)
988706f2543Smrg{
989706f2543Smrg#ifdef VENDORSUPPORT
990706f2543Smrg    ErrorF("\nPlease refer to your Operating System Vendor support pages\n"
991706f2543Smrg	   "at %s for support on this crash.\n",VENDORSUPPORT);
992706f2543Smrg#else
993706f2543Smrg    ErrorF("\nPlease consult the "XVENDORNAME" support \n"
994706f2543Smrg	   "\t at "__VENDORDWEBSUPPORT__"\n for help. \n");
995706f2543Smrg#endif
996706f2543Smrg    if (xf86LogFile && xf86LogFileWasOpened)
997706f2543Smrg	ErrorF("Please also check the log file at \"%s\" for additional "
998706f2543Smrg              "information.\n", xf86LogFile);
999706f2543Smrg    ErrorF("\n");
1000706f2543Smrg}
1001706f2543Smrg
1002706f2543Smrgint
1003706f2543Smrgxf86SetVerbosity(int verb)
1004706f2543Smrg{
1005706f2543Smrg    int save = xf86Verbose;
1006706f2543Smrg
1007706f2543Smrg    xf86Verbose = verb;
1008706f2543Smrg    LogSetParameter(XLOG_VERBOSITY, verb);
1009706f2543Smrg    return save;
1010706f2543Smrg}
1011706f2543Smrg
1012706f2543Smrgint
1013706f2543Smrgxf86SetLogVerbosity(int verb)
1014706f2543Smrg{
1015706f2543Smrg    int save = xf86LogVerbose;
1016706f2543Smrg
1017706f2543Smrg    xf86LogVerbose = verb;
1018706f2543Smrg    LogSetParameter(XLOG_FILE_VERBOSITY, verb);
1019706f2543Smrg    return save;
1020706f2543Smrg}
1021706f2543Smrg
1022706f2543Smrgstatic void
1023706f2543Smrgxf86PrintDefaultModulePath(void)
1024706f2543Smrg{
1025706f2543Smrg  ErrorF("%s\n", DEFAULT_MODULE_PATH);
1026706f2543Smrg}
1027706f2543Smrg
1028706f2543Smrgstatic void
1029706f2543Smrgxf86PrintDefaultLibraryPath(void)
1030706f2543Smrg{
1031706f2543Smrg  ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
1032706f2543Smrg}
1033706f2543Smrg
1034706f2543Smrg/*
1035706f2543Smrg * ddxProcessArgument --
1036706f2543Smrg *	Process device-dependent command line args. Returns 0 if argument is
1037706f2543Smrg *      not device dependent, otherwise Count of number of elements of argv
1038706f2543Smrg *      that are part of a device dependent commandline option.
1039706f2543Smrg *
1040706f2543Smrg */
1041706f2543Smrg
1042706f2543Smrg/* ARGSUSED */
1043706f2543Smrgint
1044706f2543SmrgddxProcessArgument(int argc, char **argv, int i)
1045706f2543Smrg{
1046706f2543Smrg#define CHECK_FOR_REQUIRED_ARGUMENT() \
1047706f2543Smrg    if (((i + 1) >= argc) || (!argv[i + 1])) { 				\
1048706f2543Smrg      ErrorF("Required argument to %s not specified\n", argv[i]); 	\
1049706f2543Smrg      UseMsg(); 							\
1050706f2543Smrg      FatalError("Required argument to %s not specified\n", argv[i]);	\
1051706f2543Smrg    }
1052706f2543Smrg
1053706f2543Smrg  /* First the options that are only allowed for root */
1054706f2543Smrg  if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
1055706f2543Smrg    if ( (geteuid() == 0) && (getuid() != 0) ) {
1056706f2543Smrg      FatalError("The '%s' option can only be used by root.\n", argv[i]);
1057706f2543Smrg    }
1058706f2543Smrg    else if (!strcmp(argv[i], "-modulepath"))
1059706f2543Smrg    {
1060706f2543Smrg      char *mp;
1061706f2543Smrg      CHECK_FOR_REQUIRED_ARGUMENT();
1062706f2543Smrg      mp = strdup(argv[i + 1]);
1063706f2543Smrg      if (!mp)
1064706f2543Smrg	FatalError("Can't allocate memory for ModulePath\n");
1065706f2543Smrg      xf86ModulePath = mp;
1066706f2543Smrg      xf86ModPathFrom = X_CMDLINE;
1067706f2543Smrg      return 2;
1068706f2543Smrg    }
1069706f2543Smrg    else if (!strcmp(argv[i], "-logfile"))
1070706f2543Smrg    {
1071706f2543Smrg      char *lf;
1072706f2543Smrg      CHECK_FOR_REQUIRED_ARGUMENT();
1073706f2543Smrg      lf = strdup(argv[i + 1]);
1074706f2543Smrg      if (!lf)
1075706f2543Smrg	FatalError("Can't allocate memory for LogFile\n");
1076706f2543Smrg      xf86LogFile = lf;
1077706f2543Smrg      xf86LogFileFrom = X_CMDLINE;
1078706f2543Smrg      return 2;
1079706f2543Smrg    }
1080706f2543Smrg  }
1081706f2543Smrg  if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
1082706f2543Smrg  {
1083706f2543Smrg    CHECK_FOR_REQUIRED_ARGUMENT();
1084706f2543Smrg    if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
1085706f2543Smrg      FatalError("\nInvalid argument for %s\n"
1086706f2543Smrg	  "\tFor non-root users, the file specified with %s must be\n"
1087706f2543Smrg	  "\ta relative path and must not contain any \"..\" elements.\n"
1088706f2543Smrg	  "\tUsing default "__XCONFIGFILE__" search path.\n\n",
1089706f2543Smrg	  argv[i], argv[i]);
1090706f2543Smrg    }
1091706f2543Smrg    xf86ConfigFile = argv[i + 1];
1092706f2543Smrg    return 2;
1093706f2543Smrg  }
1094706f2543Smrg  if (!strcmp(argv[i], "-configdir"))
1095706f2543Smrg  {
1096706f2543Smrg    CHECK_FOR_REQUIRED_ARGUMENT();
1097706f2543Smrg    if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
1098706f2543Smrg      FatalError("\nInvalid argument for %s\n"
1099706f2543Smrg	  "\tFor non-root users, the file specified with %s must be\n"
1100706f2543Smrg	  "\ta relative path and must not contain any \"..\" elements.\n"
1101706f2543Smrg	  "\tUsing default "__XCONFIGDIR__" search path.\n\n",
1102706f2543Smrg	  argv[i], argv[i]);
1103706f2543Smrg    }
1104706f2543Smrg    xf86ConfigDir = argv[i + 1];
1105706f2543Smrg    return 2;
1106706f2543Smrg  }
1107706f2543Smrg  if (!strcmp(argv[i],"-flipPixels"))
1108706f2543Smrg  {
1109706f2543Smrg    xf86FlipPixels = TRUE;
1110706f2543Smrg    return 1;
1111706f2543Smrg  }
1112706f2543Smrg#ifdef XF86VIDMODE
1113706f2543Smrg  if (!strcmp(argv[i],"-disableVidMode"))
1114706f2543Smrg  {
1115706f2543Smrg    xf86VidModeDisabled = TRUE;
1116706f2543Smrg    return 1;
1117706f2543Smrg  }
1118706f2543Smrg  if (!strcmp(argv[i],"-allowNonLocalXvidtune"))
1119706f2543Smrg  {
1120706f2543Smrg    xf86VidModeAllowNonLocal = TRUE;
1121706f2543Smrg    return 1;
1122706f2543Smrg  }
1123706f2543Smrg#endif
1124706f2543Smrg  if (!strcmp(argv[i],"-allowMouseOpenFail"))
1125706f2543Smrg  {
1126706f2543Smrg    xf86AllowMouseOpenFail = TRUE;
1127706f2543Smrg    return 1;
1128706f2543Smrg  }
1129706f2543Smrg  if (!strcmp(argv[i],"-ignoreABI"))
1130706f2543Smrg  {
1131706f2543Smrg    LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
1132706f2543Smrg    return 1;
1133706f2543Smrg  }
1134706f2543Smrg  if (!strcmp(argv[i],"-verbose"))
1135706f2543Smrg  {
1136706f2543Smrg    if (++i < argc && argv[i])
1137706f2543Smrg    {
1138706f2543Smrg      char *end;
1139706f2543Smrg      long val;
1140706f2543Smrg      val = strtol(argv[i], &end, 0);
1141706f2543Smrg      if (*end == '\0')
1142706f2543Smrg      {
1143706f2543Smrg	xf86SetVerbosity(val);
1144706f2543Smrg	return 2;
1145706f2543Smrg      }
1146706f2543Smrg    }
1147706f2543Smrg    xf86SetVerbosity(++xf86Verbose);
1148706f2543Smrg    return 1;
1149706f2543Smrg  }
1150706f2543Smrg  if (!strcmp(argv[i],"-logverbose"))
1151706f2543Smrg  {
1152706f2543Smrg    if (++i < argc && argv[i])
1153706f2543Smrg    {
1154706f2543Smrg      char *end;
1155706f2543Smrg      long val;
1156706f2543Smrg      val = strtol(argv[i], &end, 0);
1157706f2543Smrg      if (*end == '\0')
1158706f2543Smrg      {
1159706f2543Smrg	xf86SetLogVerbosity(val);
1160706f2543Smrg	return 2;
1161706f2543Smrg      }
1162706f2543Smrg    }
1163706f2543Smrg    xf86SetLogVerbosity(++xf86LogVerbose);
1164706f2543Smrg    return 1;
1165706f2543Smrg  }
1166706f2543Smrg  if (!strcmp(argv[i],"-quiet"))
1167706f2543Smrg  {
1168706f2543Smrg    xf86SetVerbosity(-1);
1169706f2543Smrg    return 1;
1170706f2543Smrg  }
1171706f2543Smrg  if (!strcmp(argv[i],"-showconfig") || !strcmp(argv[i],"-version"))
1172706f2543Smrg  {
1173706f2543Smrg    xf86PrintBanner();
1174706f2543Smrg    exit(0);
1175706f2543Smrg  }
1176706f2543Smrg  if (!strcmp(argv[i],"-showDefaultModulePath"))
1177706f2543Smrg  {
1178706f2543Smrg    xf86PrintDefaultModulePath();
1179706f2543Smrg    exit(0);
1180706f2543Smrg  }
1181706f2543Smrg  if (!strcmp(argv[i],"-showDefaultLibPath"))
1182706f2543Smrg  {
1183706f2543Smrg    xf86PrintDefaultLibraryPath();
1184706f2543Smrg    exit(0);
1185706f2543Smrg  }
1186706f2543Smrg  /* Notice the -fp flag, but allow it to pass to the dix layer */
1187706f2543Smrg  if (!strcmp(argv[i], "-fp"))
1188706f2543Smrg  {
1189706f2543Smrg    xf86fpFlag = TRUE;
1190706f2543Smrg    return 0;
1191706f2543Smrg  }
1192706f2543Smrg  /* Notice the -bs flag, but allow it to pass to the dix layer */
1193706f2543Smrg  if (!strcmp(argv[i], "-bs"))
1194706f2543Smrg  {
1195706f2543Smrg    xf86bsDisableFlag = TRUE;
1196706f2543Smrg    return 0;
1197706f2543Smrg  }
1198706f2543Smrg  /* Notice the +bs flag, but allow it to pass to the dix layer */
1199706f2543Smrg  if (!strcmp(argv[i], "+bs"))
1200706f2543Smrg  {
1201706f2543Smrg    xf86bsEnableFlag = TRUE;
1202706f2543Smrg    return 0;
1203706f2543Smrg  }
1204706f2543Smrg  /* Notice the -s flag, but allow it to pass to the dix layer */
1205706f2543Smrg  if (!strcmp(argv[i], "-s"))
1206706f2543Smrg  {
1207706f2543Smrg    xf86sFlag = TRUE;
1208706f2543Smrg    return 0;
1209706f2543Smrg  }
1210706f2543Smrg  if (!strcmp(argv[i], "-pixmap24"))
1211706f2543Smrg  {
1212706f2543Smrg    xf86Pix24 = Pix24Use24;
1213706f2543Smrg    return 1;
1214706f2543Smrg  }
1215706f2543Smrg  if (!strcmp(argv[i], "-pixmap32"))
1216706f2543Smrg  {
1217706f2543Smrg    xf86Pix24 = Pix24Use32;
1218706f2543Smrg    return 1;
1219706f2543Smrg  }
1220706f2543Smrg  if (!strcmp(argv[i], "-fbbpp"))
1221706f2543Smrg  {
1222706f2543Smrg    int bpp;
1223706f2543Smrg    CHECK_FOR_REQUIRED_ARGUMENT();
1224706f2543Smrg    if (sscanf(argv[++i], "%d", &bpp) == 1)
1225706f2543Smrg    {
1226706f2543Smrg      xf86FbBpp = bpp;
1227706f2543Smrg      return 2;
1228706f2543Smrg    }
1229706f2543Smrg    else
1230706f2543Smrg    {
1231706f2543Smrg      ErrorF("Invalid fbbpp\n");
1232706f2543Smrg      return 0;
1233706f2543Smrg    }
1234706f2543Smrg  }
1235706f2543Smrg  if (!strcmp(argv[i], "-depth"))
1236706f2543Smrg  {
1237706f2543Smrg    int depth;
1238706f2543Smrg    CHECK_FOR_REQUIRED_ARGUMENT();
1239706f2543Smrg    if (sscanf(argv[++i], "%d", &depth) == 1)
1240706f2543Smrg    {
1241706f2543Smrg      xf86Depth = depth;
1242706f2543Smrg      return 2;
1243706f2543Smrg    }
1244706f2543Smrg    else
1245706f2543Smrg    {
1246706f2543Smrg      ErrorF("Invalid depth\n");
1247706f2543Smrg      return 0;
1248706f2543Smrg    }
1249706f2543Smrg  }
1250706f2543Smrg  if (!strcmp(argv[i], "-weight"))
1251706f2543Smrg  {
1252706f2543Smrg    int red, green, blue;
1253706f2543Smrg    CHECK_FOR_REQUIRED_ARGUMENT();
1254706f2543Smrg    if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3)
1255706f2543Smrg    {
1256706f2543Smrg      xf86Weight.red = red;
1257706f2543Smrg      xf86Weight.green = green;
1258706f2543Smrg      xf86Weight.blue = blue;
1259706f2543Smrg      return 2;
1260706f2543Smrg    }
1261706f2543Smrg    else
1262706f2543Smrg    {
1263706f2543Smrg      ErrorF("Invalid weighting\n");
1264706f2543Smrg      return 0;
1265706f2543Smrg    }
1266706f2543Smrg  }
1267706f2543Smrg  if (!strcmp(argv[i], "-gamma")  || !strcmp(argv[i], "-rgamma") ||
1268706f2543Smrg      !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma"))
1269706f2543Smrg  {
1270706f2543Smrg    double gamma;
1271706f2543Smrg    CHECK_FOR_REQUIRED_ARGUMENT();
1272706f2543Smrg    if (sscanf(argv[++i], "%lf", &gamma) == 1) {
1273706f2543Smrg       if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
1274706f2543Smrg	  ErrorF("gamma out of range, only  %.2f <= gamma_value <= %.1f"
1275706f2543Smrg		 " is valid\n", GAMMA_MIN, GAMMA_MAX);
1276706f2543Smrg	  return 0;
1277706f2543Smrg       }
1278706f2543Smrg       if (!strcmp(argv[i-1], "-gamma"))
1279706f2543Smrg	  xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
1280706f2543Smrg       else if (!strcmp(argv[i-1], "-rgamma")) xf86Gamma.red = gamma;
1281706f2543Smrg       else if (!strcmp(argv[i-1], "-ggamma")) xf86Gamma.green = gamma;
1282706f2543Smrg       else if (!strcmp(argv[i-1], "-bgamma")) xf86Gamma.blue = gamma;
1283706f2543Smrg       return 2;
1284706f2543Smrg    }
1285706f2543Smrg  }
1286706f2543Smrg  if (!strcmp(argv[i], "-layout"))
1287706f2543Smrg  {
1288706f2543Smrg    CHECK_FOR_REQUIRED_ARGUMENT();
1289706f2543Smrg    xf86LayoutName = argv[++i];
1290706f2543Smrg    return 2;
1291706f2543Smrg  }
1292706f2543Smrg  if (!strcmp(argv[i], "-screen"))
1293706f2543Smrg  {
1294706f2543Smrg    CHECK_FOR_REQUIRED_ARGUMENT();
1295706f2543Smrg    xf86ScreenName = argv[++i];
1296706f2543Smrg    return 2;
1297706f2543Smrg  }
1298706f2543Smrg  if (!strcmp(argv[i], "-pointer"))
1299706f2543Smrg  {
1300706f2543Smrg    CHECK_FOR_REQUIRED_ARGUMENT();
1301706f2543Smrg    xf86PointerName = argv[++i];
1302706f2543Smrg    return 2;
1303706f2543Smrg  }
1304706f2543Smrg  if (!strcmp(argv[i], "-keyboard"))
1305706f2543Smrg  {
1306706f2543Smrg    CHECK_FOR_REQUIRED_ARGUMENT();
1307706f2543Smrg    xf86KeyboardName = argv[++i];
1308706f2543Smrg    return 2;
1309706f2543Smrg  }
1310706f2543Smrg  if (!strcmp(argv[i], "-nosilk"))
1311706f2543Smrg  {
1312706f2543Smrg    xf86silkenMouseDisableFlag = TRUE;
1313706f2543Smrg    return 1;
1314706f2543Smrg  }
1315706f2543Smrg#ifdef HAVE_ACPI
1316706f2543Smrg  if (!strcmp(argv[i], "-noacpi"))
1317706f2543Smrg  {
1318706f2543Smrg    xf86acpiDisableFlag = TRUE;
1319706f2543Smrg    return 1;
1320706f2543Smrg  }
1321706f2543Smrg#endif
1322706f2543Smrg  if (!strcmp(argv[i], "-configure"))
1323706f2543Smrg  {
1324706f2543Smrg    if (getuid() != 0 && geteuid() == 0) {
1325706f2543Smrg	ErrorF("The '-configure' option can only be used by root.\n");
1326706f2543Smrg	exit(1);
1327706f2543Smrg    }
1328706f2543Smrg    xf86DoConfigure = TRUE;
1329706f2543Smrg    xf86AllowMouseOpenFail = TRUE;
1330706f2543Smrg    return 1;
1331706f2543Smrg  }
1332706f2543Smrg  if (!strcmp(argv[i], "-showopts"))
1333706f2543Smrg  {
1334706f2543Smrg    if (getuid() != 0 && geteuid() == 0) {
1335706f2543Smrg    ErrorF("The '-showopts' option can only be used by root.\n");
1336706f2543Smrg    exit(1);
1337706f2543Smrg    }
1338706f2543Smrg    xf86DoShowOptions = TRUE;
1339706f2543Smrg    return 1;
1340706f2543Smrg  }
1341706f2543Smrg  if (!strcmp(argv[i], "-isolateDevice"))
1342706f2543Smrg  {
1343706f2543Smrg    CHECK_FOR_REQUIRED_ARGUMENT();
1344706f2543Smrg    if (strncmp(argv[++i], "PCI:", 4)) {
1345706f2543Smrg       FatalError("Bus types other than PCI not yet isolable\n");
1346706f2543Smrg    }
1347706f2543Smrg    xf86PciIsolateDevice(argv[i]);
1348706f2543Smrg    return 2;
1349706f2543Smrg  }
1350706f2543Smrg  /* Notice cmdline xkbdir, but pass to dix as well */
1351706f2543Smrg  if (!strcmp(argv[i], "-xkbdir"))
1352706f2543Smrg  {
1353706f2543Smrg    xf86xkbdirFlag = TRUE;
1354706f2543Smrg    return 0;
1355706f2543Smrg  }
1356706f2543Smrg
1357706f2543Smrg  /* OS-specific processing */
1358706f2543Smrg  return xf86ProcessArgument(argc, argv, i);
1359706f2543Smrg}
1360706f2543Smrg
1361706f2543Smrg/*
1362706f2543Smrg * ddxUseMsg --
1363706f2543Smrg *	Print out correct use of device dependent commandline options.
1364706f2543Smrg *      Maybe the user now knows what really to do ...
1365706f2543Smrg */
1366706f2543Smrg
1367706f2543Smrgvoid
1368706f2543SmrgddxUseMsg(void)
1369706f2543Smrg{
1370706f2543Smrg  ErrorF("\n");
1371706f2543Smrg  ErrorF("\n");
1372706f2543Smrg  ErrorF("Device Dependent Usage\n");
1373706f2543Smrg  if (getuid() == 0 || geteuid() != 0)
1374706f2543Smrg  {
1375706f2543Smrg    ErrorF("-modulepath paths      specify the module search path\n");
1376706f2543Smrg    ErrorF("-logfile file          specify a log file name\n");
1377706f2543Smrg    ErrorF("-configure             probe for devices and write an "__XCONFIGFILE__"\n");
1378706f2543Smrg    ErrorF("-showopts              print available options for all installed drivers\n");
1379706f2543Smrg  }
1380706f2543Smrg  ErrorF("-config file           specify a configuration file, relative to the\n");
1381706f2543Smrg  ErrorF("                       "__XCONFIGFILE__" search path, only root can use absolute\n");
1382706f2543Smrg  ErrorF("-configdir dir         specify a configuration directory, relative to the\n");
1383706f2543Smrg  ErrorF("                       "__XCONFIGDIR__" search path, only root can use absolute\n");
1384706f2543Smrg  ErrorF("-verbose [n]           verbose startup messages\n");
1385706f2543Smrg  ErrorF("-logverbose [n]        verbose log messages\n");
1386706f2543Smrg  ErrorF("-quiet                 minimal startup messages\n");
1387706f2543Smrg  ErrorF("-pixmap24              use 24bpp pixmaps for depth 24\n");
1388706f2543Smrg  ErrorF("-pixmap32              use 32bpp pixmaps for depth 24\n");
1389706f2543Smrg  ErrorF("-fbbpp n               set bpp for the framebuffer. Default: 8\n");
1390706f2543Smrg  ErrorF("-depth n               set colour depth. Default: 8\n");
1391706f2543Smrg  ErrorF("-gamma f               set gamma value (0.1 < f < 10.0) Default: 1.0\n");
1392706f2543Smrg  ErrorF("-rgamma f              set gamma value for red phase\n");
1393706f2543Smrg  ErrorF("-ggamma f              set gamma value for green phase\n");
1394706f2543Smrg  ErrorF("-bgamma f              set gamma value for blue phase\n");
1395706f2543Smrg  ErrorF("-weight nnn            set RGB weighting at 16 bpp.  Default: 565\n");
1396706f2543Smrg  ErrorF("-layout name           specify the ServerLayout section name\n");
1397706f2543Smrg  ErrorF("-screen name           specify the Screen section name\n");
1398706f2543Smrg  ErrorF("-keyboard name         specify the core keyboard InputDevice name\n");
1399706f2543Smrg  ErrorF("-pointer name          specify the core pointer InputDevice name\n");
1400706f2543Smrg  ErrorF("-nosilk                disable Silken Mouse\n");
1401706f2543Smrg  ErrorF("-flipPixels            swap default black/white Pixel values\n");
1402706f2543Smrg#ifdef XF86VIDMODE
1403706f2543Smrg  ErrorF("-disableVidMode        disable mode adjustments with xvidtune\n");
1404706f2543Smrg  ErrorF("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
1405706f2543Smrg#endif
1406706f2543Smrg  ErrorF("-allowMouseOpenFail    start server even if the mouse can't be initialized\n");
1407706f2543Smrg  ErrorF("-ignoreABI             make module ABI mismatches non-fatal\n");
1408706f2543Smrg  ErrorF("-isolateDevice bus_id  restrict device resets to bus_id (PCI only)\n");
1409706f2543Smrg  ErrorF("-version               show the server version\n");
1410706f2543Smrg  ErrorF("-showDefaultModulePath show the server default module path\n");
1411706f2543Smrg  ErrorF("-showDefaultLibPath    show the server default library path\n");
1412706f2543Smrg  /* OS-specific usage */
1413706f2543Smrg  xf86UseMsg();
1414706f2543Smrg  ErrorF("\n");
1415706f2543Smrg}
1416706f2543Smrg
1417706f2543Smrg
1418706f2543Smrg/*
1419706f2543Smrg * xf86LoadModules iterates over a list that is being passed in.
1420706f2543Smrg */
1421706f2543SmrgBool
1422706f2543Smrgxf86LoadModules(char **list, pointer *optlist)
1423706f2543Smrg{
1424706f2543Smrg    int errmaj, errmin;
1425706f2543Smrg    pointer opt;
1426706f2543Smrg    int i;
1427706f2543Smrg    char *name;
1428706f2543Smrg    Bool failed = FALSE;
1429706f2543Smrg
1430706f2543Smrg    if (!list)
1431706f2543Smrg	return TRUE;
1432706f2543Smrg
1433706f2543Smrg    for (i = 0; list[i] != NULL; i++) {
1434706f2543Smrg
1435706f2543Smrg	/* Normalise the module name */
1436706f2543Smrg	name = xf86NormalizeName(list[i]);
1437706f2543Smrg
1438706f2543Smrg	/* Skip empty names */
1439706f2543Smrg	if (name == NULL || *name == '\0') {
1440706f2543Smrg	    free(name);
1441706f2543Smrg	    continue;
1442706f2543Smrg	}
1443706f2543Smrg
1444706f2543Smrg	/* Replace obsolete keyboard driver with kbd */
1445706f2543Smrg	if (!xf86NameCmp(name, "keyboard")) {
1446706f2543Smrg	    strcpy(name, "kbd");
1447706f2543Smrg	}
1448706f2543Smrg
1449706f2543Smrg	if (optlist)
1450706f2543Smrg	    opt = optlist[i];
1451706f2543Smrg	else
1452706f2543Smrg	    opt = NULL;
1453706f2543Smrg
1454706f2543Smrg        if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
1455706f2543Smrg	    LoaderErrorMsg(NULL, name, errmaj, errmin);
1456706f2543Smrg	    failed = TRUE;
1457706f2543Smrg	}
1458706f2543Smrg	free(name);
1459706f2543Smrg    }
1460706f2543Smrg    return !failed;
1461706f2543Smrg}
1462706f2543Smrg
1463706f2543Smrg/* Pixmap format stuff */
1464706f2543Smrg
1465706f2543SmrgPixmapFormatPtr
1466706f2543Smrgxf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
1467706f2543Smrg{
1468706f2543Smrg    int i;
1469706f2543Smrg    static PixmapFormatRec format;	/* XXX not reentrant */
1470706f2543Smrg
1471706f2543Smrg    /*
1472706f2543Smrg     * When the formats[] list initialisation isn't complete, check the
1473706f2543Smrg     * depth 24 pixmap config/cmdline options and screen-specified formats.
1474706f2543Smrg     */
1475706f2543Smrg
1476706f2543Smrg    if (!formatsDone) {
1477706f2543Smrg	if (depth == 24) {
1478706f2543Smrg	    Pix24Flags pix24 = Pix24DontCare;
1479706f2543Smrg
1480706f2543Smrg	    format.depth = 24;
1481706f2543Smrg	    format.scanlinePad = BITMAP_SCANLINE_PAD;
1482706f2543Smrg	    if (xf86Info.pixmap24 != Pix24DontCare)
1483706f2543Smrg		pix24 = xf86Info.pixmap24;
1484706f2543Smrg	    else if (pScrn->pixmap24 != Pix24DontCare)
1485706f2543Smrg		pix24 = pScrn->pixmap24;
1486706f2543Smrg	    if (pix24 == Pix24Use24)
1487706f2543Smrg		format.bitsPerPixel = 24;
1488706f2543Smrg	    else
1489706f2543Smrg		format.bitsPerPixel = 32;
1490706f2543Smrg	    return &format;
1491706f2543Smrg	}
1492706f2543Smrg    }
1493706f2543Smrg
1494706f2543Smrg    for (i = 0; i < numFormats; i++)
1495706f2543Smrg	if (formats[i].depth == depth)
1496706f2543Smrg	   break;
1497706f2543Smrg    if (i != numFormats)
1498706f2543Smrg	return &formats[i];
1499706f2543Smrg    else if (!formatsDone) {
1500706f2543Smrg	/* Check for screen-specified formats */
1501706f2543Smrg	for (i = 0; i < pScrn->numFormats; i++)
1502706f2543Smrg	    if (pScrn->formats[i].depth == depth)
1503706f2543Smrg		break;
1504706f2543Smrg	if (i != pScrn->numFormats)
1505706f2543Smrg	    return &pScrn->formats[i];
1506706f2543Smrg    }
1507706f2543Smrg    return NULL;
1508706f2543Smrg}
1509706f2543Smrg
1510706f2543Smrgint
1511706f2543Smrgxf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
1512706f2543Smrg{
1513706f2543Smrg    PixmapFormatPtr format;
1514706f2543Smrg
1515706f2543Smrg
1516706f2543Smrg    format = xf86GetPixFormat(pScrn, depth);
1517706f2543Smrg    if (format)
1518706f2543Smrg	return format->bitsPerPixel;
1519706f2543Smrg    else
1520706f2543Smrg	return 0;
1521706f2543Smrg}
1522