Commit | Line | Data |
---|---|---|
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 | ||
44 | typedef 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 | ||
53 | static DevToConfigPtr DevToConfig = NULL; | |
54 | static int nDevToConfig = 0, CurrentDriver; | |
55 | ||
56 | xf86MonPtr ConfiguredMonitor; | |
57 | Bool xf86DoConfigurePass1 = TRUE; | |
58 | static Bool foundMouse = FALSE; | |
59 | ||
60 | #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) | |
61 | static const char *DFLT_MOUSE_DEV = "/dev/sysmouse"; | |
62 | static const char *DFLT_MOUSE_PROTO = "auto"; | |
63 | #elif defined(linux) | |
64 | static const char *DFLT_MOUSE_DEV = "/dev/input/mice"; | |
65 | static const char *DFLT_MOUSE_PROTO = "auto"; | |
66 | #elif defined(WSCONS_SUPPORT) | |
67 | static const char *DFLT_MOUSE_DEV = "/dev/wsmouse"; | |
68 | static const char *DFLT_MOUSE_PROTO = "wsmouse"; | |
69 | #else | |
70 | static const char *DFLT_MOUSE_DEV = "/dev/mouse"; | |
71 | static 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 | */ | |
79 | GDevPtr | |
80 | xf86AddBusDeviceToConfigure(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 | ||
153 | static XF86ConfInputPtr | |
154 | configureInputSection(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 | ||
191 | static XF86ConfScreenPtr | |
192 | configureScreenSection(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 | ||
219 | static const char * | |
220 | optionTypeToString(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 | ||
244 | static XF86ConfDevicePtr | |
245 | configureDeviceSection(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 | ||
317 | static XF86ConfLayoutPtr | |
318 | configureLayoutSection(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 | ||
379 | static XF86ConfFlagsPtr | |
380 | configureFlagsSection(void) | |
381 | { | |
382 | parsePrologue(XF86ConfFlagsPtr, XF86ConfFlagsRec) | |
383 | ||
384 | return ptr; | |
385 | } | |
386 | ||
387 | static XF86ConfModulePtr | |
388 | configureModuleSection(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 | ||
417 | static XF86ConfFilesPtr | |
418 | configureFilesSection(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 | ||
430 | static XF86ConfMonitorPtr | |
431 | configureMonitorSection(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 */ | |
443 | static void | |
444 | handle_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 | ||
467 | static XF86ConfMonitorPtr | |
468 | configureDDCMonitorSection(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 | ||
523 | void | |
524 | DoConfigure(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 | ||
765 | void | |
766 | DoShowOptions(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 | } |