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;