1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2003 by David H. Dawes.
3*4882a593Smuzhiyun * Copyright 2003 by X-Oz Technologies.
4*4882a593Smuzhiyun * All rights reserved.
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
7*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
8*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
9*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
11*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * The above copyright notice and this permission notice shall be included in
14*4882a593Smuzhiyun * all copies or substantial portions of the Software.
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*4882a593Smuzhiyun * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*4882a593Smuzhiyun * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*4882a593Smuzhiyun * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*4882a593Smuzhiyun * OTHER DEALINGS IN THE SOFTWARE.
23*4882a593Smuzhiyun *
24*4882a593Smuzhiyun * Except as contained in this notice, the name of the copyright holder(s)
25*4882a593Smuzhiyun * and author(s) shall not be used in advertising or otherwise to promote
26*4882a593Smuzhiyun * the sale, use or other dealings in this Software without prior written
27*4882a593Smuzhiyun * authorization from the copyright holder(s) and author(s).
28*4882a593Smuzhiyun *
29*4882a593Smuzhiyun * Author: David Dawes <dawes@XFree86.Org>.
30*4882a593Smuzhiyun */
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #ifdef HAVE_XORG_CONFIG_H
33*4882a593Smuzhiyun #include <xorg-config.h>
34*4882a593Smuzhiyun #endif
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #include "xf86.h"
37*4882a593Smuzhiyun #include "xf86Parser.h"
38*4882a593Smuzhiyun #include "xf86tokens.h"
39*4882a593Smuzhiyun #include "xf86Config.h"
40*4882a593Smuzhiyun #include "xf86MatchDrivers.h"
41*4882a593Smuzhiyun #include "xf86Priv.h"
42*4882a593Smuzhiyun #include "xf86_OSlib.h"
43*4882a593Smuzhiyun #include "xf86platformBus.h"
44*4882a593Smuzhiyun #include "xf86pciBus.h"
45*4882a593Smuzhiyun #ifdef __sparc__
46*4882a593Smuzhiyun #include "xf86sbusBus.h"
47*4882a593Smuzhiyun #endif
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun #ifdef __sun
50*4882a593Smuzhiyun #include <sys/visual_io.h>
51*4882a593Smuzhiyun #include <ctype.h>
52*4882a593Smuzhiyun #endif
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun /* Sections for the default built-in configuration. */
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun #define BUILTIN_DEVICE_NAME \
57*4882a593Smuzhiyun "\"Builtin Default %s Device %d\""
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun #define BUILTIN_DEVICE_SECTION_PRE \
60*4882a593Smuzhiyun "Section \"Device\"\n" \
61*4882a593Smuzhiyun "\tIdentifier\t" BUILTIN_DEVICE_NAME "\n" \
62*4882a593Smuzhiyun "\tDriver\t\"%s\"\n"
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun #define BUILTIN_DEVICE_SECTION_POST \
65*4882a593Smuzhiyun "EndSection\n\n"
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun #define BUILTIN_DEVICE_SECTION \
68*4882a593Smuzhiyun BUILTIN_DEVICE_SECTION_PRE \
69*4882a593Smuzhiyun BUILTIN_DEVICE_SECTION_POST
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun #define BUILTIN_SCREEN_NAME \
72*4882a593Smuzhiyun "\"Builtin Default %s Screen %d\""
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun #define BUILTIN_SCREEN_SECTION \
75*4882a593Smuzhiyun "Section \"Screen\"\n" \
76*4882a593Smuzhiyun "\tIdentifier\t" BUILTIN_SCREEN_NAME "\n" \
77*4882a593Smuzhiyun "\tDevice\t" BUILTIN_DEVICE_NAME "\n" \
78*4882a593Smuzhiyun "EndSection\n\n"
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun #define BUILTIN_LAYOUT_SECTION_PRE \
81*4882a593Smuzhiyun "Section \"ServerLayout\"\n" \
82*4882a593Smuzhiyun "\tIdentifier\t\"Builtin Default Layout\"\n"
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun #define BUILTIN_LAYOUT_SCREEN_LINE \
85*4882a593Smuzhiyun "\tScreen\t" BUILTIN_SCREEN_NAME "\n"
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun #define BUILTIN_LAYOUT_SECTION_POST \
88*4882a593Smuzhiyun "EndSection\n\n"
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun static const char **builtinConfig = NULL;
91*4882a593Smuzhiyun static int builtinLines = 0;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun static void listPossibleVideoDrivers(XF86MatchedDrivers *md);
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /*
96*4882a593Smuzhiyun * A built-in config file is stored as an array of strings, with each string
97*4882a593Smuzhiyun * representing a single line. AppendToConfig() breaks up the string "s"
98*4882a593Smuzhiyun * into lines, and appends those lines it to builtinConfig.
99*4882a593Smuzhiyun */
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun static void
AppendToList(const char * s,const char *** list,int * lines)102*4882a593Smuzhiyun AppendToList(const char *s, const char ***list, int *lines)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun char *str, *newstr, *p;
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun str = xnfstrdup(s);
107*4882a593Smuzhiyun for (p = strtok(str, "\n"); p; p = strtok(NULL, "\n")) {
108*4882a593Smuzhiyun (*lines)++;
109*4882a593Smuzhiyun *list = xnfreallocarray(*list, *lines + 1, sizeof(**list));
110*4882a593Smuzhiyun newstr = xnfalloc(strlen(p) + 2);
111*4882a593Smuzhiyun strcpy(newstr, p);
112*4882a593Smuzhiyun strcat(newstr, "\n");
113*4882a593Smuzhiyun (*list)[*lines - 1] = newstr;
114*4882a593Smuzhiyun (*list)[*lines] = NULL;
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun free(str);
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun static void
FreeList(const char *** list,int * lines)120*4882a593Smuzhiyun FreeList(const char ***list, int *lines)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun int i;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun for (i = 0; i < *lines; i++) {
125*4882a593Smuzhiyun free((char *) ((*list)[i]));
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun free(*list);
128*4882a593Smuzhiyun *list = NULL;
129*4882a593Smuzhiyun *lines = 0;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun static void
FreeConfig(void)133*4882a593Smuzhiyun FreeConfig(void)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun FreeList(&builtinConfig, &builtinLines);
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun static void
AppendToConfig(const char * s)139*4882a593Smuzhiyun AppendToConfig(const char *s)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun AppendToList(s, &builtinConfig, &builtinLines);
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun void
xf86AddMatchedDriver(XF86MatchedDrivers * md,const char * driver)145*4882a593Smuzhiyun xf86AddMatchedDriver(XF86MatchedDrivers *md, const char *driver)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun int j;
148*4882a593Smuzhiyun int nmatches = md->nmatches;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun for (j = 0; j < nmatches; ++j) {
151*4882a593Smuzhiyun if (xf86NameCmp(md->matches[j], driver) == 0) {
152*4882a593Smuzhiyun // Driver already in matched drivers
153*4882a593Smuzhiyun return;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun if (nmatches < MATCH_DRIVERS_LIMIT) {
158*4882a593Smuzhiyun md->matches[nmatches] = xnfstrdup(driver);
159*4882a593Smuzhiyun md->nmatches++;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun else {
162*4882a593Smuzhiyun xf86Msg(X_WARNING, "Too many drivers registered, can't add %s\n", driver);
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun Bool
xf86AutoConfig(void)167*4882a593Smuzhiyun xf86AutoConfig(void)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun XF86MatchedDrivers md;
170*4882a593Smuzhiyun int i;
171*4882a593Smuzhiyun const char **cp;
172*4882a593Smuzhiyun char buf[1024];
173*4882a593Smuzhiyun ConfigStatus ret;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun /* Make sure config rec is there */
176*4882a593Smuzhiyun if (xf86allocateConfig() != NULL) {
177*4882a593Smuzhiyun ret = CONFIG_OK; /* OK so far */
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun else {
180*4882a593Smuzhiyun xf86Msg(X_ERROR, "Couldn't allocate Config record.\n");
181*4882a593Smuzhiyun return FALSE;
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun listPossibleVideoDrivers(&md);
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun for (i = 0; i < md.nmatches; i++) {
187*4882a593Smuzhiyun snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION,
188*4882a593Smuzhiyun md.matches[i], 0, md.matches[i]);
189*4882a593Smuzhiyun AppendToConfig(buf);
190*4882a593Smuzhiyun snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION,
191*4882a593Smuzhiyun md.matches[i], 0, md.matches[i], 0);
192*4882a593Smuzhiyun AppendToConfig(buf);
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun AppendToConfig(BUILTIN_LAYOUT_SECTION_PRE);
196*4882a593Smuzhiyun for (i = 0; i < md.nmatches; i++) {
197*4882a593Smuzhiyun snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE,
198*4882a593Smuzhiyun md.matches[i], 0);
199*4882a593Smuzhiyun AppendToConfig(buf);
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun AppendToConfig(BUILTIN_LAYOUT_SECTION_POST);
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun for (i = 0; i < md.nmatches; i++) {
204*4882a593Smuzhiyun free(md.matches[i]);
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun xf86MsgVerb(X_DEFAULT, 0,
208*4882a593Smuzhiyun "Using default built-in configuration (%d lines)\n",
209*4882a593Smuzhiyun builtinLines);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun xf86MsgVerb(X_DEFAULT, 3, "--- Start of built-in configuration ---\n");
212*4882a593Smuzhiyun for (cp = builtinConfig; *cp; cp++)
213*4882a593Smuzhiyun xf86ErrorFVerb(3, "\t%s", *cp);
214*4882a593Smuzhiyun xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun xf86initConfigFiles();
217*4882a593Smuzhiyun xf86setBuiltinConfig(builtinConfig);
218*4882a593Smuzhiyun ret = xf86HandleConfigFile(TRUE);
219*4882a593Smuzhiyun FreeConfig();
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun if (ret != CONFIG_OK)
222*4882a593Smuzhiyun xf86Msg(X_ERROR, "Error parsing the built-in default configuration.\n");
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun return ret == CONFIG_OK;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun static void
listPossibleVideoDrivers(XF86MatchedDrivers * md)228*4882a593Smuzhiyun listPossibleVideoDrivers(XF86MatchedDrivers *md)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun md->nmatches = 0;
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun #ifdef XSERVER_PLATFORM_BUS
233*4882a593Smuzhiyun xf86PlatformMatchDriver(md);
234*4882a593Smuzhiyun #endif
235*4882a593Smuzhiyun #ifdef __sun
236*4882a593Smuzhiyun /* Check for driver type based on /dev/fb type and if valid, use
237*4882a593Smuzhiyun it instead of PCI bus probe results */
238*4882a593Smuzhiyun if (xf86Info.consoleFd >= 0) {
239*4882a593Smuzhiyun struct vis_identifier visid;
240*4882a593Smuzhiyun const char *cp;
241*4882a593Smuzhiyun int iret;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun SYSCALL(iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid));
244*4882a593Smuzhiyun if (iret < 0) {
245*4882a593Smuzhiyun int fbfd;
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun fbfd = open(xf86SolarisFbDev, O_RDONLY);
248*4882a593Smuzhiyun if (fbfd >= 0) {
249*4882a593Smuzhiyun SYSCALL(iret = ioctl(fbfd, VIS_GETIDENTIFIER, &visid));
250*4882a593Smuzhiyun close(fbfd);
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun if (iret < 0) {
255*4882a593Smuzhiyun xf86Msg(X_WARNING,
256*4882a593Smuzhiyun "could not get frame buffer identifier from %s\n",
257*4882a593Smuzhiyun xf86SolarisFbDev);
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun else {
260*4882a593Smuzhiyun xf86Msg(X_PROBED, "console driver: %s\n", visid.name);
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun /* Special case from before the general case was set */
263*4882a593Smuzhiyun if (strcmp(visid.name, "NVDAnvda") == 0) {
264*4882a593Smuzhiyun xf86AddMatchedDriver(md, "nvidia");
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun /* General case - split into vendor name (initial all-caps
268*4882a593Smuzhiyun prefix) & driver name (rest of the string). */
269*4882a593Smuzhiyun if (strcmp(visid.name, "SUNWtext") != 0) {
270*4882a593Smuzhiyun for (cp = visid.name; (*cp != '\0') && isupper(*cp); cp++) {
271*4882a593Smuzhiyun /* find end of all uppercase vendor section */
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun if ((cp != visid.name) && (*cp != '\0')) {
274*4882a593Smuzhiyun char *vendorName = xnfstrdup(visid.name);
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun vendorName[cp - visid.name] = '\0';
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun xf86AddMatchedDriver(md, vendorName);
279*4882a593Smuzhiyun xf86AddMatchedDriver(md, cp);
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun free(vendorName);
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun #endif
287*4882a593Smuzhiyun #ifdef __sparc__
288*4882a593Smuzhiyun char *sbusDriver = sparcDriverName();
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun if (sbusDriver)
291*4882a593Smuzhiyun xf86AddMatchedDriver(md, sbusDriver);
292*4882a593Smuzhiyun #endif
293*4882a593Smuzhiyun #ifdef XSERVER_LIBPCIACCESS
294*4882a593Smuzhiyun xf86PciMatchDriver(md);
295*4882a593Smuzhiyun #endif
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun #if defined(__linux__)
298*4882a593Smuzhiyun xf86AddMatchedDriver(md, "modesetting");
299*4882a593Smuzhiyun #endif
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun #if !defined(__sun)
302*4882a593Smuzhiyun /* Fallback to platform default frame buffer driver */
303*4882a593Smuzhiyun #if !defined(__linux__) && defined(__sparc__)
304*4882a593Smuzhiyun xf86AddMatchedDriver(md, "wsfb");
305*4882a593Smuzhiyun #else
306*4882a593Smuzhiyun xf86AddMatchedDriver(md, "fbdev");
307*4882a593Smuzhiyun #endif
308*4882a593Smuzhiyun #endif /* !__sun */
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun /* Fallback to platform default hardware */
311*4882a593Smuzhiyun #if defined(__i386__) || defined(__amd64__) || defined(__hurd__)
312*4882a593Smuzhiyun xf86AddMatchedDriver(md, "vesa");
313*4882a593Smuzhiyun #elif defined(__sparc__) && !defined(__sun)
314*4882a593Smuzhiyun xf86AddMatchedDriver(md, "sunffb");
315*4882a593Smuzhiyun #endif
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun /* copy a screen section and enter the desired driver
319*4882a593Smuzhiyun * and insert it at i in the list of screens */
320*4882a593Smuzhiyun static Bool
copyScreen(confScreenPtr oscreen,GDevPtr odev,int i,char * driver)321*4882a593Smuzhiyun copyScreen(confScreenPtr oscreen, GDevPtr odev, int i, char *driver)
322*4882a593Smuzhiyun {
323*4882a593Smuzhiyun confScreenPtr nscreen;
324*4882a593Smuzhiyun GDevPtr cptr = NULL;
325*4882a593Smuzhiyun char *identifier;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun nscreen = malloc(sizeof(confScreenRec));
328*4882a593Smuzhiyun if (!nscreen)
329*4882a593Smuzhiyun return FALSE;
330*4882a593Smuzhiyun memcpy(nscreen, oscreen, sizeof(confScreenRec));
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun cptr = malloc(sizeof(GDevRec));
333*4882a593Smuzhiyun if (!cptr) {
334*4882a593Smuzhiyun free(nscreen);
335*4882a593Smuzhiyun return FALSE;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun memcpy(cptr, odev, sizeof(GDevRec));
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun if (asprintf(&identifier, "Autoconfigured Video Device %s", driver)
340*4882a593Smuzhiyun == -1) {
341*4882a593Smuzhiyun free(cptr);
342*4882a593Smuzhiyun free(nscreen);
343*4882a593Smuzhiyun return FALSE;
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun cptr->driver = driver;
346*4882a593Smuzhiyun cptr->identifier = identifier;
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun xf86ConfigLayout.screens[i].screen = nscreen;
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun /* now associate the new driver entry with the new screen entry */
351*4882a593Smuzhiyun xf86ConfigLayout.screens[i].screen->device = cptr;
352*4882a593Smuzhiyun cptr->myScreenSection = xf86ConfigLayout.screens[i].screen;
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun return TRUE;
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun GDevPtr
autoConfigDevice(GDevPtr preconf_device)358*4882a593Smuzhiyun autoConfigDevice(GDevPtr preconf_device)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun GDevPtr ptr = NULL;
361*4882a593Smuzhiyun XF86MatchedDrivers md;
362*4882a593Smuzhiyun int num_screens = 0, i;
363*4882a593Smuzhiyun screenLayoutPtr slp;
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun if (!xf86configptr) {
366*4882a593Smuzhiyun return NULL;
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun /* If there's a configured section with no driver chosen, use it */
370*4882a593Smuzhiyun if (preconf_device) {
371*4882a593Smuzhiyun ptr = preconf_device;
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun else {
374*4882a593Smuzhiyun ptr = calloc(1, sizeof(GDevRec));
375*4882a593Smuzhiyun if (!ptr) {
376*4882a593Smuzhiyun return NULL;
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun ptr->chipID = -1;
379*4882a593Smuzhiyun ptr->chipRev = -1;
380*4882a593Smuzhiyun ptr->irq = -1;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun ptr->active = TRUE;
383*4882a593Smuzhiyun ptr->claimed = FALSE;
384*4882a593Smuzhiyun ptr->identifier = "Autoconfigured Video Device";
385*4882a593Smuzhiyun ptr->driver = NULL;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun if (!ptr->driver) {
388*4882a593Smuzhiyun /* get all possible video drivers and count them */
389*4882a593Smuzhiyun listPossibleVideoDrivers(&md);
390*4882a593Smuzhiyun for (i = 0; i < md.nmatches; i++) {
391*4882a593Smuzhiyun xf86Msg(X_DEFAULT, "Matched %s as autoconfigured driver %d\n",
392*4882a593Smuzhiyun md.matches[i], i);
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun slp = xf86ConfigLayout.screens;
396*4882a593Smuzhiyun if (slp) {
397*4882a593Smuzhiyun /* count the number of screens and make space for
398*4882a593Smuzhiyun * a new screen for each additional possible driver
399*4882a593Smuzhiyun * minus one for the already existing first one
400*4882a593Smuzhiyun * plus one for the terminating NULL */
401*4882a593Smuzhiyun for (; slp[num_screens].screen; num_screens++);
402*4882a593Smuzhiyun xf86ConfigLayout.screens = xnfcalloc(num_screens + md.nmatches,
403*4882a593Smuzhiyun sizeof(screenLayoutRec));
404*4882a593Smuzhiyun xf86ConfigLayout.screens[0] = slp[0];
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun /* do the first match and set that for the original first screen */
407*4882a593Smuzhiyun ptr->driver = md.matches[0];
408*4882a593Smuzhiyun if (!xf86ConfigLayout.screens[0].screen->device) {
409*4882a593Smuzhiyun xf86ConfigLayout.screens[0].screen->device = ptr;
410*4882a593Smuzhiyun ptr->myScreenSection = xf86ConfigLayout.screens[0].screen;
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun /* for each other driver found, copy the first screen, insert it
414*4882a593Smuzhiyun * into the list of screens and set the driver */
415*4882a593Smuzhiyun for (i = 1; i < md.nmatches; i++) {
416*4882a593Smuzhiyun if (!copyScreen(slp[0].screen, ptr, i, md.matches[i]))
417*4882a593Smuzhiyun return NULL;
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun /* shift the rest of the original screen list
421*4882a593Smuzhiyun * to the end of the current screen list
422*4882a593Smuzhiyun *
423*4882a593Smuzhiyun * TODO Handle rest of multiple screen sections */
424*4882a593Smuzhiyun for (i = 1; i < num_screens; i++) {
425*4882a593Smuzhiyun xf86ConfigLayout.screens[i + md.nmatches] = slp[i];
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun xf86ConfigLayout.screens[num_screens + md.nmatches - 1].screen =
428*4882a593Smuzhiyun NULL;
429*4882a593Smuzhiyun free(slp);
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun else {
432*4882a593Smuzhiyun /* layout does not have any screens, not much to do */
433*4882a593Smuzhiyun ptr->driver = md.matches[0];
434*4882a593Smuzhiyun for (i = 1; i < md.nmatches; i++) {
435*4882a593Smuzhiyun free(md.matches[i]);
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun }
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun xf86Msg(X_DEFAULT, "Assigned the driver to the xf86ConfigLayout\n");
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun return ptr;
443*4882a593Smuzhiyun }
444