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