1706f2543Smrg/* 2706f2543Smrg * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales. 3706f2543Smrg * 4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 6706f2543Smrg * the above copyright notice appear in all copies and that both that 7706f2543Smrg * copyright notice and this permission notice appear in supporting 8706f2543Smrg * documentation, and that the name of Alan Hourihane not be used in 9706f2543Smrg * advertising or publicity pertaining to distribution of the software without 10706f2543Smrg * specific, written prior permission. Alan Hourihane makes no representations 11706f2543Smrg * about the suitability of this software for any purpose. It is provided 12706f2543Smrg * "as is" without express or implied warranty. 13706f2543Smrg * 14706f2543Smrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16706f2543Smrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 21706f2543Smrg * 22706f2543Smrg * Author: Alan Hourihane, alanh@fairlite.demon.co.uk 23706f2543Smrg * 24706f2543Smrg */ 25706f2543Smrg 26706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 27706f2543Smrg#include <xorg-config.h> 28706f2543Smrg#endif 29706f2543Smrg 30706f2543Smrg#include "xf86.h" 31706f2543Smrg#include "xf86Config.h" 32706f2543Smrg#include "xf86_OSlib.h" 33706f2543Smrg#include "xf86Priv.h" 34706f2543Smrg#define IN_XSERVER 35706f2543Smrg#include "Configint.h" 36706f2543Smrg#include "xf86DDC.h" 37706f2543Smrg#include "xf86pciBus.h" 38706f2543Smrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 39706f2543Smrg#include "xf86Bus.h" 40706f2543Smrg#include "xf86Sbus.h" 41706f2543Smrg#endif 42706f2543Smrg 43706f2543Smrgtypedef struct _DevToConfig { 44706f2543Smrg GDevRec GDev; 45706f2543Smrg struct pci_device * pVideo; 46706f2543Smrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 47706f2543Smrg sbusDevicePtr sVideo; 48706f2543Smrg#endif 49706f2543Smrg int iDriver; 50706f2543Smrg} DevToConfigRec, *DevToConfigPtr; 51706f2543Smrg 52706f2543Smrgstatic DevToConfigPtr DevToConfig = NULL; 53706f2543Smrgstatic int nDevToConfig = 0, CurrentDriver; 54706f2543Smrg 55706f2543Smrgxf86MonPtr ConfiguredMonitor; 56706f2543SmrgBool xf86DoConfigurePass1 = TRUE; 57706f2543Smrgstatic Bool foundMouse = FALSE; 58706f2543Smrg 59706f2543Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 60706f2543Smrgstatic char *DFLT_MOUSE_DEV = "/dev/sysmouse"; 61706f2543Smrgstatic char *DFLT_MOUSE_PROTO = "auto"; 62706f2543Smrg#elif defined(linux) 63706f2543Smrgstatic char DFLT_MOUSE_DEV[] = "/dev/input/mice"; 64706f2543Smrgstatic char DFLT_MOUSE_PROTO[] = "auto"; 65706f2543Smrg#else 66706f2543Smrgstatic char *DFLT_MOUSE_DEV = "/dev/mouse"; 67706f2543Smrgstatic char *DFLT_MOUSE_PROTO = "auto"; 68706f2543Smrg#endif 69706f2543Smrg 70706f2543Smrg/* 71706f2543Smrg * This is called by the driver, either through xf86Match???Instances() or 72706f2543Smrg * directly. We allocate a GDevRec and fill it in as much as we can, letting 73706f2543Smrg * the caller fill in the rest and/or change it as it sees fit. 74706f2543Smrg */ 75706f2543SmrgGDevPtr 76706f2543Smrgxf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset) 77706f2543Smrg{ 78706f2543Smrg int ret, i, j; 79706f2543Smrg 80706f2543Smrg if (!xf86DoConfigure || !xf86DoConfigurePass1) 81706f2543Smrg return NULL; 82706f2543Smrg 83706f2543Smrg /* Check for duplicates */ 84706f2543Smrg for (i = 0; i < nDevToConfig; i++) { 85706f2543Smrg switch (bus) { 86706f2543Smrg case BUS_PCI: 87706f2543Smrg ret = xf86PciConfigure(busData, DevToConfig[i].pVideo); 88706f2543Smrg break; 89706f2543Smrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 90706f2543Smrg case BUS_SBUS: 91706f2543Smrg ret = xf86SbusConfigure(busData, DevToConfig[i].sVideo); 92706f2543Smrg break; 93706f2543Smrg#endif 94706f2543Smrg#if defined(__arm32__) 95706f2543Smrg case BUS_ISA: 96706f2543Smrg break; 97706f2543Smrg#endif 98706f2543Smrg default: 99706f2543Smrg return NULL; 100706f2543Smrg } 101706f2543Smrg if (ret == 0) 102706f2543Smrg goto out; 103706f2543Smrg } 104706f2543Smrg 105706f2543Smrg /* Allocate new structure occurrence */ 106706f2543Smrg i = nDevToConfig++; 107706f2543Smrg DevToConfig = 108706f2543Smrg xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec)); 109706f2543Smrg memset(DevToConfig + i, 0, sizeof(DevToConfigRec)); 110706f2543Smrg 111706f2543Smrg DevToConfig[i].GDev.chipID = 112706f2543Smrg DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1; 113706f2543Smrg 114706f2543Smrg DevToConfig[i].iDriver = CurrentDriver; 115706f2543Smrg 116706f2543Smrg /* Fill in what we know, converting the driver name to lower case */ 117706f2543Smrg DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1); 118706f2543Smrg for (j = 0; (DevToConfig[i].GDev.driver[j] = tolower(driver[j])); j++); 119706f2543Smrg 120706f2543Smrg switch (bus) { 121706f2543Smrg case BUS_PCI: 122706f2543Smrg xf86PciConfigureNewDev(busData, DevToConfig[i].pVideo, 123706f2543Smrg &DevToConfig[i].GDev, &chipset); 124706f2543Smrg DevToConfig[i].pVideo = busData; 125706f2543Smrg break; 126706f2543Smrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 127706f2543Smrg case BUS_SBUS: 128706f2543Smrg xf86SbusConfigureNewDev(busData, DevToConfig[i].sVideo, 129706f2543Smrg &DevToConfig[i].GDev); 130706f2543Smrg DevToConfig[i].sVideo = busData; 131706f2543Smrg break; 132706f2543Smrg#endif 133706f2543Smrg#if defined(__arm32__) 134706f2543Smrg case BUS_ISA: 135706f2543Smrg DevToConfig[i].GDev.busID = xnfalloc(6); 136706f2543Smrg strcpy(DevToConfig[i].GDev.busID, "ISA"); 137706f2543Smrg break; 138706f2543Smrg#endif 139706f2543Smrg default: 140706f2543Smrg break; 141706f2543Smrg } 142706f2543Smrg 143706f2543Smrg /* Get driver's available options */ 144706f2543Smrg if (xf86DriverList[CurrentDriver]->AvailableOptions) 145706f2543Smrg DevToConfig[i].GDev.options = (OptionInfoPtr) 146706f2543Smrg (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset, 147706f2543Smrg bus); 148706f2543Smrg 149706f2543Smrg return &DevToConfig[i].GDev; 150706f2543Smrg 151706f2543Smrgout: 152706f2543Smrg return NULL; 153706f2543Smrg} 154706f2543Smrg 155706f2543Smrgstatic XF86ConfInputPtr 156706f2543SmrgconfigureInputSection (void) 157706f2543Smrg{ 158706f2543Smrg XF86ConfInputPtr mouse = NULL; 159706f2543Smrg parsePrologue (XF86ConfInputPtr, XF86ConfInputRec) 160706f2543Smrg 161706f2543Smrg ptr->inp_identifier = "Keyboard0"; 162706f2543Smrg ptr->inp_driver = "kbd"; 163706f2543Smrg ptr->list.next = NULL; 164706f2543Smrg#if defined(WSCONS_SUPPORT) && !defined(__i386__) && !defined(__amd64__) 165706f2543Smrg ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst, 166706f2543Smrg xstrdup("Protocol"), "wskbd"); 167706f2543Smrg ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst, 168706f2543Smrg xstrdup("Device"), "/dev/wskbd"); 169706f2543Smrg#endif 170706f2543Smrg 171706f2543Smrg /* Crude mechanism to auto-detect mouse (os dependent) */ 172706f2543Smrg { 173706f2543Smrg int fd; 174706f2543Smrg#ifdef WSCONS_SUPPORT 175706f2543Smrg fd = open("/dev/wsmouse", 0); 176706f2543Smrg if (fd >= 0) { 177706f2543Smrg DFLT_MOUSE_DEV = "/dev/wsmouse"; 178706f2543Smrg DFLT_MOUSE_PROTO = "wsmouse"; 179706f2543Smrg close(fd); 180706f2543Smrg } else { 181706f2543Smrg ErrorF("cannot open /dev/wsmouse\n"); 182706f2543Smrg } 183706f2543Smrg#endif 184706f2543Smrg 185706f2543Smrg fd = open(DFLT_MOUSE_DEV, 0); 186706f2543Smrg if (fd != -1) { 187706f2543Smrg foundMouse = TRUE; 188706f2543Smrg close(fd); 189706f2543Smrg } 190706f2543Smrg } 191706f2543Smrg 192706f2543Smrg mouse = calloc(1, sizeof(XF86ConfInputRec)); 193706f2543Smrg mouse->inp_identifier = "Mouse0"; 194706f2543Smrg mouse->inp_driver = "mouse"; 195706f2543Smrg mouse->inp_option_lst = 196706f2543Smrg xf86addNewOption(mouse->inp_option_lst, strdup("Protocol"), 197706f2543Smrg strdup(DFLT_MOUSE_PROTO)); 198706f2543Smrg mouse->inp_option_lst = 199706f2543Smrg xf86addNewOption(mouse->inp_option_lst, strdup("Device"), 200706f2543Smrg strdup(DFLT_MOUSE_DEV)); 201706f2543Smrg mouse->inp_option_lst = 202706f2543Smrg xf86addNewOption(mouse->inp_option_lst, strdup("ZAxisMapping"), 203706f2543Smrg strdup("4 5 6 7")); 204706f2543Smrg ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse); 205706f2543Smrg return ptr; 206706f2543Smrg} 207706f2543Smrg 208706f2543Smrgstatic XF86ConfScreenPtr 209706f2543SmrgconfigureScreenSection (int screennum) 210706f2543Smrg{ 211706f2543Smrg int i; 212706f2543Smrg int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ }; 213706f2543Smrg parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec) 214706f2543Smrg 215706f2543Smrg XNFasprintf(&ptr->scrn_identifier, "Screen%d", screennum); 216706f2543Smrg XNFasprintf(&ptr->scrn_monitor_str, "Monitor%d", screennum); 217706f2543Smrg XNFasprintf(&ptr->scrn_device_str, "Card%d", screennum); 218706f2543Smrg 219706f2543Smrg for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++) 220706f2543Smrg { 221706f2543Smrg XF86ConfDisplayPtr display; 222706f2543Smrg 223706f2543Smrg display = calloc(1, sizeof(XF86ConfDisplayRec)); 224706f2543Smrg display->disp_depth = depths[i]; 225706f2543Smrg display->disp_black.red = display->disp_white.red = -1; 226706f2543Smrg display->disp_black.green = display->disp_white.green = -1; 227706f2543Smrg display->disp_black.blue = display->disp_white.blue = -1; 228706f2543Smrg ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem( 229706f2543Smrg (glp)ptr->scrn_display_lst, (glp)display); 230706f2543Smrg } 231706f2543Smrg 232706f2543Smrg return ptr; 233706f2543Smrg} 234706f2543Smrg 235706f2543Smrgstatic const char* 236706f2543SmrgoptionTypeToString(OptionValueType type) 237706f2543Smrg{ 238706f2543Smrg switch (type) { 239706f2543Smrg case OPTV_NONE: 240706f2543Smrg return ""; 241706f2543Smrg case OPTV_INTEGER: 242706f2543Smrg return "<i>"; 243706f2543Smrg case OPTV_STRING: 244706f2543Smrg return "<str>"; 245706f2543Smrg case OPTV_ANYSTR: 246706f2543Smrg return "[<str>]"; 247706f2543Smrg case OPTV_REAL: 248706f2543Smrg return "<f>"; 249706f2543Smrg case OPTV_BOOLEAN: 250706f2543Smrg return "[<bool>]"; 251706f2543Smrg case OPTV_FREQ: 252706f2543Smrg return "<freq>"; 253706f2543Smrg case OPTV_PERCENT: 254706f2543Smrg return "<percent>"; 255706f2543Smrg default: 256706f2543Smrg return ""; 257706f2543Smrg } 258706f2543Smrg} 259706f2543Smrg 260706f2543Smrgstatic XF86ConfDevicePtr 261706f2543SmrgconfigureDeviceSection (int screennum) 262706f2543Smrg{ 263706f2543Smrg OptionInfoPtr p; 264706f2543Smrg int i = 0; 265706f2543Smrg parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec) 266706f2543Smrg 267706f2543Smrg /* Move device info to parser structure */ 268706f2543Smrg if (asprintf(&ptr->dev_identifier, "Card%d", screennum) == -1) 269706f2543Smrg ptr->dev_identifier = NULL; 270706f2543Smrg ptr->dev_chipset = DevToConfig[screennum].GDev.chipset; 271706f2543Smrg ptr->dev_busid = DevToConfig[screennum].GDev.busID; 272706f2543Smrg ptr->dev_driver = DevToConfig[screennum].GDev.driver; 273706f2543Smrg ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac; 274706f2543Smrg for (i = 0; (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS); i++) 275706f2543Smrg ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i]; 276706f2543Smrg ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam; 277706f2543Smrg ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq; 278706f2543Smrg ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase; 279706f2543Smrg ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase; 280706f2543Smrg ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase; 281706f2543Smrg ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip; 282706f2543Smrg for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); i++) 283706f2543Smrg ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i]; 284706f2543Smrg ptr->dev_clocks = i; 285706f2543Smrg ptr->dev_chipid = DevToConfig[screennum].GDev.chipID; 286706f2543Smrg ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev; 287706f2543Smrg ptr->dev_irq = DevToConfig[screennum].GDev.irq; 288706f2543Smrg 289706f2543Smrg /* Make sure older drivers don't segv */ 290706f2543Smrg if (DevToConfig[screennum].GDev.options) { 291706f2543Smrg /* Fill in the available driver options for people to use */ 292706f2543Smrg const char *descrip = 293706f2543Smrg " ### Available Driver options are:-\n" 294706f2543Smrg " ### Values: <i>: integer, <f>: float, " 295706f2543Smrg "<bool>: \"True\"/\"False\",\n" 296706f2543Smrg " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n" 297706f2543Smrg " ### <percent>: \"<f>%\"\n" 298706f2543Smrg " ### [arg]: arg optional\n"; 299706f2543Smrg ptr->dev_comment = strdup(descrip); 300706f2543Smrg if (ptr->dev_comment) { 301706f2543Smrg for (p = DevToConfig[screennum].GDev.options; 302706f2543Smrg p->name != NULL; p++) { 303706f2543Smrg char *p_e; 304706f2543Smrg const char *prefix = " #Option "; 305706f2543Smrg const char *middle = " \t# "; 306706f2543Smrg const char *suffix = "\n"; 307706f2543Smrg const char *opttype = optionTypeToString(p->type); 308706f2543Smrg char *optname; 309706f2543Smrg int len = strlen(ptr->dev_comment) + strlen(prefix) + 310706f2543Smrg strlen(middle) + strlen(suffix) + 1; 311706f2543Smrg 312706f2543Smrg if (asprintf(&optname, "\"%s\"", p->name) == -1) 313706f2543Smrg break; 314706f2543Smrg 315706f2543Smrg len += max(20, strlen(optname)); 316706f2543Smrg len += strlen(opttype); 317706f2543Smrg 318706f2543Smrg ptr->dev_comment = realloc(ptr->dev_comment, len); 319706f2543Smrg if (!ptr->dev_comment) 320706f2543Smrg break; 321706f2543Smrg p_e = ptr->dev_comment + strlen(ptr->dev_comment); 322706f2543Smrg sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle, 323706f2543Smrg opttype, suffix); 324706f2543Smrg free(optname); 325706f2543Smrg } 326706f2543Smrg } 327706f2543Smrg } 328706f2543Smrg 329706f2543Smrg return ptr; 330706f2543Smrg} 331706f2543Smrg 332706f2543Smrgstatic XF86ConfLayoutPtr 333706f2543SmrgconfigureLayoutSection (void) 334706f2543Smrg{ 335706f2543Smrg int scrnum = 0; 336706f2543Smrg parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec) 337706f2543Smrg 338706f2543Smrg ptr->lay_identifier = "X.org Configured"; 339706f2543Smrg 340706f2543Smrg { 341706f2543Smrg XF86ConfInputrefPtr iptr; 342706f2543Smrg 343706f2543Smrg iptr = malloc (sizeof (XF86ConfInputrefRec)); 344706f2543Smrg iptr->list.next = NULL; 345706f2543Smrg iptr->iref_option_lst = NULL; 346706f2543Smrg iptr->iref_inputdev_str = "Mouse0"; 347706f2543Smrg iptr->iref_option_lst = 348706f2543Smrg xf86addNewOption (iptr->iref_option_lst, strdup("CorePointer"), NULL); 349706f2543Smrg ptr->lay_input_lst = (XF86ConfInputrefPtr) 350706f2543Smrg xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr); 351706f2543Smrg } 352706f2543Smrg 353706f2543Smrg { 354706f2543Smrg XF86ConfInputrefPtr iptr; 355706f2543Smrg 356706f2543Smrg iptr = malloc (sizeof (XF86ConfInputrefRec)); 357706f2543Smrg iptr->list.next = NULL; 358706f2543Smrg iptr->iref_option_lst = NULL; 359706f2543Smrg iptr->iref_inputdev_str = "Keyboard0"; 360706f2543Smrg iptr->iref_option_lst = 361706f2543Smrg xf86addNewOption (iptr->iref_option_lst, strdup("CoreKeyboard"), NULL); 362706f2543Smrg ptr->lay_input_lst = (XF86ConfInputrefPtr) 363706f2543Smrg xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr); 364706f2543Smrg } 365706f2543Smrg 366706f2543Smrg for (scrnum = 0; scrnum < nDevToConfig; scrnum++) { 367706f2543Smrg XF86ConfAdjacencyPtr aptr; 368706f2543Smrg 369706f2543Smrg aptr = malloc (sizeof (XF86ConfAdjacencyRec)); 370706f2543Smrg aptr->list.next = NULL; 371706f2543Smrg aptr->adj_x = 0; 372706f2543Smrg aptr->adj_y = 0; 373706f2543Smrg aptr->adj_scrnum = scrnum; 374706f2543Smrg XNFasprintf(&aptr->adj_screen_str, "Screen%d", scrnum); 375706f2543Smrg if (scrnum == 0) { 376706f2543Smrg aptr->adj_where = CONF_ADJ_ABSOLUTE; 377706f2543Smrg aptr->adj_refscreen = NULL; 378706f2543Smrg } 379706f2543Smrg else { 380706f2543Smrg aptr->adj_where = CONF_ADJ_RIGHTOF; 381706f2543Smrg XNFasprintf(&aptr->adj_refscreen, "Screen%d", scrnum - 1); 382706f2543Smrg } 383706f2543Smrg ptr->lay_adjacency_lst = 384706f2543Smrg (XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst, 385706f2543Smrg (glp)aptr); 386706f2543Smrg } 387706f2543Smrg 388706f2543Smrg return ptr; 389706f2543Smrg} 390706f2543Smrg 391706f2543Smrgstatic XF86ConfFlagsPtr 392706f2543SmrgconfigureFlagsSection (void) 393706f2543Smrg{ 394706f2543Smrg parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec) 395706f2543Smrg 396706f2543Smrg return ptr; 397706f2543Smrg} 398706f2543Smrg 399706f2543Smrgstatic XF86ConfModulePtr 400706f2543SmrgconfigureModuleSection (void) 401706f2543Smrg{ 402706f2543Smrg char **elist, **el; 403706f2543Smrg /* Find the list of extension & font modules. */ 404706f2543Smrg const char *esubdirs[] = { 405706f2543Smrg "extensions", 406706f2543Smrg "fonts", 407706f2543Smrg NULL 408706f2543Smrg }; 409706f2543Smrg parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec) 410706f2543Smrg 411706f2543Smrg elist = LoaderListDirs(esubdirs, NULL); 412706f2543Smrg if (elist) { 413706f2543Smrg for (el = elist; *el; el++) { 414706f2543Smrg XF86LoadPtr module; 415706f2543Smrg 416706f2543Smrg module = calloc(1, sizeof(XF86LoadRec)); 417706f2543Smrg module->load_name = *el; 418706f2543Smrg ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem( 419706f2543Smrg (glp)ptr->mod_load_lst, (glp)module); 420706f2543Smrg } 421706f2543Smrg free(elist); 422706f2543Smrg } 423706f2543Smrg 424706f2543Smrg return ptr; 425706f2543Smrg} 426706f2543Smrg 427706f2543Smrgstatic XF86ConfFilesPtr 428706f2543SmrgconfigureFilesSection (void) 429706f2543Smrg{ 430706f2543Smrg parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec) 431706f2543Smrg 432706f2543Smrg if (xf86ModulePath) 433706f2543Smrg ptr->file_modulepath = strdup(xf86ModulePath); 434706f2543Smrg if (defaultFontPath) 435706f2543Smrg ptr->file_fontpath = strdup(defaultFontPath); 436706f2543Smrg 437706f2543Smrg return ptr; 438706f2543Smrg} 439706f2543Smrg 440706f2543Smrgstatic XF86ConfMonitorPtr 441706f2543SmrgconfigureMonitorSection (int screennum) 442706f2543Smrg{ 443706f2543Smrg parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec) 444706f2543Smrg 445706f2543Smrg XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum); 446706f2543Smrg ptr->mon_vendor = strdup("Monitor Vendor"); 447706f2543Smrg ptr->mon_modelname = strdup("Monitor Model"); 448706f2543Smrg 449706f2543Smrg return ptr; 450706f2543Smrg} 451706f2543Smrg 452706f2543Smrg/* Initialize Configure Monitor from Detailed Timing Block */ 453706f2543Smrgstatic void handle_detailed_input(struct detailed_monitor_section *det_mon, 454706f2543Smrg void *data) 455706f2543Smrg{ 456706f2543Smrg XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data; 457706f2543Smrg 458706f2543Smrg switch (det_mon->type) { 459706f2543Smrg case DS_NAME: 460706f2543Smrg ptr->mon_modelname = realloc(ptr->mon_modelname, 461706f2543Smrg strlen((char*)(det_mon->section.name)) + 462706f2543Smrg 1); 463706f2543Smrg strcpy(ptr->mon_modelname, 464706f2543Smrg (char*)(det_mon->section.name)); 465706f2543Smrg break; 466706f2543Smrg case DS_RANGES: 467706f2543Smrg ptr->mon_hsync[ptr->mon_n_hsync].lo = 468706f2543Smrg det_mon->section.ranges.min_h; 469706f2543Smrg ptr->mon_hsync[ptr->mon_n_hsync].hi = 470706f2543Smrg det_mon->section.ranges.max_h; 471706f2543Smrg ptr->mon_n_vrefresh = 1; 472706f2543Smrg ptr->mon_vrefresh[ptr->mon_n_hsync].lo = 473706f2543Smrg det_mon->section.ranges.min_v; 474706f2543Smrg ptr->mon_vrefresh[ptr->mon_n_hsync].hi = 475706f2543Smrg det_mon->section.ranges.max_v; 476706f2543Smrg ptr->mon_n_hsync++; 477706f2543Smrg default: 478706f2543Smrg break; 479706f2543Smrg } 480706f2543Smrg} 481706f2543Smrg 482706f2543Smrgstatic XF86ConfMonitorPtr 483706f2543SmrgconfigureDDCMonitorSection (int screennum) 484706f2543Smrg{ 485706f2543Smrg int len, mon_width, mon_height; 486706f2543Smrg#define displaySizeMaxLen 80 487706f2543Smrg char displaySize_string[displaySizeMaxLen]; 488706f2543Smrg int displaySizeLen; 489706f2543Smrg 490706f2543Smrg parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec) 491706f2543Smrg 492706f2543Smrg XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum); 493706f2543Smrg ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name); 494706f2543Smrg XNFasprintf(&ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id); 495706f2543Smrg 496706f2543Smrg /* features in centimetres, we want millimetres */ 497706f2543Smrg mon_width = 10 * ConfiguredMonitor->features.hsize ; 498706f2543Smrg mon_height = 10 * ConfiguredMonitor->features.vsize ; 499706f2543Smrg 500706f2543Smrg#ifdef CONFIGURE_DISPLAYSIZE 501706f2543Smrg ptr->mon_width = mon_width; 502706f2543Smrg ptr->mon_height = mon_height; 503706f2543Smrg#else 504706f2543Smrg if (mon_width && mon_height) { 505706f2543Smrg /* when values available add DisplaySize option AS A COMMENT */ 506706f2543Smrg 507706f2543Smrg displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen, 508706f2543Smrg "\t#DisplaySize\t%5d %5d\t# mm\n", 509706f2543Smrg mon_width, mon_height); 510706f2543Smrg 511706f2543Smrg if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) { 512706f2543Smrg if (ptr->mon_comment) { 513706f2543Smrg len = strlen(ptr->mon_comment); 514706f2543Smrg } else { 515706f2543Smrg len = 0; 516706f2543Smrg } 517706f2543Smrg if ((ptr->mon_comment = 518706f2543Smrg realloc(ptr->mon_comment, len + strlen(displaySize_string) + 1))) { 519706f2543Smrg strcpy(ptr->mon_comment + len, displaySize_string); 520706f2543Smrg } 521706f2543Smrg } 522706f2543Smrg } 523706f2543Smrg#endif /* def CONFIGURE_DISPLAYSIZE */ 524706f2543Smrg 525706f2543Smrg xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input, 526706f2543Smrg ptr); 527706f2543Smrg 528706f2543Smrg if (ConfiguredMonitor->features.dpms) { 529706f2543Smrg ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, strdup("DPMS"), NULL); 530706f2543Smrg } 531706f2543Smrg 532706f2543Smrg return ptr; 533706f2543Smrg} 534706f2543Smrg 535706f2543Smrg#if !defined(PATH_MAX) 536706f2543Smrg# define PATH_MAX 1024 537706f2543Smrg#endif 538706f2543Smrg 539706f2543Smrgvoid 540706f2543SmrgDoConfigure(void) 541706f2543Smrg{ 542706f2543Smrg int i,j, screennum = -1; 543706f2543Smrg char *home = NULL; 544706f2543Smrg char filename[PATH_MAX]; 545706f2543Smrg char *addslash = ""; 546706f2543Smrg XF86ConfigPtr xf86config = NULL; 547706f2543Smrg char **vlist, **vl; 548706f2543Smrg int *dev2screen; 549706f2543Smrg 550706f2543Smrg vlist = xf86DriverlistFromCompile(); 551706f2543Smrg 552706f2543Smrg if (!vlist) { 553706f2543Smrg ErrorF("Missing output drivers. Configuration failed.\n"); 554706f2543Smrg goto bail; 555706f2543Smrg } 556706f2543Smrg 557706f2543Smrg ErrorF("List of video drivers:\n"); 558706f2543Smrg for (vl = vlist; *vl; vl++) 559706f2543Smrg ErrorF("\t%s\n", *vl); 560706f2543Smrg 561706f2543Smrg /* Load all the drivers that were found. */ 562706f2543Smrg xf86LoadModules(vlist, NULL); 563706f2543Smrg 564706f2543Smrg free(vlist); 565706f2543Smrg 566706f2543Smrg for (i = 0; i < xf86NumDrivers; i++) { 567706f2543Smrg xorgHWFlags flags; 568706f2543Smrg if (!xf86DriverList[i]->driverFunc 569706f2543Smrg || !xf86DriverList[i]->driverFunc(NULL, 570706f2543Smrg GET_REQUIRED_HW_INTERFACES, 571706f2543Smrg &flags) 572706f2543Smrg || NEED_IO_ENABLED(flags)) { 573706f2543Smrg xorgHWAccess = TRUE; 574706f2543Smrg break; 575706f2543Smrg } 576706f2543Smrg } 577706f2543Smrg /* Enable full I/O access */ 578706f2543Smrg if (xorgHWAccess) { 579706f2543Smrg if(!xf86EnableIO()) 580706f2543Smrg /* oops, we have failed */ 581706f2543Smrg xorgHWAccess = FALSE; 582706f2543Smrg } 583706f2543Smrg 584706f2543Smrg /* Create XF86Config file structure */ 585706f2543Smrg xf86config = calloc(1, sizeof(XF86ConfigRec)); 586706f2543Smrg 587706f2543Smrg /* Call all of the probe functions, reporting the results. */ 588706f2543Smrg for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) { 589706f2543Smrg xorgHWFlags flags; 590706f2543Smrg Bool found_screen; 591706f2543Smrg DriverRec * const drv = xf86DriverList[CurrentDriver]; 592706f2543Smrg 593706f2543Smrg if (!xorgHWAccess) { 594706f2543Smrg if (!drv->driverFunc 595706f2543Smrg || !drv->driverFunc( NULL, GET_REQUIRED_HW_INTERFACES, &flags ) 596706f2543Smrg || NEED_IO_ENABLED(flags)) 597706f2543Smrg continue; 598706f2543Smrg } 599706f2543Smrg 600706f2543Smrg found_screen = xf86CallDriverProbe( drv, TRUE ); 601706f2543Smrg if ( found_screen && drv->Identify ) { 602706f2543Smrg (*drv->Identify)(0); 603706f2543Smrg } 604706f2543Smrg } 605706f2543Smrg 606706f2543Smrg if (nDevToConfig <= 0) { 607706f2543Smrg ErrorF("No devices to configure. Configuration failed.\n"); 608706f2543Smrg goto bail; 609706f2543Smrg } 610706f2543Smrg 611706f2543Smrg /* Add device, monitor and screen sections for detected devices */ 612706f2543Smrg for (screennum = 0; screennum < nDevToConfig; screennum++) { 613706f2543Smrg XF86ConfDevicePtr DevicePtr; 614706f2543Smrg XF86ConfMonitorPtr MonitorPtr; 615706f2543Smrg XF86ConfScreenPtr ScreenPtr; 616706f2543Smrg 617706f2543Smrg DevicePtr = configureDeviceSection(screennum); 618706f2543Smrg xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem( 619706f2543Smrg (glp)xf86config->conf_device_lst, (glp)DevicePtr); 620706f2543Smrg MonitorPtr = configureMonitorSection(screennum); 621706f2543Smrg xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem( 622706f2543Smrg (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr); 623706f2543Smrg ScreenPtr = configureScreenSection(screennum); 624706f2543Smrg xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem( 625706f2543Smrg (glp)xf86config->conf_screen_lst, (glp)ScreenPtr); 626706f2543Smrg } 627706f2543Smrg 628706f2543Smrg xf86config->conf_files = configureFilesSection(); 629706f2543Smrg xf86config->conf_modules = configureModuleSection(); 630706f2543Smrg xf86config->conf_flags = configureFlagsSection(); 631706f2543Smrg xf86config->conf_videoadaptor_lst = NULL; 632706f2543Smrg xf86config->conf_modes_lst = NULL; 633706f2543Smrg xf86config->conf_vendor_lst = NULL; 634706f2543Smrg xf86config->conf_dri = NULL; 635706f2543Smrg xf86config->conf_input_lst = configureInputSection(); 636706f2543Smrg xf86config->conf_layout_lst = configureLayoutSection(); 637706f2543Smrg 638706f2543Smrg home = getenv("HOME"); 639706f2543Smrg if ((home == NULL) || (home[0] == '\0')) { 640706f2543Smrg home = "/"; 641706f2543Smrg } else { 642706f2543Smrg /* Determine if trailing slash is present or needed */ 643706f2543Smrg int l = strlen(home); 644706f2543Smrg 645706f2543Smrg if (home[l-1] != '/') { 646706f2543Smrg addslash = "/"; 647706f2543Smrg } 648706f2543Smrg } 649706f2543Smrg 650706f2543Smrg snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new", 651706f2543Smrg home, addslash); 652706f2543Smrg 653706f2543Smrg if (xf86writeConfigFile(filename, xf86config) == 0) { 654706f2543Smrg xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n", 655706f2543Smrg filename, strerror(errno)); 656706f2543Smrg goto bail; 657706f2543Smrg } 658706f2543Smrg 659706f2543Smrg xf86DoConfigurePass1 = FALSE; 660706f2543Smrg /* Try to get DDC information filled in */ 661706f2543Smrg xf86ConfigFile = filename; 662706f2543Smrg if (xf86HandleConfigFile(FALSE) != CONFIG_OK) { 663706f2543Smrg goto bail; 664706f2543Smrg } 665706f2543Smrg 666706f2543Smrg xf86DoConfigurePass1 = FALSE; 667706f2543Smrg 668706f2543Smrg dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int)); 669706f2543Smrg 670706f2543Smrg { 671706f2543Smrg Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool)); 672706f2543Smrg for (screennum = 0; screennum < nDevToConfig; screennum++) { 673706f2543Smrg int k,l,n,oldNumScreens; 674706f2543Smrg 675706f2543Smrg i = DevToConfig[screennum].iDriver; 676706f2543Smrg 677706f2543Smrg if (driverProbed[i]) continue; 678706f2543Smrg driverProbed[i] = TRUE; 679706f2543Smrg 680706f2543Smrg oldNumScreens = xf86NumScreens; 681706f2543Smrg 682706f2543Smrg xf86CallDriverProbe( xf86DriverList[i], FALSE ); 683706f2543Smrg 684706f2543Smrg /* reorder */ 685706f2543Smrg k = screennum > 0 ? screennum : 1; 686706f2543Smrg for (l = oldNumScreens; l < xf86NumScreens; l++) { 687706f2543Smrg /* is screen primary? */ 688706f2543Smrg Bool primary = FALSE; 689706f2543Smrg for (n = 0; n<xf86Screens[l]->numEntities; n++) { 690706f2543Smrg if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) { 691706f2543Smrg dev2screen[0] = l; 692706f2543Smrg primary = TRUE; 693706f2543Smrg break; 694706f2543Smrg } 695706f2543Smrg } 696706f2543Smrg if (primary) continue; 697706f2543Smrg /* not primary: assign it to next device of same driver */ 698706f2543Smrg /* 699706f2543Smrg * NOTE: we assume that devices in DevToConfig 700706f2543Smrg * and xf86Screens[] have the same order except 701706f2543Smrg * for the primary device which always comes first. 702706f2543Smrg */ 703706f2543Smrg for (; k < nDevToConfig; k++) { 704706f2543Smrg if (DevToConfig[k].iDriver == i) { 705706f2543Smrg dev2screen[k++] = l; 706706f2543Smrg break; 707706f2543Smrg } 708706f2543Smrg } 709706f2543Smrg } 710706f2543Smrg } 711706f2543Smrg free(driverProbed); 712706f2543Smrg } 713706f2543Smrg 714706f2543Smrg 715706f2543Smrg if (nDevToConfig != xf86NumScreens) { 716706f2543Smrg ErrorF("Number of created screens does not match number of detected" 717706f2543Smrg " devices.\n Configuration failed.\n"); 718706f2543Smrg goto bail; 719706f2543Smrg } 720706f2543Smrg 721706f2543Smrg xf86PostProbe(); 722706f2543Smrg 723706f2543Smrg for (j = 0; j < xf86NumScreens; j++) { 724706f2543Smrg xf86Screens[j]->scrnIndex = j; 725706f2543Smrg } 726706f2543Smrg 727706f2543Smrg xf86freeMonitorList(xf86config->conf_monitor_lst); 728706f2543Smrg xf86config->conf_monitor_lst = NULL; 729706f2543Smrg xf86freeScreenList(xf86config->conf_screen_lst); 730706f2543Smrg xf86config->conf_screen_lst = NULL; 731706f2543Smrg for (j = 0; j < xf86NumScreens; j++) { 732706f2543Smrg XF86ConfMonitorPtr MonitorPtr; 733706f2543Smrg XF86ConfScreenPtr ScreenPtr; 734706f2543Smrg 735706f2543Smrg ConfiguredMonitor = NULL; 736706f2543Smrg 737706f2543Smrg if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]], 738706f2543Smrg PROBE_DETECT) && 739706f2543Smrg ConfiguredMonitor) { 740706f2543Smrg MonitorPtr = configureDDCMonitorSection(j); 741706f2543Smrg } else { 742706f2543Smrg MonitorPtr = configureMonitorSection(j); 743706f2543Smrg } 744706f2543Smrg ScreenPtr = configureScreenSection(j); 745706f2543Smrg xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem( 746706f2543Smrg (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr); 747706f2543Smrg xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem( 748706f2543Smrg (glp)xf86config->conf_screen_lst, (glp)ScreenPtr); 749706f2543Smrg } 750706f2543Smrg 751706f2543Smrg if (xf86writeConfigFile(filename, xf86config) == 0) { 752706f2543Smrg xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n", 753706f2543Smrg filename, strerror(errno)); 754706f2543Smrg goto bail; 755706f2543Smrg } 756706f2543Smrg 757706f2543Smrg ErrorF("\n"); 758706f2543Smrg 759706f2543Smrg if (!foundMouse) { 760706f2543Smrg ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n" 761706f2543Smrg "Edit the file and correct the Device.\n"); 762706f2543Smrg } else { 763706f2543Smrg ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n" 764706f2543Smrg "Please check your config if the mouse is still not\n" 765706f2543Smrg "operational, as by default "__XSERVERNAME__ 766706f2543Smrg " tries to autodetect\n" 767706f2543Smrg "the protocol.\n",DFLT_MOUSE_DEV); 768706f2543Smrg } 769706f2543Smrg 770706f2543Smrg if (xf86NumScreens > 1) { 771706f2543Smrg ErrorF("\n"__XSERVERNAME__ 772706f2543Smrg " has configured a multihead system, please check your config.\n"); 773706f2543Smrg } 774706f2543Smrg 775706f2543Smrg ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename); 776706f2543Smrg ErrorF("To test the server, run 'X -config %s'\n\n", filename); 777706f2543Smrg 778706f2543Smrgbail: 779706f2543Smrg OsCleanup(TRUE); 780706f2543Smrg AbortDDX(); 781706f2543Smrg fflush(stderr); 782706f2543Smrg exit(0); 783706f2543Smrg} 784