shithub: riscv

Download patch

ref: 0d5b33a9e821ab0c3230bd25596b6567f2b28cd6
parent: 04ec990b670c761866da5bb0ab344da3407e78ca
author: ftrvxmtrx <devnull@localhost>
date: Fri Dec 26 12:01:58 EST 2014

aux/vga: scaling modes for VESA

--- a/sys/man/8/vga
+++ b/sys/man/8/vga
@@ -15,6 +15,10 @@
 .I monitor
 ]
 [
+.B -s
+.I scaling
+]
+[
 .B -x
 .I file
 ]
@@ -80,6 +84,16 @@
 is usually set by including it in the
 .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
--- 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 ] [ -x db ] [ mode [ virtualsize ] ]\n");
+	fprint(2, "usage: aux/vga [ -BcdilpvV ] [ -b bios-id ] [ -m monitor ] [-s scaling] [ -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;
+	char *type, *vtype, *scaling;
 	int virtual, len;
 	Ctlr *ctlr;
 	Vga *vga;
@@ -169,6 +169,7 @@
 	if((type = getenv("monitor")) == 0)
 		type = "vga";
 	psize = vsize = "640x480x8";
+	scaling = nil;
 
 	ARGBEGIN{
 	default:
@@ -204,6 +205,9 @@
 		 */
 		rflag++;
 		break;
+	case 's':
+		scaling = EARGF(usage());
+		break;
 	case 'v':
 		vflag = 1;
 		break;
@@ -465,6 +469,11 @@
 			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
@@ -105,6 +105,8 @@
 int vbeddcedid(Vbe *vbe, Edid *e);
 void printedid(Edid*);
 void fixbios(Vbe*);
+uchar* vbesetup(Vbe*, Ureg*, int);
+int vbecall(Vbe*, Ureg*);
 
 int
 dbvesa(Vga* vga)
@@ -192,7 +194,7 @@
 		*m = *vesamodes[i];
 		break;
 	}
-	if(edid){
+	if(edid != nil){
 		for(l = edid->modelist; l; l = l->next){
 			if(l->x != vm.dx || l->y != vm.dy)
 				continue;
@@ -272,7 +274,7 @@
 	char did[0x200];
 	uchar *p, *ep;
 
-	if(!vbe){
+	if(vbe == nil){
 		Bprint(&stdout, "no vesa bios\n");
 		return;
 	}
@@ -280,7 +282,7 @@
 	memset(did, 0, sizeof did);
 	vbeprintinfo(vbe);
 	p = vbemodes(vbe);
-	if(p){
+	if(p != nil){
 		for(ep=p+1024; (p[0]!=0xFF || p[1]!=0xFF) && p<ep; p+=2){
 			vbeprintmodeinfo(vbe, WORD(p), "");
 			if(WORD(p) < nelem(did))
@@ -290,17 +292,48 @@
 	for(i=0x100; i<0x1FF; i++)
 		if(!did[i])
 			vbeprintmodeinfo(vbe, i, " (unoffered)");
-	if(edid)
+	if(edid != nil)
 		printedid(edid);
 }
 
+static void
+scaling(Vga*, Ctlr* ctlr, char* scaling)
+{
+	Ureg u;
+	int mode;
+
+	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;
+	else{
+		ctlr->flag |= Ferror;
+		fprint(2, "vbescaling: unknown mode %s\n", scaling);
+		return;
+	}
+
+	vbesetup(vbe, &u, 0x4F14);
+	u.bx = 0x102;
+	u.cx = mode;
+	if(vbecall(vbe, &u) < 0){
+		ctlr->flag |= Ferror;
+		fprint(2, "vbescaling: %r\n");
+	}
+}
+
 Ctlr vesa = {
-	"vesa",			/* name */
-	snarf,				/* snarf */
-	options,			/* options */
-	0,				/* init */
-	load,				/* load */
-	dump,				/* dump */
+	"vesa",
+	snarf,
+	options,
+	nil,
+	load,
+	dump,
+	scaling,
 };
 
 Ctlr softhwgc = {
--- a/sys/src/cmd/aux/vga/vga.h
+++ b/sys/src/cmd/aux/vga/vga.h
@@ -49,6 +49,7 @@
 	void	(*init)(Vga*, Ctlr*);
 	void	(*load)(Vga*, Ctlr*);
 	void	(*dump)(Vga*, Ctlr*);
+	void	(*scaling)(Vga*, Ctlr*, char*);
 	char*	type;
 
 	ulong	flag;