shithub: riscv

Download patch

ref: d908aff72f875029c0d20cdd33d71a583061edff
parent: 31e1c15d441e38a740b8f209f86b8b2d0fc49d79
author: ftrvxmtrx <[email protected]>
date: Sun Dec 28 12:42:38 EST 2014

aux/vga: remove -s option, move scaling to the size string itself

--- a/sys/man/8/vga
+++ b/sys/man/8/vga
@@ -15,10 +15,6 @@
 .I monitor
 ]
 [
-.B -s
-.I scaling
-]
-[
 .B -x
 .I file
 ]
@@ -85,16 +81,6 @@
 .B plan9.ini
 file read by the PC boot program.
 .TP
-.B -s
-set scaling mode to either
-.I off
-to disable completely (image will be centered),
-.I full
-to stretch to full screen
-or
-.I aspect
-to stretch while preserving aspect ratio.
-.TP
 .B -p
 print the current or expected register values at appropriate points depending on
 other options.
@@ -113,7 +99,7 @@
 .PP
 .I Mode
 is of the form
-.IB X x Y x Z
+.IB X x Y x Z ,S
 , where
 .IR X ,
 .IR Y ,
@@ -120,6 +106,12 @@
 and
 .I Z
 are numbers specifying the display height, width, and depth respectively.
+.I S
+is scaling mode, either
+.I scalefull
+or
+.IR scaleaspect ;
+not specifying it disables scaling altogether.
 The mode must appear in 
 .B /lib/vgadb
 as a value for one of the monitor entries.
@@ -227,3 +219,7 @@
 It is useful in such cases to have
 the above command for setting the controller to a known state
 at your fingertips.
+Scaling modes currently work with Intel and NVIDIA video
+adapters only, using VESA. Intel doesn't support
+.I scaleaspect
+mode.
--- a/sys/src/cmd/aux/vga/main.c
+++ b/sys/src/cmd/aux/vga/main.c
@@ -149,7 +149,7 @@
 static void
 usage(void)
 {
-	fprint(2, "usage: aux/vga [ -BcdilpvV ] [ -b bios-id ] [ -m monitor ] [-s scaling] [ -x db ] [ mode [ virtualsize ] ]\n");
+	fprint(2, "usage: aux/vga [ -BcdilpvV ] [ -b bios-id ] [ -m monitor ] [ -x db ] [ mode [ virtualsize ] ]\n");
 	exits("usage");
 }
 
@@ -157,7 +157,7 @@
 main(int argc, char** argv)
 {
 	char *bios, buf[256], sizeb[256], *p, *vsize, *psize;
-	char *type, *vtype, *scaling;
+	char *type, *vtype;
 	int virtual, len;
 	Ctlr *ctlr;
 	Vga *vga;
@@ -169,7 +169,6 @@
 	if((type = getenv("monitor")) == 0)
 		type = "vga";
 	psize = vsize = "640x480x8";
-	scaling = nil;
 
 	ARGBEGIN{
 	default:
@@ -205,9 +204,6 @@
 		 */
 		rflag++;
 		break;
-	case 's':
-		scaling = EARGF(usage());
-		break;
 	case 'v':
 		vflag = 1;
 		break;
@@ -469,11 +465,6 @@
 			if(pflag)
 				dump(vga);
 		}
-	}
-
-	if(scaling != nil){
-		if(vga->vesa)
-			vesa.scaling(vga, vga->vesa, scaling);
 	}
 
 	trace("main->exits\n");
--- a/sys/src/cmd/aux/vga/vesa.c
+++ b/sys/src/cmd/aux/vga/vesa.c
@@ -26,6 +26,7 @@
 	uchar	*mem;	/* copy of memory; 1MB */
 	uchar	*isvalid;	/* 1byte per 4kB in mem */
 	uchar	*modebuf;
+	void (*scale)(Vga*, Ctlr*);
 };
 
 struct Vmode
@@ -144,10 +145,14 @@
 	Vmode vm;
 	Mode *m;
 	Modelist *l;
-	
+	char *scale;
+
 	if(vbe == nil)
 		return nil;
 
+	if(scale = strchr(size, ','))
+		*scale++ = 0;
+
 	if(strncmp(size, "0x", 2) == 0){
 		if(vbemodeinfo(vbe, strtol(size+2, nil, 16), &vm) == 0)
 			goto havemode;
@@ -216,6 +221,17 @@
 	a->next = nil;
 	m->attr = a;
 
+	/* scaling mode */
+	if(scale != nil){
+		a = alloc(sizeof(Attr));
+		a->attr = "scale";
+		a->val = alloc(32);
+		strncpy(a->val, scale, 32);
+
+		a->next = m->attr;
+		m->attr = a;
+	}
+
 	/* account for framebuffer stride */
 	width = vm.bpl * 8 / m->z;
 	if(width > m->x){
@@ -261,6 +277,8 @@
 {
 	if(vbe == nil)
 		error("no vesa bios\n");
+	if(vbe->scale != nil)
+		vbe->scale(vga, ctlr);
 	if(vbesetmode(vbe, atoi(dbattr(vga->mode->attr, "id"))) < 0){
 		ctlr->flag |= Ferror;
 		fprint(2, "vbesetmode: %r\n");
@@ -297,33 +315,63 @@
 }
 
 static void
-scaling(Vga*, Ctlr* ctlr, char* scaling)
+intelscale(Vga* vga, Ctlr* ctlr)
 {
 	Ureg u;
-	int mode;
+	int cx;
+	char *scale;
 
 	if(vbe == nil)
 		error("no vesa bios\n");
 
-	if(strcmp(scaling, "off") == 0)
-		mode = 1;
-	else if(strcmp(scaling, "aspect") == 0)
-		mode = 3;
-	else if(strcmp(scaling, "full") == 0)
-		mode = 0;
+	/* NOTE: intel doesn't support "aspect" scaling mode :( */
+	scale = dbattr(vga->mode->attr, "scale");
+	if(scale == nil)
+		cx = 0;
+	else if(strcmp(scale, "scalefull") == 0)
+		cx = 4;
 	else{
 		ctlr->flag |= Ferror;
-		fprint(2, "vbescaling: unknown mode %s\n", scaling);
+		fprint(2, "vbescale: unsupported mode %s\n", scale);
 		return;
 	}
 
-	vbesetup(vbe, &u, 0x4F14);
-	u.bx = 0x102;
-	u.cx = mode;
-	if(vbecall(vbe, &u) < 0){
+	vbesetup(vbe, &u, 0x5F61);
+	u.bx = 0;
+	u.cx = cx; /* horizontal */
+	u.dx = cx; /* vertical */
+	if(vbecall(vbe, &u) < 0 && (u.ax&0xFFFF) != 0x5F)
+		fprint(2, "vbescale: %r\n");
+}
+
+static void
+nvidiascale(Vga* vga, Ctlr* ctlr)
+{
+	Ureg u;
+	int cx;
+	char *scale;
+
+	if(vbe == nil)
+		error("no vesa bios\n");
+
+	scale = dbattr(vga->mode->attr, "scale");
+	if(scale == nil)
+		cx = 1;
+	else if(strcmp(scale, "scaleaspect") == 0)
+		cx = 3;
+	else if(strcmp(scale, "scalefull") == 0)
+		cx = 0;
+	else{
 		ctlr->flag |= Ferror;
-		fprint(2, "vbescaling: %r\n");
+		fprint(2, "vbescale: unsupported mode %s\n", scale);
+		return;
 	}
+
+	vbesetup(vbe, &u, 0x4F14);
+	u.bx = 0x102;
+	u.cx = cx;
+	if(vbecall(vbe, &u) < 0)
+		fprint(2, "vbescale: %r\n");
 }
 
 Ctlr vesa = {
@@ -333,7 +381,6 @@
 	nil,
 	load,
 	dump,
-	scaling,
 };
 
 Ctlr softhwgc = {
@@ -526,7 +573,7 @@
 vbecall(Vbe *vbe, Ureg *u)
 {
 	u->trap = 0x10;
-	
+
 	vbeflush(vbe);
 
 	if(pwrite(vbe->rmfd, u, sizeof *u, 0) != sizeof *u)
@@ -546,6 +593,7 @@
 int
 vbecheck(Vbe *vbe)
 {
+	char *oem;
 	uchar *p;
 	Ureg u;
 
@@ -561,6 +609,11 @@
 		werrstr("invalid vesa version: %.4H\n", p+4);
 		return -1;
 	}
+	oem = unfarptr(vbe, p+6);
+	if(memcmp(oem, "Intel", 5) == 0)
+		vbe->scale = intelscale;
+	else if(memcmp(oem, "NVIDIA", 6) == 0)
+		vbe->scale = nvidiascale;
 	return 0;
 }
 
@@ -795,7 +848,7 @@
 {
 	uchar *p;
 	Ureg u;
-	
+
 	p = vbesetup(vbe, &u, 0x4F15);
 	u.bx = 0x0001;
 	if(vbecall(vbe, &u) < 0)
@@ -806,12 +859,12 @@
 	}
 	return 0;
 }
-	
+
 void
 printedid(Edid *e)
 {
 	Modelist *l;
-	
+
 	printitem("edid", "mfr");
 	Bprint(&stdout, "%s\n", e->mfr);
 	printitem("edid", "serialstr");
@@ -838,7 +891,7 @@
 	Bprint(&stdout, "%lud\n", e->pclkmax);
 	printitem("edid", "flags");
 	printflags(edidflags, e->flags);
-	
+
 	for(l=e->modelist; l; l=l->next){
 		printitem("edid", l->name);
 		Bprint(&stdout, "\n\t\tclock=%g\n"
@@ -1144,7 +1197,7 @@
 	 */
 	estab = (p[0]<<16) | (p[1]<<8) | p[2];
 	p += 3;
-	
+
 	for(i=0, m=1<<23; i<nelem(estabtime); i++, m>>=1)
 		if(estab & m)
 			if(vesalookup(&mode, estabtime[i]) == 0)
--- a/sys/src/cmd/aux/vga/vga.h
+++ b/sys/src/cmd/aux/vga/vga.h
@@ -49,7 +49,6 @@
 	void	(*init)(Vga*, Ctlr*);
 	void	(*load)(Vga*, Ctlr*);
 	void	(*dump)(Vga*, Ctlr*);
-	void	(*scaling)(Vga*, Ctlr*, char*);
 	char*	type;
 
 	ulong	flag;