xref: /plan9/sys/src/cmd/aux/vga/db.c (revision b0dcc5a8c7c5c46439edae0dfc71a5fd27bb2a41)
1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier #include <bio.h>
4219b2ee8SDavid du Colombier #include <ndb.h>
5219b2ee8SDavid du Colombier 
69a747e4fSDavid du Colombier #include "pci.h"
7219b2ee8SDavid du Colombier #include "vga.h"
8219b2ee8SDavid du Colombier 
9219b2ee8SDavid du Colombier static Ndb*
dbopen(char * dbname)10219b2ee8SDavid du Colombier dbopen(char* dbname)
11219b2ee8SDavid du Colombier {
12219b2ee8SDavid du Colombier 	Ndb *db;
13219b2ee8SDavid du Colombier 
14219b2ee8SDavid du Colombier 	if((db = ndbopen(dbname)) == 0)
15219b2ee8SDavid du Colombier 		error("dbopen: %s: %r\n", dbname);
16219b2ee8SDavid du Colombier 	return db;
17219b2ee8SDavid du Colombier }
18219b2ee8SDavid du Colombier 
197dd7cddfSDavid du Colombier static void
addattr(Attr ** app,Ndbtuple * t)207dd7cddfSDavid du Colombier addattr(Attr** app, Ndbtuple* t)
217dd7cddfSDavid du Colombier {
227dd7cddfSDavid du Colombier 	Attr *attr, *l;
237dd7cddfSDavid du Colombier 
247dd7cddfSDavid du Colombier 	attr = alloc(sizeof(Attr));
257dd7cddfSDavid du Colombier 	attr->attr = alloc(strlen(t->attr)+1);
267dd7cddfSDavid du Colombier 	strcpy(attr->attr, t->attr);
277dd7cddfSDavid du Colombier 	attr->val = alloc(strlen(t->val)+1);
287dd7cddfSDavid du Colombier 	strcpy(attr->val, t->val);
297dd7cddfSDavid du Colombier 
307dd7cddfSDavid du Colombier 	for(l = *app; l; l = l->next)
317dd7cddfSDavid du Colombier 		app = &l->next;
327dd7cddfSDavid du Colombier 	*app = attr;
337dd7cddfSDavid du Colombier }
347dd7cddfSDavid du Colombier 
357dd7cddfSDavid du Colombier char*
dbattr(Attr * ap,char * attr)367dd7cddfSDavid du Colombier dbattr(Attr* ap, char* attr)
377dd7cddfSDavid du Colombier {
387dd7cddfSDavid du Colombier 	while(ap){
397dd7cddfSDavid du Colombier 		if(strcmp(ap->attr, attr) == 0)
407dd7cddfSDavid du Colombier 			return ap->val;
417dd7cddfSDavid du Colombier 		ap = ap->next;
427dd7cddfSDavid du Colombier 	}
437dd7cddfSDavid du Colombier 
447dd7cddfSDavid du Colombier 	return 0;
457dd7cddfSDavid du Colombier }
467dd7cddfSDavid du Colombier 
47219b2ee8SDavid du Colombier static Ctlr*
addctlr(Vga * vga,char * val)48219b2ee8SDavid du Colombier addctlr(Vga* vga, char* val)
49219b2ee8SDavid du Colombier {
50219b2ee8SDavid du Colombier 	Ctlr **ctlr;
519a747e4fSDavid du Colombier 	char name[Namelen+1], *p;
52219b2ee8SDavid du Colombier 	int i;
53219b2ee8SDavid du Colombier 
54219b2ee8SDavid du Colombier 	/*
55219b2ee8SDavid du Colombier 	 * A controller name may have an extension on the end
56219b2ee8SDavid du Colombier 	 * following a '-' which can be used as a speed grade or
57219b2ee8SDavid du Colombier 	 * subtype.  Do the match without the extension.
58219b2ee8SDavid du Colombier 	 * The linked copy of the controller struct gets the
59219b2ee8SDavid du Colombier 	 * full name with extension.
60219b2ee8SDavid du Colombier 	 */
619a747e4fSDavid du Colombier 	strncpy(name, val, Namelen);
629a747e4fSDavid du Colombier 	name[Namelen] = 0;
63219b2ee8SDavid du Colombier 	if(p = strchr(name, '-'))
64219b2ee8SDavid du Colombier 		*p = 0;
65219b2ee8SDavid du Colombier 
66219b2ee8SDavid du Colombier 	for(i = 0; ctlrs[i]; i++){
67219b2ee8SDavid du Colombier 		if(strcmp(ctlrs[i]->name, name))
68219b2ee8SDavid du Colombier 			continue;
69219b2ee8SDavid du Colombier 		for(ctlr = &vga->link; *ctlr; ctlr = &((*ctlr)->link))
70219b2ee8SDavid du Colombier 			;
71219b2ee8SDavid du Colombier 		*ctlr = alloc(sizeof(Ctlr));
72219b2ee8SDavid du Colombier 		**ctlr = *ctlrs[i];
739a747e4fSDavid du Colombier 		strncpy((*ctlr)->name, val, Namelen);
74219b2ee8SDavid du Colombier 		return *ctlr;
75219b2ee8SDavid du Colombier 	}
76219b2ee8SDavid du Colombier 
77*b0dcc5a8SDavid du Colombier 	fprint(2, "dbctlr: unknown controller \"%s\" ctlr\n", val);
78219b2ee8SDavid du Colombier 	return 0;
79219b2ee8SDavid du Colombier }
80219b2ee8SDavid du Colombier 
81219b2ee8SDavid du Colombier int
dbbios(Vga * vga,Ndbtuple * tuple)829a747e4fSDavid du Colombier dbbios(Vga *vga, Ndbtuple *tuple)
83219b2ee8SDavid du Colombier {
847dd7cddfSDavid du Colombier 	char *bios, *p, *string;
85219b2ee8SDavid du Colombier 	int len;
869a747e4fSDavid du Colombier 	long offset, offset1;
879a747e4fSDavid du Colombier 	Ndbtuple *t;
88219b2ee8SDavid du Colombier 
89219b2ee8SDavid du Colombier 	for(t = tuple->entry; t; t = t->entry){
907dd7cddfSDavid du Colombier 		if((offset = strtol(t->attr, 0, 0)) == 0)
91219b2ee8SDavid du Colombier 			continue;
92219b2ee8SDavid du Colombier 
93219b2ee8SDavid du Colombier 		string = t->val;
94219b2ee8SDavid du Colombier 		len = strlen(string);
957dd7cddfSDavid du Colombier 
967dd7cddfSDavid du Colombier 		if(p = strchr(t->attr, '-')) {
977dd7cddfSDavid du Colombier 			if((offset1 = strtol(p+1, 0, 0)) < offset+len)
987dd7cddfSDavid du Colombier 				continue;
997dd7cddfSDavid du Colombier 		} else
1007dd7cddfSDavid du Colombier 			offset1 = offset+len;
1017dd7cddfSDavid du Colombier 
1027dd7cddfSDavid du Colombier 		if(vga->offset) {
1037dd7cddfSDavid du Colombier 			if(offset > vga->offset || vga->offset+len > offset1)
1047dd7cddfSDavid du Colombier 				continue;
1057dd7cddfSDavid du Colombier 			offset = vga->offset;
1067dd7cddfSDavid du Colombier 			offset1 = offset+len;
1077dd7cddfSDavid du Colombier 		}
1087dd7cddfSDavid du Colombier 
1097dd7cddfSDavid du Colombier 		for(; offset+len<=offset1; offset++) {
1107dd7cddfSDavid du Colombier 			if(vga->bios)
1117dd7cddfSDavid du Colombier 				bios = vga->bios;
1127dd7cddfSDavid du Colombier 			else
1137dd7cddfSDavid du Colombier 				bios = readbios(len, offset);
114219b2ee8SDavid du Colombier 			if(strncmp(bios, string, len) == 0){
1159a747e4fSDavid du Colombier 				if(vga->bios == 0){
1169a747e4fSDavid du Colombier 					vga->bios = alloc(len+1);
1179a747e4fSDavid du Colombier 					strncpy(vga->bios, bios, len);
1189a747e4fSDavid du Colombier 				}
1197dd7cddfSDavid du Colombier 				addattr(&vga->attr, t);
1209a747e4fSDavid du Colombier 				return 1;
1219a747e4fSDavid du Colombier 			}
1229a747e4fSDavid du Colombier 		}
1239a747e4fSDavid du Colombier 	}
1249a747e4fSDavid du Colombier 	return 0;
1259a747e4fSDavid du Colombier }
1269a747e4fSDavid du Colombier 
1279a747e4fSDavid du Colombier int
dbpci(Vga * vga,Ndbtuple * tuple)1289a747e4fSDavid du Colombier dbpci(Vga *vga, Ndbtuple *tuple)
1299a747e4fSDavid du Colombier {
1309a747e4fSDavid du Colombier 	int did, vid;
1319a747e4fSDavid du Colombier 	Ndbtuple *t, *td;
1329a747e4fSDavid du Colombier 	Pcidev *pci;
1339a747e4fSDavid du Colombier 
1349a747e4fSDavid du Colombier 	for(t = tuple->entry; t; t = t->entry){
1359a747e4fSDavid du Colombier 		if(strcmp(t->attr, "vid") != 0 || (vid=atoi(t->val)) == 0)
1369a747e4fSDavid du Colombier 			continue;
1379a747e4fSDavid du Colombier 		for(td = t->line; td != t; td = td->line){
138fb7f0c93SDavid du Colombier 			if(strcmp(td->attr, "did") != 0)
139fb7f0c93SDavid du Colombier 				continue;
140fb7f0c93SDavid du Colombier 			if(strcmp(td->val, "*") == 0)
141fb7f0c93SDavid du Colombier 				did = 0;
142fb7f0c93SDavid du Colombier 			else if((did=atoi(td->val)) == 0)
143fb7f0c93SDavid du Colombier 				continue;
144fb7f0c93SDavid du Colombier 			for(pci=nil; pci=pcimatch(pci, vid, did);)
145fb7f0c93SDavid du Colombier 				if((pci->ccru>>8) == 3)
146fb7f0c93SDavid du Colombier 					break;
147fb7f0c93SDavid du Colombier 			if(pci == nil)
148fb7f0c93SDavid du Colombier 				continue;
1499a747e4fSDavid du Colombier 			vga->pci = pci;
1509a747e4fSDavid du Colombier 			addattr(&vga->attr, t);
1519a747e4fSDavid du Colombier 			addattr(&vga->attr, td);
1529a747e4fSDavid du Colombier 			return 1;
1539a747e4fSDavid du Colombier 		}
1549a747e4fSDavid du Colombier 	}
1559a747e4fSDavid du Colombier 	return 0;
1569a747e4fSDavid du Colombier }
1579a747e4fSDavid du Colombier 
1589a747e4fSDavid du Colombier static void
save(Vga * vga,Ndbtuple * tuple)1599a747e4fSDavid du Colombier save(Vga *vga, Ndbtuple *tuple)
1609a747e4fSDavid du Colombier {
161*b0dcc5a8SDavid du Colombier 	Ctlr *c;
1629a747e4fSDavid du Colombier 	Ndbtuple *t;
1639a747e4fSDavid du Colombier 
164219b2ee8SDavid du Colombier 	for(t = tuple->entry; t; t = t->entry){
165*b0dcc5a8SDavid du Colombier 		if(strcmp(t->attr, "ctlr") == 0){
166219b2ee8SDavid du Colombier 			vga->ctlr = addctlr(vga, t->val);
167*b0dcc5a8SDavid du Colombier 			if(strcmp(t->val, "vesa") == 0)
168*b0dcc5a8SDavid du Colombier 				vga->vesa = vga->ctlr;
169*b0dcc5a8SDavid du Colombier 		}else if(strcmp(t->attr, "ramdac") == 0)
170219b2ee8SDavid du Colombier 			vga->ramdac = addctlr(vga, t->val);
171219b2ee8SDavid du Colombier 		else if(strcmp(t->attr, "clock") == 0)
172219b2ee8SDavid du Colombier 			vga->clock = addctlr(vga, t->val);
173219b2ee8SDavid du Colombier 		else if(strcmp(t->attr, "hwgc") == 0)
174219b2ee8SDavid du Colombier 			vga->hwgc = addctlr(vga, t->val);
175*b0dcc5a8SDavid du Colombier 		else if(strcmp(t->attr, "link") == 0){
176*b0dcc5a8SDavid du Colombier 			c = addctlr(vga, t->val);
177*b0dcc5a8SDavid du Colombier 			if(strcmp(t->val, "vesa") == 0)
178*b0dcc5a8SDavid du Colombier 				vga->vesa = c;
179*b0dcc5a8SDavid du Colombier 		}else if(strcmp(t->attr, "linear") == 0)
1807dd7cddfSDavid du Colombier 			vga->linear = strtol(t->val, 0, 0);
1817dd7cddfSDavid du Colombier 		else if(strcmp(t->attr, "membw") == 0)
1827dd7cddfSDavid du Colombier 			vga->membw = strtol(t->val, 0, 0)*1000000;
1839a747e4fSDavid du Colombier 		else if(strcmp(t->attr, "vid")==0 || strcmp(t->attr, "did")==0)
1849a747e4fSDavid du Colombier 			{}
1857dd7cddfSDavid du Colombier 		else if(strtol(t->attr, 0, 0) == 0)
1867dd7cddfSDavid du Colombier 			addattr(&vga->attr, t);
187219b2ee8SDavid du Colombier 	}
1887dd7cddfSDavid du Colombier }
1897dd7cddfSDavid du Colombier 
1909a747e4fSDavid du Colombier int
dbctlr(char * name,Vga * vga)1919a747e4fSDavid du Colombier dbctlr(char* name, Vga* vga)
1929a747e4fSDavid du Colombier {
1939a747e4fSDavid du Colombier 	Ndb *db;
1949a747e4fSDavid du Colombier 	Ndbs s;
1959a747e4fSDavid du Colombier 	Ndbtuple *tuple;
1969a747e4fSDavid du Colombier 	Ndbtuple *pcituple;
1979a747e4fSDavid du Colombier 
1989a747e4fSDavid du Colombier 	db = dbopen(name);
1999a747e4fSDavid du Colombier 
2009a747e4fSDavid du Colombier 	/*
2019a747e4fSDavid du Colombier 	 * Search vgadb for a matching BIOS string or PCI id.
2029a747e4fSDavid du Colombier 	 * If we have both, the BIOS string wins.
2039a747e4fSDavid du Colombier 	 */
2049a747e4fSDavid du Colombier 	pcituple = nil;
2059a747e4fSDavid du Colombier 	for(tuple = ndbsearch(db, &s, "ctlr", ""); tuple; tuple = ndbsnext(&s, "ctlr", "")){
2069a747e4fSDavid du Colombier 		if(!pcituple && dbpci(vga, tuple))
2079a747e4fSDavid du Colombier 			pcituple = tuple;
2089a747e4fSDavid du Colombier 		if(dbbios(vga, tuple)){
2099a747e4fSDavid du Colombier 			save(vga, tuple);
2109a747e4fSDavid du Colombier 			if(pcituple && pcituple != tuple)
2119a747e4fSDavid du Colombier 				ndbfree(pcituple);
212219b2ee8SDavid du Colombier 			ndbfree(tuple);
213219b2ee8SDavid du Colombier 			ndbclose(db);
214219b2ee8SDavid du Colombier 			return 1;
215219b2ee8SDavid du Colombier 		}
2169a747e4fSDavid du Colombier 		if(tuple != pcituple)
217219b2ee8SDavid du Colombier 			ndbfree(tuple);
218219b2ee8SDavid du Colombier 	}
219219b2ee8SDavid du Colombier 
2209a747e4fSDavid du Colombier 	if(pcituple){
2219a747e4fSDavid du Colombier 		save(vga, pcituple);
2229a747e4fSDavid du Colombier 		ndbfree(pcituple);
2239a747e4fSDavid du Colombier 	}
224219b2ee8SDavid du Colombier 	ndbclose(db);
2259a747e4fSDavid du Colombier 	if(pcituple)
2269a747e4fSDavid du Colombier 		return 1;
227219b2ee8SDavid du Colombier 	return 0;
228219b2ee8SDavid du Colombier }
229219b2ee8SDavid du Colombier 
230219b2ee8SDavid du Colombier static int
dbmonitor(Ndb * db,Mode * mode,char * type,char * size)231219b2ee8SDavid du Colombier dbmonitor(Ndb* db, Mode* mode, char* type, char* size)
232219b2ee8SDavid du Colombier {
233219b2ee8SDavid du Colombier 	Ndbs s;
234219b2ee8SDavid du Colombier 	Ndbtuple *t, *tuple;
23557837e0bSDavid du Colombier 	char *p, attr[Namelen+1], val[Namelen+1], buf[2*Namelen+1];
236e0d6d19cSDavid du Colombier 	int clock, x, i;
2377dd7cddfSDavid du Colombier 
2387dd7cddfSDavid du Colombier 	/*
2397dd7cddfSDavid du Colombier 	 * Clock rate hack.
2407dd7cddfSDavid du Colombier 	 * If the size is 'XxYxZ@NMHz' then override the database entry's
2417dd7cddfSDavid du Colombier 	 * 'clock=' with 'N*1000000'.
2427dd7cddfSDavid du Colombier 	 */
2437dd7cddfSDavid du Colombier 	clock = 0;
2447dd7cddfSDavid du Colombier 	strcpy(buf, size);
2457dd7cddfSDavid du Colombier 	if(p = strchr(buf, '@')){
2467dd7cddfSDavid du Colombier 		*p++ = 0;
2477dd7cddfSDavid du Colombier 		if((clock = strtol(p, &p, 0)) && strcmp(p, "MHz") == 0)
2487dd7cddfSDavid du Colombier 			clock *= 1000000;
2497dd7cddfSDavid du Colombier 	}
250219b2ee8SDavid du Colombier 
251219b2ee8SDavid du Colombier 	memset(mode, 0, sizeof(Mode));
2527dd7cddfSDavid du Colombier 
2537dd7cddfSDavid du Colombier 	if((p = strchr(buf, 'x')) && (p = strchr(p+1, 'x'))){
2547dd7cddfSDavid du Colombier 		*p++ = 0;
2557dd7cddfSDavid du Colombier 		mode->z = atoi(p);
2567dd7cddfSDavid du Colombier 	}
2577dd7cddfSDavid du Colombier 
258219b2ee8SDavid du Colombier 	strcpy(attr, type);
2597dd7cddfSDavid du Colombier 	strcpy(val, buf);
2607dd7cddfSDavid du Colombier 
26157837e0bSDavid du Colombier 	if(p = ndbgetvalue(db, &s, attr, "", "videobw", nil)){
26257837e0bSDavid du Colombier 		mode->videobw = atol(p)*1000000UL;
26357837e0bSDavid du Colombier 		free(p);
2647dd7cddfSDavid du Colombier 	}
265219b2ee8SDavid du Colombier 
266219b2ee8SDavid du Colombier 	if(mode->x == 0 && ((mode->x = strtol(val, &p, 0)) == 0 || *p++ != 'x'))
267219b2ee8SDavid du Colombier 		return 0;
2687dd7cddfSDavid du Colombier 	if(mode->y == 0 && (mode->y = strtol(p, &p, 0)) == 0)
269219b2ee8SDavid du Colombier 		return 0;
270e0d6d19cSDavid du Colombier 	i = 0;
2717dd7cddfSDavid du Colombier buggery:
2727dd7cddfSDavid du Colombier 	if((tuple = ndbsearch(db, &s, attr, val)) == 0)
273219b2ee8SDavid du Colombier 		return 0;
274219b2ee8SDavid du Colombier 
275219b2ee8SDavid du Colombier 	for(t = tuple->entry; t; t = t->entry){
276219b2ee8SDavid du Colombier 		if(strcmp(t->attr, "clock") == 0 && mode->frequency == 0)
277219b2ee8SDavid du Colombier 			mode->frequency = strtod(t->val, 0)*1000000;
2787dd7cddfSDavid du Colombier 		else if(strcmp(t->attr, "defaultclock") == 0 && mode->deffrequency == 0)
2797dd7cddfSDavid du Colombier 			mode->deffrequency = strtod(t->val, 0)*1000000;
280219b2ee8SDavid du Colombier 		else if(strcmp(t->attr, "ht") == 0 && mode->ht == 0)
281219b2ee8SDavid du Colombier 			mode->ht = strtol(t->val, 0, 0);
282219b2ee8SDavid du Colombier 		else if(strcmp(t->attr, "shb") == 0 && mode->shb == 0)
283219b2ee8SDavid du Colombier 			mode->shb = strtol(t->val, 0, 0);
284219b2ee8SDavid du Colombier 		else if(strcmp(t->attr, "ehb") == 0 && mode->ehb == 0)
285219b2ee8SDavid du Colombier 			mode->ehb = strtol(t->val, 0, 0);
2867dd7cddfSDavid du Colombier 		else if(strcmp(t->attr, "shs") == 0 && mode->shs == 0)
2877dd7cddfSDavid du Colombier 			mode->shs = strtol(t->val, 0, 0);
2887dd7cddfSDavid du Colombier 		else if(strcmp(t->attr, "ehs") == 0 && mode->ehs == 0)
2897dd7cddfSDavid du Colombier 			mode->ehs = strtol(t->val, 0, 0);
290219b2ee8SDavid du Colombier 		else if(strcmp(t->attr, "vt") == 0 && mode->vt == 0)
291219b2ee8SDavid du Colombier 			mode->vt = strtol(t->val, 0, 0);
292219b2ee8SDavid du Colombier 		else if(strcmp(t->attr, "vrs") == 0 && mode->vrs == 0)
293219b2ee8SDavid du Colombier 			mode->vrs = strtol(t->val, 0, 0);
294219b2ee8SDavid du Colombier 		else if(strcmp(t->attr, "vre") == 0 && mode->vre == 0)
295219b2ee8SDavid du Colombier 			mode->vre = strtol(t->val, 0, 0);
296219b2ee8SDavid du Colombier 		else if(strcmp(t->attr, "hsync") == 0)
297219b2ee8SDavid du Colombier 			mode->hsync = *t->val;
298219b2ee8SDavid du Colombier 		else if(strcmp(t->attr, "vsync") == 0)
299219b2ee8SDavid du Colombier 			mode->vsync = *t->val;
300219b2ee8SDavid du Colombier 		else if(strcmp(t->attr, "interlace") == 0)
301219b2ee8SDavid du Colombier 			mode->interlace = *t->val;
3027dd7cddfSDavid du Colombier 		else if(strcmp(t->attr, "include") == 0 /*&& strcmp(t->val, val) != 0*/){
303219b2ee8SDavid du Colombier 			strcpy(attr, t->attr);
304219b2ee8SDavid du Colombier 			strcpy(val, t->val);
305219b2ee8SDavid du Colombier 			ndbfree(tuple);
306e0d6d19cSDavid du Colombier 			if(i++ > 5)
307e0d6d19cSDavid du Colombier 				error("dbmonitor: implausible include depth at %s=%s\n", attr, val);
308219b2ee8SDavid du Colombier 			goto buggery;
309219b2ee8SDavid du Colombier 		}
3107dd7cddfSDavid du Colombier 		else if(strcmp(t->attr, "include") == 0){
3117dd7cddfSDavid du Colombier 			print("warning: bailed out of infinite loop in attr %s=%s\n", attr, val);
3127dd7cddfSDavid du Colombier 		}
3137dd7cddfSDavid du Colombier 		else
3147dd7cddfSDavid du Colombier 			addattr(&mode->attr, t);
315219b2ee8SDavid du Colombier 	}
316219b2ee8SDavid du Colombier 	ndbfree(tuple);
317219b2ee8SDavid du Colombier 
318219b2ee8SDavid du Colombier 	if((x = strtol(size, &p, 0)) == 0 || x != mode->x || *p++ != 'x')
319219b2ee8SDavid du Colombier 		return 0;
320219b2ee8SDavid du Colombier 	if((x = strtol(p, &p, 0)) == 0 || x != mode->y || *p++ != 'x')
321219b2ee8SDavid du Colombier 		return 0;
322219b2ee8SDavid du Colombier 	if((x = strtol(p, &p, 0)) == 0 || x != mode->z)
323219b2ee8SDavid du Colombier 		return 0;
324219b2ee8SDavid du Colombier 
3257dd7cddfSDavid du Colombier 	if(clock)
3267dd7cddfSDavid du Colombier 		mode->frequency = clock;
3277dd7cddfSDavid du Colombier 
328219b2ee8SDavid du Colombier 	return 1;
329219b2ee8SDavid du Colombier }
330219b2ee8SDavid du Colombier 
331219b2ee8SDavid du Colombier Mode*
dbmode(char * name,char * type,char * size)332219b2ee8SDavid du Colombier dbmode(char* name, char* type, char* size)
333219b2ee8SDavid du Colombier {
334219b2ee8SDavid du Colombier 	Ndb *db;
335219b2ee8SDavid du Colombier 	Ndbs s;
336219b2ee8SDavid du Colombier 	Ndbtuple *t, *tuple;
337219b2ee8SDavid du Colombier 	Mode *mode;
3389a747e4fSDavid du Colombier 	char attr[Namelen+1];
3397dd7cddfSDavid du Colombier 	ulong videobw;
340219b2ee8SDavid du Colombier 
341219b2ee8SDavid du Colombier 	db = dbopen(name);
342219b2ee8SDavid du Colombier 	mode = alloc(sizeof(Mode));
343219b2ee8SDavid du Colombier 	strcpy(attr, type);
344219b2ee8SDavid du Colombier 
3457dd7cddfSDavid du Colombier 	videobw = 0;
346219b2ee8SDavid du Colombier 	/*
347219b2ee8SDavid du Colombier 	 * Look for the attr=size entry.
348219b2ee8SDavid du Colombier 	 */
349219b2ee8SDavid du Colombier 	if(dbmonitor(db, mode, attr, size)){
350219b2ee8SDavid du Colombier 		strcpy(mode->type, type);
351219b2ee8SDavid du Colombier 		strcpy(mode->size, size);
352219b2ee8SDavid du Colombier 		ndbclose(db);
353219b2ee8SDavid du Colombier 		return mode;
354219b2ee8SDavid du Colombier 	}
355219b2ee8SDavid du Colombier 
3567dd7cddfSDavid du Colombier 	if(mode->videobw && videobw == 0)	/* we at least found that; save it away */
3577dd7cddfSDavid du Colombier 		videobw = mode->videobw;
3587dd7cddfSDavid du Colombier 
359219b2ee8SDavid du Colombier 	/*
360219b2ee8SDavid du Colombier 	 * Not found. Look for an attr="" entry and then
361219b2ee8SDavid du Colombier 	 * for an alias=attr within.
362219b2ee8SDavid du Colombier 	 */
363219b2ee8SDavid du Colombier buggery:
364219b2ee8SDavid du Colombier 	for(tuple = ndbsearch(db, &s, attr, ""); tuple; tuple = ndbsnext(&s, attr, "")){
365219b2ee8SDavid du Colombier 		for(t = tuple->entry; t; t = t->entry){
366219b2ee8SDavid du Colombier 			if(strcmp(t->attr, "alias"))
367219b2ee8SDavid du Colombier 				continue;
368219b2ee8SDavid du Colombier 			strcpy(attr, t->val);
369219b2ee8SDavid du Colombier 			if(dbmonitor(db, mode, attr, size)){
370219b2ee8SDavid du Colombier 				strcpy(mode->type, type);
371219b2ee8SDavid du Colombier 				strcpy(mode->size, size);
372219b2ee8SDavid du Colombier 				ndbfree(tuple);
373219b2ee8SDavid du Colombier 				ndbclose(db);
3747dd7cddfSDavid du Colombier 				if(videobw)
3757dd7cddfSDavid du Colombier 					mode->videobw = videobw;
376219b2ee8SDavid du Colombier 				return mode;
377219b2ee8SDavid du Colombier 			}
378219b2ee8SDavid du Colombier 
379219b2ee8SDavid du Colombier 			/*
380219b2ee8SDavid du Colombier 			 * Found an alias but no match for size,
381219b2ee8SDavid du Colombier 			 * restart looking for attr="" with the
382219b2ee8SDavid du Colombier 			 * new attr.
383219b2ee8SDavid du Colombier 			 */
384219b2ee8SDavid du Colombier 			ndbfree(tuple);
385219b2ee8SDavid du Colombier 			goto buggery;
386219b2ee8SDavid du Colombier 		}
387219b2ee8SDavid du Colombier 		ndbfree(tuple);
388219b2ee8SDavid du Colombier 	}
389219b2ee8SDavid du Colombier 
390219b2ee8SDavid du Colombier 	free(mode);
391219b2ee8SDavid du Colombier 	ndbclose(db);
392219b2ee8SDavid du Colombier 	return 0;
393219b2ee8SDavid du Colombier }
394219b2ee8SDavid du Colombier 
395219b2ee8SDavid du Colombier void
dbdumpmode(Mode * mode)396219b2ee8SDavid du Colombier dbdumpmode(Mode* mode)
397219b2ee8SDavid du Colombier {
3987dd7cddfSDavid du Colombier 	Attr *attr;
399219b2ee8SDavid du Colombier 
4007dd7cddfSDavid du Colombier 	Bprint(&stdout, "dbdumpmode\n");
4017dd7cddfSDavid du Colombier 
4027dd7cddfSDavid du Colombier 	Bprint(&stdout, "type=%s, size=%s\n", mode->type, mode->size);
4037dd7cddfSDavid du Colombier 	Bprint(&stdout, "frequency=%d\n", mode->frequency);
4047dd7cddfSDavid du Colombier 	Bprint(&stdout, "x=%d (0x%X), y=%d (0x%X), z=%d (0x%X)\n",
405219b2ee8SDavid du Colombier 		mode->x, mode->x, mode->y,  mode->y, mode->z, mode->z);
4067dd7cddfSDavid du Colombier 	Bprint(&stdout, "ht=%d (0x%X), shb=%d (0x%X), ehb=%d (0x%X)\n",
407219b2ee8SDavid du Colombier 		mode->ht, mode->ht, mode->shb, mode->shb, mode->ehb, mode->ehb);
4087dd7cddfSDavid du Colombier 	Bprint(&stdout, "shs=%d (0x%X), ehs=%d (0x%X)\n",
4097dd7cddfSDavid du Colombier 		mode->shs, mode->shs, mode->ehs, mode->ehs);
4107dd7cddfSDavid du Colombier 	Bprint(&stdout, "vt=%d (0x%X), vrs=%d (0x%X), vre=%d (0x%X)\n",
411219b2ee8SDavid du Colombier 		mode->vt, mode->vt, mode->vrs, mode->vrs, mode->vre, mode->vre);
4127dd7cddfSDavid du Colombier 	Bprint(&stdout, "hsync=%d, vsync=%d, interlace=%d\n",
413219b2ee8SDavid du Colombier 		mode->hsync, mode->vsync, mode->interlace);
4147dd7cddfSDavid du Colombier 
4157dd7cddfSDavid du Colombier 	for(attr = mode->attr; attr; attr = attr->next)
4167dd7cddfSDavid du Colombier 		Bprint(&stdout, "mode->attr: %s=%s\n", attr->attr, attr->val);
417219b2ee8SDavid du Colombier }
418