shithub: riscv

Download patch

ref: 604f00d9bc0fada5b392ab555b1ad49e4500c9da
parent: 2ab042f11e5848089b343cc565acb65d4a5bc64a
author: ftrvxmtrx <devnull@localhost>
date: Fri Dec 26 10:24:07 EST 2014

vga, vesa: scaling modes

--- a/sys/man/3/vga
+++ b/sys/man/3/vga
@@ -198,6 +198,17 @@
 .B blank
 above).
 .TP
+.BI scaling " mode"
+Set the GPU scaling
+.I mode
+to
+.BR off ,
+.B full
+or
+.B aspect
+to either disable scaling, scale to full screen, or
+to scale while preserving aspect ratio.
+.TP
 .BI linear " size align"
 Use a linear screen aperture of size
 .I size
--- a/sys/src/9/pc/devvga.c
+++ b/sys/src/9/pc/devvga.c
@@ -48,6 +48,7 @@
 	CMunblank,
 	CMsoftscreen,
 	CMpcidev,
+	CMscaling,
 };
 
 static Cmdtab vgactlmsg[] = {
@@ -67,6 +68,7 @@
 	CMunblank,	"unblank",	1,
 	CMsoftscreen,	"softscreen",	2,
 	CMpcidev,	"pcidev",	2,
+	CMscaling,	"scaling",	2,
 };
 
 static void
@@ -303,6 +305,19 @@
 				scr->pci = p;
 		} else
 			error(Ebadarg);
+		return;
+
+	case CMscaling:
+		if(scr != nil && scr->dev != nil){
+			if(scr->dev->scaling == nil)
+				error("scaling not supported");
+			else if(strcmp(cb->f[1], "aspect") == 0)
+				scr->dev->scaling(scr, Saspect);
+			else if(strcmp(cb->f[1], "full") == 0)
+				scr->dev->scaling(scr, Sfull);
+			else if(strcmp(cb->f[1], "off") == 0)
+				scr->dev->scaling(scr, Soff);
+		}
 		return;
 
 	case CMtype:
--- a/sys/src/9/pc/screen.h
+++ b/sys/src/9/pc/screen.h
@@ -49,6 +49,15 @@
 	Pwhite		= 0xFF,
 };
 
+/*
+ * Scaling modes.
+ */
+enum {
+	Soff,
+	Sfull,
+	Saspect,
+};
+
 #define VGAMEM()	0xA0000
 #define vgai(port)		inb(port)
 #define vgao(port, data)	outb(port, data)
@@ -74,6 +83,7 @@
 	void	(*ovlctl)(VGAscr*, Chan*, void*, int);
 	int	(*ovlwrite)(VGAscr*, void*, int, vlong);
 	void (*flush)(VGAscr*, Rectangle);
+	void	(*scaling)(VGAscr*, int);
 };
 
 struct VGAcur {
--- a/sys/src/9/pc/vgavesa.c
+++ b/sys/src/9/pc/vgavesa.c
@@ -23,6 +23,7 @@
 	Cdisable = 0,
 	Cenable,
 	Cblank,
+	Cscaling,
 
 	RealModeBuf = 0x9000,
 };
@@ -32,6 +33,7 @@
 static QLock vesaq;
 static Rendez vesar;
 static int vesactl;
+static int scaling;
 
 #define WORD(p) ((p)[0] | ((p)[1]<<8))
 #define LONG(p) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24))
@@ -183,11 +185,17 @@
 			sleep(&vesar, gotctl, &ctl);
 			ctl = vesactl;
 
-			vbesetup(&u, 0x4f10);
-			if(ctl == Cblank)
-				u.bx = 0x0101;
-			else	
-				u.bx = 0x0001;
+			if(ctl == Cscaling){
+				vbesetup(&u, 0x4f14);
+				u.bx = 0x102;
+				u.cx = scaling;
+			}else{
+				vbesetup(&u, 0x4f10);
+				if(ctl == Cblank)
+					u.bx = 0x0101;
+				else	
+					u.bx = 0x0001;
+			}
 
 			/*
 			 * dont wait forever here. some BIOS get stuck
@@ -253,6 +261,21 @@
 }
 
 static void
+vesascaling(VGAscr *, int mode)
+{
+	if(vesactl != Cdisable){
+		vesactl = Cscaling;
+		if(mode == Soff)
+			scaling = 1;
+		else if(mode == Saspect)
+			scaling = 3;
+		else if(mode == Sfull)
+			scaling = 0;
+		wakeup(&vesar);
+	}
+}
+
+static void
 vesadrawinit(VGAscr *scr)
 {
 	scr->blank = vesablank;
@@ -262,7 +285,12 @@
 	"vesa",
 	vesaenable,
 	vesadisable,
-	0,
+	nil,
 	vesalinear,
 	vesadrawinit,
+	nil,
+	nil,
+	nil,
+	nil,
+	vesascaling,
 };