2 * Functions to manipulate card database.
11 /* Some vars to make path names in texts more flexible. */
13 # define PROJECTROOT "/usr"
15 #define TREEROOT PROJECTROOT
16 #define TREEROOTLX TREEROOT "/lib/X11"
17 #define TREEROOTCFG TREEROOT "/etc/X11"
19 # define TREEROOTDOC XDOCDIR
21 # define TREEROOTDOC TREEROOTLX "/doc"
28 * CHIPSET <chipset description>
29 * SERVER <server name>
30 * DRIVER <driver name>
33 * RAMDAC <ramdac identifier>
34 * CLOCKCHIP <clockchip identifier>
39 * SEE <name of card> refers to another card definition; parameters that
40 * are already defined are not overridden.
42 * <server name> is one of Mono, VGA16, SVGA, S3, Mach32, Mach8, 8514,
45 * A useful additional keywords may be CLOCKS.
58 getnextline(FILE *f
, char *l
)
60 if (fgets(l
, 128, f
) == NULL
)
66 appendstring(char **destp
, char *src
)
69 newstr
= malloc(strlen(*destp
) + strlen(src
) + 1);
70 strcpy(newstr
, *destp
);
72 if (strlen(*destp
) > 0)
78 lookupcard(char *name
) {
80 for (i
= 0; i
<= lastcard
; i
++)
81 if (strcmp(name
, card
[i
].name
) == 0)
86 static char *s3_comment
=
87 "# Use Option \"nolinear\" if the server doesn't start up correctly\n"
88 "# (this avoids the linear framebuffer probe). If that fails try\n"
89 "# option \"nomemaccess\".\n"
91 "# Refer to " TREEROOTDOC
"/README.S3, and the XF86_S3 man page.\n";
93 static char *cirrus_comment
=
94 "# Use Option \"no_bitblt\" if you have graphics problems. If that fails\n"
95 "# try Option \"noaccel\".\n"
96 "# Refer to " TREEROOTDOC
"/README.cirrus.\n"
97 "# To allow linear addressing, uncomment the Option line and the\n"
98 "# address that the card maps the framebuffer to.\n";
100 int parse_database() {
106 strcpy(filename
, CARD_DATABASE_FILE
);
107 f
= fopen(filename
, "r");
115 if (getnextline(f
, buf
))
121 if (strncmp(buf
, "END", 3) == 0)
122 /* End of database. */
124 if (strncmp(buf
, "LINE", 4) == 0 && lastcard
>=0) {
125 /* Line of Device comment. */
126 /* Append to existing lines. */
127 appendstring(&card
[lastcard
].lines
, buf
+ 5);
131 * The following keywords require the trailing newline
137 /* remove trailing spaces or tabs */
138 for(--i
; i
>=0 && (buf
[i
] == ' ' || buf
[i
] == '\011'); i
--) ;
142 continue; /* skip empty lines */
144 if (strncmp(buf
, "NAME", 4) == 0) {
147 card
[lastcard
].name
= malloc(strlen(buf
+ 5) + 1);
148 strcpy(card
[lastcard
].name
, buf
+ 5);
149 card
[lastcard
].chipset
= NULL
;
150 card
[lastcard
].server
= NULL
;
151 card
[lastcard
].driver
= NULL
;
152 card
[lastcard
].ramdac
= NULL
;
153 card
[lastcard
].clockchip
= NULL
;
154 card
[lastcard
].dacspeed
= NULL
;
155 card
[lastcard
].flags
= 0;
156 card
[lastcard
].lines
= "";
159 if (lastcard
< 0) /* no NAME line found yet */
161 if (strncmp(buf
, "SEE", 3) == 0) {
162 /* Reference to another entry. */
164 i
= lookupcard(buf
+ 4);
166 printf("Error in database, invalid reference: %s.\n",
168 free(card
[lastcard
].name
);
172 if (card
[lastcard
].chipset
== NULL
)
173 card
[lastcard
].chipset
= card
[i
].chipset
;
174 if (card
[lastcard
].server
== NULL
)
175 card
[lastcard
].server
= card
[i
].server
;
176 if (card
[lastcard
].driver
== NULL
)
177 card
[lastcard
].driver
= card
[i
].driver
;
178 if (card
[lastcard
].ramdac
== NULL
)
179 card
[lastcard
].ramdac
= card
[i
].ramdac
;
180 if (card
[lastcard
].clockchip
== NULL
)
181 card
[lastcard
].clockchip
= card
[i
].clockchip
;
182 if (card
[lastcard
].dacspeed
== NULL
)
183 card
[lastcard
].dacspeed
= card
[i
].dacspeed
;
184 card
[lastcard
].flags
|= card
[i
].flags
;
185 appendstring(&card
[lastcard
].lines
, card
[i
].lines
);
188 if (strncmp(buf
, "CHIPSET", 7) == 0) {
189 /* Chipset description. */
190 card
[lastcard
].chipset
= malloc(strlen(buf
+ 8) + 1);
191 strcpy(card
[lastcard
].chipset
, buf
+ 8);
194 if (strncmp(buf
, "SERVER", 6) == 0) {
195 /* Server identifier. */
196 card
[lastcard
].server
= malloc(strlen(buf
+ 7) + 1);
197 strcpy(card
[lastcard
].server
, buf
+ 7);
200 if (strncmp(buf
, "DRIVER", 6) == 0) {
201 /* Driver identifier. */
202 card
[lastcard
].driver
= malloc(strlen(buf
+ 7) + 1);
203 strcpy(card
[lastcard
].driver
, buf
+ 7);
206 if (strncmp(buf
, "RAMDAC", 6) == 0) {
207 /* Ramdac indentifier. */
208 card
[lastcard
].ramdac
= malloc(strlen(buf
+ 7) + 1);
209 strcpy(card
[lastcard
].ramdac
, buf
+ 7);
212 if (strncmp(buf
, "CLOCKCHIP", 9) == 0) {
213 /* Clockchip indentifier. */
214 card
[lastcard
].clockchip
= malloc(strlen(buf
+ 10) + 1);
215 strcpy(card
[lastcard
].clockchip
, buf
+ 10);
216 card
[lastcard
].flags
|= NOCLOCKPROBE
;
219 if (strncmp(buf
, "DACSPEED", 8) == 0) {
220 /* Clockchip indentifier. */
221 card
[lastcard
].dacspeed
= malloc(strlen(buf
+ 9) + 1);
222 strcpy(card
[lastcard
].dacspeed
, buf
+ 9);
225 if (strncmp(buf
, "NOCLOCKPROBE", 12) == 0) {
226 card
[lastcard
].flags
|= NOCLOCKPROBE
;
229 if (strncmp(buf
, "UNSUPPORTED", 12) == 0) {
230 card
[lastcard
].flags
|= UNSUPPORTED
;
233 /* test for missing required fields */
234 if (card
[lastcard
].driver
== NULL
) {
235 fprintf(stderr
, "Warning DRIVER specification missing "
236 "in Card database entry %s (line %d).\n",
237 card
[lastcard
].name
, lineno
);
239 card
[lastcard
].driver
= "unknown";
241 if (card
[lastcard
].chipset
== NULL
) {
242 fprintf(stderr
, "Warning CHIPSET specification missing "
243 "in Card database entry %s (line %d).\n",
244 card
[lastcard
].name
, lineno
);
246 card
[lastcard
].chipset
= "unknown";
253 * Add general comments.
255 for (i
= 0; i
<= lastcard
; i
++) {
256 if (card
[i
].server
&& strcmp(card
[i
].server
, "S3") == 0)
257 appendstring(&card
[i
].lines
, s3_comment
);
258 if (card
[i
].chipset
&&
259 strncmp(card
[i
].chipset
, "CL-GD", 5) == 0)
260 appendstring(&card
[i
].lines
, cirrus_comment
);
269 compare_card(const void *e1
, const void *e2
)
271 return strcmp(((Card
*)e1
)->name
, ((Card
*)e2
)->name
);
276 /* Each element is a bunch of words, but nothing too bad. */
277 qsort(card
, lastcard
+ 1, sizeof(Card
), compare_card
);