devvga: properly handle physical screen size and panning
- remove arbitrary limits on screen size, just check with badrect() - post resize when physgscreenr is changed (actualsize ctl command) - preserve physgscreenr across softscreen flag toggle - honor panning flag on resize - fix nil dereference in panning ctl command when scr->gscreen == nil - use clipr when drawing vga plan 9 console (vgascreenwin())
This commit is contained in:
parent
a08727d9da
commit
65566dda8e
2 changed files with 26 additions and 30 deletions
|
@ -212,11 +212,13 @@ vgaread(Chan* c, void* a, long n, vlong off)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char Ebusy[] = "vga already configured";
|
static char Ebusy[] = "vga already configured";
|
||||||
|
static char Enoscreen[] = "set the screen size first";
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vgactl(Cmdbuf *cb)
|
vgactl(Cmdbuf *cb)
|
||||||
{
|
{
|
||||||
int align, i, size, x, y, z;
|
int align, i, size, x, y, z;
|
||||||
|
Rectangle r;
|
||||||
char *chanstr, *p;
|
char *chanstr, *p;
|
||||||
ulong chan;
|
ulong chan;
|
||||||
Cmdtab *ct;
|
Cmdtab *ct;
|
||||||
|
@ -229,8 +231,7 @@ vgactl(Cmdbuf *cb)
|
||||||
switch(ct->index){
|
switch(ct->index){
|
||||||
case CMhwgc:
|
case CMhwgc:
|
||||||
if(scr->gscreen == nil)
|
if(scr->gscreen == nil)
|
||||||
error("hwgc: no gscreen");
|
error(Enoscreen);
|
||||||
|
|
||||||
if(strcmp(cb->f[1], "off") == 0){
|
if(strcmp(cb->f[1], "off") == 0){
|
||||||
lock(&cursor);
|
lock(&cursor);
|
||||||
if(scr->cur){
|
if(scr->cur){
|
||||||
|
@ -305,26 +306,19 @@ vgactl(Cmdbuf *cb)
|
||||||
|
|
||||||
case CMsize:
|
case CMsize:
|
||||||
x = strtoul(cb->f[1], &p, 0);
|
x = strtoul(cb->f[1], &p, 0);
|
||||||
if(x == 0 || x > 10240)
|
|
||||||
error(Ebadarg);
|
|
||||||
if(*p)
|
if(*p)
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
y = strtoul(p, &p, 0);
|
y = strtoul(p, &p, 0);
|
||||||
if(y == 0 || y > 10240)
|
|
||||||
error(Ebadarg);
|
|
||||||
if(*p)
|
if(*p)
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
z = strtoul(p, &p, 0);
|
z = strtoul(p, &p, 0);
|
||||||
|
if(badrect(Rect(0,0,x,y)))
|
||||||
|
error(Ebadarg);
|
||||||
chanstr = cb->f[2];
|
chanstr = cb->f[2];
|
||||||
if((chan = strtochan(chanstr)) == 0)
|
if((chan = strtochan(chanstr)) == 0)
|
||||||
error("bad channel");
|
error("bad channel");
|
||||||
|
|
||||||
if(chantodepth(chan) != z)
|
if(chantodepth(chan) != z)
|
||||||
error("depth, channel do not match");
|
error("depth, channel do not match");
|
||||||
|
|
||||||
cursoroff();
|
cursoroff();
|
||||||
deletescreenimage();
|
deletescreenimage();
|
||||||
if(screensize(x, y, z, chan))
|
if(screensize(x, y, z, chan))
|
||||||
|
@ -334,30 +328,25 @@ vgactl(Cmdbuf *cb)
|
||||||
|
|
||||||
case CMactualsize:
|
case CMactualsize:
|
||||||
if(scr->gscreen == nil)
|
if(scr->gscreen == nil)
|
||||||
error("set the screen size first");
|
error(Enoscreen);
|
||||||
|
|
||||||
x = strtoul(cb->f[1], &p, 0);
|
x = strtoul(cb->f[1], &p, 0);
|
||||||
if(x == 0 || x > 2048)
|
|
||||||
error(Ebadarg);
|
|
||||||
if(*p)
|
if(*p)
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
y = strtoul(p, nil, 0);
|
y = strtoul(p, nil, 0);
|
||||||
if(y == 0 || y > 2048)
|
r = Rect(0,0,x,y);
|
||||||
|
if(badrect(r))
|
||||||
error(Ebadarg);
|
error(Ebadarg);
|
||||||
|
if(!rectinrect(r, scr->gscreen->r))
|
||||||
if(x > scr->gscreen->r.max.x || y > scr->gscreen->r.max.y)
|
|
||||||
error("physical screen bigger than virtual");
|
error("physical screen bigger than virtual");
|
||||||
|
cursoroff();
|
||||||
physgscreenr = Rect(0,0,x,y);
|
deletescreenimage();
|
||||||
scr->gscreen->clipr = physgscreenr;
|
physgscreenr = r;
|
||||||
return;
|
goto Resized;
|
||||||
|
|
||||||
case CMpalettedepth:
|
case CMpalettedepth:
|
||||||
x = strtoul(cb->f[1], &p, 0);
|
x = strtoul(cb->f[1], &p, 0);
|
||||||
if(x != 8 && x != 6)
|
if(x != 8 && x != 6)
|
||||||
error(Ebadarg);
|
error(Ebadarg);
|
||||||
|
|
||||||
scr->palettedepth = x;
|
scr->palettedepth = x;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -370,6 +359,7 @@ vgactl(Cmdbuf *cb)
|
||||||
break;
|
break;
|
||||||
if(scr->gscreen == nil)
|
if(scr->gscreen == nil)
|
||||||
return;
|
return;
|
||||||
|
r = physgscreenr;
|
||||||
x = scr->gscreen->r.max.x;
|
x = scr->gscreen->r.max.x;
|
||||||
y = scr->gscreen->r.max.y;
|
y = scr->gscreen->r.max.y;
|
||||||
z = scr->gscreen->depth;
|
z = scr->gscreen->depth;
|
||||||
|
@ -378,14 +368,17 @@ vgactl(Cmdbuf *cb)
|
||||||
deletescreenimage();
|
deletescreenimage();
|
||||||
if(screensize(x, y, z, chan))
|
if(screensize(x, y, z, chan))
|
||||||
error(Egreg);
|
error(Egreg);
|
||||||
|
physgscreenr = r;
|
||||||
/* no break */
|
/* no break */
|
||||||
case CMdrawinit:
|
case CMdrawinit:
|
||||||
if(scr->gscreen == nil)
|
if(scr->gscreen == nil)
|
||||||
error("drawinit: no gscreen");
|
error(Enoscreen);
|
||||||
if(scr->dev && scr->dev->drawinit)
|
if(scr->dev && scr->dev->drawinit)
|
||||||
scr->dev->drawinit(scr);
|
scr->dev->drawinit(scr);
|
||||||
hwblank = scr->blank != nil;
|
hwblank = scr->blank != nil;
|
||||||
hwaccel = scr->fill != nil || scr->scroll != nil;
|
hwaccel = scr->fill != nil || scr->scroll != nil;
|
||||||
|
Resized:
|
||||||
|
scr->gscreen->clipr = panning ? scr->gscreen->r : physgscreenr;
|
||||||
vgascreenwin(scr);
|
vgascreenwin(scr);
|
||||||
resetscreenimage();
|
resetscreenimage();
|
||||||
cursoron();
|
cursoron();
|
||||||
|
@ -405,19 +398,21 @@ vgactl(Cmdbuf *cb)
|
||||||
|
|
||||||
case CMpanning:
|
case CMpanning:
|
||||||
if(strcmp(cb->f[1], "on") == 0){
|
if(strcmp(cb->f[1], "on") == 0){
|
||||||
if(scr == nil || scr->cur == nil)
|
if(scr->cur == nil)
|
||||||
error("set screen first");
|
error("set cursor first");
|
||||||
if(!scr->cur->doespanning)
|
if(!scr->cur->doespanning)
|
||||||
error("panning not supported");
|
error("panning not supported");
|
||||||
scr->gscreen->clipr = scr->gscreen->r;
|
|
||||||
panning = 1;
|
panning = 1;
|
||||||
}
|
}
|
||||||
else if(strcmp(cb->f[1], "off") == 0){
|
else if(strcmp(cb->f[1], "off") == 0){
|
||||||
scr->gscreen->clipr = physgscreenr;
|
|
||||||
panning = 0;
|
panning = 0;
|
||||||
}else
|
}else
|
||||||
break;
|
break;
|
||||||
return;
|
if(scr->gscreen == nil)
|
||||||
|
return;
|
||||||
|
cursoroff();
|
||||||
|
deletescreenimage();
|
||||||
|
goto Resized;
|
||||||
|
|
||||||
case CMhwaccel:
|
case CMhwaccel:
|
||||||
if(strcmp(cb->f[1], "on") == 0)
|
if(strcmp(cb->f[1], "on") == 0)
|
||||||
|
|
|
@ -193,6 +193,7 @@ vgascreenwin(VGAscr* scr)
|
||||||
freememimage(i);
|
freememimage(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = scr->gscreen->clipr;
|
||||||
window = insetrect(r, 20);
|
window = insetrect(r, 20);
|
||||||
memimagedraw(scr->gscreen, window, conscol, ZP, memopaque, ZP, S);
|
memimagedraw(scr->gscreen, window, conscol, ZP, memopaque, ZP, S);
|
||||||
window = insetrect(window, 4);
|
window = insetrect(window, 4);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue