2 * Copyright 2003 by David H. Dawes.
3 * Copyright 2003 by X-Oz Technologies.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
24 * Except as contained in this notice, the name of the copyright holder(s)
25 * and author(s) shall not be used in advertising or otherwise to promote
26 * the sale, use or other dealings in this Software without prior written
27 * authorization from the copyright holder(s) and author(s).
29 * Author: David Dawes <dawes@XFree86.Org>.
32 #ifdef HAVE_XORG_CONFIG_H
33 #include <xorg-config.h>
37 #include "xf86Parser.h"
38 #include "xf86tokens.h"
39 #include "xf86Config.h"
41 #include "xf86_OSlib.h"
42 #include "xf86platformBus.h"
43 #include "xf86pciBus.h"
45 #include "xf86sbusBus.h"
49 #include <sys/visual_io.h>
53 /* Sections for the default built-in configuration. */
55 #define BUILTIN_DEVICE_NAME \
56 "\"Builtin Default %s Device %d\""
58 #define BUILTIN_DEVICE_SECTION_PRE \
59 "Section \"Device\"\n" \
60 "\tIdentifier\t" BUILTIN_DEVICE_NAME "\n" \
63 #define BUILTIN_DEVICE_SECTION_POST \
66 #define BUILTIN_DEVICE_SECTION \
67 BUILTIN_DEVICE_SECTION_PRE \
68 BUILTIN_DEVICE_SECTION_POST
70 #define BUILTIN_SCREEN_NAME \
71 "\"Builtin Default %s Screen %d\""
73 #define BUILTIN_SCREEN_SECTION \
74 "Section \"Screen\"\n" \
75 "\tIdentifier\t" BUILTIN_SCREEN_NAME "\n" \
76 "\tDevice\t" BUILTIN_DEVICE_NAME "\n" \
79 #define BUILTIN_LAYOUT_SECTION_PRE \
80 "Section \"ServerLayout\"\n" \
81 "\tIdentifier\t\"Builtin Default Layout\"\n"
83 #define BUILTIN_LAYOUT_SCREEN_LINE \
84 "\tScreen\t" BUILTIN_SCREEN_NAME "\n"
86 #define BUILTIN_LAYOUT_SECTION_POST \
89 static const char **builtinConfig
= NULL
;
90 static int builtinLines
= 0;
92 static void listPossibleVideoDrivers(char *matches
[], int nmatches
);
95 * A built-in config file is stored as an array of strings, with each string
96 * representing a single line. AppendToConfig() breaks up the string "s"
97 * into lines, and appends those lines it to builtinConfig.
101 AppendToList(const char *s
, const char ***list
, int *lines
)
103 char *str
, *newstr
, *p
;
106 for (p
= strtok(str
, "\n"); p
; p
= strtok(NULL
, "\n")) {
108 *list
= xnfrealloc(*list
, (*lines
+ 1) * sizeof(**list
));
109 newstr
= xnfalloc(strlen(p
) + 2);
111 strcat(newstr
, "\n");
112 (*list
)[*lines
- 1] = newstr
;
113 (*list
)[*lines
] = NULL
;
119 FreeList(const char ***list
, int *lines
)
123 for (i
= 0; i
< *lines
; i
++) {
124 free((char *) ((*list
)[i
]));
134 FreeList(&builtinConfig
, &builtinLines
);
138 AppendToConfig(const char *s
)
140 AppendToList(s
, &builtinConfig
, &builtinLines
);
146 char *deviceList
[20];
152 listPossibleVideoDrivers(deviceList
, 20);
154 for (p
= deviceList
; *p
; p
++) {
155 snprintf(buf
, sizeof(buf
), BUILTIN_DEVICE_SECTION
, *p
, 0, *p
);
157 snprintf(buf
, sizeof(buf
), BUILTIN_SCREEN_SECTION
, *p
, 0, *p
, 0);
161 AppendToConfig(BUILTIN_LAYOUT_SECTION_PRE
);
162 for (p
= deviceList
; *p
; p
++) {
163 snprintf(buf
, sizeof(buf
), BUILTIN_LAYOUT_SCREEN_LINE
, *p
, 0);
166 AppendToConfig(BUILTIN_LAYOUT_SECTION_POST
);
168 for (p
= deviceList
; *p
; p
++) {
172 xf86MsgVerb(X_DEFAULT
, 0,
173 "Using default built-in configuration (%d lines)\n",
176 xf86MsgVerb(X_DEFAULT
, 3, "--- Start of built-in configuration ---\n");
177 for (cp
= builtinConfig
; *cp
; cp
++)
178 xf86ErrorFVerb(3, "\t%s", *cp
);
179 xf86MsgVerb(X_DEFAULT
, 3, "--- End of built-in configuration ---\n");
181 xf86initConfigFiles();
182 xf86setBuiltinConfig(builtinConfig
);
183 ret
= xf86HandleConfigFile(TRUE
);
186 if (ret
!= CONFIG_OK
)
187 xf86Msg(X_ERROR
, "Error parsing the built-in default configuration.\n");
189 return ret
== CONFIG_OK
;
193 listPossibleVideoDrivers(char *matches
[], int nmatches
)
197 for (i
= 0; i
< nmatches
; i
++) {
202 #ifdef XSERVER_PLATFORM_BUS
203 i
= xf86PlatformMatchDriver(matches
, nmatches
);
206 /* Check for driver type based on /dev/fb type and if valid, use
207 it instead of PCI bus probe results */
208 if (xf86Info
.consoleFd
>= 0 && (i
< (nmatches
- 1))) {
209 struct vis_identifier visid
;
211 extern char xf86SolarisFbDev
[PATH_MAX
];
214 SYSCALL(iret
= ioctl(xf86Info
.consoleFd
, VIS_GETIDENTIFIER
, &visid
));
218 fbfd
= open(xf86SolarisFbDev
, O_RDONLY
);
220 SYSCALL(iret
= ioctl(fbfd
, VIS_GETIDENTIFIER
, &visid
));
227 "could not get frame buffer identifier from %s\n",
231 xf86Msg(X_PROBED
, "console driver: %s\n", visid
.name
);
233 /* Special case from before the general case was set */
234 if (strcmp(visid
.name
, "NVDAnvda") == 0) {
235 matches
[i
++] = xnfstrdup("nvidia");
238 /* General case - split into vendor name (initial all-caps
239 prefix) & driver name (rest of the string). */
240 if (strcmp(visid
.name
, "SUNWtext") != 0) {
241 for (cp
= visid
.name
; (*cp
!= '\0') && isupper(*cp
); cp
++) {
242 /* find end of all uppercase vendor section */
244 if ((cp
!= visid
.name
) && (*cp
!= '\0')) {
245 char *driverName
= xnfstrdup(cp
);
246 char *vendorName
= xnfstrdup(visid
.name
);
248 vendorName
[cp
- visid
.name
] = '\0';
250 matches
[i
++] = vendorName
;
251 matches
[i
++] = driverName
;
258 if (i
< (nmatches
- 1))
260 char *sbusDriver
= sparcDriverName();
263 matches
[i
++] = xnfstrdup(sbusDriver
);
266 #ifdef XSERVER_LIBPCIACCESS
267 if (i
< (nmatches
- 1))
268 i
= xf86PciMatchDriver(matches
, nmatches
);
271 #if defined(__linux__)
272 matches
[i
++] = xnfstrdup("modesetting");
276 /* Fallback to platform default frame buffer driver */
277 if (i
< (nmatches
- 1)) {
278 #if !defined(__linux__) && defined(__sparc__)
279 matches
[i
++] = xnfstrdup("wsfb");
281 matches
[i
++] = xnfstrdup("fbdev");
286 /* Fallback to platform default hardware */
287 if (i
< (nmatches
- 1)) {
288 #if defined(__i386__) || defined(__amd64__) || defined(__hurd__)
289 matches
[i
++] = xnfstrdup("vesa");
290 #elif defined(__sparc__) && !defined(sun)
291 matches
[i
++] = xnfstrdup("sunffb");
296 /* copy a screen section and enter the desired driver
297 * and insert it at i in the list of screens */
299 copyScreen(confScreenPtr oscreen
, GDevPtr odev
, int i
, char *driver
)
301 confScreenPtr nscreen
;
304 nscreen
= malloc(sizeof(confScreenRec
));
307 memcpy(nscreen
, oscreen
, sizeof(confScreenRec
));
309 cptr
= malloc(sizeof(GDevRec
));
314 memcpy(cptr
, odev
, sizeof(GDevRec
));
316 if (asprintf(&cptr
->identifier
, "Autoconfigured Video Device %s", driver
)
322 cptr
->driver
= driver
;
324 xf86ConfigLayout
.screens
[i
].screen
= nscreen
;
326 /* now associate the new driver entry with the new screen entry */
327 xf86ConfigLayout
.screens
[i
].screen
->device
= cptr
;
328 cptr
->myScreenSection
= xf86ConfigLayout
.screens
[i
].screen
;
334 autoConfigDevice(GDevPtr preconf_device
)
337 char *matches
[20]; /* If we have more than 20 drivers we're in trouble */
338 int num_matches
= 0, num_screens
= 0, i
;
341 if (!xf86configptr
) {
345 /* If there's a configured section with no driver chosen, use it */
346 if (preconf_device
) {
347 ptr
= preconf_device
;
350 ptr
= calloc(1, sizeof(GDevRec
));
359 ptr
->claimed
= FALSE
;
360 ptr
->identifier
= "Autoconfigured Video Device";
364 /* get all possible video drivers and count them */
365 listPossibleVideoDrivers(matches
, 20);
366 for (; matches
[num_matches
]; num_matches
++) {
367 xf86Msg(X_DEFAULT
, "Matched %s as autoconfigured driver %d\n",
368 matches
[num_matches
], num_matches
);
371 slp
= xf86ConfigLayout
.screens
;
373 /* count the number of screens and make space for
374 * a new screen for each additional possible driver
375 * minus one for the already existing first one
376 * plus one for the terminating NULL */
377 for (; slp
[num_screens
].screen
; num_screens
++);
378 xf86ConfigLayout
.screens
= xnfcalloc(num_screens
+ num_matches
,
379 sizeof(screenLayoutRec
));
380 xf86ConfigLayout
.screens
[0] = slp
[0];
382 /* do the first match and set that for the original first screen */
383 ptr
->driver
= matches
[0];
384 if (!xf86ConfigLayout
.screens
[0].screen
->device
) {
385 xf86ConfigLayout
.screens
[0].screen
->device
= ptr
;
386 ptr
->myScreenSection
= xf86ConfigLayout
.screens
[0].screen
;
389 /* for each other driver found, copy the first screen, insert it
390 * into the list of screens and set the driver */
392 while (i
++ < num_matches
) {
393 if (!copyScreen(slp
[0].screen
, ptr
, i
, matches
[i
]))
397 /* shift the rest of the original screen list
398 * to the end of the current screen list
400 * TODO Handle rest of multiple screen sections */
401 for (i
= 1; i
< num_screens
; i
++) {
402 xf86ConfigLayout
.screens
[i
+ num_matches
] = slp
[i
];
404 xf86ConfigLayout
.screens
[num_screens
+ num_matches
- 1].screen
=
409 /* layout does not have any screens, not much to do */
410 ptr
->driver
= matches
[0];
411 for (i
= 1; matches
[i
]; i
++) {
412 if (matches
[i
] != matches
[0]) {
419 xf86Msg(X_DEFAULT
, "Assigned the driver to the xf86ConfigLayout\n");