Initial commit
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / common / xf86Configure.c
blob19f040b0364db43f63504bdfda8097eb94dd8c05
1 /*
2 * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
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.
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.
22 * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
26 #ifdef HAVE_XORG_CONFIG_H
27 #include <xorg-config.h>
28 #endif
30 #include <ctype.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <X11/X.h>
37 #include <X11/Xmd.h>
38 #include "os.h"
39 #include "loaderProcs.h"
40 #include "xf86.h"
41 #include "xf86Config.h"
42 #include "xf86_OSlib.h"
43 #include "xf86Priv.h"
44 #include "xf86PciData.h"
45 #define IN_XSERVER
46 #include "xf86Parser.h"
47 #include "xf86tokens.h"
48 #include "Configint.h"
49 #include "vbe.h"
50 #include "xf86DDC.h"
51 #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
52 #include "xf86Bus.h"
53 #include "xf86Sbus.h"
54 #endif
55 #include "globals.h"
57 typedef struct _DevToConfig {
58 GDevRec GDev;
59 pciVideoPtr pVideo;
60 #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
61 sbusDevicePtr sVideo;
62 #endif
63 int iDriver;
64 } DevToConfigRec, *DevToConfigPtr;
66 static DevToConfigPtr DevToConfig = NULL;
67 static int nDevToConfig = 0, CurrentDriver;
69 _X_EXPORT xf86MonPtr ConfiguredMonitor;
70 Bool xf86DoConfigurePass1 = TRUE;
71 static Bool foundMouse = FALSE;
73 #if defined(__SCO__)
74 static char *DFLT_MOUSE_PROTO = "OSMouse";
75 #elif defined(__UNIXWARE__)
76 static char *DFLT_MOUSE_PROTO = "OSMouse";
77 static char *DFLT_MOUSE_DEV = "/dev/mouse";
78 #elif defined(QNX4)
79 static char *DFLT_MOUSE_PROTO = "OSMouse";
80 static char *DFLT_MOUSE_DEV = "/dev/mouse";
81 #elif defined(__QNXNTO__)
82 static char *DFLT_MOUSE_PROTO = "OSMouse";
83 static char *DFLT_MOUSE_DEV = "/dev/devi/mouse0";
84 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
85 static char *DFLT_MOUSE_DEV = "/dev/sysmouse";
86 static char *DFLT_MOUSE_PROTO = "auto";
87 #elif defined(linux)
88 static char DFLT_MOUSE_DEV[] = "/dev/input/mice";
89 static char DFLT_MOUSE_PROTO[] = "auto";
90 #else
91 static char *DFLT_MOUSE_DEV = "/dev/mouse";
92 static char *DFLT_MOUSE_PROTO = "auto";
93 #endif
96 * This is called by the driver, either through xf86Match???Instances() or
97 * directly. We allocate a GDevRec and fill it in as much as we can, letting
98 * the caller fill in the rest and/or change it as it sees fit.
100 GDevPtr
101 xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset)
103 int i, j;
104 pciVideoPtr pVideo = NULL;
105 Bool isPrimary = FALSE;
107 if (xf86DoProbe || !xf86DoConfigure || !xf86DoConfigurePass1)
108 return NULL;
110 /* Check for duplicates */
111 switch (bus) {
112 case BUS_PCI:
113 pVideo = (pciVideoPtr) busData;
114 for (i = 0; i < nDevToConfig; i++)
115 if (DevToConfig[i].pVideo &&
116 (DevToConfig[i].pVideo->bus == pVideo->bus) &&
117 (DevToConfig[i].pVideo->device == pVideo->device) &&
118 (DevToConfig[i].pVideo->func == pVideo->func))
119 return NULL;
120 isPrimary = xf86IsPrimaryPci(pVideo);
121 break;
122 case BUS_ISA:
124 * This needs to be revisited as it doesn't allow for non-PCI
125 * multihead.
127 if (!xf86IsPrimaryIsa())
128 return NULL;
129 isPrimary = TRUE;
130 for (i = 0; i < nDevToConfig; i++)
131 if (!DevToConfig[i].pVideo)
132 return NULL;
133 break;
134 #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
135 case BUS_SBUS:
136 for (i = 0; i < nDevToConfig; i++)
137 if (DevToConfig[i].sVideo &&
138 DevToConfig[i].sVideo->fbNum == ((sbusDevicePtr) busData)->fbNum)
139 return NULL;
140 break;
141 #endif
142 default:
143 return NULL;
146 /* Allocate new structure occurrence */
147 i = nDevToConfig++;
148 DevToConfig =
149 xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
150 #if 1 /* Doesn't work when a driver detects more than one adapter */
151 if ((i > 0) && isPrimary) {
152 memmove(DevToConfig + 1,DevToConfig,
153 (nDevToConfig - 1) * sizeof(DevToConfigRec));
154 i = 0;
156 #endif
157 memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
159 # define NewDevice DevToConfig[i]
161 NewDevice.GDev.chipID = NewDevice.GDev.chipRev = NewDevice.GDev.irq = -1;
163 NewDevice.iDriver = CurrentDriver;
165 /* Fill in what we know, converting the driver name to lower case */
166 NewDevice.GDev.driver = xnfalloc(strlen(driver) + 1);
167 for (j = 0; (NewDevice.GDev.driver[j] = tolower(driver[j])); j++);
169 switch (bus) {
170 case BUS_PCI: {
171 const char *VendorName;
172 const char *CardName;
173 char busnum[8];
175 NewDevice.pVideo = pVideo;
176 xf86FindPciNamesByDevice(pVideo->vendor, pVideo->chipType,
177 NOVENDOR, NOSUBSYS,
178 &VendorName, &CardName, NULL, NULL);
180 if (!VendorName) {
181 VendorName = xnfalloc(15);
182 sprintf((char*)VendorName, "Unknown Vendor");
185 if (!CardName) {
186 CardName = xnfalloc(14);
187 sprintf((char*)CardName, "Unknown Board");
190 NewDevice.GDev.identifier =
191 xnfalloc(strlen(VendorName) + strlen(CardName) + 2);
192 sprintf(NewDevice.GDev.identifier, "%s %s", VendorName, CardName);
194 NewDevice.GDev.vendor = (char *)VendorName;
195 NewDevice.GDev.board = (char *)CardName;
197 NewDevice.GDev.busID = xnfalloc(16);
198 xf86FormatPciBusNumber(pVideo->bus, busnum);
199 sprintf(NewDevice.GDev.busID, "PCI:%s:%d:%d",
200 busnum, pVideo->device, pVideo->func);
202 NewDevice.GDev.chipID = pVideo->chipType;
203 NewDevice.GDev.chipRev = pVideo->chipRev;
205 if (chipset < 0)
206 chipset = (pVideo->vendor << 16) | pVideo->chipType;
208 break;
209 case BUS_ISA:
210 NewDevice.GDev.identifier = "ISA Adapter";
211 NewDevice.GDev.busID = "ISA";
212 break;
213 #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
214 case BUS_SBUS: {
215 char *promPath = NULL;
216 NewDevice.sVideo = (sbusDevicePtr) busData;
217 NewDevice.GDev.identifier = NewDevice.sVideo->descr;
218 if (sparcPromInit() >= 0) {
219 promPath = sparcPromNode2Pathname(&NewDevice.sVideo->node);
220 sparcPromClose();
222 if (promPath) {
223 NewDevice.GDev.busID = xnfalloc(strlen(promPath) + 6);
224 sprintf(NewDevice.GDev.busID, "SBUS:%s", promPath);
225 xfree(promPath);
226 } else {
227 NewDevice.GDev.busID = xnfalloc(12);
228 sprintf(NewDevice.GDev.busID, "SBUS:fb%d", NewDevice.sVideo->fbNum);
231 break;
232 #endif
233 default:
234 break;
237 /* Get driver's available options */
238 if (xf86DriverList[CurrentDriver]->AvailableOptions)
239 NewDevice.GDev.options = (OptionInfoPtr)
240 (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset,
241 bus);
243 return &NewDevice.GDev;
245 # undef NewDevice
249 * Backwards compatibility
251 _X_EXPORT GDevPtr
252 xf86AddDeviceToConfigure(const char *driver, pciVideoPtr pVideo, int chipset)
254 return xf86AddBusDeviceToConfigure(driver, pVideo ? BUS_PCI : BUS_ISA,
255 pVideo, chipset);
258 static XF86ConfInputPtr
259 configureInputSection (void)
261 XF86ConfInputPtr mouse = NULL;
262 parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
264 ptr->inp_identifier = "Keyboard0";
265 ptr->inp_driver = "kbd";
266 ptr->list.next = NULL;
268 /* Crude mechanism to auto-detect mouse (os dependent) */
270 int fd;
271 #ifdef WSCONS_SUPPORT
272 fd = open("/dev/wsmouse", 0);
273 if (fd > 0) {
274 DFLT_MOUSE_DEV = "/dev/wsmouse";
275 DFLT_MOUSE_PROTO = "wsmouse";
276 close(fd);
277 } else {
278 ErrorF("cannot open /dev/wsmouse\n");
280 #endif
282 #ifndef __SCO__
283 fd = open(DFLT_MOUSE_DEV, 0);
284 if (fd != -1) {
285 foundMouse = TRUE;
286 close(fd);
288 #else
289 foundMouse = TRUE;
290 #endif
293 mouse = xf86confmalloc(sizeof(XF86ConfInputRec));
294 memset((XF86ConfInputPtr)mouse,0,sizeof(XF86ConfInputRec));
295 mouse->inp_identifier = "Mouse0";
296 mouse->inp_driver = "mouse";
297 mouse->inp_option_lst =
298 xf86addNewOption(mouse->inp_option_lst, xstrdup("Protocol"),
299 xstrdup(DFLT_MOUSE_PROTO));
300 #ifndef __SCO__
301 mouse->inp_option_lst =
302 xf86addNewOption(mouse->inp_option_lst, xstrdup("Device"),
303 xstrdup(DFLT_MOUSE_DEV));
304 #endif
305 mouse->inp_option_lst =
306 xf86addNewOption(mouse->inp_option_lst, xstrdup("ZAxisMapping"),
307 xstrdup("4 5 6 7"));
308 ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse);
309 return ptr;
312 static XF86ConfScreenPtr
313 configureScreenSection (int screennum)
315 int i;
316 int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ };
317 parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
319 ptr->scrn_identifier = xf86confmalloc(18);
320 sprintf(ptr->scrn_identifier, "Screen%d", screennum);
321 ptr->scrn_monitor_str = xf86confmalloc(19);
322 sprintf(ptr->scrn_monitor_str, "Monitor%d", screennum);
323 ptr->scrn_device_str = xf86confmalloc(16);
324 sprintf(ptr->scrn_device_str, "Card%d", screennum);
326 for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++)
328 XF86ConfDisplayPtr display;
330 display = xf86confmalloc(sizeof(XF86ConfDisplayRec));
331 memset((XF86ConfDisplayPtr)display,0,sizeof(XF86ConfDisplayRec));
332 display->disp_depth = depths[i];
333 display->disp_black.red = display->disp_white.red = -1;
334 display->disp_black.green = display->disp_white.green = -1;
335 display->disp_black.blue = display->disp_white.blue = -1;
336 ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem(
337 (glp)ptr->scrn_display_lst, (glp)display);
340 return ptr;
343 static const char*
344 optionTypeToSting(OptionValueType type)
346 switch (type) {
347 case OPTV_NONE:
348 return "";
349 case OPTV_INTEGER:
350 return "<i>";
351 case OPTV_STRING:
352 return "<str>";
353 case OPTV_ANYSTR:
354 return "[<str>]";
355 case OPTV_REAL:
356 return "<f>";
357 case OPTV_BOOLEAN:
358 return "[<bool>]";
359 case OPTV_FREQ:
360 return "<freq>";
361 default:
362 return "";
366 static XF86ConfDevicePtr
367 configureDeviceSection (int screennum)
369 char identifier[16];
370 OptionInfoPtr p;
371 int i = 0;
372 #ifdef DO_FBDEV_PROBE
373 Bool foundFBDEV = FALSE;
374 #endif
375 parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
377 /* Move device info to parser structure */
378 sprintf(identifier, "Card%d", screennum);
379 ptr->dev_identifier = strdup(identifier);
380 /* ptr->dev_identifier = DevToConfig[screennum].GDev.identifier;*/
381 ptr->dev_vendor = DevToConfig[screennum].GDev.vendor;
382 ptr->dev_board = DevToConfig[screennum].GDev.board;
383 ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
384 ptr->dev_busid = DevToConfig[screennum].GDev.busID;
385 ptr->dev_driver = DevToConfig[screennum].GDev.driver;
386 ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
387 for (i = 0; (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS); i++)
388 ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
389 ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
390 ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq;
391 ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase;
392 ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase;
393 ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase;
394 ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip;
395 for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); i++)
396 ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i];
397 ptr->dev_clocks = i;
398 ptr->dev_chipid = DevToConfig[screennum].GDev.chipID;
399 ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev;
400 ptr->dev_irq = DevToConfig[screennum].GDev.irq;
402 /* Make sure older drivers don't segv */
403 if (DevToConfig[screennum].GDev.options) {
404 /* Fill in the available driver options for people to use */
405 const char *descrip =
406 " ### Available Driver options are:-\n"
407 " ### Values: <i>: integer, <f>: float, "
408 "<bool>: \"True\"/\"False\",\n"
409 " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\"\n"
410 " ### [arg]: arg optional\n";
411 ptr->dev_comment = xstrdup(descrip);
412 if (ptr->dev_comment) {
413 for (p = DevToConfig[screennum].GDev.options;
414 p->name != NULL; p++) {
415 char *p_e;
416 const char *prefix = " #Option ";
417 const char *middle = " \t# ";
418 const char *suffix = "\n";
419 const char *opttype = optionTypeToSting(p->type);
420 char *optname;
421 int len = strlen(ptr->dev_comment) + strlen(prefix) +
422 strlen(middle) + strlen(suffix) + 1;
424 optname = xalloc(strlen(p->name) + 2 + 1);
425 if (!optname)
426 break;
427 sprintf(optname, "\"%s\"", p->name);
429 len += max(20, strlen(optname));
430 len += strlen(opttype);
432 ptr->dev_comment = xrealloc(ptr->dev_comment, len);
433 if (!ptr->dev_comment)
434 break;
435 p_e = ptr->dev_comment + strlen(ptr->dev_comment);
436 sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle,
437 opttype, suffix);
438 xfree(optname);
443 #ifdef DO_FBDEV_PROBE
444 /* Crude mechanism to auto-detect fbdev (os dependent) */
445 /* Skip it for now. Options list it anyway, and we can't
446 * determine which screen/driver this belongs too anyway. */
448 int fd;
450 fd = open("/dev/fb0", 0);
451 if (fd != -1) {
452 foundFBDEV = TRUE;
453 close(fd);
457 if (foundFBDEV) {
458 XF86OptionPtr fbdev;
460 fbdev = xf86confmalloc(sizeof(XF86OptionRec));
461 memset((XF86OptionPtr)fbdev,0,sizeof(XF86OptionRec));
462 fbdev->opt_name = "UseFBDev";
463 fbdev->opt_val = "ON";
464 ptr->dev_option_lst = (XF86OptionPtr)xf86addListItem(
465 (glp)ptr->dev_option_lst, (glp)fbdev);
467 #endif
469 return ptr;
472 static XF86ConfLayoutPtr
473 configureLayoutSection (void)
475 int scrnum = 0;
476 parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
478 ptr->lay_identifier = "X.org Configured";
481 XF86ConfInputrefPtr iptr;
483 iptr = xf86confmalloc (sizeof (XF86ConfInputrefRec));
484 iptr->list.next = NULL;
485 iptr->iref_option_lst = NULL;
486 iptr->iref_inputdev_str = "Mouse0";
487 iptr->iref_option_lst =
488 xf86addNewOption (iptr->iref_option_lst, xstrdup("CorePointer"), NULL);
489 ptr->lay_input_lst = (XF86ConfInputrefPtr)
490 xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
494 XF86ConfInputrefPtr iptr;
496 iptr = xf86confmalloc (sizeof (XF86ConfInputrefRec));
497 iptr->list.next = NULL;
498 iptr->iref_option_lst = NULL;
499 iptr->iref_inputdev_str = "Keyboard0";
500 iptr->iref_option_lst =
501 xf86addNewOption (iptr->iref_option_lst, xstrdup("CoreKeyboard"), NULL);
502 ptr->lay_input_lst = (XF86ConfInputrefPtr)
503 xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
506 for (scrnum = 0; scrnum < nDevToConfig; scrnum++) {
507 XF86ConfAdjacencyPtr aptr;
509 aptr = xf86confmalloc (sizeof (XF86ConfAdjacencyRec));
510 aptr->list.next = NULL;
511 aptr->adj_x = 0;
512 aptr->adj_y = 0;
513 aptr->adj_scrnum = scrnum;
514 aptr->adj_screen_str = xnfalloc(18);
515 sprintf(aptr->adj_screen_str, "Screen%d", scrnum);
516 if (scrnum == 0) {
517 aptr->adj_where = CONF_ADJ_ABSOLUTE;
518 aptr->adj_refscreen = NULL;
520 else {
521 aptr->adj_where = CONF_ADJ_RIGHTOF;
522 aptr->adj_refscreen = xnfalloc(18);
523 sprintf(aptr->adj_refscreen, "Screen%d", scrnum - 1);
525 ptr->lay_adjacency_lst =
526 (XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst,
527 (glp)aptr);
530 return ptr;
533 static XF86ConfFlagsPtr
534 configureFlagsSection (void)
536 parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
538 return ptr;
541 static XF86ConfModulePtr
542 configureModuleSection (void)
544 char **elist, **el;
545 /* Find the list of extension modules. */
546 const char *esubdirs[] = {
547 "extensions",
548 NULL
550 const char *fsubdirs[] = {
551 "fonts",
552 NULL
554 parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
556 elist = LoaderListDirs(esubdirs, NULL);
557 if (elist) {
558 for (el = elist; *el; el++) {
559 XF86LoadPtr module;
561 module = xf86confmalloc(sizeof(XF86LoadRec));
562 memset((XF86LoadPtr)module,0,sizeof(XF86LoadRec));
563 module->load_name = *el;
564 ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
565 (glp)ptr->mod_load_lst, (glp)module);
567 xfree(elist);
570 /* Process list of font backends separately to include only required ones */
571 elist = LoaderListDirs(fsubdirs, NULL);
572 if (elist) {
573 for (el = elist; *el; el++) {
574 XF86LoadPtr module;
576 module = xf86confmalloc(sizeof(XF86LoadRec));
577 memset((XF86LoadPtr)module,0,sizeof(XF86LoadRec));
578 module->load_name = *el;
580 /* Add only those font backends which are referenced by fontpath */
581 /* 'strstr(dFP,"/dir")' is meant as 'dFP =~ m(/dir\W)' */
582 if (defaultFontPath && (
583 (strcmp(*el, "freetype") == 0 &&
584 strstr(defaultFontPath, "/TTF")) ||
585 (strcmp(*el, "type1") == 0 &&
586 strstr(defaultFontPath, "/Type1"))))
587 ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
588 (glp)ptr->mod_load_lst, (glp)module);
590 xfree(elist);
593 return ptr;
596 static XF86ConfFilesPtr
597 configureFilesSection (void)
599 parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
601 if (xf86ModulePath)
602 ptr->file_modulepath = strdup(xf86ModulePath);
603 if (defaultFontPath)
604 ptr->file_fontpath = strdup(defaultFontPath);
605 if (rgbPath)
606 ptr->file_rgbpath = strdup(rgbPath);
608 return ptr;
611 static XF86ConfMonitorPtr
612 configureMonitorSection (int screennum)
614 parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
616 ptr->mon_identifier = xf86confmalloc(19);
617 sprintf(ptr->mon_identifier, "Monitor%d", screennum);
618 ptr->mon_vendor = strdup("Monitor Vendor");
619 ptr->mon_modelname = strdup("Monitor Model");
621 return ptr;
624 static XF86ConfMonitorPtr
625 configureDDCMonitorSection (int screennum)
627 int i = 0;
628 int len, mon_width, mon_height;
629 #define displaySizeMaxLen 80
630 char displaySize_string[displaySizeMaxLen];
631 int displaySizeLen;
633 parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
635 ptr->mon_identifier = xf86confmalloc(19);
636 sprintf(ptr->mon_identifier, "Monitor%d", screennum);
637 ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
638 ptr->mon_modelname = xf86confmalloc(12);
639 sprintf(ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
641 /* features in centimetres, we want millimetres */
642 mon_width = 10 * ConfiguredMonitor->features.hsize ;
643 mon_height = 10 * ConfiguredMonitor->features.vsize ;
645 #ifdef CONFIGURE_DISPLAYSIZE
646 ptr->mon_width = mon_width;
647 ptr->mon_height = mon_height;
648 #else
649 if (mon_width && mon_height) {
650 /* when values available add DisplaySize option AS A COMMENT */
652 displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen,
653 "\t#DisplaySize\t%5d %5d\t# mm\n",
654 mon_width, mon_height);
656 if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) {
657 if (ptr->mon_comment) {
658 len = strlen(ptr->mon_comment);
659 } else {
660 len = 0;
662 if ((ptr->mon_comment =
663 xf86confrealloc(ptr->mon_comment,
664 len+strlen(displaySize_string)))) {
665 strcpy(ptr->mon_comment + len, displaySize_string);
669 #endif /* def CONFIGURE_DISPLAYSIZE */
671 for (i=0;i<4;i++) {
672 switch (ConfiguredMonitor->det_mon[i].type) {
673 case DS_NAME:
674 ptr->mon_modelname = xf86confrealloc(ptr->mon_modelname,
675 strlen((char*)(ConfiguredMonitor->det_mon[i].section.name))
676 + 1);
677 strcpy(ptr->mon_modelname,
678 (char*)(ConfiguredMonitor->det_mon[i].section.name));
679 break;
680 case DS_RANGES:
681 ptr->mon_hsync[ptr->mon_n_hsync].lo =
682 ConfiguredMonitor->det_mon[i].section.ranges.min_h;
683 ptr->mon_hsync[ptr->mon_n_hsync].hi =
684 ConfiguredMonitor->det_mon[i].section.ranges.max_h;
685 ptr->mon_n_vrefresh = 1;
686 ptr->mon_vrefresh[ptr->mon_n_hsync].lo =
687 ConfiguredMonitor->det_mon[i].section.ranges.min_v;
688 ptr->mon_vrefresh[ptr->mon_n_hsync].hi =
689 ConfiguredMonitor->det_mon[i].section.ranges.max_v;
690 ptr->mon_n_hsync++;
691 default:
692 break;
696 if (ConfiguredMonitor->features.dpms) {
697 ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, xstrdup("DPMS"), NULL);
700 return ptr;
703 void
704 DoConfigure()
706 int i,j, screennum = -1;
707 char *home = NULL;
708 char *filename = NULL;
709 XF86ConfigPtr xf86config = NULL;
710 char **vlist, **vl;
711 int *dev2screen;
713 vlist = xf86DriverlistFromCompile();
715 if (!vlist) {
716 ErrorF("Missing output drivers. Configuration failed.\n");
717 goto bail;
720 ErrorF("List of video drivers:\n");
721 for (vl = vlist; *vl; vl++)
722 ErrorF("\t%s\n", *vl);
724 /* Load all the drivers that were found. */
725 xf86LoadModules(vlist, NULL);
727 xfree(vlist);
729 for (i = 0; i < xf86NumDrivers; i++) {
730 xorgHWFlags flags;
731 if (!xf86DriverList[i]->driverFunc
732 || !xf86DriverList[i]->driverFunc(NULL,
733 GET_REQUIRED_HW_INTERFACES,
734 &flags)
735 || NEED_IO_ENABLED(flags)) {
736 xorgHWAccess = TRUE;
737 break;
740 /* Enable full I/O access */
741 if (xorgHWAccess) {
742 if(!xf86EnableIO())
743 /* oops, we have failed */
744 xorgHWAccess = FALSE;
747 /* Disable PCI devices */
748 xf86ResourceBrokerInit();
749 xf86AccessInit();
750 xf86FindPrimaryDevice();
752 /* Create XF86Config file structure */
753 xf86config = malloc(sizeof(XF86ConfigRec));
754 memset ((XF86ConfigPtr)xf86config, 0, sizeof(XF86ConfigRec));
755 xf86config->conf_device_lst = NULL;
756 xf86config->conf_screen_lst = NULL;
757 xf86config->conf_monitor_lst = NULL;
759 /* Call all of the probe functions, reporting the results. */
760 for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) {
761 xorgHWFlags flags;
763 if (!xorgHWAccess) {
764 if (!xf86DriverList[CurrentDriver]->driverFunc
765 || !xf86DriverList[CurrentDriver]->driverFunc(NULL,
766 GET_REQUIRED_HW_INTERFACES,
767 &flags)
768 || NEED_IO_ENABLED(flags))
769 continue;
772 if (xf86DriverList[CurrentDriver]->Probe == NULL) continue;
774 if ((*xf86DriverList[CurrentDriver]->Probe)(
775 xf86DriverList[CurrentDriver], PROBE_DETECT) &&
776 xf86DriverList[CurrentDriver]->Identify)
777 (*xf86DriverList[CurrentDriver]->Identify)(0);
780 if (nDevToConfig <= 0) {
781 ErrorF("No devices to configure. Configuration failed.\n");
782 goto bail;
785 /* Add device, monitor and screen sections for detected devices */
786 for (screennum = 0; screennum < nDevToConfig; screennum++) {
787 XF86ConfDevicePtr DevicePtr;
788 XF86ConfMonitorPtr MonitorPtr;
789 XF86ConfScreenPtr ScreenPtr;
791 DevicePtr = configureDeviceSection(screennum);
792 xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem(
793 (glp)xf86config->conf_device_lst, (glp)DevicePtr);
794 MonitorPtr = configureMonitorSection(screennum);
795 xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
796 (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
797 ScreenPtr = configureScreenSection(screennum);
798 xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
799 (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
802 xf86config->conf_files = configureFilesSection();
803 xf86config->conf_modules = configureModuleSection();
804 xf86config->conf_flags = configureFlagsSection();
805 xf86config->conf_videoadaptor_lst = NULL;
806 xf86config->conf_modes_lst = NULL;
807 xf86config->conf_vendor_lst = NULL;
808 xf86config->conf_dri = NULL;
809 xf86config->conf_input_lst = configureInputSection();
810 xf86config->conf_layout_lst = configureLayoutSection();
812 if (!(home = getenv("HOME")))
813 home = "/";
815 #if !defined(PATH_MAX)
816 #define PATH_MAX 1024
817 #endif
818 const char* configfile = XF86CONFIGFILE".new";
819 char homebuf[PATH_MAX];
820 /* getenv might return R/O memory, as with OS/2 */
821 strncpy(homebuf,home,PATH_MAX-1);
822 homebuf[PATH_MAX-1] = '\0';
823 home = homebuf;
824 if (!(filename =
825 (char *)ALLOCATE_LOCAL(strlen(home) +
826 strlen(configfile) + 3)))
828 if (home[0] == '/' && home[1] == '\0')
829 home[0] = '\0';
830 #ifndef QNX4
831 sprintf(filename, "%s/%s", home,configfile);
832 #else
833 sprintf(filename, "//%d%s/%s", getnid(),home,configfile);
834 #endif
838 xf86writeConfigFile(filename, xf86config);
840 xf86DoConfigurePass1 = FALSE;
841 /* Try to get DDC information filled in */
842 xf86ConfigFile = filename;
843 if (xf86HandleConfigFile(FALSE) != CONFIG_OK) {
844 goto bail;
847 xf86DoConfigurePass1 = FALSE;
849 dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int));
852 Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool));
853 for (screennum = 0; screennum < nDevToConfig; screennum++) {
854 int k,l,n,oldNumScreens;
856 i = DevToConfig[screennum].iDriver;
858 if (driverProbed[i]) continue;
859 driverProbed[i] = TRUE;
861 oldNumScreens = xf86NumScreens;
863 (*xf86DriverList[i]->Probe)(xf86DriverList[i], 0);
865 /* reorder */
866 k = screennum > 0 ? screennum : 1;
867 for (l = oldNumScreens; l < xf86NumScreens; l++) {
868 /* is screen primary? */
869 Bool primary = FALSE;
870 for (n = 0; n<xf86Screens[l]->numEntities; n++) {
871 if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) {
872 dev2screen[0] = l;
873 primary = TRUE;
874 break;
877 if (primary) continue;
878 /* not primary: assign it to next device of same driver */
880 * NOTE: we assume that devices in DevToConfig
881 * and xf86Screens[] have the same order except
882 * for the primary device which always comes first.
884 for (; k < nDevToConfig; k++) {
885 if (DevToConfig[k].iDriver == i) {
886 dev2screen[k++] = l;
887 break;
891 xf86SetPciVideo(NULL,NONE);
893 xfree(driverProbed);
897 if (nDevToConfig != xf86NumScreens) {
898 ErrorF("Number of created screens does not match number of detected"
899 " devices.\n Configuration failed.\n");
900 goto bail;
903 xf86PostProbe();
904 xf86EntityInit();
906 for (j = 0; j < xf86NumScreens; j++) {
907 xf86Screens[j]->scrnIndex = j;
910 xf86freeMonitorList(xf86config->conf_monitor_lst);
911 xf86config->conf_monitor_lst = NULL;
912 xf86freeScreenList(xf86config->conf_screen_lst);
913 xf86config->conf_screen_lst = NULL;
914 for (j = 0; j < xf86NumScreens; j++) {
915 XF86ConfMonitorPtr MonitorPtr;
916 XF86ConfScreenPtr ScreenPtr;
918 ConfiguredMonitor = NULL;
920 xf86EnableAccess(xf86Screens[dev2screen[j]]);
921 if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]],
922 PROBE_DETECT) &&
923 ConfiguredMonitor) {
924 MonitorPtr = configureDDCMonitorSection(j);
925 } else {
926 MonitorPtr = configureMonitorSection(j);
928 ScreenPtr = configureScreenSection(j);
929 xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
930 (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
931 xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
932 (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
935 xf86writeConfigFile(filename, xf86config);
937 ErrorF("\n");
939 #ifdef __SCO__
940 ErrorF("\n"__XSERVERNAME__
941 " is using the kernel event driver to access the mouse.\n"
942 "If you wish to use the internal "__XSERVERNAME__
943 " mouse drivers, please\n"
944 "edit the file and correct the Device.\n");
945 #else /* !__SCO__ */
946 if (!foundMouse) {
947 ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n"
948 "Edit the file and correct the Device.\n");
949 } else {
950 ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n"
951 "Please check your config if the mouse is still not\n"
952 "operational, as by default "__XSERVERNAME__
953 " tries to autodetect\n"
954 "the protocol.\n",DFLT_MOUSE_DEV);
956 #endif /* !__SCO__ */
958 if (xf86NumScreens > 1) {
959 ErrorF("\n"__XSERVERNAME__
960 " has configured a multihead system, please check your config.\n");
963 ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename);
964 ErrorF("To test the server, run 'X -config %s'\n\n", filename);
966 bail:
967 OsCleanup(TRUE);
968 AbortDDX();
969 fflush(stderr);
970 exit(0);