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