1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Permission to use, copy, modify, distribute, and sell this software and its
5*4882a593Smuzhiyun * documentation for any purpose is hereby granted without fee, provided that
6*4882a593Smuzhiyun * the above copyright notice appear in all copies and that both that
7*4882a593Smuzhiyun * copyright notice and this permission notice appear in supporting
8*4882a593Smuzhiyun * documentation, and that the name of Alan Hourihane not be used in
9*4882a593Smuzhiyun * advertising or publicity pertaining to distribution of the software without
10*4882a593Smuzhiyun * specific, written prior permission. Alan Hourihane makes no representations
11*4882a593Smuzhiyun * about the suitability of this software for any purpose. It is provided
12*4882a593Smuzhiyun * "as is" without express or implied warranty.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15*4882a593Smuzhiyun * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16*4882a593Smuzhiyun * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17*4882a593Smuzhiyun * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18*4882a593Smuzhiyun * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19*4882a593Smuzhiyun * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20*4882a593Smuzhiyun * PERFORMANCE OF THIS SOFTWARE.
21*4882a593Smuzhiyun *
22*4882a593Smuzhiyun * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
23*4882a593Smuzhiyun *
24*4882a593Smuzhiyun */
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #ifdef HAVE_XORG_CONFIG_H
27*4882a593Smuzhiyun #include <xorg-config.h>
28*4882a593Smuzhiyun #endif
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #include "xf86.h"
31*4882a593Smuzhiyun #include "xf86Config.h"
32*4882a593Smuzhiyun #include "xf86_OSlib.h"
33*4882a593Smuzhiyun #include "xf86Priv.h"
34*4882a593Smuzhiyun #define IN_XSERVER
35*4882a593Smuzhiyun #include "Configint.h"
36*4882a593Smuzhiyun #include "xf86DDC.h"
37*4882a593Smuzhiyun #include "xf86pciBus.h"
38*4882a593Smuzhiyun #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
39*4882a593Smuzhiyun #include "xf86Bus.h"
40*4882a593Smuzhiyun #include "xf86Sbus.h"
41*4882a593Smuzhiyun #endif
42*4882a593Smuzhiyun #include "misc.h"
43*4882a593Smuzhiyun #include "loaderProcs.h"
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun typedef struct _DevToConfig {
46*4882a593Smuzhiyun GDevRec GDev;
47*4882a593Smuzhiyun struct pci_device *pVideo;
48*4882a593Smuzhiyun #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
49*4882a593Smuzhiyun sbusDevicePtr sVideo;
50*4882a593Smuzhiyun #endif
51*4882a593Smuzhiyun int iDriver;
52*4882a593Smuzhiyun } DevToConfigRec, *DevToConfigPtr;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun static DevToConfigPtr DevToConfig = NULL;
55*4882a593Smuzhiyun static int nDevToConfig = 0, CurrentDriver;
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun xf86MonPtr ConfiguredMonitor;
58*4882a593Smuzhiyun Bool xf86DoConfigurePass1 = TRUE;
59*4882a593Smuzhiyun static Bool foundMouse = FALSE;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
62*4882a593Smuzhiyun static const char *DFLT_MOUSE_DEV = "/dev/sysmouse";
63*4882a593Smuzhiyun static const char *DFLT_MOUSE_PROTO = "auto";
64*4882a593Smuzhiyun #elif defined(__linux__)
65*4882a593Smuzhiyun static const char *DFLT_MOUSE_DEV = "/dev/input/mice";
66*4882a593Smuzhiyun static const char *DFLT_MOUSE_PROTO = "auto";
67*4882a593Smuzhiyun #elif defined(WSCONS_SUPPORT)
68*4882a593Smuzhiyun static const char *DFLT_MOUSE_DEV = "/dev/wsmouse";
69*4882a593Smuzhiyun static const char *DFLT_MOUSE_PROTO = "wsmouse";
70*4882a593Smuzhiyun #else
71*4882a593Smuzhiyun static const char *DFLT_MOUSE_DEV = "/dev/mouse";
72*4882a593Smuzhiyun static const char *DFLT_MOUSE_PROTO = "auto";
73*4882a593Smuzhiyun #endif
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /*
76*4882a593Smuzhiyun * This is called by the driver, either through xf86Match???Instances() or
77*4882a593Smuzhiyun * directly. We allocate a GDevRec and fill it in as much as we can, letting
78*4882a593Smuzhiyun * the caller fill in the rest and/or change it as it sees fit.
79*4882a593Smuzhiyun */
80*4882a593Smuzhiyun GDevPtr
xf86AddBusDeviceToConfigure(const char * driver,BusType bus,void * busData,int chipset)81*4882a593Smuzhiyun xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData,
82*4882a593Smuzhiyun int chipset)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun int ret, i, j;
85*4882a593Smuzhiyun char *lower_driver;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun if (!xf86DoConfigure || !xf86DoConfigurePass1)
88*4882a593Smuzhiyun return NULL;
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun /* Check for duplicates */
91*4882a593Smuzhiyun for (i = 0; i < nDevToConfig; i++) {
92*4882a593Smuzhiyun switch (bus) {
93*4882a593Smuzhiyun #ifdef XSERVER_LIBPCIACCESS
94*4882a593Smuzhiyun case BUS_PCI:
95*4882a593Smuzhiyun ret = xf86PciConfigure(busData, DevToConfig[i].pVideo);
96*4882a593Smuzhiyun break;
97*4882a593Smuzhiyun #endif
98*4882a593Smuzhiyun #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
99*4882a593Smuzhiyun case BUS_SBUS:
100*4882a593Smuzhiyun ret = xf86SbusConfigure(busData, DevToConfig[i].sVideo);
101*4882a593Smuzhiyun break;
102*4882a593Smuzhiyun #endif
103*4882a593Smuzhiyun default:
104*4882a593Smuzhiyun return NULL;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun if (ret == 0)
107*4882a593Smuzhiyun goto out;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun /* Allocate new structure occurrence */
111*4882a593Smuzhiyun i = nDevToConfig++;
112*4882a593Smuzhiyun DevToConfig =
113*4882a593Smuzhiyun xnfreallocarray(DevToConfig, nDevToConfig, sizeof(DevToConfigRec));
114*4882a593Smuzhiyun memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun DevToConfig[i].GDev.chipID =
117*4882a593Smuzhiyun DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun DevToConfig[i].iDriver = CurrentDriver;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun /* Fill in what we know, converting the driver name to lower case */
122*4882a593Smuzhiyun lower_driver = xnfalloc(strlen(driver) + 1);
123*4882a593Smuzhiyun for (j = 0; (lower_driver[j] = tolower(driver[j])); j++);
124*4882a593Smuzhiyun DevToConfig[i].GDev.driver = lower_driver;
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun switch (bus) {
127*4882a593Smuzhiyun #ifdef XSERVER_LIBPCIACCESS
128*4882a593Smuzhiyun case BUS_PCI:
129*4882a593Smuzhiyun DevToConfig[i].pVideo = busData;
130*4882a593Smuzhiyun xf86PciConfigureNewDev(busData, DevToConfig[i].pVideo,
131*4882a593Smuzhiyun &DevToConfig[i].GDev, &chipset);
132*4882a593Smuzhiyun break;
133*4882a593Smuzhiyun #endif
134*4882a593Smuzhiyun #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
135*4882a593Smuzhiyun case BUS_SBUS:
136*4882a593Smuzhiyun DevToConfig[i].sVideo = busData;
137*4882a593Smuzhiyun xf86SbusConfigureNewDev(busData, DevToConfig[i].sVideo,
138*4882a593Smuzhiyun &DevToConfig[i].GDev);
139*4882a593Smuzhiyun break;
140*4882a593Smuzhiyun #endif
141*4882a593Smuzhiyun default:
142*4882a593Smuzhiyun break;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun /* Get driver's available options */
146*4882a593Smuzhiyun if (xf86DriverList[CurrentDriver]->AvailableOptions)
147*4882a593Smuzhiyun DevToConfig[i].GDev.options = (OptionInfoPtr)
148*4882a593Smuzhiyun (*xf86DriverList[CurrentDriver]->AvailableOptions) (chipset, bus);
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun return &DevToConfig[i].GDev;
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun out:
153*4882a593Smuzhiyun return NULL;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun static XF86ConfInputPtr
configureInputSection(void)157*4882a593Smuzhiyun configureInputSection(void)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun XF86ConfInputPtr mouse = NULL;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun parsePrologue(XF86ConfInputPtr, XF86ConfInputRec);
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun ptr->inp_identifier = xnfstrdup("Keyboard0");
164*4882a593Smuzhiyun ptr->inp_driver = xnfstrdup("kbd");
165*4882a593Smuzhiyun ptr->list.next = NULL;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun /* Crude mechanism to auto-detect mouse (os dependent) */
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun int fd;
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun fd = open(DFLT_MOUSE_DEV, 0);
172*4882a593Smuzhiyun if (fd != -1) {
173*4882a593Smuzhiyun foundMouse = TRUE;
174*4882a593Smuzhiyun close(fd);
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun mouse = calloc(1, sizeof(XF86ConfInputRec));
179*4882a593Smuzhiyun mouse->inp_identifier = xnfstrdup("Mouse0");
180*4882a593Smuzhiyun mouse->inp_driver = xnfstrdup("mouse");
181*4882a593Smuzhiyun mouse->inp_option_lst =
182*4882a593Smuzhiyun xf86addNewOption(mouse->inp_option_lst, xnfstrdup("Protocol"),
183*4882a593Smuzhiyun xnfstrdup(DFLT_MOUSE_PROTO));
184*4882a593Smuzhiyun mouse->inp_option_lst =
185*4882a593Smuzhiyun xf86addNewOption(mouse->inp_option_lst, xnfstrdup("Device"),
186*4882a593Smuzhiyun xnfstrdup(DFLT_MOUSE_DEV));
187*4882a593Smuzhiyun mouse->inp_option_lst =
188*4882a593Smuzhiyun xf86addNewOption(mouse->inp_option_lst, xnfstrdup("ZAxisMapping"),
189*4882a593Smuzhiyun xnfstrdup("4 5 6 7"));
190*4882a593Smuzhiyun ptr = (XF86ConfInputPtr) xf86addListItem((glp) ptr, (glp) mouse);
191*4882a593Smuzhiyun return ptr;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun static XF86ConfScreenPtr
configureScreenSection(int screennum)195*4882a593Smuzhiyun configureScreenSection(int screennum)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun int i;
198*4882a593Smuzhiyun int depths[] = { 1, 4, 8, 15, 16, 24 /*, 32 */ };
199*4882a593Smuzhiyun char *tmp;
200*4882a593Smuzhiyun parsePrologue(XF86ConfScreenPtr, XF86ConfScreenRec);
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun XNFasprintf(&tmp, "Screen%d", screennum);
203*4882a593Smuzhiyun ptr->scrn_identifier = tmp;
204*4882a593Smuzhiyun XNFasprintf(&tmp, "Monitor%d", screennum);
205*4882a593Smuzhiyun ptr->scrn_monitor_str = tmp;
206*4882a593Smuzhiyun XNFasprintf(&tmp, "Card%d", screennum);
207*4882a593Smuzhiyun ptr->scrn_device_str = tmp;
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(depths); i++) {
210*4882a593Smuzhiyun XF86ConfDisplayPtr conf_display;
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun conf_display = calloc(1, sizeof(XF86ConfDisplayRec));
213*4882a593Smuzhiyun conf_display->disp_depth = depths[i];
214*4882a593Smuzhiyun conf_display->disp_black.red = conf_display->disp_white.red = -1;
215*4882a593Smuzhiyun conf_display->disp_black.green = conf_display->disp_white.green = -1;
216*4882a593Smuzhiyun conf_display->disp_black.blue = conf_display->disp_white.blue = -1;
217*4882a593Smuzhiyun ptr->scrn_display_lst = (XF86ConfDisplayPtr) xf86addListItem((glp) ptr->
218*4882a593Smuzhiyun scrn_display_lst,
219*4882a593Smuzhiyun (glp)
220*4882a593Smuzhiyun conf_display);
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun return ptr;
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun static const char *
optionTypeToString(OptionValueType type)227*4882a593Smuzhiyun optionTypeToString(OptionValueType type)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun switch (type) {
230*4882a593Smuzhiyun case OPTV_NONE:
231*4882a593Smuzhiyun return "";
232*4882a593Smuzhiyun case OPTV_INTEGER:
233*4882a593Smuzhiyun return "<i>";
234*4882a593Smuzhiyun case OPTV_STRING:
235*4882a593Smuzhiyun return "<str>";
236*4882a593Smuzhiyun case OPTV_ANYSTR:
237*4882a593Smuzhiyun return "[<str>]";
238*4882a593Smuzhiyun case OPTV_REAL:
239*4882a593Smuzhiyun return "<f>";
240*4882a593Smuzhiyun case OPTV_BOOLEAN:
241*4882a593Smuzhiyun return "[<bool>]";
242*4882a593Smuzhiyun case OPTV_FREQ:
243*4882a593Smuzhiyun return "<freq>";
244*4882a593Smuzhiyun case OPTV_PERCENT:
245*4882a593Smuzhiyun return "<percent>";
246*4882a593Smuzhiyun default:
247*4882a593Smuzhiyun return "";
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun static XF86ConfDevicePtr
configureDeviceSection(int screennum)252*4882a593Smuzhiyun configureDeviceSection(int screennum)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun OptionInfoPtr p;
255*4882a593Smuzhiyun int i = 0;
256*4882a593Smuzhiyun char *identifier;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun parsePrologue(XF86ConfDevicePtr, XF86ConfDeviceRec);
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun /* Move device info to parser structure */
261*4882a593Smuzhiyun if (asprintf(&identifier, "Card%d", screennum) == -1)
262*4882a593Smuzhiyun identifier = NULL;
263*4882a593Smuzhiyun ptr->dev_identifier = identifier;
264*4882a593Smuzhiyun ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
265*4882a593Smuzhiyun ptr->dev_busid = DevToConfig[screennum].GDev.busID;
266*4882a593Smuzhiyun ptr->dev_driver = DevToConfig[screennum].GDev.driver;
267*4882a593Smuzhiyun ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
268*4882a593Smuzhiyun for (i = 0; i < MAXDACSPEEDS; i++)
269*4882a593Smuzhiyun ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
270*4882a593Smuzhiyun ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
271*4882a593Smuzhiyun ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase;
272*4882a593Smuzhiyun ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase;
273*4882a593Smuzhiyun ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip;
274*4882a593Smuzhiyun for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks);
275*4882a593Smuzhiyun i++)
276*4882a593Smuzhiyun ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i];
277*4882a593Smuzhiyun ptr->dev_clocks = i;
278*4882a593Smuzhiyun ptr->dev_chipid = DevToConfig[screennum].GDev.chipID;
279*4882a593Smuzhiyun ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev;
280*4882a593Smuzhiyun ptr->dev_irq = DevToConfig[screennum].GDev.irq;
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun /* Make sure older drivers don't segv */
283*4882a593Smuzhiyun if (DevToConfig[screennum].GDev.options) {
284*4882a593Smuzhiyun /* Fill in the available driver options for people to use */
285*4882a593Smuzhiyun const char *descrip =
286*4882a593Smuzhiyun " ### Available Driver options are:-\n"
287*4882a593Smuzhiyun " ### Values: <i>: integer, <f>: float, "
288*4882a593Smuzhiyun "<bool>: \"True\"/\"False\",\n"
289*4882a593Smuzhiyun " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n"
290*4882a593Smuzhiyun " ### <percent>: \"<f>%\"\n"
291*4882a593Smuzhiyun " ### [arg]: arg optional\n";
292*4882a593Smuzhiyun ptr->dev_comment = xnfstrdup(descrip);
293*4882a593Smuzhiyun if (ptr->dev_comment) {
294*4882a593Smuzhiyun for (p = DevToConfig[screennum].GDev.options; p->name != NULL; p++) {
295*4882a593Smuzhiyun char *p_e;
296*4882a593Smuzhiyun const char *prefix = " #Option ";
297*4882a593Smuzhiyun const char *middle = " \t# ";
298*4882a593Smuzhiyun const char *suffix = "\n";
299*4882a593Smuzhiyun const char *opttype = optionTypeToString(p->type);
300*4882a593Smuzhiyun char *optname;
301*4882a593Smuzhiyun int len = strlen(ptr->dev_comment) + strlen(prefix) +
302*4882a593Smuzhiyun strlen(middle) + strlen(suffix) + 1;
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun if (asprintf(&optname, "\"%s\"", p->name) == -1)
305*4882a593Smuzhiyun break;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun len += max(20, strlen(optname));
308*4882a593Smuzhiyun len += strlen(opttype);
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun ptr->dev_comment = realloc(ptr->dev_comment, len);
311*4882a593Smuzhiyun if (!ptr->dev_comment)
312*4882a593Smuzhiyun break;
313*4882a593Smuzhiyun p_e = ptr->dev_comment + strlen(ptr->dev_comment);
314*4882a593Smuzhiyun sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle,
315*4882a593Smuzhiyun opttype, suffix);
316*4882a593Smuzhiyun free(optname);
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun return ptr;
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun static XF86ConfLayoutPtr
configureLayoutSection(void)325*4882a593Smuzhiyun configureLayoutSection(void)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun int scrnum = 0;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun parsePrologue(XF86ConfLayoutPtr, XF86ConfLayoutRec);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun ptr->lay_identifier = "X.org Configured";
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun XF86ConfInputrefPtr iptr;
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun iptr = malloc(sizeof(XF86ConfInputrefRec));
337*4882a593Smuzhiyun iptr->list.next = NULL;
338*4882a593Smuzhiyun iptr->iref_option_lst = NULL;
339*4882a593Smuzhiyun iptr->iref_inputdev_str = xnfstrdup("Mouse0");
340*4882a593Smuzhiyun iptr->iref_option_lst =
341*4882a593Smuzhiyun xf86addNewOption(iptr->iref_option_lst, xnfstrdup("CorePointer"),
342*4882a593Smuzhiyun NULL);
343*4882a593Smuzhiyun ptr->lay_input_lst = (XF86ConfInputrefPtr)
344*4882a593Smuzhiyun xf86addListItem((glp) ptr->lay_input_lst, (glp) iptr);
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun XF86ConfInputrefPtr iptr;
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun iptr = malloc(sizeof(XF86ConfInputrefRec));
351*4882a593Smuzhiyun iptr->list.next = NULL;
352*4882a593Smuzhiyun iptr->iref_option_lst = NULL;
353*4882a593Smuzhiyun iptr->iref_inputdev_str = xnfstrdup("Keyboard0");
354*4882a593Smuzhiyun iptr->iref_option_lst =
355*4882a593Smuzhiyun xf86addNewOption(iptr->iref_option_lst, xnfstrdup("CoreKeyboard"),
356*4882a593Smuzhiyun NULL);
357*4882a593Smuzhiyun ptr->lay_input_lst = (XF86ConfInputrefPtr)
358*4882a593Smuzhiyun xf86addListItem((glp) ptr->lay_input_lst, (glp) iptr);
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun for (scrnum = 0; scrnum < nDevToConfig; scrnum++) {
362*4882a593Smuzhiyun XF86ConfAdjacencyPtr aptr;
363*4882a593Smuzhiyun char *tmp;
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun aptr = malloc(sizeof(XF86ConfAdjacencyRec));
366*4882a593Smuzhiyun aptr->list.next = NULL;
367*4882a593Smuzhiyun aptr->adj_x = 0;
368*4882a593Smuzhiyun aptr->adj_y = 0;
369*4882a593Smuzhiyun aptr->adj_scrnum = scrnum;
370*4882a593Smuzhiyun XNFasprintf(&tmp, "Screen%d", scrnum);
371*4882a593Smuzhiyun aptr->adj_screen_str = tmp;
372*4882a593Smuzhiyun if (scrnum == 0) {
373*4882a593Smuzhiyun aptr->adj_where = CONF_ADJ_ABSOLUTE;
374*4882a593Smuzhiyun aptr->adj_refscreen = NULL;
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun else {
377*4882a593Smuzhiyun aptr->adj_where = CONF_ADJ_RIGHTOF;
378*4882a593Smuzhiyun XNFasprintf(&tmp, "Screen%d", scrnum - 1);
379*4882a593Smuzhiyun aptr->adj_refscreen = tmp;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun ptr->lay_adjacency_lst =
382*4882a593Smuzhiyun (XF86ConfAdjacencyPtr) xf86addListItem((glp) ptr->lay_adjacency_lst,
383*4882a593Smuzhiyun (glp) aptr);
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun return ptr;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun static XF86ConfFlagsPtr
configureFlagsSection(void)390*4882a593Smuzhiyun configureFlagsSection(void)
391*4882a593Smuzhiyun {
392*4882a593Smuzhiyun parsePrologue(XF86ConfFlagsPtr, XF86ConfFlagsRec);
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun return ptr;
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun static XF86ConfModulePtr
configureModuleSection(void)398*4882a593Smuzhiyun configureModuleSection(void)
399*4882a593Smuzhiyun {
400*4882a593Smuzhiyun const char **elist, **el;
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun parsePrologue(XF86ConfModulePtr, XF86ConfModuleRec);
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun elist = LoaderListDir("extensions", NULL);
405*4882a593Smuzhiyun if (elist) {
406*4882a593Smuzhiyun for (el = elist; *el; el++) {
407*4882a593Smuzhiyun XF86LoadPtr module;
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun module = calloc(1, sizeof(XF86LoadRec));
410*4882a593Smuzhiyun module->load_name = *el;
411*4882a593Smuzhiyun ptr->mod_load_lst = (XF86LoadPtr) xf86addListItem((glp) ptr->
412*4882a593Smuzhiyun mod_load_lst,
413*4882a593Smuzhiyun (glp) module);
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun free(elist);
416*4882a593Smuzhiyun }
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun return ptr;
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun static XF86ConfFilesPtr
configureFilesSection(void)422*4882a593Smuzhiyun configureFilesSection(void)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun parsePrologue(XF86ConfFilesPtr, XF86ConfFilesRec);
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun if (xf86ModulePath)
427*4882a593Smuzhiyun ptr->file_modulepath = xnfstrdup(xf86ModulePath);
428*4882a593Smuzhiyun if (defaultFontPath)
429*4882a593Smuzhiyun ptr->file_fontpath = xnfstrdup(defaultFontPath);
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun return ptr;
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun static XF86ConfMonitorPtr
configureMonitorSection(int screennum)435*4882a593Smuzhiyun configureMonitorSection(int screennum)
436*4882a593Smuzhiyun {
437*4882a593Smuzhiyun char *tmp;
438*4882a593Smuzhiyun parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec);
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun XNFasprintf(&tmp, "Monitor%d", screennum);
441*4882a593Smuzhiyun ptr->mon_identifier = tmp;
442*4882a593Smuzhiyun ptr->mon_vendor = xnfstrdup("Monitor Vendor");
443*4882a593Smuzhiyun ptr->mon_modelname = xnfstrdup("Monitor Model");
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun return ptr;
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun /* Initialize Configure Monitor from Detailed Timing Block */
449*4882a593Smuzhiyun static void
handle_detailed_input(struct detailed_monitor_section * det_mon,void * data)450*4882a593Smuzhiyun handle_detailed_input(struct detailed_monitor_section *det_mon, void *data)
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data;
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun switch (det_mon->type) {
455*4882a593Smuzhiyun case DS_NAME:
456*4882a593Smuzhiyun ptr->mon_modelname = realloc(ptr->mon_modelname,
457*4882a593Smuzhiyun strlen((char *) (det_mon->section.name)) +
458*4882a593Smuzhiyun 1);
459*4882a593Smuzhiyun strcpy(ptr->mon_modelname, (char *) (det_mon->section.name));
460*4882a593Smuzhiyun break;
461*4882a593Smuzhiyun case DS_RANGES:
462*4882a593Smuzhiyun ptr->mon_hsync[ptr->mon_n_hsync].lo = det_mon->section.ranges.min_h;
463*4882a593Smuzhiyun ptr->mon_hsync[ptr->mon_n_hsync].hi = det_mon->section.ranges.max_h;
464*4882a593Smuzhiyun ptr->mon_n_vrefresh = 1;
465*4882a593Smuzhiyun ptr->mon_vrefresh[ptr->mon_n_hsync].lo = det_mon->section.ranges.min_v;
466*4882a593Smuzhiyun ptr->mon_vrefresh[ptr->mon_n_hsync].hi = det_mon->section.ranges.max_v;
467*4882a593Smuzhiyun ptr->mon_n_hsync++;
468*4882a593Smuzhiyun default:
469*4882a593Smuzhiyun break;
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun static XF86ConfMonitorPtr
configureDDCMonitorSection(int screennum)474*4882a593Smuzhiyun configureDDCMonitorSection(int screennum)
475*4882a593Smuzhiyun {
476*4882a593Smuzhiyun int len, mon_width, mon_height;
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun #define displaySizeMaxLen 80
479*4882a593Smuzhiyun char displaySize_string[displaySizeMaxLen];
480*4882a593Smuzhiyun int displaySizeLen;
481*4882a593Smuzhiyun char *tmp;
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec);
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun XNFasprintf(&tmp, "Monitor%d", screennum);
486*4882a593Smuzhiyun ptr->mon_identifier = tmp;
487*4882a593Smuzhiyun ptr->mon_vendor = xnfstrdup(ConfiguredMonitor->vendor.name);
488*4882a593Smuzhiyun XNFasprintf(&ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun /* features in centimetres, we want millimetres */
491*4882a593Smuzhiyun mon_width = 10 * ConfiguredMonitor->features.hsize;
492*4882a593Smuzhiyun mon_height = 10 * ConfiguredMonitor->features.vsize;
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun #ifdef CONFIGURE_DISPLAYSIZE
495*4882a593Smuzhiyun ptr->mon_width = mon_width;
496*4882a593Smuzhiyun ptr->mon_height = mon_height;
497*4882a593Smuzhiyun #else
498*4882a593Smuzhiyun if (mon_width && mon_height) {
499*4882a593Smuzhiyun /* when values available add DisplaySize option AS A COMMENT */
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen,
502*4882a593Smuzhiyun "\t#DisplaySize\t%5d %5d\t# mm\n",
503*4882a593Smuzhiyun mon_width, mon_height);
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun if (displaySizeLen > 0 && displaySizeLen < displaySizeMaxLen) {
506*4882a593Smuzhiyun if (ptr->mon_comment) {
507*4882a593Smuzhiyun len = strlen(ptr->mon_comment);
508*4882a593Smuzhiyun }
509*4882a593Smuzhiyun else {
510*4882a593Smuzhiyun len = 0;
511*4882a593Smuzhiyun }
512*4882a593Smuzhiyun if ((ptr->mon_comment =
513*4882a593Smuzhiyun realloc(ptr->mon_comment,
514*4882a593Smuzhiyun len + strlen(displaySize_string) + 1))) {
515*4882a593Smuzhiyun strcpy(ptr->mon_comment + len, displaySize_string);
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun #endif /* def CONFIGURE_DISPLAYSIZE */
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input, ptr);
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun if (ConfiguredMonitor->features.dpms) {
524*4882a593Smuzhiyun ptr->mon_option_lst =
525*4882a593Smuzhiyun xf86addNewOption(ptr->mon_option_lst, xnfstrdup("DPMS"), NULL);
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun return ptr;
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun static int
is_fallback(const char * s)532*4882a593Smuzhiyun is_fallback(const char *s)
533*4882a593Smuzhiyun {
534*4882a593Smuzhiyun /* later entries are less preferred */
535*4882a593Smuzhiyun const char *fallback[5] = { "modesetting", "fbdev", "vesa", "wsfb", NULL };
536*4882a593Smuzhiyun int i;
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun for (i = 0; fallback[i]; i++)
539*4882a593Smuzhiyun if (strstr(s, fallback[i]))
540*4882a593Smuzhiyun return i;
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun return -1;
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun static int
driver_sort(const void * _l,const void * _r)546*4882a593Smuzhiyun driver_sort(const void *_l, const void *_r)
547*4882a593Smuzhiyun {
548*4882a593Smuzhiyun const char *l = *(const char **)_l;
549*4882a593Smuzhiyun const char *r = *(const char **)_r;
550*4882a593Smuzhiyun int left = is_fallback(l);
551*4882a593Smuzhiyun int right = is_fallback(r);
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun /* neither is a fallback, asciibetize */
554*4882a593Smuzhiyun if (left == -1 && right == -1)
555*4882a593Smuzhiyun return strcmp(l, r);
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun /* left is a fallback, right is not */
558*4882a593Smuzhiyun if (left >= 0 && right == -1)
559*4882a593Smuzhiyun return 1;
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun /* right is a fallback, left is not */
562*4882a593Smuzhiyun if (right >= 0 && left == -1)
563*4882a593Smuzhiyun return -1;
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun /* both are fallbacks, decide which is worse */
566*4882a593Smuzhiyun return left - right;
567*4882a593Smuzhiyun }
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun static void
fixup_video_driver_list(const char ** drivers)570*4882a593Smuzhiyun fixup_video_driver_list(const char **drivers)
571*4882a593Smuzhiyun {
572*4882a593Smuzhiyun const char **end;
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun /* walk to the end of the list */
575*4882a593Smuzhiyun for (end = drivers; *end && **end; end++);
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun qsort(drivers, end - drivers, sizeof(const char *), driver_sort);
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun static const char **
GenerateDriverList(void)581*4882a593Smuzhiyun GenerateDriverList(void)
582*4882a593Smuzhiyun {
583*4882a593Smuzhiyun const char **ret;
584*4882a593Smuzhiyun static const char *patlist[] = { "(.*)_drv\\.so", NULL };
585*4882a593Smuzhiyun ret = LoaderListDir("drivers", patlist);
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun /* fix up the probe order for video drivers */
588*4882a593Smuzhiyun if (ret != NULL)
589*4882a593Smuzhiyun fixup_video_driver_list(ret);
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun return ret;
592*4882a593Smuzhiyun }
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun void
DoConfigure(void)595*4882a593Smuzhiyun DoConfigure(void)
596*4882a593Smuzhiyun {
597*4882a593Smuzhiyun int i, j, screennum = -1;
598*4882a593Smuzhiyun const char *home = NULL;
599*4882a593Smuzhiyun char filename[PATH_MAX];
600*4882a593Smuzhiyun const char *addslash = "";
601*4882a593Smuzhiyun XF86ConfigPtr xf86config = NULL;
602*4882a593Smuzhiyun const char **vlist, **vl;
603*4882a593Smuzhiyun int *dev2screen;
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun vlist = GenerateDriverList();
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun if (!vlist) {
608*4882a593Smuzhiyun ErrorF("Missing output drivers. Configuration failed.\n");
609*4882a593Smuzhiyun goto bail;
610*4882a593Smuzhiyun }
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun ErrorF("List of video drivers:\n");
613*4882a593Smuzhiyun for (vl = vlist; *vl; vl++)
614*4882a593Smuzhiyun ErrorF("\t%s\n", *vl);
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun /* Load all the drivers that were found. */
617*4882a593Smuzhiyun xf86LoadModules(vlist, NULL);
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun free(vlist);
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun xorgHWAccess = xf86EnableIO();
622*4882a593Smuzhiyun
623*4882a593Smuzhiyun /* Create XF86Config file structure */
624*4882a593Smuzhiyun xf86config = calloc(1, sizeof(XF86ConfigRec));
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun /* Call all of the probe functions, reporting the results. */
627*4882a593Smuzhiyun for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) {
628*4882a593Smuzhiyun Bool found_screen;
629*4882a593Smuzhiyun DriverRec *const drv = xf86DriverList[CurrentDriver];
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun found_screen = xf86CallDriverProbe(drv, TRUE);
632*4882a593Smuzhiyun if (found_screen && drv->Identify) {
633*4882a593Smuzhiyun (*drv->Identify) (0);
634*4882a593Smuzhiyun }
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun if (nDevToConfig <= 0) {
638*4882a593Smuzhiyun ErrorF("No devices to configure. Configuration failed.\n");
639*4882a593Smuzhiyun goto bail;
640*4882a593Smuzhiyun }
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun /* Add device, monitor and screen sections for detected devices */
643*4882a593Smuzhiyun for (screennum = 0; screennum < nDevToConfig; screennum++) {
644*4882a593Smuzhiyun XF86ConfDevicePtr device_ptr;
645*4882a593Smuzhiyun XF86ConfMonitorPtr monitor_ptr;
646*4882a593Smuzhiyun XF86ConfScreenPtr screen_ptr;
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun device_ptr = configureDeviceSection(screennum);
649*4882a593Smuzhiyun xf86config->conf_device_lst = (XF86ConfDevicePtr) xf86addListItem((glp)
650*4882a593Smuzhiyun xf86config->
651*4882a593Smuzhiyun conf_device_lst,
652*4882a593Smuzhiyun (glp)
653*4882a593Smuzhiyun device_ptr);
654*4882a593Smuzhiyun monitor_ptr = configureMonitorSection(screennum);
655*4882a593Smuzhiyun xf86config->conf_monitor_lst = (XF86ConfMonitorPtr) xf86addListItem((glp) xf86config->conf_monitor_lst, (glp) monitor_ptr);
656*4882a593Smuzhiyun screen_ptr = configureScreenSection(screennum);
657*4882a593Smuzhiyun xf86config->conf_screen_lst = (XF86ConfScreenPtr) xf86addListItem((glp)
658*4882a593Smuzhiyun xf86config->
659*4882a593Smuzhiyun conf_screen_lst,
660*4882a593Smuzhiyun (glp)
661*4882a593Smuzhiyun screen_ptr);
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun xf86config->conf_files = configureFilesSection();
665*4882a593Smuzhiyun xf86config->conf_modules = configureModuleSection();
666*4882a593Smuzhiyun xf86config->conf_flags = configureFlagsSection();
667*4882a593Smuzhiyun xf86config->conf_videoadaptor_lst = NULL;
668*4882a593Smuzhiyun xf86config->conf_modes_lst = NULL;
669*4882a593Smuzhiyun xf86config->conf_vendor_lst = NULL;
670*4882a593Smuzhiyun xf86config->conf_dri = NULL;
671*4882a593Smuzhiyun xf86config->conf_input_lst = configureInputSection();
672*4882a593Smuzhiyun xf86config->conf_layout_lst = configureLayoutSection();
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun home = getenv("HOME");
675*4882a593Smuzhiyun if ((home == NULL) || (home[0] == '\0')) {
676*4882a593Smuzhiyun home = "/";
677*4882a593Smuzhiyun }
678*4882a593Smuzhiyun else {
679*4882a593Smuzhiyun /* Determine if trailing slash is present or needed */
680*4882a593Smuzhiyun int l = strlen(home);
681*4882a593Smuzhiyun
682*4882a593Smuzhiyun if (home[l - 1] != '/') {
683*4882a593Smuzhiyun addslash = "/";
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun }
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new",
688*4882a593Smuzhiyun home, addslash);
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun if (xf86writeConfigFile(filename, xf86config) == 0) {
691*4882a593Smuzhiyun xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
692*4882a593Smuzhiyun filename, strerror(errno));
693*4882a593Smuzhiyun goto bail;
694*4882a593Smuzhiyun }
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun xf86DoConfigurePass1 = FALSE;
697*4882a593Smuzhiyun /* Try to get DDC information filled in */
698*4882a593Smuzhiyun xf86ConfigFile = filename;
699*4882a593Smuzhiyun if (xf86HandleConfigFile(FALSE) != CONFIG_OK) {
700*4882a593Smuzhiyun goto bail;
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun xf86DoConfigurePass1 = FALSE;
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun dev2screen = xnfcalloc(nDevToConfig, sizeof(int));
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun {
708*4882a593Smuzhiyun Bool *driverProbed = xnfcalloc(xf86NumDrivers, sizeof(Bool));
709*4882a593Smuzhiyun
710*4882a593Smuzhiyun for (screennum = 0; screennum < nDevToConfig; screennum++) {
711*4882a593Smuzhiyun int k, l, n, oldNumScreens;
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun i = DevToConfig[screennum].iDriver;
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun if (driverProbed[i])
716*4882a593Smuzhiyun continue;
717*4882a593Smuzhiyun driverProbed[i] = TRUE;
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun oldNumScreens = xf86NumScreens;
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun xf86CallDriverProbe(xf86DriverList[i], FALSE);
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun /* reorder */
724*4882a593Smuzhiyun k = screennum > 0 ? screennum : 1;
725*4882a593Smuzhiyun for (l = oldNumScreens; l < xf86NumScreens; l++) {
726*4882a593Smuzhiyun /* is screen primary? */
727*4882a593Smuzhiyun Bool primary = FALSE;
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun for (n = 0; n < xf86Screens[l]->numEntities; n++) {
730*4882a593Smuzhiyun if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) {
731*4882a593Smuzhiyun dev2screen[0] = l;
732*4882a593Smuzhiyun primary = TRUE;
733*4882a593Smuzhiyun break;
734*4882a593Smuzhiyun }
735*4882a593Smuzhiyun }
736*4882a593Smuzhiyun if (primary)
737*4882a593Smuzhiyun continue;
738*4882a593Smuzhiyun /* not primary: assign it to next device of same driver */
739*4882a593Smuzhiyun /*
740*4882a593Smuzhiyun * NOTE: we assume that devices in DevToConfig
741*4882a593Smuzhiyun * and xf86Screens[] have the same order except
742*4882a593Smuzhiyun * for the primary device which always comes first.
743*4882a593Smuzhiyun */
744*4882a593Smuzhiyun for (; k < nDevToConfig; k++) {
745*4882a593Smuzhiyun if (DevToConfig[k].iDriver == i) {
746*4882a593Smuzhiyun dev2screen[k++] = l;
747*4882a593Smuzhiyun break;
748*4882a593Smuzhiyun }
749*4882a593Smuzhiyun }
750*4882a593Smuzhiyun }
751*4882a593Smuzhiyun }
752*4882a593Smuzhiyun free(driverProbed);
753*4882a593Smuzhiyun }
754*4882a593Smuzhiyun
755*4882a593Smuzhiyun if (nDevToConfig != xf86NumScreens) {
756*4882a593Smuzhiyun ErrorF("Number of created screens does not match number of detected"
757*4882a593Smuzhiyun " devices.\n Configuration failed.\n");
758*4882a593Smuzhiyun goto bail;
759*4882a593Smuzhiyun }
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun xf86PostProbe();
762*4882a593Smuzhiyun
763*4882a593Smuzhiyun for (j = 0; j < xf86NumScreens; j++) {
764*4882a593Smuzhiyun xf86Screens[j]->scrnIndex = j;
765*4882a593Smuzhiyun }
766*4882a593Smuzhiyun
767*4882a593Smuzhiyun xf86freeMonitorList(xf86config->conf_monitor_lst);
768*4882a593Smuzhiyun xf86config->conf_monitor_lst = NULL;
769*4882a593Smuzhiyun xf86freeScreenList(xf86config->conf_screen_lst);
770*4882a593Smuzhiyun xf86config->conf_screen_lst = NULL;
771*4882a593Smuzhiyun for (j = 0; j < xf86NumScreens; j++) {
772*4882a593Smuzhiyun XF86ConfMonitorPtr monitor_ptr;
773*4882a593Smuzhiyun XF86ConfScreenPtr screen_ptr;
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun ConfiguredMonitor = NULL;
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun if ((*xf86Screens[dev2screen[j]]->PreInit) &&
778*4882a593Smuzhiyun (*xf86Screens[dev2screen[j]]->PreInit) (xf86Screens[dev2screen[j]],
779*4882a593Smuzhiyun PROBE_DETECT) &&
780*4882a593Smuzhiyun ConfiguredMonitor) {
781*4882a593Smuzhiyun monitor_ptr = configureDDCMonitorSection(j);
782*4882a593Smuzhiyun }
783*4882a593Smuzhiyun else {
784*4882a593Smuzhiyun monitor_ptr = configureMonitorSection(j);
785*4882a593Smuzhiyun }
786*4882a593Smuzhiyun screen_ptr = configureScreenSection(j);
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun xf86config->conf_monitor_lst = (XF86ConfMonitorPtr) xf86addListItem((glp) xf86config->conf_monitor_lst, (glp) monitor_ptr);
789*4882a593Smuzhiyun xf86config->conf_screen_lst = (XF86ConfScreenPtr) xf86addListItem((glp)
790*4882a593Smuzhiyun xf86config->
791*4882a593Smuzhiyun conf_screen_lst,
792*4882a593Smuzhiyun (glp)
793*4882a593Smuzhiyun screen_ptr);
794*4882a593Smuzhiyun }
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun if (xf86writeConfigFile(filename, xf86config) == 0) {
797*4882a593Smuzhiyun xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
798*4882a593Smuzhiyun filename, strerror(errno));
799*4882a593Smuzhiyun goto bail;
800*4882a593Smuzhiyun }
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun ErrorF("\n");
803*4882a593Smuzhiyun
804*4882a593Smuzhiyun if (!foundMouse) {
805*4882a593Smuzhiyun ErrorF("\n" __XSERVERNAME__ " is not able to detect your mouse.\n"
806*4882a593Smuzhiyun "Edit the file and correct the Device.\n");
807*4882a593Smuzhiyun }
808*4882a593Smuzhiyun else {
809*4882a593Smuzhiyun ErrorF("\n" __XSERVERNAME__ " detected your mouse at device %s.\n"
810*4882a593Smuzhiyun "Please check your config if the mouse is still not\n"
811*4882a593Smuzhiyun "operational, as by default " __XSERVERNAME__
812*4882a593Smuzhiyun " tries to autodetect\n" "the protocol.\n", DFLT_MOUSE_DEV);
813*4882a593Smuzhiyun }
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun if (xf86NumScreens > 1) {
816*4882a593Smuzhiyun ErrorF("\n" __XSERVERNAME__
817*4882a593Smuzhiyun " has configured a multihead system, please check your config.\n");
818*4882a593Smuzhiyun }
819*4882a593Smuzhiyun
820*4882a593Smuzhiyun ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE, filename);
821*4882a593Smuzhiyun ErrorF("To test the server, run 'X -config %s'\n\n", filename);
822*4882a593Smuzhiyun
823*4882a593Smuzhiyun bail:
824*4882a593Smuzhiyun OsCleanup(TRUE);
825*4882a593Smuzhiyun AbortDDX(EXIT_ERR_CONFIGURE);
826*4882a593Smuzhiyun fflush(stderr);
827*4882a593Smuzhiyun exit(0);
828*4882a593Smuzhiyun }
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun /* Xorg -showopts:
831*4882a593Smuzhiyun * For each driver module installed, print out the list
832*4882a593Smuzhiyun * of options and their argument types, then exit
833*4882a593Smuzhiyun *
834*4882a593Smuzhiyun * Author: Marcus Schaefer, ms@suse.de
835*4882a593Smuzhiyun */
836*4882a593Smuzhiyun
837*4882a593Smuzhiyun void
DoShowOptions(void)838*4882a593Smuzhiyun DoShowOptions(void)
839*4882a593Smuzhiyun {
840*4882a593Smuzhiyun int i = 0;
841*4882a593Smuzhiyun const char **vlist = NULL;
842*4882a593Smuzhiyun char *pSymbol = 0;
843*4882a593Smuzhiyun XF86ModuleData *initData = 0;
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun if (!(vlist = GenerateDriverList())) {
846*4882a593Smuzhiyun ErrorF("Missing output drivers\n");
847*4882a593Smuzhiyun goto bail;
848*4882a593Smuzhiyun }
849*4882a593Smuzhiyun xf86LoadModules(vlist, 0);
850*4882a593Smuzhiyun free(vlist);
851*4882a593Smuzhiyun for (i = 0; i < xf86NumDrivers; i++) {
852*4882a593Smuzhiyun if (xf86DriverList[i]->AvailableOptions) {
853*4882a593Smuzhiyun const OptionInfoRec *pOption =
854*4882a593Smuzhiyun (*xf86DriverList[i]->AvailableOptions) (0, 0);
855*4882a593Smuzhiyun if (!pOption) {
856*4882a593Smuzhiyun ErrorF("(EE) Couldn't read option table for %s driver\n",
857*4882a593Smuzhiyun xf86DriverList[i]->driverName);
858*4882a593Smuzhiyun continue;
859*4882a593Smuzhiyun }
860*4882a593Smuzhiyun XNFasprintf(&pSymbol, "%sModuleData",
861*4882a593Smuzhiyun xf86DriverList[i]->driverName);
862*4882a593Smuzhiyun initData = LoaderSymbol(pSymbol);
863*4882a593Smuzhiyun if (initData) {
864*4882a593Smuzhiyun XF86ModuleVersionInfo *vers = initData->vers;
865*4882a593Smuzhiyun const OptionInfoRec *p;
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun ErrorF("Driver[%d]:%s[%s] {\n",
868*4882a593Smuzhiyun i, xf86DriverList[i]->driverName, vers->vendor);
869*4882a593Smuzhiyun for (p = pOption; p->name != NULL; p++) {
870*4882a593Smuzhiyun ErrorF("\t%s:%s\n", p->name, optionTypeToString(p->type));
871*4882a593Smuzhiyun }
872*4882a593Smuzhiyun ErrorF("}\n");
873*4882a593Smuzhiyun }
874*4882a593Smuzhiyun }
875*4882a593Smuzhiyun }
876*4882a593Smuzhiyun bail:
877*4882a593Smuzhiyun OsCleanup(TRUE);
878*4882a593Smuzhiyun AbortDDX(EXIT_ERR_DRIVERS);
879*4882a593Smuzhiyun fflush(stderr);
880*4882a593Smuzhiyun exit(0);
881*4882a593Smuzhiyun }
882