xf86Init.c revision ed6184df
1/*
2 * Loosely based on code bearing the following copyright:
3 *
4 *   Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
5 */
6/*
7 * Copyright (c) 1992-2003 by The XFree86 Project, Inc.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Except as contained in this notice, the name of the copyright holder(s)
28 * and author(s) shall not be used in advertising or otherwise to promote
29 * the sale, use or other dealings in this Software without prior written
30 * authorization from the copyright holder(s) and author(s).
31 */
32
33#ifdef HAVE_XORG_CONFIG_H
34#include <xorg-config.h>
35#endif
36
37#include <stdlib.h>
38#include <errno.h>
39
40#undef HAS_UTSNAME
41#if !defined(WIN32)
42#define HAS_UTSNAME 1
43#include <sys/utsname.h>
44#endif
45
46#include <X11/X.h>
47#include <X11/Xmd.h>
48#include <X11/Xproto.h>
49#include <X11/Xatom.h>
50#include "input.h"
51#include "servermd.h"
52#include "windowstr.h"
53#include "scrnintstr.h"
54#include "mi.h"
55#include "dbus-core.h"
56#include "systemd-logind.h"
57
58#include "loaderProcs.h"
59
60#define XF86_OS_PRIVS
61#include "xf86.h"
62#include "xf86Priv.h"
63#include "xf86Config.h"
64#include "xf86_OSlib.h"
65#include "xf86cmap.h"
66#include "xorgVersion.h"
67#include "mipointer.h"
68#include <X11/extensions/XI.h>
69#include <X11/extensions/XIproto.h>
70#include "xf86Extensions.h"
71#include "xf86DDC.h"
72#include "xf86Xinput.h"
73#include "xf86InPriv.h"
74#include "xf86Crtc.h"
75#include "picturestr.h"
76#include "randrstr.h"
77#include "xf86Bus.h"
78#ifdef XSERVER_LIBPCIACCESS
79#include "xf86VGAarbiter.h"
80#endif
81#include "globals.h"
82#include "xserver-properties.h"
83
84#ifdef DPMSExtension
85#include <X11/extensions/dpmsconst.h>
86#include "dpmsproc.h"
87#endif
88
89#ifdef __linux__
90#include <linux/major.h>
91#include <sys/sysmacros.h>
92#endif
93#include <hotplug.h>
94
95void (*xf86OSPMClose) (void) = NULL;
96static Bool xorgHWOpenConsole = FALSE;
97
98/* Common pixmap formats */
99
100static PixmapFormatRec formats[MAXFORMATS] = {
101    {1, 1, BITMAP_SCANLINE_PAD},
102    {4, 8, BITMAP_SCANLINE_PAD},
103    {8, 8, BITMAP_SCANLINE_PAD},
104    {15, 16, BITMAP_SCANLINE_PAD},
105    {16, 16, BITMAP_SCANLINE_PAD},
106    {24, 32, BITMAP_SCANLINE_PAD},
107    {32, 32, BITMAP_SCANLINE_PAD},
108};
109
110static int numFormats = 7;
111static Bool formatsDone = FALSE;
112
113
114static void
115xf86PrintBanner(void)
116{
117    xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
118                   XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH);
119#if XORG_VERSION_SNAP > 0
120    xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
121#endif
122
123#if XORG_VERSION_SNAP >= 900
124    /* When the minor number is 99, that signifies that the we are making
125     * a release candidate for a major version.  (X.0.0)
126     * When the patch number is 99, that signifies that the we are making
127     * a release candidate for a minor version.  (X.Y.0)
128     * When the patch number is < 99, then we are making a release
129     * candidate for the next point release.  (X.Y.Z)
130     */
131#if XORG_VERSION_MINOR >= 99
132    xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR + 1,
133                   XORG_VERSION_SNAP - 900);
134#elif XORG_VERSION_PATCH == 99
135    xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
136                   XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
137#else
138    xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
139                   XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
140                   XORG_VERSION_SNAP - 900);
141#endif
142#endif
143
144#ifdef XORG_CUSTOM_VERSION
145    xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
146#endif
147    xf86ErrorFVerb(0, "\nX Protocol Version %d, Revision %d\n",
148                   X_PROTOCOL, X_PROTOCOL_REVISION);
149#ifdef HAS_UTSNAME
150    {
151        struct utsname name;
152
153        /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
154           and Irix) and Single Unix Spec 3 just say that non-negative is success.
155           All agree that failure is represented by a negative number.
156         */
157        if (uname(&name) >= 0) {
158            xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
159                           name.sysname, name.nodename, name.release,
160                           name.version, name.machine);
161#ifdef __linux__
162            do {
163                char buf[80];
164                int fd = open("/proc/cmdline", O_RDONLY);
165
166                if (fd != -1) {
167                    xf86ErrorFVerb(0, "Kernel command line: ");
168                    memset(buf, 0, 80);
169                    while (read(fd, buf, 80) > 0) {
170                        xf86ErrorFVerb(0, "%.80s", buf);
171                        memset(buf, 0, 80);
172                    }
173                    close(fd);
174                }
175            } while (0);
176#endif
177        }
178    }
179#endif
180#if defined(BUILDERSTRING)
181    xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
182#endif
183    xf86ErrorFVerb(0, "Current version of pixman: %s\n",
184                   pixman_version_string());
185    xf86ErrorFVerb(0, "\tBefore reporting problems, check "
186                   "" __VENDORDWEBSUPPORT__ "\n"
187                   "\tto make sure that you have the latest version.\n");
188}
189
190Bool
191xf86PrivsElevated(void)
192{
193    return PrivsElevated();
194}
195
196Bool
197xf86HasTTYs(void)
198{
199#ifdef __linux__
200    struct stat tty0devAttributes;
201    return (stat("/dev/tty0", &tty0devAttributes) == 0 && major(tty0devAttributes.st_rdev) == TTY_MAJOR);
202#else
203    return TRUE;
204#endif
205}
206
207static void
208xf86AutoConfigOutputDevices(void)
209{
210    int i;
211
212    if (!xf86Info.autoBindGPU)
213        return;
214
215    for (i = 0; i < xf86NumGPUScreens; i++) {
216        int scrnum = xf86GPUScreens[i]->confScreen->screennum;
217        RRProviderAutoConfigGpuScreen(xf86ScrnToScreen(xf86GPUScreens[i]),
218                                      xf86ScrnToScreen(xf86Screens[scrnum]));
219    }
220}
221
222static void
223AddSeatId(CallbackListPtr *pcbl, void *data, void *screen)
224{
225    ScreenPtr pScreen = screen;
226    Atom SeatAtom = MakeAtom(SEAT_ATOM_NAME, sizeof(SEAT_ATOM_NAME) - 1, TRUE);
227    int err;
228
229    err = dixChangeWindowProperty(serverClient, pScreen->root, SeatAtom,
230                                  XA_STRING, 8, PropModeReplace,
231                                  strlen(data) + 1, data, FALSE);
232
233    if (err != Success)
234        xf86DrvMsg(pScreen->myNum, X_WARNING,
235                   "Failed to register seat property\n");
236}
237
238static void
239AddVTAtoms(CallbackListPtr *pcbl, void *data, void *screen)
240{
241#define VT_ATOM_NAME         "XFree86_VT"
242    int err, HasVT = 1;
243    ScreenPtr pScreen = screen;
244    Atom VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
245    Atom HasVTAtom = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1,
246                              TRUE);
247
248    err = dixChangeWindowProperty(serverClient, pScreen->root, VTAtom,
249                                  XA_INTEGER, 32, PropModeReplace, 1,
250                                  &xf86Info.vtno, FALSE);
251
252    err |= dixChangeWindowProperty(serverClient, pScreen->root, HasVTAtom,
253                                   XA_INTEGER, 32, PropModeReplace, 1,
254                                   &HasVT, FALSE);
255
256    if (err != Success)
257        xf86DrvMsg(pScreen->myNum, X_WARNING,
258                   "Failed to register VT properties\n");
259}
260
261static Bool
262xf86ScreenInit(ScreenPtr pScreen, int argc, char **argv)
263{
264    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
265
266    pScrn->pScreen = pScreen;
267    return pScrn->ScreenInit (pScreen, argc, argv);
268}
269
270static void
271xf86EnsureRANDR(ScreenPtr pScreen)
272{
273#ifdef RANDR
274        if (!dixPrivateKeyRegistered(rrPrivKey) ||
275            !rrGetScrPriv(pScreen))
276            xf86RandRInit(pScreen);
277#endif
278}
279
280/*
281 * InitOutput --
282 *	Initialize screenInfo for all actually accessible framebuffers.
283 *      That includes vt-manager setup, querying all possible devices and
284 *      collecting the pixmap formats.
285 */
286void
287InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
288{
289    int i, j, k, scr_index;
290    const char **modulelist;
291    void **optionlist;
292    Bool autoconfig = FALSE;
293    Bool sigio_blocked = FALSE;
294    Bool want_hw_access = FALSE;
295    GDevPtr configured_device;
296
297    xf86Initialising = TRUE;
298
299    config_pre_init();
300
301    if (serverGeneration == 1) {
302        xf86PrintBanner();
303        LogPrintMarkers();
304        if (xf86LogFile) {
305            time_t t;
306            const char *ct;
307
308            t = time(NULL);
309            ct = ctime(&t);
310            xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
311                        xf86LogFile, ct);
312        }
313
314        /* Read and parse the config file */
315        if (!xf86DoConfigure && !xf86DoShowOptions) {
316            switch (xf86HandleConfigFile(FALSE)) {
317            case CONFIG_OK:
318                break;
319            case CONFIG_PARSE_ERROR:
320                xf86Msg(X_ERROR, "Error parsing the config file\n");
321                return;
322            case CONFIG_NOFILE:
323                autoconfig = TRUE;
324                break;
325            }
326        }
327
328        /* Initialise the loader */
329        LoaderInit();
330
331        /* Tell the loader the default module search path */
332        LoaderSetPath(xf86ModulePath);
333
334        if (xf86Info.ignoreABI) {
335            LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
336        }
337
338        if (xf86DoShowOptions)
339            DoShowOptions();
340
341        dbus_core_init();
342        systemd_logind_init();
343
344        /* Do a general bus probe.  This will be a PCI probe for x86 platforms */
345        xf86BusProbe();
346
347        if (xf86DoConfigure)
348            DoConfigure();
349
350        if (autoconfig) {
351            if (!xf86AutoConfig()) {
352                xf86Msg(X_ERROR, "Auto configuration failed\n");
353                return;
354            }
355        }
356
357        xf86OSPMClose = xf86OSPMOpen();
358
359        xf86ExtensionInit();
360
361        /* Load all modules specified explicitly in the config file */
362        if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
363            xf86LoadModules(modulelist, optionlist);
364            free(modulelist);
365            free(optionlist);
366        }
367
368        /* Load all driver modules specified in the config file */
369        /* If there aren't any specified in the config file, autoconfig them */
370        /* FIXME: Does not handle multiple active screen sections, but I'm not
371         * sure if we really want to handle that case*/
372        configured_device = xf86ConfigLayout.screens->screen->device;
373        if ((!configured_device) || (!configured_device->driver)) {
374            if (!autoConfigDevice(configured_device)) {
375                xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
376                return;
377            }
378        }
379        if ((modulelist = xf86DriverlistFromConfig())) {
380            xf86LoadModules(modulelist, NULL);
381            free(modulelist);
382        }
383
384        /* Load all input driver modules specified in the config file. */
385        if ((modulelist = xf86InputDriverlistFromConfig())) {
386            xf86LoadModules(modulelist, NULL);
387            free(modulelist);
388        }
389
390        /*
391         * It is expected that xf86AddDriver()/xf86AddInputDriver will be
392         * called for each driver as it is loaded.  Those functions save the
393         * module pointers for drivers.
394         * XXX Nothing keeps track of them for other modules.
395         */
396        /* XXX What do we do if not all of these could be loaded? */
397
398        /*
399         * At this point, xf86DriverList[] is all filled in with entries for
400         * each of the drivers to try and xf86NumDrivers has the number of
401         * drivers.  If there are none, return now.
402         */
403
404        if (xf86NumDrivers == 0) {
405            xf86Msg(X_ERROR, "No drivers available.\n");
406            return;
407        }
408
409        /*
410         * Call each of the Identify functions and call the driverFunc to check
411         * if HW access is required.  The Identify functions print out some
412         * identifying information, and anything else that might be
413         * needed at this early stage.
414         */
415
416        for (i = 0; i < xf86NumDrivers; i++) {
417            xorgHWFlags flags = HW_IO;
418
419            if (xf86DriverList[i]->Identify != NULL)
420                xf86DriverList[i]->Identify(0);
421
422            if (xf86DriverList[i]->driverFunc)
423                xf86DriverList[i]->driverFunc(NULL,
424                                              GET_REQUIRED_HW_INTERFACES,
425                                              &flags);
426
427            if (NEED_IO_ENABLED(flags))
428                want_hw_access = TRUE;
429
430            /* Non-seat0 X servers should not open console */
431            if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0() && xf86HasTTYs())
432                xorgHWOpenConsole = TRUE;
433        }
434
435        if (xorgHWOpenConsole)
436            xf86OpenConsole();
437        else
438            xf86Info.dontVTSwitch = TRUE;
439
440	/* Enable full I/O access */
441	if (want_hw_access)
442	    xorgHWAccess = xf86EnableIO();
443
444        if (xf86BusConfig() == FALSE)
445            return;
446
447        xf86PostProbe();
448
449        /*
450         * Sort the drivers to match the requested ording.  Using a slow
451         * bubble sort.
452         */
453        for (j = 0; j < xf86NumScreens - 1; j++) {
454            for (i = 0; i < xf86NumScreens - j - 1; i++) {
455                if (xf86Screens[i + 1]->confScreen->screennum <
456                    xf86Screens[i]->confScreen->screennum) {
457                    ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
458
459                    xf86Screens[i + 1] = xf86Screens[i];
460                    xf86Screens[i] = tmpScrn;
461                }
462            }
463        }
464        /* Fix up the indexes */
465        for (i = 0; i < xf86NumScreens; i++) {
466            xf86Screens[i]->scrnIndex = i;
467        }
468
469        /*
470         * Call the driver's PreInit()'s to complete initialisation for the first
471         * generation.
472         */
473
474        for (i = 0; i < xf86NumScreens; i++) {
475            xf86VGAarbiterScrnInit(xf86Screens[i]);
476            xf86VGAarbiterLock(xf86Screens[i]);
477            if (xf86Screens[i]->PreInit &&
478                xf86Screens[i]->PreInit(xf86Screens[i], 0))
479                xf86Screens[i]->configured = TRUE;
480            xf86VGAarbiterUnlock(xf86Screens[i]);
481        }
482        for (i = 0; i < xf86NumScreens; i++)
483            if (!xf86Screens[i]->configured)
484                xf86DeleteScreen(xf86Screens[i--]);
485
486        for (i = 0; i < xf86NumGPUScreens; i++) {
487            xf86VGAarbiterScrnInit(xf86GPUScreens[i]);
488            xf86VGAarbiterLock(xf86GPUScreens[i]);
489            if (xf86GPUScreens[i]->PreInit &&
490                xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0))
491                xf86GPUScreens[i]->configured = TRUE;
492            xf86VGAarbiterUnlock(xf86GPUScreens[i]);
493        }
494        for (i = 0; i < xf86NumGPUScreens; i++)
495            if (!xf86GPUScreens[i]->configured)
496                xf86DeleteScreen(xf86GPUScreens[i--]);
497
498        /*
499         * If no screens left, return now.
500         */
501
502        if (xf86NumScreens == 0) {
503            xf86Msg(X_ERROR,
504                    "Screen(s) found, but none have a usable configuration.\n");
505            return;
506        }
507
508        /* Remove (unload) drivers that are not required */
509        for (i = 0; i < xf86NumDrivers; i++)
510            if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
511                xf86DeleteDriver(i);
512
513        /*
514         * At this stage we know how many screens there are.
515         */
516
517        for (i = 0; i < xf86NumScreens; i++)
518            xf86InitViewport(xf86Screens[i]);
519
520        /*
521         * Collect all pixmap formats and check for conflicts at the display
522         * level.  Should we die here?  Or just delete the offending screens?
523         */
524        for (i = 0; i < xf86NumScreens; i++) {
525            if (xf86Screens[i]->imageByteOrder !=
526                xf86Screens[0]->imageByteOrder)
527                FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
528            if (xf86Screens[i]->bitmapScanlinePad !=
529                xf86Screens[0]->bitmapScanlinePad)
530                FatalError
531                    ("Inconsistent display bitmapScanlinePad.  Exiting\n");
532            if (xf86Screens[i]->bitmapScanlineUnit !=
533                xf86Screens[0]->bitmapScanlineUnit)
534                FatalError
535                    ("Inconsistent display bitmapScanlineUnit.  Exiting\n");
536            if (xf86Screens[i]->bitmapBitOrder !=
537                xf86Screens[0]->bitmapBitOrder)
538                FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
539        }
540
541        /* Collect additional formats */
542        for (i = 0; i < xf86NumScreens; i++) {
543            for (j = 0; j < xf86Screens[i]->numFormats; j++) {
544                for (k = 0;; k++) {
545                    if (k >= numFormats) {
546                        if (k >= MAXFORMATS)
547                            FatalError("Too many pixmap formats!  Exiting\n");
548                        formats[k] = xf86Screens[i]->formats[j];
549                        numFormats++;
550                        break;
551                    }
552                    if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
553                        if ((formats[k].bitsPerPixel ==
554                             xf86Screens[i]->formats[j].bitsPerPixel) &&
555                            (formats[k].scanlinePad ==
556                             xf86Screens[i]->formats[j].scanlinePad))
557                            break;
558                        FatalError("Inconsistent pixmap format for depth %d."
559                                   "  Exiting\n", formats[k].depth);
560                    }
561                }
562            }
563        }
564        formatsDone = TRUE;
565    }
566    else {
567        /*
568         * serverGeneration != 1; some OSs have to do things here, too.
569         */
570        if (xorgHWOpenConsole)
571            xf86OpenConsole();
572
573        /*
574           should we reopen it here? We need to deal with an already opened
575           device. We could leave this to the OS layer. For now we simply
576           close it here
577         */
578        if (xf86OSPMClose)
579            xf86OSPMClose();
580        if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
581            xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
582
583        /* Make sure full I/O access is enabled */
584        if (xorgHWAccess)
585            xf86EnableIO();
586    }
587
588    if (xf86Info.vtno >= 0)
589        AddCallback(&RootWindowFinalizeCallback, AddVTAtoms, NULL);
590
591    if (SeatId)
592        AddCallback(&RootWindowFinalizeCallback, AddSeatId, SeatId);
593
594    /*
595     * Use the previously collected parts to setup pScreenInfo
596     */
597
598    pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
599    pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
600    pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
601    pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
602    pScreenInfo->numPixmapFormats = numFormats;
603    for (i = 0; i < numFormats; i++)
604        pScreenInfo->formats[i] = formats[i];
605
606    /* Make sure the server's VT is active */
607
608    if (serverGeneration != 1) {
609        xf86Resetting = TRUE;
610        /* All screens are in the same state, so just check the first */
611        if (!xf86VTOwner()) {
612#ifdef HAS_USL_VTS
613            ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
614#endif
615            input_lock();
616            sigio_blocked = TRUE;
617        }
618    }
619
620    for (i = 0; i < xf86NumScreens; i++)
621        if (!xf86ColormapAllocatePrivates(xf86Screens[i]))
622            FatalError("Cannot register DDX private keys");
623
624    if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0))
625        FatalError("Cannot register DDX private keys");
626
627    for (i = 0; i < xf86NumScreens; i++) {
628        xf86VGAarbiterLock(xf86Screens[i]);
629        /*
630         * Almost everything uses these defaults, and many of those that
631         * don't, will wrap them.
632         */
633        xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
634#ifdef XFreeXDGA
635        xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
636#endif
637        scr_index = AddScreen(xf86ScreenInit, argc, argv);
638        xf86VGAarbiterUnlock(xf86Screens[i]);
639        if (scr_index == i) {
640            /*
641             * Hook in our ScrnInfoRec, and initialise some other pScreen
642             * fields.
643             */
644            dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
645                          xf86ScreenKey, xf86Screens[i]);
646            xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
647            /* The driver should set this, but make sure it is set anyway */
648            xf86Screens[i]->vtSema = TRUE;
649        }
650        else {
651            /* This shouldn't normally happen */
652            FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
653        }
654
655        if (PictureGetSubpixelOrder(xf86Screens[i]->pScreen) == SubPixelUnknown) {
656            xf86MonPtr DDC = (xf86MonPtr) (xf86Screens[i]->monitor->DDC);
657
658            PictureSetSubpixelOrder(xf86Screens[i]->pScreen,
659                                    DDC ?
660                                    (DDC->features.input_type ?
661                                     SubPixelHorizontalRGB : SubPixelNone) :
662                                    SubPixelUnknown);
663        }
664
665        /*
666         * If the driver hasn't set up its own RANDR support, install the
667         * fallback support.
668         */
669        xf86EnsureRANDR(xf86Screens[i]->pScreen);
670    }
671
672    for (i = 0; i < xf86NumGPUScreens; i++) {
673        ScrnInfoPtr pScrn = xf86GPUScreens[i];
674        xf86VGAarbiterLock(pScrn);
675
676        /*
677         * Almost everything uses these defaults, and many of those that
678         * don't, will wrap them.
679         */
680        pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
681#ifdef XFreeXDGA
682        pScrn->SetDGAMode = xf86SetDGAMode;
683#endif
684        scr_index = AddGPUScreen(xf86ScreenInit, argc, argv);
685        xf86VGAarbiterUnlock(pScrn);
686        if (scr_index == i) {
687            dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates,
688                          xf86ScreenKey, xf86GPUScreens[i]);
689            pScrn->pScreen = screenInfo.gpuscreens[scr_index];
690            /* The driver should set this, but make sure it is set anyway */
691            pScrn->vtSema = TRUE;
692        } else {
693            FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index);
694        }
695    }
696
697    for (i = 0; i < xf86NumGPUScreens; i++) {
698        int scrnum = xf86GPUScreens[i]->confScreen->screennum;
699        AttachUnboundGPU(xf86Screens[scrnum]->pScreen, xf86GPUScreens[i]->pScreen);
700    }
701
702    xf86AutoConfigOutputDevices();
703
704    xf86VGAarbiterWrapFunctions();
705    if (sigio_blocked)
706        input_unlock();
707
708    xf86InitOrigins();
709
710    xf86Resetting = FALSE;
711    xf86Initialising = FALSE;
712
713    RegisterBlockAndWakeupHandlers((ServerBlockHandlerProcPtr) NoopDDA, xf86Wakeup,
714                                   NULL);
715}
716
717/**
718 * Initialize all supported input devices present and referenced in the
719 * xorg.conf.
720 */
721void
722InitInput(int argc, char **argv)
723{
724    InputInfoPtr *pInfo;
725    DeviceIntPtr dev;
726
727    xf86Info.vtRequestsPending = FALSE;
728
729    /* Enable threaded input */
730    InputThreadPreInit();
731
732    mieqInit();
733
734    /* Initialize all configured input devices */
735    for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) {
736        (*pInfo)->options =
737            xf86AddNewOption((*pInfo)->options, "driver", (*pInfo)->driver);
738        (*pInfo)->options =
739            xf86AddNewOption((*pInfo)->options, "identifier", (*pInfo)->name);
740        /* If one fails, the others will too */
741        if (NewInputDeviceRequest((*pInfo)->options, NULL, &dev) == BadAlloc)
742            break;
743    }
744
745    config_init();
746}
747
748void
749CloseInput(void)
750{
751    config_fini();
752    mieqFini();
753}
754
755/*
756 * OsVendorInit --
757 *      OS/Vendor-specific initialisations.  Called from OsInit(), which
758 *      is called by dix before establishing the well known sockets.
759 */
760
761void
762OsVendorInit(void)
763{
764    static Bool beenHere = FALSE;
765
766    OsSignal(SIGCHLD, SIG_DFL);   /* Need to wait for child processes */
767
768    if (!beenHere) {
769        umask(022);
770        xf86LogInit();
771    }
772
773    /* Set stderr to non-blocking. */
774#ifndef O_NONBLOCK
775#if defined(FNDELAY)
776#define O_NONBLOCK FNDELAY
777#elif defined(O_NDELAY)
778#define O_NONBLOCK O_NDELAY
779#endif
780
781#ifdef O_NONBLOCK
782    if (!beenHere) {
783        if (PrivsElevated()) {
784            int status;
785
786            status = fcntl(fileno(stderr), F_GETFL, 0);
787            if (status != -1) {
788                fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
789            }
790        }
791    }
792#endif
793#endif
794
795    beenHere = TRUE;
796}
797
798/*
799 * ddxGiveUp --
800 *      Device dependent cleanup. Called by by dix before normal server death.
801 *      For SYSV386 we must switch the terminal back to normal mode. No error-
802 *      checking here, since there should be restored as much as possible.
803 */
804
805void
806ddxGiveUp(enum ExitCode error)
807{
808    int i;
809
810    if (error == EXIT_ERR_ABORT) {
811        input_lock();
812
813        /* try to restore the original video state */
814#ifdef DPMSExtension            /* Turn screens back on */
815        if (DPMSPowerLevel != DPMSModeOn)
816            DPMSSet(serverClient, DPMSModeOn);
817#endif
818        if (xf86Screens) {
819            for (i = 0; i < xf86NumScreens; i++)
820                if (xf86Screens[i]->vtSema) {
821                    /*
822                     * if we are aborting before ScreenInit() has finished we
823                     * might not have been wrapped yet. Therefore enable screen
824                     * explicitly.
825                     */
826                    xf86VGAarbiterLock(xf86Screens[i]);
827                    (xf86Screens[i]->LeaveVT) (xf86Screens[i]);
828                    xf86VGAarbiterUnlock(xf86Screens[i]);
829                }
830        }
831    }
832
833    xf86VGAarbiterFini();
834
835    if (xf86OSPMClose)
836        xf86OSPMClose();
837    xf86OSPMClose = NULL;
838
839    for (i = 0; i < xf86NumScreens; i++) {
840        /*
841         * zero all access functions to
842         * trap calls when switched away.
843         */
844        xf86Screens[i]->vtSema = FALSE;
845    }
846
847    if (xorgHWOpenConsole)
848        xf86CloseConsole();
849
850    systemd_logind_fini();
851    dbus_core_fini();
852
853    xf86CloseLog(error);
854}
855
856void
857OsVendorFatalError(const char *f, va_list args)
858{
859#ifdef VENDORSUPPORT
860    ErrorFSigSafe("\nPlease refer to your Operating System Vendor support "
861                 "pages\nat %s for support on this crash.\n", VENDORSUPPORT);
862#else
863    ErrorFSigSafe("\nPlease consult the " XVENDORNAME " support \n\t at "
864                 __VENDORDWEBSUPPORT__ "\n for help. \n");
865#endif
866    if (xf86LogFile && xf86LogFileWasOpened)
867        ErrorFSigSafe("Please also check the log file at \"%s\" for additional "
868                     "information.\n", xf86LogFile);
869    ErrorFSigSafe("\n");
870}
871
872int
873xf86SetVerbosity(int verb)
874{
875    int save = xf86Verbose;
876
877    xf86Verbose = verb;
878    LogSetParameter(XLOG_VERBOSITY, verb);
879    return save;
880}
881
882int
883xf86SetLogVerbosity(int verb)
884{
885    int save = xf86LogVerbose;
886
887    xf86LogVerbose = verb;
888    LogSetParameter(XLOG_FILE_VERBOSITY, verb);
889    return save;
890}
891
892static void
893xf86PrintDefaultModulePath(void)
894{
895    ErrorF("%s\n", DEFAULT_MODULE_PATH);
896}
897
898static void
899xf86PrintDefaultLibraryPath(void)
900{
901    ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
902}
903
904static void
905xf86CheckPrivs(const char *option, const char *arg)
906{
907    if (PrivsElevated() && !xf86PathIsSafe(arg)) {
908        FatalError("\nInvalid argument for %s - \"%s\"\n"
909                    "\tWith elevated privileges %s must specify a relative path\n"
910                    "\twithout any \"..\" elements.\n\n", option, arg, option);
911    }
912}
913
914/*
915 * ddxProcessArgument --
916 *	Process device-dependent command line args. Returns 0 if argument is
917 *      not device dependent, otherwise Count of number of elements of argv
918 *      that are part of a device dependent commandline option.
919 *
920 */
921
922/* ARGSUSED */
923int
924ddxProcessArgument(int argc, char **argv, int i)
925{
926    /* First the options that are not allowed with elevated privileges */
927    if (!strcmp(argv[i], "-modulepath")) {
928        CHECK_FOR_REQUIRED_ARGUMENTS(1);
929        if (xf86PrivsElevated())
930              FatalError("\nInvalid argument -modulepath "
931                "with elevated privileges\n");
932        xf86ModulePath = argv[i + 1];
933        xf86ModPathFrom = X_CMDLINE;
934        return 2;
935    }
936    if (!strcmp(argv[i], "-logfile")) {
937        CHECK_FOR_REQUIRED_ARGUMENTS(1);
938        if (xf86PrivsElevated())
939              FatalError("\nInvalid argument -logfile "
940                "with elevated privileges\n");
941        xf86LogFile = argv[i + 1];
942        xf86LogFileFrom = X_CMDLINE;
943        return 2;
944    }
945    if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config")) {
946        CHECK_FOR_REQUIRED_ARGUMENTS(1);
947        xf86CheckPrivs(argv[i], argv[i + 1]);
948        xf86ConfigFile = argv[i + 1];
949        return 2;
950    }
951    if (!strcmp(argv[i], "-configdir")) {
952        CHECK_FOR_REQUIRED_ARGUMENTS(1);
953        xf86CheckPrivs(argv[i], argv[i + 1]);
954        xf86ConfigDir = argv[i + 1];
955        return 2;
956    }
957#ifdef XF86VIDMODE
958    if (!strcmp(argv[i], "-disableVidMode")) {
959        xf86VidModeDisabled = TRUE;
960        return 1;
961    }
962    if (!strcmp(argv[i], "-allowNonLocalXvidtune")) {
963        xf86VidModeAllowNonLocal = TRUE;
964        return 1;
965    }
966#endif
967    if (!strcmp(argv[i], "-allowMouseOpenFail")) {
968        xf86AllowMouseOpenFail = TRUE;
969        return 1;
970    }
971    if (!strcmp(argv[i], "-ignoreABI")) {
972        LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
973        return 1;
974    }
975    if (!strcmp(argv[i], "-verbose")) {
976        if (++i < argc && argv[i]) {
977            char *end;
978            long val;
979
980            val = strtol(argv[i], &end, 0);
981            if (*end == '\0') {
982                xf86SetVerbosity(val);
983                return 2;
984            }
985        }
986        xf86SetVerbosity(++xf86Verbose);
987        return 1;
988    }
989    if (!strcmp(argv[i], "-logverbose")) {
990        if (++i < argc && argv[i]) {
991            char *end;
992            long val;
993
994            val = strtol(argv[i], &end, 0);
995            if (*end == '\0') {
996                xf86SetLogVerbosity(val);
997                return 2;
998            }
999        }
1000        xf86SetLogVerbosity(++xf86LogVerbose);
1001        return 1;
1002    }
1003    if (!strcmp(argv[i], "-quiet")) {
1004        xf86SetVerbosity(-1);
1005        return 1;
1006    }
1007    if (!strcmp(argv[i], "-showconfig") || !strcmp(argv[i], "-version")) {
1008        xf86PrintBanner();
1009        exit(0);
1010    }
1011    if (!strcmp(argv[i], "-showDefaultModulePath")) {
1012        xf86PrintDefaultModulePath();
1013        exit(0);
1014    }
1015    if (!strcmp(argv[i], "-showDefaultLibPath")) {
1016        xf86PrintDefaultLibraryPath();
1017        exit(0);
1018    }
1019    /* Notice the -fp flag, but allow it to pass to the dix layer */
1020    if (!strcmp(argv[i], "-fp")) {
1021        xf86fpFlag = TRUE;
1022        return 0;
1023    }
1024    /* Notice the -bs flag, but allow it to pass to the dix layer */
1025    if (!strcmp(argv[i], "-bs")) {
1026        xf86bsDisableFlag = TRUE;
1027        return 0;
1028    }
1029    /* Notice the +bs flag, but allow it to pass to the dix layer */
1030    if (!strcmp(argv[i], "+bs")) {
1031        xf86bsEnableFlag = TRUE;
1032        return 0;
1033    }
1034    /* Notice the -s flag, but allow it to pass to the dix layer */
1035    if (!strcmp(argv[i], "-s")) {
1036        xf86sFlag = TRUE;
1037        return 0;
1038    }
1039    if (!strcmp(argv[i], "-pixmap32") || !strcmp(argv[i], "-pixmap24")) {
1040        /* silently accept */
1041        return 1;
1042    }
1043    if (!strcmp(argv[i], "-fbbpp")) {
1044        int bpp;
1045
1046        CHECK_FOR_REQUIRED_ARGUMENTS(1);
1047        if (sscanf(argv[++i], "%d", &bpp) == 1) {
1048            xf86FbBpp = bpp;
1049            return 2;
1050        }
1051        else {
1052            ErrorF("Invalid fbbpp\n");
1053            return 0;
1054        }
1055    }
1056    if (!strcmp(argv[i], "-depth")) {
1057        int depth;
1058
1059        CHECK_FOR_REQUIRED_ARGUMENTS(1);
1060        if (sscanf(argv[++i], "%d", &depth) == 1) {
1061            xf86Depth = depth;
1062            return 2;
1063        }
1064        else {
1065            ErrorF("Invalid depth\n");
1066            return 0;
1067        }
1068    }
1069    if (!strcmp(argv[i], "-weight")) {
1070        int red, green, blue;
1071
1072        CHECK_FOR_REQUIRED_ARGUMENTS(1);
1073        if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3) {
1074            xf86Weight.red = red;
1075            xf86Weight.green = green;
1076            xf86Weight.blue = blue;
1077            return 2;
1078        }
1079        else {
1080            ErrorF("Invalid weighting\n");
1081            return 0;
1082        }
1083    }
1084    if (!strcmp(argv[i], "-gamma") || !strcmp(argv[i], "-rgamma") ||
1085        !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma")) {
1086        double gamma;
1087
1088        CHECK_FOR_REQUIRED_ARGUMENTS(1);
1089        if (sscanf(argv[++i], "%lf", &gamma) == 1) {
1090            if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
1091                ErrorF("gamma out of range, only  %.2f <= gamma_value <= %.1f"
1092                       " is valid\n", GAMMA_MIN, GAMMA_MAX);
1093                return 0;
1094            }
1095            if (!strcmp(argv[i - 1], "-gamma"))
1096                xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
1097            else if (!strcmp(argv[i - 1], "-rgamma"))
1098                xf86Gamma.red = gamma;
1099            else if (!strcmp(argv[i - 1], "-ggamma"))
1100                xf86Gamma.green = gamma;
1101            else if (!strcmp(argv[i - 1], "-bgamma"))
1102                xf86Gamma.blue = gamma;
1103            return 2;
1104        }
1105    }
1106    if (!strcmp(argv[i], "-layout")) {
1107        CHECK_FOR_REQUIRED_ARGUMENTS(1);
1108        xf86LayoutName = argv[++i];
1109        return 2;
1110    }
1111    if (!strcmp(argv[i], "-screen")) {
1112        CHECK_FOR_REQUIRED_ARGUMENTS(1);
1113        xf86ScreenName = argv[++i];
1114        return 2;
1115    }
1116    if (!strcmp(argv[i], "-pointer")) {
1117        CHECK_FOR_REQUIRED_ARGUMENTS(1);
1118        xf86PointerName = argv[++i];
1119        return 2;
1120    }
1121    if (!strcmp(argv[i], "-keyboard")) {
1122        CHECK_FOR_REQUIRED_ARGUMENTS(1);
1123        xf86KeyboardName = argv[++i];
1124        return 2;
1125    }
1126    if (!strcmp(argv[i], "-nosilk")) {
1127        xf86silkenMouseDisableFlag = TRUE;
1128        return 1;
1129    }
1130#ifdef HAVE_ACPI
1131    if (!strcmp(argv[i], "-noacpi")) {
1132        xf86acpiDisableFlag = TRUE;
1133        return 1;
1134    }
1135#endif
1136    if (!strcmp(argv[i], "-configure")) {
1137        if (getuid() != 0 && geteuid() == 0) {
1138            ErrorF("The '-configure' option can only be used by root.\n");
1139            exit(1);
1140        }
1141        xf86DoConfigure = TRUE;
1142        xf86AllowMouseOpenFail = TRUE;
1143        return 1;
1144    }
1145    if (!strcmp(argv[i], "-showopts")) {
1146        if (getuid() != 0 && geteuid() == 0) {
1147            ErrorF("The '-showopts' option can only be used by root.\n");
1148            exit(1);
1149        }
1150        xf86DoShowOptions = TRUE;
1151        return 1;
1152    }
1153#ifdef XSERVER_LIBPCIACCESS
1154    if (!strcmp(argv[i], "-isolateDevice")) {
1155        CHECK_FOR_REQUIRED_ARGUMENTS(1);
1156        if (strncmp(argv[++i], "PCI:", 4)) {
1157            FatalError("Bus types other than PCI not yet isolable\n");
1158        }
1159        xf86PciIsolateDevice(argv[i]);
1160        return 2;
1161    }
1162#endif
1163    /* Notice cmdline xkbdir, but pass to dix as well */
1164    if (!strcmp(argv[i], "-xkbdir")) {
1165        xf86xkbdirFlag = TRUE;
1166        return 0;
1167    }
1168    if (!strcmp(argv[i], "-novtswitch")) {
1169        xf86Info.autoVTSwitch = FALSE;
1170        return 1;
1171    }
1172    if (!strcmp(argv[i], "-sharevts")) {
1173        xf86Info.ShareVTs = TRUE;
1174        return 1;
1175    }
1176    if (!strcmp(argv[i], "-iglx") || !strcmp(argv[i], "+iglx")) {
1177        xf86Info.iglxFrom = X_CMDLINE;
1178        return 0;
1179    }
1180    if (!strcmp(argv[i], "-noautoBindGPU")) {
1181        xf86AutoBindGPUDisabled = TRUE;
1182        return 1;
1183    }
1184
1185    /* OS-specific processing */
1186    return xf86ProcessArgument(argc, argv, i);
1187}
1188
1189/*
1190 * ddxUseMsg --
1191 *	Print out correct use of device dependent commandline options.
1192 *      Maybe the user now knows what really to do ...
1193 */
1194
1195void
1196ddxUseMsg(void)
1197{
1198    ErrorF("\n");
1199    ErrorF("\n");
1200    ErrorF("Device Dependent Usage\n");
1201    if (!PrivsElevated()) {
1202        ErrorF("-modulepath paths      specify the module search path\n");
1203        ErrorF("-logfile file          specify a log file name\n");
1204        ErrorF("-configure             probe for devices and write an "
1205               XCONFIGFILE "\n");
1206        ErrorF
1207            ("-showopts              print available options for all installed drivers\n");
1208    }
1209    ErrorF
1210        ("-config file           specify a configuration file, relative to the\n");
1211    ErrorF("                       " XCONFIGFILE
1212           " search path, only root can use absolute\n");
1213    ErrorF
1214        ("-configdir dir         specify a configuration directory, relative to the\n");
1215    ErrorF("                       " XCONFIGDIR
1216           " search path, only root can use absolute\n");
1217    ErrorF("-verbose [n]           verbose startup messages\n");
1218    ErrorF("-logverbose [n]        verbose log messages\n");
1219    ErrorF("-quiet                 minimal startup messages\n");
1220    ErrorF("-fbbpp n               set bpp for the framebuffer. Default: 8\n");
1221    ErrorF("-depth n               set colour depth. Default: 8\n");
1222    ErrorF
1223        ("-gamma f               set gamma value (0.1 < f < 10.0) Default: 1.0\n");
1224    ErrorF("-rgamma f              set gamma value for red phase\n");
1225    ErrorF("-ggamma f              set gamma value for green phase\n");
1226    ErrorF("-bgamma f              set gamma value for blue phase\n");
1227    ErrorF
1228        ("-weight nnn            set RGB weighting at 16 bpp.  Default: 565\n");
1229    ErrorF("-layout name           specify the ServerLayout section name\n");
1230    ErrorF("-screen name           specify the Screen section name\n");
1231    ErrorF
1232        ("-keyboard name         specify the core keyboard InputDevice name\n");
1233    ErrorF
1234        ("-pointer name          specify the core pointer InputDevice name\n");
1235    ErrorF("-nosilk                disable Silken Mouse\n");
1236#ifdef XF86VIDMODE
1237    ErrorF("-disableVidMode        disable mode adjustments with xvidtune\n");
1238    ErrorF
1239        ("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
1240#endif
1241    ErrorF
1242        ("-allowMouseOpenFail    start server even if the mouse can't be initialized\n");
1243    ErrorF("-ignoreABI             make module ABI mismatches non-fatal\n");
1244#ifdef XSERVER_LIBPCIACCESS
1245    ErrorF
1246        ("-isolateDevice bus_id  restrict device resets to bus_id (PCI only)\n");
1247#endif
1248    ErrorF("-version               show the server version\n");
1249    ErrorF("-showDefaultModulePath show the server default module path\n");
1250    ErrorF("-showDefaultLibPath    show the server default library path\n");
1251    ErrorF
1252        ("-novtswitch            don't automatically switch VT at reset & exit\n");
1253    ErrorF("-sharevts              share VTs with another X server\n");
1254    /* OS-specific usage */
1255    xf86UseMsg();
1256    ErrorF("\n");
1257}
1258
1259/*
1260 * xf86LoadModules iterates over a list that is being passed in.
1261 */
1262Bool
1263xf86LoadModules(const char **list, void **optlist)
1264{
1265    int errmaj;
1266    void *opt;
1267    int i;
1268    char *name;
1269    Bool failed = FALSE;
1270
1271    if (!list)
1272        return TRUE;
1273
1274    for (i = 0; list[i] != NULL; i++) {
1275
1276        /* Normalise the module name */
1277        name = xf86NormalizeName(list[i]);
1278
1279        /* Skip empty names */
1280        if (name == NULL || *name == '\0') {
1281            free(name);
1282            continue;
1283        }
1284
1285        /* Replace obsolete keyboard driver with kbd */
1286        if (!xf86NameCmp(name, "keyboard")) {
1287            strcpy(name, "kbd");
1288        }
1289
1290        if (optlist)
1291            opt = optlist[i];
1292        else
1293            opt = NULL;
1294
1295        if (!LoadModule(name, opt, NULL, &errmaj)) {
1296            LoaderErrorMsg(NULL, name, errmaj, 0);
1297            failed = TRUE;
1298        }
1299        free(name);
1300    }
1301    return !failed;
1302}
1303
1304/* Pixmap format stuff */
1305
1306PixmapFormatPtr
1307xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
1308{
1309    int i;
1310
1311    for (i = 0; i < numFormats; i++)
1312        if (formats[i].depth == depth)
1313            break;
1314    if (i != numFormats)
1315        return &formats[i];
1316    else if (!formatsDone) {
1317        /* Check for screen-specified formats */
1318        for (i = 0; i < pScrn->numFormats; i++)
1319            if (pScrn->formats[i].depth == depth)
1320                break;
1321        if (i != pScrn->numFormats)
1322            return &pScrn->formats[i];
1323    }
1324    return NULL;
1325}
1326
1327int
1328xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
1329{
1330    PixmapFormatPtr format;
1331
1332    format = xf86GetPixFormat(pScrn, depth);
1333    if (format)
1334        return format->bitsPerPixel;
1335    else
1336        return 0;
1337}
1338
1339#ifdef DDXBEFORERESET
1340void
1341ddxBeforeReset(void)
1342{
1343}
1344#endif
1345
1346#if INPUTTHREAD
1347/** This function is called in Xserver/os/inputthread.c when starting
1348    the input thread. */
1349void
1350ddxInputThreadInit(void)
1351{
1352    xf86OSInputThreadInit();
1353}
1354#endif
1355