diff options
Diffstat (limited to 'xorg-server/hw/xfree86/utils/xorgconfig/cards.c')
-rw-r--r-- | xorg-server/hw/xfree86/utils/xorgconfig/cards.c | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/xorg-server/hw/xfree86/utils/xorgconfig/cards.c b/xorg-server/hw/xfree86/utils/xorgconfig/cards.c new file mode 100644 index 000000000..8116f0a03 --- /dev/null +++ b/xorg-server/hw/xfree86/utils/xorgconfig/cards.c @@ -0,0 +1,278 @@ +/* + * Functions to manipulate card database. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "cards.h" + +/* Some vars to make path names in texts more flexible. */ +#ifndef PROJECTROOT +# define PROJECTROOT "/usr" +#endif +#define TREEROOT PROJECTROOT +#define TREEROOTLX TREEROOT "/lib/X11" +#define TREEROOTCFG TREEROOT "/etc/X11" +#ifdef XDOCDIR +# define TREEROOTDOC XDOCDIR +#else +# define TREEROOTDOC TREEROOTLX "/doc" +#endif + +/* + * Database format: + * + * NAME <name of card> + * CHIPSET <chipset description> + * SERVER <server name> + * DRIVER <driver name> + * + * Optional keywords: + * RAMDAC <ramdac identifier> + * CLOCKCHIP <clockchip identifier> + * DACSPEED <dacspeed> + * NOCLOCKPROBE + * UNSUPPORTED + * + * SEE <name of card> refers to another card definition; parameters that + * are already defined are not overridden. + * + * <server name> is one of Mono, VGA16, SVGA, S3, Mach32, Mach8, 8514, + * P9000, AGX, W32. + * + * A useful additional keywords may be CLOCKS. + */ + + + +/* Database vars. */ + +int lastcard; + +Card card[MAX_CARDS]; + + +static int +getnextline(FILE *f, char *l) +{ + if (fgets(l, 128, f) == NULL) + return -1; + return 0; +} + +static void +appendstring(char **destp, char *src) +{ + char *newstr; + newstr = malloc(strlen(*destp) + strlen(src) + 1); + strcpy(newstr, *destp); + strcat(newstr, src); + if (strlen(*destp) > 0) + free(*destp); + *destp = newstr; +} + +int +lookupcard(char *name) { + int i; + for (i = 0; i <= lastcard; i++) + if (strcmp(name, card[i].name) == 0) + return i; + return -1; +} + +static char *s3_comment = +"# Use Option \"nolinear\" if the server doesn't start up correctly\n" +"# (this avoids the linear framebuffer probe). If that fails try\n" +"# option \"nomemaccess\".\n" +"#\n" +"# Refer to " TREEROOTDOC "/README.S3, and the XF86_S3 man page.\n"; + +static char *cirrus_comment = +"# Use Option \"no_bitblt\" if you have graphics problems. If that fails\n" +"# try Option \"noaccel\".\n" +"# Refer to " TREEROOTDOC "/README.cirrus.\n" +"# To allow linear addressing, uncomment the Option line and the\n" +"# address that the card maps the framebuffer to.\n"; + +int parse_database() { + FILE *f; + char buf[128]; + int i, lineno; + char filename[128]; + + strcpy(filename, CARD_DATABASE_FILE); + f = fopen(filename, "r"); + if (f == NULL) + return -1; + + lastcard = -1; + lineno = 0; + + for (;;) { + if (getnextline(f, buf)) + break; + lineno++; + if (buf[0] == '#') + /* Comment. */ + continue; + if (strncmp(buf, "END", 3) == 0) + /* End of database. */ + break; + if (strncmp(buf, "LINE", 4) == 0 && lastcard>=0) { + /* Line of Device comment. */ + /* Append to existing lines. */ + appendstring(&card[lastcard].lines, buf + 5); + continue; + } + /* + * The following keywords require the trailing newline + * to be deleted. + */ + i = strlen(buf); + buf[--i] = '\0'; + + /* remove trailing spaces or tabs */ + for(--i; i>=0 && (buf[i] == ' ' || buf[i] == '\011'); i--) ; + if (i>=0) + buf[i+1] = '\0'; + else + continue; /* skip empty lines */ + + if (strncmp(buf, "NAME", 4) == 0) { + /* New entry. */ + lastcard++; + card[lastcard].name = malloc(strlen(buf + 5) + 1); + strcpy(card[lastcard].name, buf + 5); + card[lastcard].chipset = NULL; + card[lastcard].server = NULL; + card[lastcard].driver = NULL; + card[lastcard].ramdac = NULL; + card[lastcard].clockchip = NULL; + card[lastcard].dacspeed = NULL; + card[lastcard].flags = 0; + card[lastcard].lines = ""; + continue; + } + if (lastcard < 0) /* no NAME line found yet */ + continue; + if (strncmp(buf, "SEE", 3) == 0) { + /* Reference to another entry. */ + int i; + i = lookupcard(buf + 4); + if (i == -1) { + printf("Error in database, invalid reference: %s.\n", + buf + 4); + free(card[lastcard].name); + lastcard--; + continue; + } + if (card[lastcard].chipset == NULL) + card[lastcard].chipset = card[i].chipset; + if (card[lastcard].server == NULL) + card[lastcard].server = card[i].server; + if (card[lastcard].driver == NULL) + card[lastcard].driver = card[i].driver; + if (card[lastcard].ramdac == NULL) + card[lastcard].ramdac = card[i].ramdac; + if (card[lastcard].clockchip == NULL) + card[lastcard].clockchip = card[i].clockchip; + if (card[lastcard].dacspeed == NULL) + card[lastcard].dacspeed = card[i].dacspeed; + card[lastcard].flags |= card[i].flags; + appendstring(&card[lastcard].lines, card[i].lines); + continue; + } + if (strncmp(buf, "CHIPSET", 7) == 0) { + /* Chipset description. */ + card[lastcard].chipset = malloc(strlen(buf + 8) + 1); + strcpy(card[lastcard].chipset, buf + 8); + continue; + } + if (strncmp(buf, "SERVER", 6) == 0) { + /* Server identifier. */ + card[lastcard].server = malloc(strlen(buf + 7) + 1); + strcpy(card[lastcard].server, buf + 7); + continue; + } + if (strncmp(buf, "DRIVER", 6) == 0) { + /* Driver identifier. */ + card[lastcard].driver = malloc(strlen(buf + 7) + 1); + strcpy(card[lastcard].driver, buf + 7); + continue; + } + if (strncmp(buf, "RAMDAC", 6) == 0) { + /* Ramdac indentifier. */ + card[lastcard].ramdac = malloc(strlen(buf + 7) + 1); + strcpy(card[lastcard].ramdac, buf + 7); + continue; + } + if (strncmp(buf, "CLOCKCHIP", 9) == 0) { + /* Clockchip indentifier. */ + card[lastcard].clockchip = malloc(strlen(buf + 10) + 1); + strcpy(card[lastcard].clockchip, buf + 10); + card[lastcard].flags |= NOCLOCKPROBE; + continue; + } + if (strncmp(buf, "DACSPEED", 8) == 0) { + /* Clockchip indentifier. */ + card[lastcard].dacspeed = malloc(strlen(buf + 9) + 1); + strcpy(card[lastcard].dacspeed, buf + 9); + continue; + } + if (strncmp(buf, "NOCLOCKPROBE", 12) == 0) { + card[lastcard].flags |= NOCLOCKPROBE; + continue; + } + if (strncmp(buf, "UNSUPPORTED", 12) == 0) { + card[lastcard].flags |= UNSUPPORTED; + continue; + } + /* test for missing required fields */ + if (card[lastcard].driver == NULL) { + fprintf(stderr, "Warning DRIVER specification missing " + "in Card database entry %s (line %d).\n", + card[lastcard].name, lineno); + keypress(); + card[lastcard].driver = "unknown"; + } + if (card[lastcard].chipset == NULL) { + fprintf(stderr, "Warning CHIPSET specification missing " + "in Card database entry %s (line %d).\n", + card[lastcard].name, lineno); + keypress(); + card[lastcard].chipset = "unknown"; + } + } + + fclose(f); + + /* + * Add general comments. + */ + for (i = 0; i <= lastcard; i++) { + if (card[i].server && strcmp(card[i].server, "S3") == 0) + appendstring(&card[i].lines, s3_comment); + if (card[i].chipset && + strncmp(card[i].chipset, "CL-GD", 5) == 0) + appendstring(&card[i].lines, cirrus_comment); + } + + sort_database(); + + return 0; +} + +static int +compare_card(const void *e1, const void *e2) +{ + return strcmp(((Card *)e1)->name, ((Card *)e2)->name); +} + +void +sort_database() { + /* Each element is a bunch of words, but nothing too bad. */ + qsort(card, lastcard + 1, sizeof(Card), compare_card); +} |