First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / utils / xorgconfig / cards.c
blob8116f0a03b95ab5c4ea4319af6a1843f34c53764
1 /*
2 * Functions to manipulate card database.
3 */
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
9 #include "cards.h"
11 /* Some vars to make path names in texts more flexible. */
12 #ifndef PROJECTROOT
13 # define PROJECTROOT "/usr"
14 #endif
15 #define TREEROOT PROJECTROOT
16 #define TREEROOTLX TREEROOT "/lib/X11"
17 #define TREEROOTCFG TREEROOT "/etc/X11"
18 #ifdef XDOCDIR
19 # define TREEROOTDOC XDOCDIR
20 #else
21 # define TREEROOTDOC TREEROOTLX "/doc"
22 #endif
25 * Database format:
27 * NAME <name of card>
28 * CHIPSET <chipset description>
29 * SERVER <server name>
30 * DRIVER <driver name>
32 * Optional keywords:
33 * RAMDAC <ramdac identifier>
34 * CLOCKCHIP <clockchip identifier>
35 * DACSPEED <dacspeed>
36 * NOCLOCKPROBE
37 * UNSUPPORTED
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,
43 * P9000, AGX, W32.
45 * A useful additional keywords may be CLOCKS.
50 /* Database vars. */
52 int lastcard;
54 Card card[MAX_CARDS];
57 static int
58 getnextline(FILE *f, char *l)
60 if (fgets(l, 128, f) == NULL)
61 return -1;
62 return 0;
65 static void
66 appendstring(char **destp, char *src)
68 char *newstr;
69 newstr = malloc(strlen(*destp) + strlen(src) + 1);
70 strcpy(newstr, *destp);
71 strcat(newstr, src);
72 if (strlen(*destp) > 0)
73 free(*destp);
74 *destp = newstr;
77 int
78 lookupcard(char *name) {
79 int i;
80 for (i = 0; i <= lastcard; i++)
81 if (strcmp(name, card[i].name) == 0)
82 return i;
83 return -1;
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"
90 "#\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() {
101 FILE *f;
102 char buf[128];
103 int i, lineno;
104 char filename[128];
106 strcpy(filename, CARD_DATABASE_FILE);
107 f = fopen(filename, "r");
108 if (f == NULL)
109 return -1;
111 lastcard = -1;
112 lineno = 0;
114 for (;;) {
115 if (getnextline(f, buf))
116 break;
117 lineno++;
118 if (buf[0] == '#')
119 /* Comment. */
120 continue;
121 if (strncmp(buf, "END", 3) == 0)
122 /* End of database. */
123 break;
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);
128 continue;
131 * The following keywords require the trailing newline
132 * to be deleted.
134 i = strlen(buf);
135 buf[--i] = '\0';
137 /* remove trailing spaces or tabs */
138 for(--i; i>=0 && (buf[i] == ' ' || buf[i] == '\011'); i--) ;
139 if (i>=0)
140 buf[i+1] = '\0';
141 else
142 continue; /* skip empty lines */
144 if (strncmp(buf, "NAME", 4) == 0) {
145 /* New entry. */
146 lastcard++;
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 = "";
157 continue;
159 if (lastcard < 0) /* no NAME line found yet */
160 continue;
161 if (strncmp(buf, "SEE", 3) == 0) {
162 /* Reference to another entry. */
163 int i;
164 i = lookupcard(buf + 4);
165 if (i == -1) {
166 printf("Error in database, invalid reference: %s.\n",
167 buf + 4);
168 free(card[lastcard].name);
169 lastcard--;
170 continue;
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);
186 continue;
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);
192 continue;
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);
198 continue;
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);
204 continue;
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);
210 continue;
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;
217 continue;
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);
223 continue;
225 if (strncmp(buf, "NOCLOCKPROBE", 12) == 0) {
226 card[lastcard].flags |= NOCLOCKPROBE;
227 continue;
229 if (strncmp(buf, "UNSUPPORTED", 12) == 0) {
230 card[lastcard].flags |= UNSUPPORTED;
231 continue;
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);
238 keypress();
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);
245 keypress();
246 card[lastcard].chipset = "unknown";
250 fclose(f);
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);
263 sort_database();
265 return 0;
268 static int
269 compare_card(const void *e1, const void *e2)
271 return strcmp(((Card *)e1)->name, ((Card *)e2)->name);
274 void
275 sort_database() {
276 /* Each element is a bunch of words, but nothing too bad. */
277 qsort(card, lastcard + 1, sizeof(Card), compare_card);