M pc/devvga.c => pc/devvga.c +10 -13
@@ 1,4 1,5 @@
/*
+ * VGA controller
*/
#include "u.h"
#include "../port/lib.h"
@@ 151,10 152,6 @@ vgactl(char* a)
if(n < 2)
error(Ebadarg);
- /* BUG: drawinit should become a different message rather than piggybacking */
- if(scr && scr->dev && scr->dev->drawinit)
- scr->dev->drawinit(scr);
-
if(strcmp(field[1], "off") == 0){
lock(&cursor);
if(scr->cur){
@@ 269,17 266,8 @@ vgactl(char* a)
return;
}
else if(strcmp(field[0], "drawinit") == 0){
- /*
- * This is a separate message, but first we need to make
- * aux/vga send it; once everyone has the new vga, we
- * can take the drawinit stuff out of hwgc.
- */
-
- /*
if(scr && scr->dev && scr->dev->drawinit)
scr->dev->drawinit(scr);
- */
-
return;
}
else if(strcmp(field[0], "linear") == 0){
@@ 317,6 305,15 @@ vgactl(char* a)
hwaccel = 0;
return;
}
+ else if(strcmp(field[0], "hwblank") == 0){
+ if(n < 2)
+ error(Ebadarg);
+ if(strcmp(field[1], "on") == 0)
+ hwblank = 1;
+ else if(strcmp(field[1], "off") == 0)
+ hwblank = 0;
+ return;
+ }
error(Ebadarg);
}
M pc/screen.c => pc/screen.c +11 -0
@@ 463,6 463,7 @@ Memimage *lastbadi;
Memdata *lastbad;
Memimage *lastbadsrc, *lastbaddst;
int hwaccel = 1;
+int hwblank = 1;
int
hwdraw(Memdrawparam *par)
@@ 516,3 517,13 @@ hwdraw(Memdrawparam *par)
return 0;
}
+
+void
+blankscreen(int blank)
+{
+ VGAscr *scr;
+
+ scr = &vgascreen[0];
+ if(hwblank && scr->blank)
+ scr->blank(scr, blank);
+}
M pc/screen.h => pc/screen.h +3 -0
@@ 110,6 110,7 @@ struct VGAscr {
int (*fill)(VGAscr*, Rectangle, ulong);
int (*scroll)(VGAscr*, Rectangle, Rectangle);
+ void (*blank)(VGAscr*, int);
ulong id; /* internal identifier for driver use */
};
@@ 124,6 125,7 @@ extern void mousectl(char*[], int);
/* screen.c */
extern int hwaccel; /* use hw acceleration; default on */
+extern int hwblank; /* use hw blanking; default on */
extern void flushmemscreen(Rectangle);
extern int cursoron(int);
extern void cursoroff(int);
@@ 131,6 133,7 @@ extern void setcursor(Cursor*);
extern int screensize(int, int, int, ulong);
extern int screenaperture(int, int);
extern Rectangle physgscreenr; /* actual monitor size */
+extern void blankscreen(int);
/* devdraw.c */
extern void deletescreenimage(void);
M pc/vgas3.c => pc/vgas3.c +21 -0
@@ 441,6 441,26 @@ hwfill(VGAscr *scr, Rectangle r, ulong sval)
return 1;
}
+enum {
+ CursorSyncCtl = 0x0D, /* in Seqx */
+ VsyncHi = 0x80,
+ VsyncLo = 0x40,
+ HsyncHi = 0x20,
+ HsyncLo = 0x10,
+};
+
+static void
+s3blank(int blank)
+{
+ uchar x;
+
+ x = vgaxi(Seqx, CursorSyncCtl);
+ x &= ~0xF0;
+ if(blank)
+ x |= VsyncLo | HsyncLo;
+ vgaxo(Seqx, CursorSyncCtl, x);
+}
+
static void
s3drawinit(VGAscr *scr)
{
@@ 463,6 483,7 @@ s3drawinit(VGAscr *scr)
scr->mmio = (ulong*)(scr->aperture+0x1000000);
scr->fill = hwfill;
scr->scroll = hwscroll;
+ /* scr->blank = hwblank; */
}
}
M pc/vgat2r4.c => pc/vgat2r4.c +19 -0
@@ 25,6 25,12 @@ enum {
};
enum { /* index registers */
+ CursorSyncCtl = 0x03,
+ HsyncHi = 0x01,
+ HsyncLo = 0x02,
+ VsyncHi = 0x04,
+ VsyncLo = 0x08,
+
CursorCtl = 0x30,
CursorXLo = 0x31,
CursorXHi = 0x32,
@@ 514,6 520,18 @@ t2r4hwfill(VGAscr *scr, Rectangle r, ulong sval)
}
static void
+t2r4blank(VGAscr *scr, int blank)
+{
+ uchar x;
+
+ x = t2r4xi(scr, CursorSyncCtl);
+ x &= ~0x0F;
+ if(blank)
+ x |= HsyncLo | VsyncLo;
+ t2r4xo(scr, CursorSyncCtl, x);
+}
+
+static void
t2r4drawinit(VGAscr *scr)
{
ulong pitch;
@@ 557,6 575,7 @@ t2r4drawinit(VGAscr *scr)
scr->fill = t2r4hwfill;
scr->scroll = t2r4hwscroll;
+ scr->blank = t2r4blank;
}
VGAdev vgat2r4dev = {
M port/chan.c => port/chan.c +1 -0
@@ 721,6 721,7 @@ namec(char *name, int amode, int omode, ulong perm)
* c time and pid, but also cons and consctl
* p control of your own processes (and unfortunately
* any others left unprotected)
+ * all are ASCII, so it's safe to use strchr to check.
*/
if(up->pgrp->noattach)
if(strchr("|decp", name[1]) == 0)
M port/devdraw.c => port/devdraw.c +10 -2
@@ 1980,14 1980,22 @@ drawblankscreen(int blank)
p = sdraw.savemap;
nc = screenimage->depth > 8 ? 256 : 1<<screenimage->depth;
- if(blank == 0) /* turn screen on */
+ /*
+ * blankscreen uses the hardware to blank the screen
+ * when possible. to help in cases when it is not possible,
+ * we set the color map to be all black.
+ */
+ if(blank == 0){ /* turn screen on */
for(i=0; i<nc; i++, p+=3)
setcolor(i, p[0], p[1], p[2]);
- else /* turn screen off */
+ blankscreen(0);
+ }else{ /* turn screen off */
+ blankscreen(1);
for(i=0; i<nc; i++, p+=3){
getcolor(i, &p[0], &p[1], &p[2]);
setcolor(i, 0, 0, 0);
}
+ }
sdraw.blanked = blank;
qunlock(&sdraw);
}