105b261ecSmrg/*
205b261ecSmrg * Loosely based on code bearing the following copyright:
305b261ecSmrg *
405b261ecSmrg *   Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
505b261ecSmrg */
605b261ecSmrg/*
705b261ecSmrg * Copyright (c) 1992-2003 by The XFree86 Project, Inc.
805b261ecSmrg *
905b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
1005b261ecSmrg * copy of this software and associated documentation files (the "Software"),
1105b261ecSmrg * to deal in the Software without restriction, including without limitation
1205b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1305b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the
1405b261ecSmrg * Software is furnished to do so, subject to the following conditions:
1505b261ecSmrg *
1605b261ecSmrg * The above copyright notice and this permission notice shall be included in
1705b261ecSmrg * all copies or substantial portions of the Software.
1805b261ecSmrg *
1905b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2005b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2105b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2205b261ecSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
2305b261ecSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2405b261ecSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2505b261ecSmrg * OTHER DEALINGS IN THE SOFTWARE.
2605b261ecSmrg *
2705b261ecSmrg * Except as contained in this notice, the name of the copyright holder(s)
2805b261ecSmrg * and author(s) shall not be used in advertising or otherwise to promote
2905b261ecSmrg * the sale, use or other dealings in this Software without prior written
3005b261ecSmrg * authorization from the copyright holder(s) and author(s).
3105b261ecSmrg */
3205b261ecSmrg
3305b261ecSmrg#ifdef HAVE_XORG_CONFIG_H
3405b261ecSmrg#include <xorg-config.h>
3505b261ecSmrg#endif
3605b261ecSmrg
3705b261ecSmrg#include <stdlib.h>
3805b261ecSmrg#include <errno.h>
3905b261ecSmrg
4005b261ecSmrg#undef HAS_UTSNAME
4105b261ecSmrg#if !defined(WIN32)
4205b261ecSmrg#define HAS_UTSNAME 1
4305b261ecSmrg#include <sys/utsname.h>
4405b261ecSmrg#endif
4505b261ecSmrg
4605b261ecSmrg#include <X11/X.h>
4705b261ecSmrg#include <X11/Xmd.h>
4805b261ecSmrg#include <X11/Xproto.h>
4905b261ecSmrg#include <X11/Xatom.h>
5005b261ecSmrg#include "input.h"
5105b261ecSmrg#include "servermd.h"
5205b261ecSmrg#include "windowstr.h"
5305b261ecSmrg#include "scrnintstr.h"
5405b261ecSmrg#include "mi.h"
5535c4bbdfSmrg#include "dbus-core.h"
5635c4bbdfSmrg#include "systemd-logind.h"
5705b261ecSmrg
5805b261ecSmrg#include "loaderProcs.h"
5905b261ecSmrg
6005b261ecSmrg#define XF86_OS_PRIVS
6105b261ecSmrg#include "xf86.h"
6205b261ecSmrg#include "xf86Priv.h"
6305b261ecSmrg#include "xf86Config.h"
6405b261ecSmrg#include "xf86_OSlib.h"
656747b715Smrg#include "xf86cmap.h"
6605b261ecSmrg#include "xorgVersion.h"
6705b261ecSmrg#include "mipointer.h"
6805b261ecSmrg#include <X11/extensions/XI.h>
6905b261ecSmrg#include <X11/extensions/XIproto.h>
7035c4bbdfSmrg#include "xf86Extensions.h"
7105b261ecSmrg#include "xf86DDC.h"
7205b261ecSmrg#include "xf86Xinput.h"
7305b261ecSmrg#include "xf86InPriv.h"
74ed6184dfSmrg#include "xf86Crtc.h"
7505b261ecSmrg#include "picturestr.h"
761b5d61b8Smrg#include "randrstr.h"
776747b715Smrg#include "xf86Bus.h"
7835c4bbdfSmrg#ifdef XSERVER_LIBPCIACCESS
796747b715Smrg#include "xf86VGAarbiter.h"
8035c4bbdfSmrg#endif
8105b261ecSmrg#include "globals.h"
8235c4bbdfSmrg#include "xserver-properties.h"
8305b261ecSmrg
8405b261ecSmrg#ifdef DPMSExtension
856747b715Smrg#include <X11/extensions/dpmsconst.h>
8605b261ecSmrg#include "dpmsproc.h"
8705b261ecSmrg#endif
88ed6184dfSmrg
89ed6184dfSmrg#ifdef __linux__
90ed6184dfSmrg#include <linux/major.h>
91ed6184dfSmrg#include <sys/sysmacros.h>
92ed6184dfSmrg#endif
936747b715Smrg#include <hotplug.h>
9405b261ecSmrg
9535c4bbdfSmrgvoid (*xf86OSPMClose) (void) = NULL;
966747b715Smrgstatic Bool xorgHWOpenConsole = FALSE;
9705b261ecSmrg
9805b261ecSmrg/* Common pixmap formats */
9905b261ecSmrg
10005b261ecSmrgstatic PixmapFormatRec formats[MAXFORMATS] = {
10135c4bbdfSmrg    {1, 1, BITMAP_SCANLINE_PAD},
10235c4bbdfSmrg    {4, 8, BITMAP_SCANLINE_PAD},
10335c4bbdfSmrg    {8, 8, BITMAP_SCANLINE_PAD},
10435c4bbdfSmrg    {15, 16, BITMAP_SCANLINE_PAD},
10535c4bbdfSmrg    {16, 16, BITMAP_SCANLINE_PAD},
10635c4bbdfSmrg    {24, 32, BITMAP_SCANLINE_PAD},
10735c4bbdfSmrg    {32, 32, BITMAP_SCANLINE_PAD},
10805b261ecSmrg};
10935c4bbdfSmrg
11005b261ecSmrgstatic int numFormats = 7;
11105b261ecSmrgstatic Bool formatsDone = FALSE;
11205b261ecSmrg
1134642e01fSmrg
1144642e01fSmrgstatic void
1154642e01fSmrgxf86PrintBanner(void)
1164642e01fSmrg{
11735c4bbdfSmrg    xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
11835c4bbdfSmrg                   XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH);
1194642e01fSmrg#if XORG_VERSION_SNAP > 0
12035c4bbdfSmrg    xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
1214642e01fSmrg#endif
1224642e01fSmrg
1234642e01fSmrg#if XORG_VERSION_SNAP >= 900
12435c4bbdfSmrg    /* When the minor number is 99, that signifies that the we are making
12535c4bbdfSmrg     * a release candidate for a major version.  (X.0.0)
12635c4bbdfSmrg     * When the patch number is 99, that signifies that the we are making
12735c4bbdfSmrg     * a release candidate for a minor version.  (X.Y.0)
12835c4bbdfSmrg     * When the patch number is < 99, then we are making a release
12935c4bbdfSmrg     * candidate for the next point release.  (X.Y.Z)
13035c4bbdfSmrg     */
1314642e01fSmrg#if XORG_VERSION_MINOR >= 99
13235c4bbdfSmrg    xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR + 1,
13335c4bbdfSmrg                   XORG_VERSION_SNAP - 900);
1344642e01fSmrg#elif XORG_VERSION_PATCH == 99
13535c4bbdfSmrg    xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
13635c4bbdfSmrg                   XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
1374642e01fSmrg#else
13835c4bbdfSmrg    xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
13935c4bbdfSmrg                   XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
14035c4bbdfSmrg                   XORG_VERSION_SNAP - 900);
1414642e01fSmrg#endif
1424642e01fSmrg#endif
1434642e01fSmrg
1444642e01fSmrg#ifdef XORG_CUSTOM_VERSION
14535c4bbdfSmrg    xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
1464642e01fSmrg#endif
1471b5d61b8Smrg    xf86ErrorFVerb(0, "\nX Protocol Version %d, Revision %d\n",
14835c4bbdfSmrg                   X_PROTOCOL, X_PROTOCOL_REVISION);
1494642e01fSmrg#ifdef HAS_UTSNAME
15035c4bbdfSmrg    {
15135c4bbdfSmrg        struct utsname name;
1524642e01fSmrg
15335c4bbdfSmrg        /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
15435c4bbdfSmrg           and Irix) and Single Unix Spec 3 just say that non-negative is success.
15535c4bbdfSmrg           All agree that failure is represented by a negative number.
15635c4bbdfSmrg         */
15735c4bbdfSmrg        if (uname(&name) >= 0) {
15835c4bbdfSmrg            xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
15935c4bbdfSmrg                           name.sysname, name.nodename, name.release,
16035c4bbdfSmrg                           name.version, name.machine);
1611b5d61b8Smrg#ifdef __linux__
16235c4bbdfSmrg            do {
16335c4bbdfSmrg                char buf[80];
16435c4bbdfSmrg                int fd = open("/proc/cmdline", O_RDONLY);
16535c4bbdfSmrg
16635c4bbdfSmrg                if (fd != -1) {
16735c4bbdfSmrg                    xf86ErrorFVerb(0, "Kernel command line: ");
16835c4bbdfSmrg                    memset(buf, 0, 80);
16935c4bbdfSmrg                    while (read(fd, buf, 80) > 0) {
17035c4bbdfSmrg                        xf86ErrorFVerb(0, "%.80s", buf);
17135c4bbdfSmrg                        memset(buf, 0, 80);
17235c4bbdfSmrg                    }
17335c4bbdfSmrg                    close(fd);
17435c4bbdfSmrg                }
17535c4bbdfSmrg            } while (0);
1766747b715Smrg#endif
17735c4bbdfSmrg        }
1784642e01fSmrg    }
1794642e01fSmrg#endif
1804642e01fSmrg#if defined(BUILDERSTRING)
18135c4bbdfSmrg    xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
1824642e01fSmrg#endif
18335c4bbdfSmrg    xf86ErrorFVerb(0, "Current version of pixman: %s\n",
18435c4bbdfSmrg                   pixman_version_string());
18535c4bbdfSmrg    xf86ErrorFVerb(0, "\tBefore reporting problems, check "
18635c4bbdfSmrg                   "" __VENDORDWEBSUPPORT__ "\n"
18735c4bbdfSmrg                   "\tto make sure that you have the latest version.\n");
1884642e01fSmrg}
1894642e01fSmrg
19035c4bbdfSmrgBool
19135c4bbdfSmrgxf86PrivsElevated(void)
1924642e01fSmrg{
1931b5d61b8Smrg    return PrivsElevated();
1941b5d61b8Smrg}
19535c4bbdfSmrg
196ed6184dfSmrgBool
197ed6184dfSmrgxf86HasTTYs(void)
1981b5d61b8Smrg{
199ed6184dfSmrg#ifdef __linux__
200ed6184dfSmrg    struct stat tty0devAttributes;
201ed6184dfSmrg    return (stat("/dev/tty0", &tty0devAttributes) == 0 && major(tty0devAttributes.st_rdev) == TTY_MAJOR);
202ed6184dfSmrg#else
203ed6184dfSmrg    return TRUE;
20435c4bbdfSmrg#endif
205ed6184dfSmrg}
206ed6184dfSmrg
207ed6184dfSmrgstatic void
208ed6184dfSmrgxf86AutoConfigOutputDevices(void)
209ed6184dfSmrg{
210ed6184dfSmrg    int i;
211ed6184dfSmrg
212ed6184dfSmrg    if (!xf86Info.autoBindGPU)
213ed6184dfSmrg        return;
214ed6184dfSmrg
215ed6184dfSmrg    for (i = 0; i < xf86NumGPUScreens; i++) {
216ed6184dfSmrg        int scrnum = xf86GPUScreens[i]->confScreen->screennum;
217ed6184dfSmrg        RRProviderAutoConfigGpuScreen(xf86ScrnToScreen(xf86GPUScreens[i]),
218ed6184dfSmrg                                      xf86ScrnToScreen(xf86Screens[scrnum]));
21935c4bbdfSmrg    }
2204642e01fSmrg}
2214642e01fSmrg
2221b5d61b8Smrgstatic void
2231b5d61b8SmrgAddSeatId(CallbackListPtr *pcbl, void *data, void *screen)
22405b261ecSmrg{
2251b5d61b8Smrg    ScreenPtr pScreen = screen;
2261b5d61b8Smrg    Atom SeatAtom = MakeAtom(SEAT_ATOM_NAME, sizeof(SEAT_ATOM_NAME) - 1, TRUE);
2271b5d61b8Smrg    int err;
22805b261ecSmrg
2291b5d61b8Smrg    err = dixChangeWindowProperty(serverClient, pScreen->root, SeatAtom,
2301b5d61b8Smrg                                  XA_STRING, 8, PropModeReplace,
2311b5d61b8Smrg                                  strlen(data) + 1, data, FALSE);
23235c4bbdfSmrg
2331b5d61b8Smrg    if (err != Success)
2341b5d61b8Smrg        xf86DrvMsg(pScreen->myNum, X_WARNING,
2351b5d61b8Smrg                   "Failed to register seat property\n");
2361b5d61b8Smrg}
23735c4bbdfSmrg
2381b5d61b8Smrgstatic void
2391b5d61b8SmrgAddVTAtoms(CallbackListPtr *pcbl, void *data, void *screen)
2401b5d61b8Smrg{
2411b5d61b8Smrg#define VT_ATOM_NAME         "XFree86_VT"
2421b5d61b8Smrg    int err, HasVT = 1;
2431b5d61b8Smrg    ScreenPtr pScreen = screen;
2441b5d61b8Smrg    Atom VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
2451b5d61b8Smrg    Atom HasVTAtom = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1,
2461b5d61b8Smrg                              TRUE);
2471b5d61b8Smrg
2481b5d61b8Smrg    err = dixChangeWindowProperty(serverClient, pScreen->root, VTAtom,
2491b5d61b8Smrg                                  XA_INTEGER, 32, PropModeReplace, 1,
2501b5d61b8Smrg                                  &xf86Info.vtno, FALSE);
2511b5d61b8Smrg
2521b5d61b8Smrg    err |= dixChangeWindowProperty(serverClient, pScreen->root, HasVTAtom,
2531b5d61b8Smrg                                   XA_INTEGER, 32, PropModeReplace, 1,
2541b5d61b8Smrg                                   &HasVT, FALSE);
2551b5d61b8Smrg
2561b5d61b8Smrg    if (err != Success)
2571b5d61b8Smrg        xf86DrvMsg(pScreen->myNum, X_WARNING,
2581b5d61b8Smrg                   "Failed to register VT properties\n");
2591b5d61b8Smrg}
26005b261ecSmrg
2611b5d61b8Smrgstatic Bool
2621b5d61b8Smrgxf86ScreenInit(ScreenPtr pScreen, int argc, char **argv)
2631b5d61b8Smrg{
2641b5d61b8Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2651b5d61b8Smrg
2661b5d61b8Smrg    pScrn->pScreen = pScreen;
2671b5d61b8Smrg    return pScrn->ScreenInit (pScreen, argc, argv);
26835c4bbdfSmrg}
26905b261ecSmrg
27005b261ecSmrgstatic void
2711b5d61b8Smrgxf86EnsureRANDR(ScreenPtr pScreen)
27205b261ecSmrg{
2731b5d61b8Smrg#ifdef RANDR
2741b5d61b8Smrg        if (!dixPrivateKeyRegistered(rrPrivKey) ||
2751b5d61b8Smrg            !rrGetScrPriv(pScreen))
2761b5d61b8Smrg            xf86RandRInit(pScreen);
27705b261ecSmrg#endif
27805b261ecSmrg}
27905b261ecSmrg
2804642e01fSmrg/*
2814642e01fSmrg * InitOutput --
2824642e01fSmrg *	Initialize screenInfo for all actually accessible framebuffers.
2834642e01fSmrg *      That includes vt-manager setup, querying all possible devices and
2844642e01fSmrg *      collecting the pixmap formats.
2854642e01fSmrg */
28605b261ecSmrgvoid
28735c4bbdfSmrgInitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
28805b261ecSmrg{
28935c4bbdfSmrg    int i, j, k, scr_index;
29035c4bbdfSmrg    const char **modulelist;
29135c4bbdfSmrg    void **optionlist;
29235c4bbdfSmrg    Bool autoconfig = FALSE;
29335c4bbdfSmrg    Bool sigio_blocked = FALSE;
29435c4bbdfSmrg    Bool want_hw_access = FALSE;
29535c4bbdfSmrg    GDevPtr configured_device;
29635c4bbdfSmrg
29735c4bbdfSmrg    xf86Initialising = TRUE;
29835c4bbdfSmrg
29935c4bbdfSmrg    config_pre_init();
30035c4bbdfSmrg
30135c4bbdfSmrg    if (serverGeneration == 1) {
30235c4bbdfSmrg        xf86PrintBanner();
30335c4bbdfSmrg        LogPrintMarkers();
30435c4bbdfSmrg        if (xf86LogFile) {
30535c4bbdfSmrg            time_t t;
30635c4bbdfSmrg            const char *ct;
30735c4bbdfSmrg
30835c4bbdfSmrg            t = time(NULL);
30935c4bbdfSmrg            ct = ctime(&t);
31035c4bbdfSmrg            xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
31135c4bbdfSmrg                        xf86LogFile, ct);
31235c4bbdfSmrg        }
31305b261ecSmrg
31435c4bbdfSmrg        /* Read and parse the config file */
31535c4bbdfSmrg        if (!xf86DoConfigure && !xf86DoShowOptions) {
31635c4bbdfSmrg            switch (xf86HandleConfigFile(FALSE)) {
31735c4bbdfSmrg            case CONFIG_OK:
31835c4bbdfSmrg                break;
31935c4bbdfSmrg            case CONFIG_PARSE_ERROR:
32035c4bbdfSmrg                xf86Msg(X_ERROR, "Error parsing the config file\n");
32135c4bbdfSmrg                return;
32235c4bbdfSmrg            case CONFIG_NOFILE:
32335c4bbdfSmrg                autoconfig = TRUE;
32435c4bbdfSmrg                break;
32535c4bbdfSmrg            }
32635c4bbdfSmrg        }
32705b261ecSmrg
32835c4bbdfSmrg        /* Initialise the loader */
32935c4bbdfSmrg        LoaderInit();
33005b261ecSmrg
33135c4bbdfSmrg        /* Tell the loader the default module search path */
33235c4bbdfSmrg        LoaderSetPath(xf86ModulePath);
33335c4bbdfSmrg
33435c4bbdfSmrg        if (xf86Info.ignoreABI) {
33535c4bbdfSmrg            LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
33635c4bbdfSmrg        }
33705b261ecSmrg
33835c4bbdfSmrg        if (xf86DoShowOptions)
33935c4bbdfSmrg            DoShowOptions();
3404642e01fSmrg
34135c4bbdfSmrg        dbus_core_init();
34235c4bbdfSmrg        systemd_logind_init();
34305b261ecSmrg
34435c4bbdfSmrg        /* Do a general bus probe.  This will be a PCI probe for x86 platforms */
34535c4bbdfSmrg        xf86BusProbe();
34605b261ecSmrg
34735c4bbdfSmrg        if (xf86DoConfigure)
34835c4bbdfSmrg            DoConfigure();
34935c4bbdfSmrg
35035c4bbdfSmrg        if (autoconfig) {
35135c4bbdfSmrg            if (!xf86AutoConfig()) {
35235c4bbdfSmrg                xf86Msg(X_ERROR, "Auto configuration failed\n");
35335c4bbdfSmrg                return;
35435c4bbdfSmrg            }
35535c4bbdfSmrg        }
35605b261ecSmrg
35735c4bbdfSmrg        xf86OSPMClose = xf86OSPMOpen();
3584642e01fSmrg
35935c4bbdfSmrg        xf86ExtensionInit();
36005b261ecSmrg
36135c4bbdfSmrg        /* Load all modules specified explicitly in the config file */
36235c4bbdfSmrg        if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
36335c4bbdfSmrg            xf86LoadModules(modulelist, optionlist);
36435c4bbdfSmrg            free(modulelist);
36535c4bbdfSmrg            free(optionlist);
3664642e01fSmrg        }
36705b261ecSmrg
36835c4bbdfSmrg        /* Load all driver modules specified in the config file */
36935c4bbdfSmrg        /* If there aren't any specified in the config file, autoconfig them */
37035c4bbdfSmrg        /* FIXME: Does not handle multiple active screen sections, but I'm not
37135c4bbdfSmrg         * sure if we really want to handle that case*/
37235c4bbdfSmrg        configured_device = xf86ConfigLayout.screens->screen->device;
37335c4bbdfSmrg        if ((!configured_device) || (!configured_device->driver)) {
37435c4bbdfSmrg            if (!autoConfigDevice(configured_device)) {
37535c4bbdfSmrg                xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
37635c4bbdfSmrg                return;
37735c4bbdfSmrg            }
37835c4bbdfSmrg        }
37935c4bbdfSmrg        if ((modulelist = xf86DriverlistFromConfig())) {
38035c4bbdfSmrg            xf86LoadModules(modulelist, NULL);
38135c4bbdfSmrg            free(modulelist);
38235c4bbdfSmrg        }
38305b261ecSmrg
38435c4bbdfSmrg        /* Load all input driver modules specified in the config file. */
38535c4bbdfSmrg        if ((modulelist = xf86InputDriverlistFromConfig())) {
38635c4bbdfSmrg            xf86LoadModules(modulelist, NULL);
38735c4bbdfSmrg            free(modulelist);
38835c4bbdfSmrg        }
38905b261ecSmrg
39035c4bbdfSmrg        /*
39135c4bbdfSmrg         * It is expected that xf86AddDriver()/xf86AddInputDriver will be
39235c4bbdfSmrg         * called for each driver as it is loaded.  Those functions save the
39335c4bbdfSmrg         * module pointers for drivers.
39435c4bbdfSmrg         * XXX Nothing keeps track of them for other modules.
39535c4bbdfSmrg         */
39635c4bbdfSmrg        /* XXX What do we do if not all of these could be loaded? */
39705b261ecSmrg
39835c4bbdfSmrg        /*
39935c4bbdfSmrg         * At this point, xf86DriverList[] is all filled in with entries for
40035c4bbdfSmrg         * each of the drivers to try and xf86NumDrivers has the number of
40135c4bbdfSmrg         * drivers.  If there are none, return now.
40235c4bbdfSmrg         */
40305b261ecSmrg
40435c4bbdfSmrg        if (xf86NumDrivers == 0) {
40535c4bbdfSmrg            xf86Msg(X_ERROR, "No drivers available.\n");
40635c4bbdfSmrg            return;
40735c4bbdfSmrg        }
40805b261ecSmrg
40935c4bbdfSmrg        /*
41035c4bbdfSmrg         * Call each of the Identify functions and call the driverFunc to check
41135c4bbdfSmrg         * if HW access is required.  The Identify functions print out some
41235c4bbdfSmrg         * identifying information, and anything else that might be
41335c4bbdfSmrg         * needed at this early stage.
41435c4bbdfSmrg         */
41505b261ecSmrg
41635c4bbdfSmrg        for (i = 0; i < xf86NumDrivers; i++) {
41735c4bbdfSmrg            xorgHWFlags flags = HW_IO;
41805b261ecSmrg
41935c4bbdfSmrg            if (xf86DriverList[i]->Identify != NULL)
42035c4bbdfSmrg                xf86DriverList[i]->Identify(0);
42105b261ecSmrg
42235c4bbdfSmrg            if (xf86DriverList[i]->driverFunc)
42335c4bbdfSmrg                xf86DriverList[i]->driverFunc(NULL,
42435c4bbdfSmrg                                              GET_REQUIRED_HW_INTERFACES,
42535c4bbdfSmrg                                              &flags);
42605b261ecSmrg
42735c4bbdfSmrg            if (NEED_IO_ENABLED(flags))
42835c4bbdfSmrg                want_hw_access = TRUE;
42905b261ecSmrg
43035c4bbdfSmrg            /* Non-seat0 X servers should not open console */
431ed6184dfSmrg            if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0() && xf86HasTTYs())
43235c4bbdfSmrg                xorgHWOpenConsole = TRUE;
43335c4bbdfSmrg        }
4344642e01fSmrg
43535c4bbdfSmrg        if (xorgHWOpenConsole)
43635c4bbdfSmrg            xf86OpenConsole();
43735c4bbdfSmrg        else
43835c4bbdfSmrg            xf86Info.dontVTSwitch = TRUE;
4394642e01fSmrg
44035c4bbdfSmrg	/* Enable full I/O access */
44135c4bbdfSmrg	if (want_hw_access)
44235c4bbdfSmrg	    xorgHWAccess = xf86EnableIO();
44305b261ecSmrg
44435c4bbdfSmrg        if (xf86BusConfig() == FALSE)
44535c4bbdfSmrg            return;
44605b261ecSmrg
44735c4bbdfSmrg        xf86PostProbe();
44835c4bbdfSmrg
44935c4bbdfSmrg        /*
45035c4bbdfSmrg         * Sort the drivers to match the requested ording.  Using a slow
45135c4bbdfSmrg         * bubble sort.
45235c4bbdfSmrg         */
45335c4bbdfSmrg        for (j = 0; j < xf86NumScreens - 1; j++) {
45435c4bbdfSmrg            for (i = 0; i < xf86NumScreens - j - 1; i++) {
45535c4bbdfSmrg                if (xf86Screens[i + 1]->confScreen->screennum <
45635c4bbdfSmrg                    xf86Screens[i]->confScreen->screennum) {
45735c4bbdfSmrg                    ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
45835c4bbdfSmrg
45935c4bbdfSmrg                    xf86Screens[i + 1] = xf86Screens[i];
46035c4bbdfSmrg                    xf86Screens[i] = tmpScrn;
46135c4bbdfSmrg                }
46235c4bbdfSmrg            }
46335c4bbdfSmrg        }
46435c4bbdfSmrg        /* Fix up the indexes */
46535c4bbdfSmrg        for (i = 0; i < xf86NumScreens; i++) {
46635c4bbdfSmrg            xf86Screens[i]->scrnIndex = i;
46735c4bbdfSmrg        }
46805b261ecSmrg
46935c4bbdfSmrg        /*
47035c4bbdfSmrg         * Call the driver's PreInit()'s to complete initialisation for the first
47135c4bbdfSmrg         * generation.
47235c4bbdfSmrg         */
47305b261ecSmrg
47435c4bbdfSmrg        for (i = 0; i < xf86NumScreens; i++) {
47535c4bbdfSmrg            xf86VGAarbiterScrnInit(xf86Screens[i]);
47635c4bbdfSmrg            xf86VGAarbiterLock(xf86Screens[i]);
47735c4bbdfSmrg            if (xf86Screens[i]->PreInit &&
47835c4bbdfSmrg                xf86Screens[i]->PreInit(xf86Screens[i], 0))
47935c4bbdfSmrg                xf86Screens[i]->configured = TRUE;
48035c4bbdfSmrg            xf86VGAarbiterUnlock(xf86Screens[i]);
48135c4bbdfSmrg        }
48235c4bbdfSmrg        for (i = 0; i < xf86NumScreens; i++)
48335c4bbdfSmrg            if (!xf86Screens[i]->configured)
48435c4bbdfSmrg                xf86DeleteScreen(xf86Screens[i--]);
48535c4bbdfSmrg
48635c4bbdfSmrg        for (i = 0; i < xf86NumGPUScreens; i++) {
48735c4bbdfSmrg            xf86VGAarbiterScrnInit(xf86GPUScreens[i]);
48835c4bbdfSmrg            xf86VGAarbiterLock(xf86GPUScreens[i]);
48935c4bbdfSmrg            if (xf86GPUScreens[i]->PreInit &&
49035c4bbdfSmrg                xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0))
49135c4bbdfSmrg                xf86GPUScreens[i]->configured = TRUE;
49235c4bbdfSmrg            xf86VGAarbiterUnlock(xf86GPUScreens[i]);
49335c4bbdfSmrg        }
49435c4bbdfSmrg        for (i = 0; i < xf86NumGPUScreens; i++)
49535c4bbdfSmrg            if (!xf86GPUScreens[i]->configured)
49635c4bbdfSmrg                xf86DeleteScreen(xf86GPUScreens[i--]);
49705b261ecSmrg
49835c4bbdfSmrg        /*
49935c4bbdfSmrg         * If no screens left, return now.
50035c4bbdfSmrg         */
50105b261ecSmrg
50235c4bbdfSmrg        if (xf86NumScreens == 0) {
50335c4bbdfSmrg            xf86Msg(X_ERROR,
50435c4bbdfSmrg                    "Screen(s) found, but none have a usable configuration.\n");
50535c4bbdfSmrg            return;
50635c4bbdfSmrg        }
50735c4bbdfSmrg
50835c4bbdfSmrg        /* Remove (unload) drivers that are not required */
50935c4bbdfSmrg        for (i = 0; i < xf86NumDrivers; i++)
51035c4bbdfSmrg            if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
51135c4bbdfSmrg                xf86DeleteDriver(i);
51235c4bbdfSmrg
51335c4bbdfSmrg        /*
51435c4bbdfSmrg         * At this stage we know how many screens there are.
51535c4bbdfSmrg         */
51635c4bbdfSmrg
51735c4bbdfSmrg        for (i = 0; i < xf86NumScreens; i++)
51835c4bbdfSmrg            xf86InitViewport(xf86Screens[i]);
51935c4bbdfSmrg
52035c4bbdfSmrg        /*
52135c4bbdfSmrg         * Collect all pixmap formats and check for conflicts at the display
52235c4bbdfSmrg         * level.  Should we die here?  Or just delete the offending screens?
52335c4bbdfSmrg         */
52435c4bbdfSmrg        for (i = 0; i < xf86NumScreens; i++) {
52535c4bbdfSmrg            if (xf86Screens[i]->imageByteOrder !=
52635c4bbdfSmrg                xf86Screens[0]->imageByteOrder)
52735c4bbdfSmrg                FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
52835c4bbdfSmrg            if (xf86Screens[i]->bitmapScanlinePad !=
52935c4bbdfSmrg                xf86Screens[0]->bitmapScanlinePad)
53035c4bbdfSmrg                FatalError
53135c4bbdfSmrg                    ("Inconsistent display bitmapScanlinePad.  Exiting\n");
53235c4bbdfSmrg            if (xf86Screens[i]->bitmapScanlineUnit !=
53335c4bbdfSmrg                xf86Screens[0]->bitmapScanlineUnit)
53435c4bbdfSmrg                FatalError
53535c4bbdfSmrg                    ("Inconsistent display bitmapScanlineUnit.  Exiting\n");
53635c4bbdfSmrg            if (xf86Screens[i]->bitmapBitOrder !=
53735c4bbdfSmrg                xf86Screens[0]->bitmapBitOrder)
53835c4bbdfSmrg                FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
53935c4bbdfSmrg        }
54035c4bbdfSmrg
54135c4bbdfSmrg        /* Collect additional formats */
54235c4bbdfSmrg        for (i = 0; i < xf86NumScreens; i++) {
54335c4bbdfSmrg            for (j = 0; j < xf86Screens[i]->numFormats; j++) {
54435c4bbdfSmrg                for (k = 0;; k++) {
54535c4bbdfSmrg                    if (k >= numFormats) {
54635c4bbdfSmrg                        if (k >= MAXFORMATS)
54735c4bbdfSmrg                            FatalError("Too many pixmap formats!  Exiting\n");
54835c4bbdfSmrg                        formats[k] = xf86Screens[i]->formats[j];
54935c4bbdfSmrg                        numFormats++;
55035c4bbdfSmrg                        break;
55135c4bbdfSmrg                    }
55235c4bbdfSmrg                    if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
55335c4bbdfSmrg                        if ((formats[k].bitsPerPixel ==
55435c4bbdfSmrg                             xf86Screens[i]->formats[j].bitsPerPixel) &&
55535c4bbdfSmrg                            (formats[k].scanlinePad ==
55635c4bbdfSmrg                             xf86Screens[i]->formats[j].scanlinePad))
55735c4bbdfSmrg                            break;
55835c4bbdfSmrg                        FatalError("Inconsistent pixmap format for depth %d."
55935c4bbdfSmrg                                   "  Exiting\n", formats[k].depth);
56035c4bbdfSmrg                    }
56135c4bbdfSmrg                }
56235c4bbdfSmrg            }
56335c4bbdfSmrg        }
56435c4bbdfSmrg        formatsDone = TRUE;
56505b261ecSmrg    }
56635c4bbdfSmrg    else {
56735c4bbdfSmrg        /*
56835c4bbdfSmrg         * serverGeneration != 1; some OSs have to do things here, too.
56935c4bbdfSmrg         */
57035c4bbdfSmrg        if (xorgHWOpenConsole)
57135c4bbdfSmrg            xf86OpenConsole();
57205b261ecSmrg
57335c4bbdfSmrg        /*
57435c4bbdfSmrg           should we reopen it here? We need to deal with an already opened
57535c4bbdfSmrg           device. We could leave this to the OS layer. For now we simply
57635c4bbdfSmrg           close it here
57735c4bbdfSmrg         */
57835c4bbdfSmrg        if (xf86OSPMClose)
57935c4bbdfSmrg            xf86OSPMClose();
58035c4bbdfSmrg        if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
58135c4bbdfSmrg            xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
58235c4bbdfSmrg
58335c4bbdfSmrg        /* Make sure full I/O access is enabled */
58435c4bbdfSmrg        if (xorgHWAccess)
58535c4bbdfSmrg            xf86EnableIO();
58605b261ecSmrg    }
58735c4bbdfSmrg
5881b5d61b8Smrg    if (xf86Info.vtno >= 0)
5891b5d61b8Smrg        AddCallback(&RootWindowFinalizeCallback, AddVTAtoms, NULL);
5901b5d61b8Smrg
5911b5d61b8Smrg    if (SeatId)
5921b5d61b8Smrg        AddCallback(&RootWindowFinalizeCallback, AddSeatId, SeatId);
5931b5d61b8Smrg
59405b261ecSmrg    /*
59535c4bbdfSmrg     * Use the previously collected parts to setup pScreenInfo
59605b261ecSmrg     */
59705b261ecSmrg
59835c4bbdfSmrg    pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
59935c4bbdfSmrg    pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
60035c4bbdfSmrg    pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
60135c4bbdfSmrg    pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
60235c4bbdfSmrg    pScreenInfo->numPixmapFormats = numFormats;
60335c4bbdfSmrg    for (i = 0; i < numFormats; i++)
60435c4bbdfSmrg        pScreenInfo->formats[i] = formats[i];
60535c4bbdfSmrg
60635c4bbdfSmrg    /* Make sure the server's VT is active */
60705b261ecSmrg
60835c4bbdfSmrg    if (serverGeneration != 1) {
60935c4bbdfSmrg        xf86Resetting = TRUE;
61035c4bbdfSmrg        /* All screens are in the same state, so just check the first */
61135c4bbdfSmrg        if (!xf86VTOwner()) {
61205b261ecSmrg#ifdef HAS_USL_VTS
61335c4bbdfSmrg            ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
61405b261ecSmrg#endif
6151b5d61b8Smrg            input_lock();
61635c4bbdfSmrg            sigio_blocked = TRUE;
61735c4bbdfSmrg        }
61805b261ecSmrg    }
61935c4bbdfSmrg
62035c4bbdfSmrg    for (i = 0; i < xf86NumScreens; i++)
62135c4bbdfSmrg        if (!xf86ColormapAllocatePrivates(xf86Screens[i]))
62235c4bbdfSmrg            FatalError("Cannot register DDX private keys");
62335c4bbdfSmrg
6241b5d61b8Smrg    if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0))
62535c4bbdfSmrg        FatalError("Cannot register DDX private keys");
62635c4bbdfSmrg
62735c4bbdfSmrg    for (i = 0; i < xf86NumScreens; i++) {
62835c4bbdfSmrg        xf86VGAarbiterLock(xf86Screens[i]);
62935c4bbdfSmrg        /*
63035c4bbdfSmrg         * Almost everything uses these defaults, and many of those that
63135c4bbdfSmrg         * don't, will wrap them.
63235c4bbdfSmrg         */
63335c4bbdfSmrg        xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
63435c4bbdfSmrg#ifdef XFreeXDGA
63535c4bbdfSmrg        xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
63635c4bbdfSmrg#endif
6371b5d61b8Smrg        scr_index = AddScreen(xf86ScreenInit, argc, argv);
63835c4bbdfSmrg        xf86VGAarbiterUnlock(xf86Screens[i]);
63935c4bbdfSmrg        if (scr_index == i) {
64035c4bbdfSmrg            /*
64135c4bbdfSmrg             * Hook in our ScrnInfoRec, and initialise some other pScreen
64235c4bbdfSmrg             * fields.
64335c4bbdfSmrg             */
64435c4bbdfSmrg            dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
64535c4bbdfSmrg                          xf86ScreenKey, xf86Screens[i]);
64635c4bbdfSmrg            xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
64735c4bbdfSmrg            /* The driver should set this, but make sure it is set anyway */
64835c4bbdfSmrg            xf86Screens[i]->vtSema = TRUE;
64935c4bbdfSmrg        }
65035c4bbdfSmrg        else {
65135c4bbdfSmrg            /* This shouldn't normally happen */
65235c4bbdfSmrg            FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
65335c4bbdfSmrg        }
65435c4bbdfSmrg
65535c4bbdfSmrg        if (PictureGetSubpixelOrder(xf86Screens[i]->pScreen) == SubPixelUnknown) {
65635c4bbdfSmrg            xf86MonPtr DDC = (xf86MonPtr) (xf86Screens[i]->monitor->DDC);
65735c4bbdfSmrg
65835c4bbdfSmrg            PictureSetSubpixelOrder(xf86Screens[i]->pScreen,
65935c4bbdfSmrg                                    DDC ?
66035c4bbdfSmrg                                    (DDC->features.input_type ?
66135c4bbdfSmrg                                     SubPixelHorizontalRGB : SubPixelNone) :
66235c4bbdfSmrg                                    SubPixelUnknown);
66335c4bbdfSmrg        }
6641b5d61b8Smrg
6651b5d61b8Smrg        /*
6661b5d61b8Smrg         * If the driver hasn't set up its own RANDR support, install the
6671b5d61b8Smrg         * fallback support.
6681b5d61b8Smrg         */
6691b5d61b8Smrg        xf86EnsureRANDR(xf86Screens[i]->pScreen);
67035c4bbdfSmrg    }
67105b261ecSmrg
67225da500fSmrg    for (i = 0; i < xf86NumGPUScreens; i++) {
67325da500fSmrg        ScrnInfoPtr pScrn = xf86GPUScreens[i];
67425da500fSmrg        xf86VGAarbiterLock(pScrn);
67525da500fSmrg
67625da500fSmrg        /*
67725da500fSmrg         * Almost everything uses these defaults, and many of those that
67825da500fSmrg         * don't, will wrap them.
67925da500fSmrg         */
68025da500fSmrg        pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
68125da500fSmrg#ifdef XFreeXDGA
68225da500fSmrg        pScrn->SetDGAMode = xf86SetDGAMode;
68325da500fSmrg#endif
68425da500fSmrg        scr_index = AddGPUScreen(xf86ScreenInit, argc, argv);
68525da500fSmrg        xf86VGAarbiterUnlock(pScrn);
68625da500fSmrg        if (scr_index == i) {
68725da500fSmrg            dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates,
68825da500fSmrg                          xf86ScreenKey, xf86GPUScreens[i]);
68925da500fSmrg            pScrn->pScreen = screenInfo.gpuscreens[scr_index];
69025da500fSmrg            /* The driver should set this, but make sure it is set anyway */
69125da500fSmrg            pScrn->vtSema = TRUE;
69225da500fSmrg        } else {
69325da500fSmrg            FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index);
69425da500fSmrg        }
69525da500fSmrg    }
69625da500fSmrg
697ed6184dfSmrg    for (i = 0; i < xf86NumGPUScreens; i++) {
698ed6184dfSmrg        int scrnum = xf86GPUScreens[i]->confScreen->screennum;
699ed6184dfSmrg        AttachUnboundGPU(xf86Screens[scrnum]->pScreen, xf86GPUScreens[i]->pScreen);
700ed6184dfSmrg    }
701ed6184dfSmrg
702ed6184dfSmrg    xf86AutoConfigOutputDevices();
70305b261ecSmrg
70435c4bbdfSmrg    xf86VGAarbiterWrapFunctions();
70535c4bbdfSmrg    if (sigio_blocked)
7061b5d61b8Smrg        input_unlock();
70705b261ecSmrg
70835c4bbdfSmrg    xf86InitOrigins();
70905b261ecSmrg
71035c4bbdfSmrg    xf86Resetting = FALSE;
71135c4bbdfSmrg    xf86Initialising = FALSE;
71205b261ecSmrg
7131b5d61b8Smrg    RegisterBlockAndWakeupHandlers((ServerBlockHandlerProcPtr) NoopDDA, xf86Wakeup,
71435c4bbdfSmrg                                   NULL);
715475c125cSmrg}
716475c125cSmrg
71735c4bbdfSmrg/**
71835c4bbdfSmrg * Initialize all supported input devices present and referenced in the
71935c4bbdfSmrg * xorg.conf.
72005b261ecSmrg */
72105b261ecSmrgvoid
7226747b715SmrgInitInput(int argc, char **argv)
72305b261ecSmrg{
72435c4bbdfSmrg    InputInfoPtr *pInfo;
7254642e01fSmrg    DeviceIntPtr dev;
72605b261ecSmrg
72705b261ecSmrg    xf86Info.vtRequestsPending = FALSE;
72805b261ecSmrg
7291b5d61b8Smrg    /* Enable threaded input */
7301b5d61b8Smrg    InputThreadPreInit();
7311b5d61b8Smrg
73205b261ecSmrg    mieqInit();
73305b261ecSmrg
7349ace9065Smrg    /* Initialize all configured input devices */
735475c125cSmrg    for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) {
73635c4bbdfSmrg        (*pInfo)->options =
73735c4bbdfSmrg            xf86AddNewOption((*pInfo)->options, "driver", (*pInfo)->driver);
73835c4bbdfSmrg        (*pInfo)->options =
73935c4bbdfSmrg            xf86AddNewOption((*pInfo)->options, "identifier", (*pInfo)->name);
7404642e01fSmrg        /* If one fails, the others will too */
74135c4bbdfSmrg        if (NewInputDeviceRequest((*pInfo)->options, NULL, &dev) == BadAlloc)
7424642e01fSmrg            break;
7434642e01fSmrg    }
7446747b715Smrg
7456747b715Smrg    config_init();
7466747b715Smrg}
7476747b715Smrg
7486747b715Smrgvoid
74935c4bbdfSmrgCloseInput(void)
7506747b715Smrg{
7516747b715Smrg    config_fini();
75235c4bbdfSmrg    mieqFini();
7534642e01fSmrg}
75405b261ecSmrg
75505b261ecSmrg/*
75605b261ecSmrg * OsVendorInit --
75705b261ecSmrg *      OS/Vendor-specific initialisations.  Called from OsInit(), which
75805b261ecSmrg *      is called by dix before establishing the well known sockets.
75905b261ecSmrg */
7604642e01fSmrg
76105b261ecSmrgvoid
7626747b715SmrgOsVendorInit(void)
76305b261ecSmrg{
76435c4bbdfSmrg    static Bool beenHere = FALSE;
76505b261ecSmrg
7661b5d61b8Smrg    OsSignal(SIGCHLD, SIG_DFL);   /* Need to wait for child processes */
76705b261ecSmrg
76835c4bbdfSmrg    if (!beenHere) {
76935c4bbdfSmrg        umask(022);
77035c4bbdfSmrg        xf86LogInit();
77135c4bbdfSmrg    }
77205b261ecSmrg
77335c4bbdfSmrg    /* Set stderr to non-blocking. */
77405b261ecSmrg#ifndef O_NONBLOCK
77505b261ecSmrg#if defined(FNDELAY)
77605b261ecSmrg#define O_NONBLOCK FNDELAY
77705b261ecSmrg#elif defined(O_NDELAY)
77805b261ecSmrg#define O_NONBLOCK O_NDELAY
77905b261ecSmrg#endif
78005b261ecSmrg
78105b261ecSmrg#ifdef O_NONBLOCK
78235c4bbdfSmrg    if (!beenHere) {
7831b5d61b8Smrg        if (PrivsElevated()) {
78435c4bbdfSmrg            int status;
78535c4bbdfSmrg
78635c4bbdfSmrg            status = fcntl(fileno(stderr), F_GETFL, 0);
78735c4bbdfSmrg            if (status != -1) {
78835c4bbdfSmrg                fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
78935c4bbdfSmrg            }
79035c4bbdfSmrg        }
79105b261ecSmrg    }
79205b261ecSmrg#endif
79305b261ecSmrg#endif
79405b261ecSmrg
79535c4bbdfSmrg    beenHere = TRUE;
79605b261ecSmrg}
79705b261ecSmrg
79805b261ecSmrg/*
79905b261ecSmrg * ddxGiveUp --
80005b261ecSmrg *      Device dependent cleanup. Called by by dix before normal server death.
80105b261ecSmrg *      For SYSV386 we must switch the terminal back to normal mode. No error-
80205b261ecSmrg *      checking here, since there should be restored as much as possible.
80305b261ecSmrg */
80405b261ecSmrg
80505b261ecSmrgvoid
80635c4bbdfSmrgddxGiveUp(enum ExitCode error)
80705b261ecSmrg{
80805b261ecSmrg    int i;
80905b261ecSmrg
810ed6184dfSmrg    if (error == EXIT_ERR_ABORT) {
811ed6184dfSmrg        input_lock();
812ed6184dfSmrg
813ed6184dfSmrg        /* try to restore the original video state */
814ed6184dfSmrg#ifdef DPMSExtension            /* Turn screens back on */
815ed6184dfSmrg        if (DPMSPowerLevel != DPMSModeOn)
816ed6184dfSmrg            DPMSSet(serverClient, DPMSModeOn);
817ed6184dfSmrg#endif
818ed6184dfSmrg        if (xf86Screens) {
819ed6184dfSmrg            for (i = 0; i < xf86NumScreens; i++)
820ed6184dfSmrg                if (xf86Screens[i]->vtSema) {
821ed6184dfSmrg                    /*
822ed6184dfSmrg                     * if we are aborting before ScreenInit() has finished we
823ed6184dfSmrg                     * might not have been wrapped yet. Therefore enable screen
824ed6184dfSmrg                     * explicitly.
825ed6184dfSmrg                     */
826ed6184dfSmrg                    xf86VGAarbiterLock(xf86Screens[i]);
827ed6184dfSmrg                    (xf86Screens[i]->LeaveVT) (xf86Screens[i]);
828ed6184dfSmrg                    xf86VGAarbiterUnlock(xf86Screens[i]);
829ed6184dfSmrg                }
830ed6184dfSmrg        }
831ed6184dfSmrg    }
832ed6184dfSmrg
8336747b715Smrg    xf86VGAarbiterFini();
8346747b715Smrg
83505b261ecSmrg    if (xf86OSPMClose)
83635c4bbdfSmrg        xf86OSPMClose();
83705b261ecSmrg    xf86OSPMClose = NULL;
83805b261ecSmrg
83905b261ecSmrg    for (i = 0; i < xf86NumScreens; i++) {
84035c4bbdfSmrg        /*
84135c4bbdfSmrg         * zero all access functions to
84235c4bbdfSmrg         * trap calls when switched away.
84335c4bbdfSmrg         */
84435c4bbdfSmrg        xf86Screens[i]->vtSema = FALSE;
84505b261ecSmrg    }
84605b261ecSmrg
8476747b715Smrg    if (xorgHWOpenConsole)
84835c4bbdfSmrg        xf86CloseConsole();
84935c4bbdfSmrg
85035c4bbdfSmrg    systemd_logind_fini();
85135c4bbdfSmrg    dbus_core_fini();
85205b261ecSmrg
85335c4bbdfSmrg    xf86CloseLog(error);
85405b261ecSmrg}
85505b261ecSmrg
85605b261ecSmrgvoid
85735c4bbdfSmrgOsVendorFatalError(const char *f, va_list args)
85805b261ecSmrg{
85905b261ecSmrg#ifdef VENDORSUPPORT
86035c4bbdfSmrg    ErrorFSigSafe("\nPlease refer to your Operating System Vendor support "
86135c4bbdfSmrg                 "pages\nat %s for support on this crash.\n", VENDORSUPPORT);
86205b261ecSmrg#else
86335c4bbdfSmrg    ErrorFSigSafe("\nPlease consult the " XVENDORNAME " support \n\t at "
86435c4bbdfSmrg                 __VENDORDWEBSUPPORT__ "\n for help. \n");
86505b261ecSmrg#endif
86605b261ecSmrg    if (xf86LogFile && xf86LogFileWasOpened)
86735c4bbdfSmrg        ErrorFSigSafe("Please also check the log file at \"%s\" for additional "
86835c4bbdfSmrg                     "information.\n", xf86LogFile);
86935c4bbdfSmrg    ErrorFSigSafe("\n");
87005b261ecSmrg}
87105b261ecSmrg
87205b261ecSmrgint
87305b261ecSmrgxf86SetVerbosity(int verb)
87405b261ecSmrg{
87505b261ecSmrg    int save = xf86Verbose;
87605b261ecSmrg
87705b261ecSmrg    xf86Verbose = verb;
87805b261ecSmrg    LogSetParameter(XLOG_VERBOSITY, verb);
87905b261ecSmrg    return save;
88005b261ecSmrg}
88105b261ecSmrg
88205b261ecSmrgint
88305b261ecSmrgxf86SetLogVerbosity(int verb)
88405b261ecSmrg{
88505b261ecSmrg    int save = xf86LogVerbose;
88605b261ecSmrg
88705b261ecSmrg    xf86LogVerbose = verb;
88805b261ecSmrg    LogSetParameter(XLOG_FILE_VERBOSITY, verb);
88905b261ecSmrg    return save;
89005b261ecSmrg}
89105b261ecSmrg
8924642e01fSmrgstatic void
8934642e01fSmrgxf86PrintDefaultModulePath(void)
8944642e01fSmrg{
89535c4bbdfSmrg    ErrorF("%s\n", DEFAULT_MODULE_PATH);
8964642e01fSmrg}
8974642e01fSmrg
8984642e01fSmrgstatic void
8994642e01fSmrgxf86PrintDefaultLibraryPath(void)
9004642e01fSmrg{
90135c4bbdfSmrg    ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
9024642e01fSmrg}
9034642e01fSmrg
9041b5d61b8Smrgstatic void
9051b5d61b8Smrgxf86CheckPrivs(const char *option, const char *arg)
9061b5d61b8Smrg{
9071b5d61b8Smrg    if (PrivsElevated() && !xf86PathIsSafe(arg)) {
9081b5d61b8Smrg        FatalError("\nInvalid argument for %s - \"%s\"\n"
9091b5d61b8Smrg                    "\tWith elevated privileges %s must specify a relative path\n"
9101b5d61b8Smrg                    "\twithout any \"..\" elements.\n\n", option, arg, option);
9111b5d61b8Smrg    }
9121b5d61b8Smrg}
9131b5d61b8Smrg
91405b261ecSmrg/*
91505b261ecSmrg * ddxProcessArgument --
91605b261ecSmrg *	Process device-dependent command line args. Returns 0 if argument is
91705b261ecSmrg *      not device dependent, otherwise Count of number of elements of argv
91805b261ecSmrg *      that are part of a device dependent commandline option.
91905b261ecSmrg *
92005b261ecSmrg */
92105b261ecSmrg
92205b261ecSmrg/* ARGSUSED */
92305b261ecSmrgint
92405b261ecSmrgddxProcessArgument(int argc, char **argv, int i)
92505b261ecSmrg{
92635c4bbdfSmrg    /* First the options that are not allowed with elevated privileges */
9271b5d61b8Smrg    if (!strcmp(argv[i], "-modulepath")) {
928ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
9291b5d61b8Smrg        if (xf86PrivsElevated())
9301b5d61b8Smrg              FatalError("\nInvalid argument -modulepath "
9311b5d61b8Smrg                "with elevated privileges\n");
9321b5d61b8Smrg        xf86ModulePath = argv[i + 1];
9331b5d61b8Smrg        xf86ModPathFrom = X_CMDLINE;
9341b5d61b8Smrg        return 2;
9351b5d61b8Smrg    }
9361b5d61b8Smrg    if (!strcmp(argv[i], "-logfile")) {
937ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
9381b5d61b8Smrg        if (xf86PrivsElevated())
9391b5d61b8Smrg              FatalError("\nInvalid argument -logfile "
9401b5d61b8Smrg                "with elevated privileges\n");
9411b5d61b8Smrg        xf86LogFile = argv[i + 1];
9421b5d61b8Smrg        xf86LogFileFrom = X_CMDLINE;
9431b5d61b8Smrg        return 2;
94405b261ecSmrg    }
94535c4bbdfSmrg    if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config")) {
946ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
9471b5d61b8Smrg        xf86CheckPrivs(argv[i], argv[i + 1]);
94835c4bbdfSmrg        xf86ConfigFile = argv[i + 1];
94935c4bbdfSmrg        return 2;
95005b261ecSmrg    }
95135c4bbdfSmrg    if (!strcmp(argv[i], "-configdir")) {
952ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
9531b5d61b8Smrg        xf86CheckPrivs(argv[i], argv[i + 1]);
95435c4bbdfSmrg        xf86ConfigDir = argv[i + 1];
95535c4bbdfSmrg        return 2;
95605b261ecSmrg    }
9579b06bd19Stsutsui    if (!strcmp(argv[i], "-flipPixels")) {
9589b06bd19Stsutsui        xf86FlipPixels = TRUE;
9599b06bd19Stsutsui        return 1;
9609b06bd19Stsutsui    }
96105b261ecSmrg#ifdef XF86VIDMODE
96235c4bbdfSmrg    if (!strcmp(argv[i], "-disableVidMode")) {
96335c4bbdfSmrg        xf86VidModeDisabled = TRUE;
96435c4bbdfSmrg        return 1;
96535c4bbdfSmrg    }
96635c4bbdfSmrg    if (!strcmp(argv[i], "-allowNonLocalXvidtune")) {
96735c4bbdfSmrg        xf86VidModeAllowNonLocal = TRUE;
96835c4bbdfSmrg        return 1;
96935c4bbdfSmrg    }
97005b261ecSmrg#endif
97135c4bbdfSmrg    if (!strcmp(argv[i], "-allowMouseOpenFail")) {
97235c4bbdfSmrg        xf86AllowMouseOpenFail = TRUE;
97335c4bbdfSmrg        return 1;
97405b261ecSmrg    }
97535c4bbdfSmrg    if (!strcmp(argv[i], "-ignoreABI")) {
97635c4bbdfSmrg        LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
97735c4bbdfSmrg        return 1;
97805b261ecSmrg    }
97935c4bbdfSmrg    if (!strcmp(argv[i], "-verbose")) {
98035c4bbdfSmrg        if (++i < argc && argv[i]) {
98135c4bbdfSmrg            char *end;
98235c4bbdfSmrg            long val;
98335c4bbdfSmrg
98435c4bbdfSmrg            val = strtol(argv[i], &end, 0);
98535c4bbdfSmrg            if (*end == '\0') {
98635c4bbdfSmrg                xf86SetVerbosity(val);
98735c4bbdfSmrg                return 2;
98835c4bbdfSmrg            }
98935c4bbdfSmrg        }
99035c4bbdfSmrg        xf86SetVerbosity(++xf86Verbose);
99135c4bbdfSmrg        return 1;
99205b261ecSmrg    }
99335c4bbdfSmrg    if (!strcmp(argv[i], "-logverbose")) {
99435c4bbdfSmrg        if (++i < argc && argv[i]) {
99535c4bbdfSmrg            char *end;
99635c4bbdfSmrg            long val;
99735c4bbdfSmrg
99835c4bbdfSmrg            val = strtol(argv[i], &end, 0);
99935c4bbdfSmrg            if (*end == '\0') {
100035c4bbdfSmrg                xf86SetLogVerbosity(val);
100135c4bbdfSmrg                return 2;
100235c4bbdfSmrg            }
100335c4bbdfSmrg        }
100435c4bbdfSmrg        xf86SetLogVerbosity(++xf86LogVerbose);
100535c4bbdfSmrg        return 1;
100605b261ecSmrg    }
100735c4bbdfSmrg    if (!strcmp(argv[i], "-quiet")) {
100835c4bbdfSmrg        xf86SetVerbosity(-1);
100935c4bbdfSmrg        return 1;
101005b261ecSmrg    }
101135c4bbdfSmrg    if (!strcmp(argv[i], "-showconfig") || !strcmp(argv[i], "-version")) {
101235c4bbdfSmrg        xf86PrintBanner();
101335c4bbdfSmrg        exit(0);
101405b261ecSmrg    }
101535c4bbdfSmrg    if (!strcmp(argv[i], "-showDefaultModulePath")) {
101635c4bbdfSmrg        xf86PrintDefaultModulePath();
101735c4bbdfSmrg        exit(0);
101805b261ecSmrg    }
101935c4bbdfSmrg    if (!strcmp(argv[i], "-showDefaultLibPath")) {
102035c4bbdfSmrg        xf86PrintDefaultLibraryPath();
102135c4bbdfSmrg        exit(0);
102235c4bbdfSmrg    }
102335c4bbdfSmrg    /* Notice the -fp flag, but allow it to pass to the dix layer */
102435c4bbdfSmrg    if (!strcmp(argv[i], "-fp")) {
102535c4bbdfSmrg        xf86fpFlag = TRUE;
102635c4bbdfSmrg        return 0;
102735c4bbdfSmrg    }
102835c4bbdfSmrg    /* Notice the -bs flag, but allow it to pass to the dix layer */
102935c4bbdfSmrg    if (!strcmp(argv[i], "-bs")) {
103035c4bbdfSmrg        xf86bsDisableFlag = TRUE;
103135c4bbdfSmrg        return 0;
103235c4bbdfSmrg    }
103335c4bbdfSmrg    /* Notice the +bs flag, but allow it to pass to the dix layer */
103435c4bbdfSmrg    if (!strcmp(argv[i], "+bs")) {
103535c4bbdfSmrg        xf86bsEnableFlag = TRUE;
103635c4bbdfSmrg        return 0;
103735c4bbdfSmrg    }
103835c4bbdfSmrg    /* Notice the -s flag, but allow it to pass to the dix layer */
103935c4bbdfSmrg    if (!strcmp(argv[i], "-s")) {
104035c4bbdfSmrg        xf86sFlag = TRUE;
104135c4bbdfSmrg        return 0;
104235c4bbdfSmrg    }
10431b5d61b8Smrg    if (!strcmp(argv[i], "-pixmap32") || !strcmp(argv[i], "-pixmap24")) {
10441b5d61b8Smrg        /* silently accept */
104535c4bbdfSmrg        return 1;
104635c4bbdfSmrg    }
104735c4bbdfSmrg    if (!strcmp(argv[i], "-fbbpp")) {
104835c4bbdfSmrg        int bpp;
104935c4bbdfSmrg
1050ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
105135c4bbdfSmrg        if (sscanf(argv[++i], "%d", &bpp) == 1) {
105235c4bbdfSmrg            xf86FbBpp = bpp;
105335c4bbdfSmrg            return 2;
105435c4bbdfSmrg        }
105535c4bbdfSmrg        else {
105635c4bbdfSmrg            ErrorF("Invalid fbbpp\n");
105735c4bbdfSmrg            return 0;
105835c4bbdfSmrg        }
105935c4bbdfSmrg    }
106035c4bbdfSmrg    if (!strcmp(argv[i], "-depth")) {
106135c4bbdfSmrg        int depth;
106235c4bbdfSmrg
1063ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
106435c4bbdfSmrg        if (sscanf(argv[++i], "%d", &depth) == 1) {
106535c4bbdfSmrg            xf86Depth = depth;
106635c4bbdfSmrg            return 2;
106735c4bbdfSmrg        }
106835c4bbdfSmrg        else {
106935c4bbdfSmrg            ErrorF("Invalid depth\n");
107035c4bbdfSmrg            return 0;
107135c4bbdfSmrg        }
107235c4bbdfSmrg    }
107335c4bbdfSmrg    if (!strcmp(argv[i], "-weight")) {
107435c4bbdfSmrg        int red, green, blue;
107535c4bbdfSmrg
1076ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
107735c4bbdfSmrg        if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3) {
107835c4bbdfSmrg            xf86Weight.red = red;
107935c4bbdfSmrg            xf86Weight.green = green;
108035c4bbdfSmrg            xf86Weight.blue = blue;
108135c4bbdfSmrg            return 2;
108235c4bbdfSmrg        }
108335c4bbdfSmrg        else {
108435c4bbdfSmrg            ErrorF("Invalid weighting\n");
108535c4bbdfSmrg            return 0;
108635c4bbdfSmrg        }
108735c4bbdfSmrg    }
108835c4bbdfSmrg    if (!strcmp(argv[i], "-gamma") || !strcmp(argv[i], "-rgamma") ||
108935c4bbdfSmrg        !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma")) {
109035c4bbdfSmrg        double gamma;
109135c4bbdfSmrg
1092ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
109335c4bbdfSmrg        if (sscanf(argv[++i], "%lf", &gamma) == 1) {
109435c4bbdfSmrg            if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
109535c4bbdfSmrg                ErrorF("gamma out of range, only  %.2f <= gamma_value <= %.1f"
109635c4bbdfSmrg                       " is valid\n", GAMMA_MIN, GAMMA_MAX);
109735c4bbdfSmrg                return 0;
109835c4bbdfSmrg            }
109935c4bbdfSmrg            if (!strcmp(argv[i - 1], "-gamma"))
110035c4bbdfSmrg                xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
110135c4bbdfSmrg            else if (!strcmp(argv[i - 1], "-rgamma"))
110235c4bbdfSmrg                xf86Gamma.red = gamma;
110335c4bbdfSmrg            else if (!strcmp(argv[i - 1], "-ggamma"))
110435c4bbdfSmrg                xf86Gamma.green = gamma;
110535c4bbdfSmrg            else if (!strcmp(argv[i - 1], "-bgamma"))
110635c4bbdfSmrg                xf86Gamma.blue = gamma;
110735c4bbdfSmrg            return 2;
110835c4bbdfSmrg        }
110905b261ecSmrg    }
111035c4bbdfSmrg    if (!strcmp(argv[i], "-layout")) {
1111ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
111235c4bbdfSmrg        xf86LayoutName = argv[++i];
111335c4bbdfSmrg        return 2;
111435c4bbdfSmrg    }
111535c4bbdfSmrg    if (!strcmp(argv[i], "-screen")) {
1116ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
111735c4bbdfSmrg        xf86ScreenName = argv[++i];
111835c4bbdfSmrg        return 2;
111935c4bbdfSmrg    }
112035c4bbdfSmrg    if (!strcmp(argv[i], "-pointer")) {
1121ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
112235c4bbdfSmrg        xf86PointerName = argv[++i];
112335c4bbdfSmrg        return 2;
112435c4bbdfSmrg    }
112535c4bbdfSmrg    if (!strcmp(argv[i], "-keyboard")) {
1126ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
112735c4bbdfSmrg        xf86KeyboardName = argv[++i];
112835c4bbdfSmrg        return 2;
112935c4bbdfSmrg    }
113035c4bbdfSmrg    if (!strcmp(argv[i], "-nosilk")) {
113135c4bbdfSmrg        xf86silkenMouseDisableFlag = TRUE;
113235c4bbdfSmrg        return 1;
113305b261ecSmrg    }
113405b261ecSmrg#ifdef HAVE_ACPI
113535c4bbdfSmrg    if (!strcmp(argv[i], "-noacpi")) {
113635c4bbdfSmrg        xf86acpiDisableFlag = TRUE;
113735c4bbdfSmrg        return 1;
113835c4bbdfSmrg    }
113935c4bbdfSmrg#endif
114035c4bbdfSmrg    if (!strcmp(argv[i], "-configure")) {
114135c4bbdfSmrg        if (getuid() != 0 && geteuid() == 0) {
114235c4bbdfSmrg            ErrorF("The '-configure' option can only be used by root.\n");
114335c4bbdfSmrg            exit(1);
114435c4bbdfSmrg        }
114535c4bbdfSmrg        xf86DoConfigure = TRUE;
114635c4bbdfSmrg        xf86AllowMouseOpenFail = TRUE;
114735c4bbdfSmrg        return 1;
114835c4bbdfSmrg    }
114935c4bbdfSmrg    if (!strcmp(argv[i], "-showopts")) {
115035c4bbdfSmrg        if (getuid() != 0 && geteuid() == 0) {
115135c4bbdfSmrg            ErrorF("The '-showopts' option can only be used by root.\n");
115235c4bbdfSmrg            exit(1);
115335c4bbdfSmrg        }
115435c4bbdfSmrg        xf86DoShowOptions = TRUE;
115535c4bbdfSmrg        return 1;
115635c4bbdfSmrg    }
115735c4bbdfSmrg#ifdef XSERVER_LIBPCIACCESS
115835c4bbdfSmrg    if (!strcmp(argv[i], "-isolateDevice")) {
1159ed6184dfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
116035c4bbdfSmrg        if (strncmp(argv[++i], "PCI:", 4)) {
116135c4bbdfSmrg            FatalError("Bus types other than PCI not yet isolable\n");
116235c4bbdfSmrg        }
116335c4bbdfSmrg        xf86PciIsolateDevice(argv[i]);
116435c4bbdfSmrg        return 2;
116535c4bbdfSmrg    }
116605b261ecSmrg#endif
116735c4bbdfSmrg    /* Notice cmdline xkbdir, but pass to dix as well */
116835c4bbdfSmrg    if (!strcmp(argv[i], "-xkbdir")) {
116935c4bbdfSmrg        xf86xkbdirFlag = TRUE;
117035c4bbdfSmrg        return 0;
117105b261ecSmrg    }
117235c4bbdfSmrg    if (!strcmp(argv[i], "-novtswitch")) {
117335c4bbdfSmrg        xf86Info.autoVTSwitch = FALSE;
117435c4bbdfSmrg        return 1;
11754642e01fSmrg    }
117635c4bbdfSmrg    if (!strcmp(argv[i], "-sharevts")) {
117735c4bbdfSmrg        xf86Info.ShareVTs = TRUE;
117835c4bbdfSmrg        return 1;
117905b261ecSmrg    }
118035c4bbdfSmrg    if (!strcmp(argv[i], "-iglx") || !strcmp(argv[i], "+iglx")) {
118135c4bbdfSmrg        xf86Info.iglxFrom = X_CMDLINE;
118235c4bbdfSmrg        return 0;
118335c4bbdfSmrg    }
1184ed6184dfSmrg    if (!strcmp(argv[i], "-noautoBindGPU")) {
1185ed6184dfSmrg        xf86AutoBindGPUDisabled = TRUE;
1186ed6184dfSmrg        return 1;
1187ed6184dfSmrg    }
118835c4bbdfSmrg
118935c4bbdfSmrg    /* OS-specific processing */
119035c4bbdfSmrg    return xf86ProcessArgument(argc, argv, i);
119105b261ecSmrg}
119205b261ecSmrg
119305b261ecSmrg/*
119405b261ecSmrg * ddxUseMsg --
119505b261ecSmrg *	Print out correct use of device dependent commandline options.
119605b261ecSmrg *      Maybe the user now knows what really to do ...
119705b261ecSmrg */
119805b261ecSmrg
119905b261ecSmrgvoid
12006747b715SmrgddxUseMsg(void)
120105b261ecSmrg{
120235c4bbdfSmrg    ErrorF("\n");
120335c4bbdfSmrg    ErrorF("\n");
120435c4bbdfSmrg    ErrorF("Device Dependent Usage\n");
12051b5d61b8Smrg    if (!PrivsElevated()) {
120635c4bbdfSmrg        ErrorF("-modulepath paths      specify the module search path\n");
120735c4bbdfSmrg        ErrorF("-logfile file          specify a log file name\n");
120835c4bbdfSmrg        ErrorF("-configure             probe for devices and write an "
12091b5d61b8Smrg               XCONFIGFILE "\n");
121035c4bbdfSmrg        ErrorF
121135c4bbdfSmrg            ("-showopts              print available options for all installed drivers\n");
121235c4bbdfSmrg    }
121335c4bbdfSmrg    ErrorF
121435c4bbdfSmrg        ("-config file           specify a configuration file, relative to the\n");
12151b5d61b8Smrg    ErrorF("                       " XCONFIGFILE
121635c4bbdfSmrg           " search path, only root can use absolute\n");
121735c4bbdfSmrg    ErrorF
121835c4bbdfSmrg        ("-configdir dir         specify a configuration directory, relative to the\n");
12191b5d61b8Smrg    ErrorF("                       " XCONFIGDIR
122035c4bbdfSmrg           " search path, only root can use absolute\n");
122135c4bbdfSmrg    ErrorF("-verbose [n]           verbose startup messages\n");
122235c4bbdfSmrg    ErrorF("-logverbose [n]        verbose log messages\n");
122335c4bbdfSmrg    ErrorF("-quiet                 minimal startup messages\n");
122435c4bbdfSmrg    ErrorF("-fbbpp n               set bpp for the framebuffer. Default: 8\n");
122535c4bbdfSmrg    ErrorF("-depth n               set colour depth. Default: 8\n");
122635c4bbdfSmrg    ErrorF
122735c4bbdfSmrg        ("-gamma f               set gamma value (0.1 < f < 10.0) Default: 1.0\n");
122835c4bbdfSmrg    ErrorF("-rgamma f              set gamma value for red phase\n");
122935c4bbdfSmrg    ErrorF("-ggamma f              set gamma value for green phase\n");
123035c4bbdfSmrg    ErrorF("-bgamma f              set gamma value for blue phase\n");
123135c4bbdfSmrg    ErrorF
123235c4bbdfSmrg        ("-weight nnn            set RGB weighting at 16 bpp.  Default: 565\n");
123335c4bbdfSmrg    ErrorF("-layout name           specify the ServerLayout section name\n");
123435c4bbdfSmrg    ErrorF("-screen name           specify the Screen section name\n");
123535c4bbdfSmrg    ErrorF
123635c4bbdfSmrg        ("-keyboard name         specify the core keyboard InputDevice name\n");
123735c4bbdfSmrg    ErrorF
123835c4bbdfSmrg        ("-pointer name          specify the core pointer InputDevice name\n");
123935c4bbdfSmrg    ErrorF("-nosilk                disable Silken Mouse\n");
12409b06bd19Stsutsui    ErrorF("-flipPixels            swap default black/white Pixel values\n");
124105b261ecSmrg#ifdef XF86VIDMODE
124235c4bbdfSmrg    ErrorF("-disableVidMode        disable mode adjustments with xvidtune\n");
124335c4bbdfSmrg    ErrorF
124435c4bbdfSmrg        ("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
124535c4bbdfSmrg#endif
124635c4bbdfSmrg    ErrorF
124735c4bbdfSmrg        ("-allowMouseOpenFail    start server even if the mouse can't be initialized\n");
124835c4bbdfSmrg    ErrorF("-ignoreABI             make module ABI mismatches non-fatal\n");
124935c4bbdfSmrg#ifdef XSERVER_LIBPCIACCESS
125035c4bbdfSmrg    ErrorF
125135c4bbdfSmrg        ("-isolateDevice bus_id  restrict device resets to bus_id (PCI only)\n");
125205b261ecSmrg#endif
125335c4bbdfSmrg    ErrorF("-version               show the server version\n");
125435c4bbdfSmrg    ErrorF("-showDefaultModulePath show the server default module path\n");
125535c4bbdfSmrg    ErrorF("-showDefaultLibPath    show the server default library path\n");
125635c4bbdfSmrg    ErrorF
125735c4bbdfSmrg        ("-novtswitch            don't automatically switch VT at reset & exit\n");
125835c4bbdfSmrg    ErrorF("-sharevts              share VTs with another X server\n");
125935c4bbdfSmrg    /* OS-specific usage */
126035c4bbdfSmrg    xf86UseMsg();
126135c4bbdfSmrg    ErrorF("\n");
126205b261ecSmrg}
126305b261ecSmrg
126405b261ecSmrg/*
126505b261ecSmrg * xf86LoadModules iterates over a list that is being passed in.
12664642e01fSmrg */
126705b261ecSmrgBool
126835c4bbdfSmrgxf86LoadModules(const char **list, void **optlist)
126905b261ecSmrg{
12701b5d61b8Smrg    int errmaj;
127135c4bbdfSmrg    void *opt;
127205b261ecSmrg    int i;
127305b261ecSmrg    char *name;
127405b261ecSmrg    Bool failed = FALSE;
127505b261ecSmrg
127605b261ecSmrg    if (!list)
127735c4bbdfSmrg        return TRUE;
127805b261ecSmrg
127905b261ecSmrg    for (i = 0; list[i] != NULL; i++) {
128005b261ecSmrg
128135c4bbdfSmrg        /* Normalise the module name */
128235c4bbdfSmrg        name = xf86NormalizeName(list[i]);
128305b261ecSmrg
128435c4bbdfSmrg        /* Skip empty names */
128535c4bbdfSmrg        if (name == NULL || *name == '\0') {
128635c4bbdfSmrg            free(name);
128735c4bbdfSmrg            continue;
128835c4bbdfSmrg        }
128905b261ecSmrg
129035c4bbdfSmrg        /* Replace obsolete keyboard driver with kbd */
129135c4bbdfSmrg        if (!xf86NameCmp(name, "keyboard")) {
129235c4bbdfSmrg            strcpy(name, "kbd");
129335c4bbdfSmrg        }
129405b261ecSmrg
129535c4bbdfSmrg        if (optlist)
129635c4bbdfSmrg            opt = optlist[i];
129735c4bbdfSmrg        else
129835c4bbdfSmrg            opt = NULL;
129905b261ecSmrg
13001b5d61b8Smrg        if (!LoadModule(name, opt, NULL, &errmaj)) {
13011b5d61b8Smrg            LoaderErrorMsg(NULL, name, errmaj, 0);
130235c4bbdfSmrg            failed = TRUE;
130335c4bbdfSmrg        }
130435c4bbdfSmrg        free(name);
130505b261ecSmrg    }
130605b261ecSmrg    return !failed;
130705b261ecSmrg}
130805b261ecSmrg
130905b261ecSmrg/* Pixmap format stuff */
131005b261ecSmrg
13116747b715SmrgPixmapFormatPtr
131205b261ecSmrgxf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
131305b261ecSmrg{
131405b261ecSmrg    int i;
13154642e01fSmrg
131605b261ecSmrg    for (i = 0; i < numFormats; i++)
131735c4bbdfSmrg        if (formats[i].depth == depth)
131835c4bbdfSmrg            break;
131905b261ecSmrg    if (i != numFormats)
132035c4bbdfSmrg        return &formats[i];
132105b261ecSmrg    else if (!formatsDone) {
132235c4bbdfSmrg        /* Check for screen-specified formats */
132335c4bbdfSmrg        for (i = 0; i < pScrn->numFormats; i++)
132435c4bbdfSmrg            if (pScrn->formats[i].depth == depth)
132535c4bbdfSmrg                break;
132635c4bbdfSmrg        if (i != pScrn->numFormats)
132735c4bbdfSmrg            return &pScrn->formats[i];
132805b261ecSmrg    }
132905b261ecSmrg    return NULL;
133005b261ecSmrg}
133105b261ecSmrg
13326747b715Smrgint
133305b261ecSmrgxf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
133405b261ecSmrg{
133505b261ecSmrg    PixmapFormatPtr format;
133605b261ecSmrg
133705b261ecSmrg    format = xf86GetPixFormat(pScrn, depth);
133805b261ecSmrg    if (format)
133935c4bbdfSmrg        return format->bitsPerPixel;
134005b261ecSmrg    else
134135c4bbdfSmrg        return 0;
134235c4bbdfSmrg}
134335c4bbdfSmrg
134435c4bbdfSmrg#ifdef DDXBEFORERESET
134535c4bbdfSmrgvoid
134635c4bbdfSmrgddxBeforeReset(void)
134735c4bbdfSmrg{
134805b261ecSmrg}
134935c4bbdfSmrg#endif
13505a7dfde8Smrg
13515a7dfde8Smrg#if INPUTTHREAD
13525a7dfde8Smrg/** This function is called in Xserver/os/inputthread.c when starting
13535a7dfde8Smrg    the input thread. */
13545a7dfde8Smrgvoid
13555a7dfde8SmrgddxInputThreadInit(void)
13565a7dfde8Smrg{
13575a7dfde8Smrg    xf86OSInputThreadInit();
13585a7dfde8Smrg}
13595a7dfde8Smrg#endif
1360