summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorftrvxmtrx <devnull@localhost>2014-12-26 15:24:07 +0100
committerftrvxmtrx <devnull@localhost>2014-12-26 15:24:07 +0100
commit604f00d9bc0fada5b392ab555b1ad49e4500c9da (patch)
tree0662dadbd00d216c77bbfa591bcd923d5149620c
parent2ab042f11e5848089b343cc565acb65d4a5bc64a (diff)
downloadplan9front-604f00d9bc0fada5b392ab555b1ad49e4500c9da.tar.xz
vga, vesa: scaling modes
-rw-r--r--sys/man/3/vga11
-rw-r--r--sys/src/9/pc/devvga.c15
-rw-r--r--sys/src/9/pc/screen.h10
-rw-r--r--sys/src/9/pc/vgavesa.c40
4 files changed, 70 insertions, 6 deletions
diff --git a/sys/man/3/vga b/sys/man/3/vga
index d17858008..6b148093e 100644
--- a/sys/man/3/vga
+++ b/sys/man/3/vga
@@ -198,6 +198,17 @@ enable or disable the use of DPMS blanking
.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
diff --git a/sys/src/9/pc/devvga.c b/sys/src/9/pc/devvga.c
index 3867d36dc..918da32b0 100644
--- a/sys/src/9/pc/devvga.c
+++ b/sys/src/9/pc/devvga.c
@@ -48,6 +48,7 @@ enum {
CMunblank,
CMsoftscreen,
CMpcidev,
+ CMscaling,
};
static Cmdtab vgactlmsg[] = {
@@ -67,6 +68,7 @@ static Cmdtab vgactlmsg[] = {
CMunblank, "unblank", 1,
CMsoftscreen, "softscreen", 2,
CMpcidev, "pcidev", 2,
+ CMscaling, "scaling", 2,
};
static void
@@ -305,6 +307,19 @@ vgactl(Cmdbuf *cb)
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:
for(i = 0; vgadev[i]; i++){
if(strcmp(cb->f[1], vgadev[i]->name))
diff --git a/sys/src/9/pc/screen.h b/sys/src/9/pc/screen.h
index bbe6b2512..7928ca616 100644
--- a/sys/src/9/pc/screen.h
+++ b/sys/src/9/pc/screen.h
@@ -49,6 +49,15 @@ enum {
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 @@ struct VGAdev {
void (*ovlctl)(VGAscr*, Chan*, void*, int);
int (*ovlwrite)(VGAscr*, void*, int, vlong);
void (*flush)(VGAscr*, Rectangle);
+ void (*scaling)(VGAscr*, int);
};
struct VGAcur {
diff --git a/sys/src/9/pc/vgavesa.c b/sys/src/9/pc/vgavesa.c
index 794533a9d..4eeffbe85 100644
--- a/sys/src/9/pc/vgavesa.c
+++ b/sys/src/9/pc/vgavesa.c
@@ -23,6 +23,7 @@ enum {
Cdisable = 0,
Cenable,
Cblank,
+ Cscaling,
RealModeBuf = 0x9000,
};
@@ -32,6 +33,7 @@ static Chan *creg, *cmem;
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 @@ vesaproc(void*)
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 @@ vesablank(VGAscr *, int blank)
}
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 @@ VGAdev vgavesadev = {
"vesa",
vesaenable,
vesadisable,
- 0,
+ nil,
vesalinear,
vesadrawinit,
+ nil,
+ nil,
+ nil,
+ nil,
+ vesascaling,
};