vesa-changes
This commit is contained in:
parent
45bab89362
commit
632defb656
10 changed files with 548 additions and 395 deletions
|
@ -368,11 +368,6 @@ vgactl(Cmdbuf *cb)
|
||||||
if(screenaperture(size, align) < 0)
|
if(screenaperture(size, align) < 0)
|
||||||
error("not enough free address space");
|
error("not enough free address space");
|
||||||
return;
|
return;
|
||||||
/*
|
|
||||||
case CMmemset:
|
|
||||||
memset((void*)strtoul(cb->f[1], 0, 0), atoi(cb->f[2]), atoi(cb->f[3]));
|
|
||||||
return;
|
|
||||||
*/
|
|
||||||
|
|
||||||
case CMblank:
|
case CMblank:
|
||||||
drawblankscreen(1);
|
drawblankscreen(1);
|
||||||
|
|
|
@ -19,7 +19,6 @@ Point ZP = {0, 0};
|
||||||
|
|
||||||
Rectangle physgscreenr;
|
Rectangle physgscreenr;
|
||||||
|
|
||||||
Memdata gscreendata;
|
|
||||||
Memimage *gscreen;
|
Memimage *gscreen;
|
||||||
|
|
||||||
VGAscr vgascreen[1];
|
VGAscr vgascreen[1];
|
||||||
|
@ -40,13 +39,18 @@ Cursor arrow = {
|
||||||
|
|
||||||
int didswcursorinit;
|
int didswcursorinit;
|
||||||
|
|
||||||
static void *softscreen;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
screensize(int x, int y, int z, ulong chan)
|
screensize(int x, int y, int, ulong chan)
|
||||||
{
|
{
|
||||||
VGAscr *scr;
|
VGAscr *scr;
|
||||||
void *oldsoft;
|
|
||||||
|
qlock(&drawlock);
|
||||||
|
if(waserror()){
|
||||||
|
qunlock(&drawlock);
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
|
||||||
|
memimageinit();
|
||||||
|
|
||||||
lock(&vgascreenlock);
|
lock(&vgascreenlock);
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
|
@ -54,54 +58,51 @@ screensize(int x, int y, int z, ulong chan)
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
|
|
||||||
memimageinit();
|
|
||||||
scr = &vgascreen[0];
|
scr = &vgascreen[0];
|
||||||
oldsoft = softscreen;
|
scr->gscreendata = nil;
|
||||||
|
scr->gscreen = nil;
|
||||||
|
if(gscreen){
|
||||||
|
freememimage(gscreen);
|
||||||
|
gscreen = nil;
|
||||||
|
}
|
||||||
|
|
||||||
if(scr->paddr == 0){
|
if(scr->paddr == 0){
|
||||||
int width = (x*z)/BI2WD;
|
gscreen = allocmemimage(Rect(0,0,x,y), chan);
|
||||||
void *p;
|
|
||||||
|
|
||||||
p = xalloc(width*BY2WD*y);
|
|
||||||
if(p == nil)
|
|
||||||
error("no memory for vga soft screen");
|
|
||||||
gscreendata.bdata = softscreen = p;
|
|
||||||
if(scr->dev && scr->dev->page){
|
if(scr->dev && scr->dev->page){
|
||||||
scr->vaddr = KADDR(VGAMEM());
|
scr->vaddr = KADDR(VGAMEM());
|
||||||
scr->apsize = 1<<16;
|
scr->apsize = 1<<16;
|
||||||
}
|
}
|
||||||
scr->useflush = 1;
|
scr->useflush = 1;
|
||||||
}
|
}else{
|
||||||
else{
|
static Memdata md;
|
||||||
gscreendata.bdata = scr->vaddr;
|
|
||||||
|
md.ref = 1;
|
||||||
|
md.bdata = scr->vaddr;
|
||||||
|
gscreen = allocmemimaged(Rect(0,0,x,y), chan, &md);
|
||||||
scr->useflush = scr->dev && scr->dev->flush;
|
scr->useflush = scr->dev && scr->dev->flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
scr->gscreen = nil;
|
|
||||||
if(gscreen)
|
|
||||||
freememimage(gscreen);
|
|
||||||
gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata);
|
|
||||||
if(gscreen == nil)
|
if(gscreen == nil)
|
||||||
error("no memory for vga memimage");
|
error("no memory for vga memimage");
|
||||||
vgaimageinit(chan);
|
|
||||||
|
|
||||||
scr->palettedepth = 6; /* default */
|
scr->palettedepth = 6; /* default */
|
||||||
scr->gscreendata = &gscreendata;
|
|
||||||
scr->memdefont = getmemdefont();
|
scr->memdefont = getmemdefont();
|
||||||
scr->gscreen = gscreen;
|
scr->gscreen = gscreen;
|
||||||
|
scr->gscreendata = gscreen->data;
|
||||||
|
|
||||||
physgscreenr = gscreen->r;
|
physgscreenr = gscreen->r;
|
||||||
|
|
||||||
|
vgaimageinit(chan);
|
||||||
|
|
||||||
unlock(&vgascreenlock);
|
unlock(&vgascreenlock);
|
||||||
poperror();
|
poperror();
|
||||||
if(oldsoft)
|
|
||||||
xfree(oldsoft);
|
|
||||||
|
|
||||||
memimagedraw(gscreen, gscreen->r, memblack, ZP, nil, ZP, S);
|
|
||||||
flushmemscreen(gscreen->r);
|
|
||||||
|
|
||||||
|
drawcmap();
|
||||||
if(didswcursorinit)
|
if(didswcursorinit)
|
||||||
swcursorinit();
|
swcursorinit();
|
||||||
drawcmap();
|
|
||||||
|
qunlock(&drawlock);
|
||||||
|
poperror();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,8 +153,17 @@ attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen)
|
||||||
*chan = scr->gscreen->chan;
|
*chan = scr->gscreen->chan;
|
||||||
*d = scr->gscreen->depth;
|
*d = scr->gscreen->depth;
|
||||||
*width = scr->gscreen->width;
|
*width = scr->gscreen->width;
|
||||||
*softscreen = scr->useflush;
|
if(scr->gscreendata->allocd){
|
||||||
|
/*
|
||||||
|
* we use a memimage as softscreen. devdraw will create its own
|
||||||
|
* screen image on the backing store of that image. when our gscreen
|
||||||
|
* and devdraws screenimage gets freed, the imagedata will
|
||||||
|
* be released.
|
||||||
|
*/
|
||||||
|
*softscreen = 0xa110c;
|
||||||
|
scr->gscreendata->ref++;
|
||||||
|
} else
|
||||||
|
*softscreen = scr->useflush ? 1 : 0;
|
||||||
return scr->gscreendata->bdata;
|
return scr->gscreendata->bdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,12 +178,12 @@ flushmemscreen(Rectangle r)
|
||||||
int y, len, incs, off, page;
|
int y, len, incs, off, page;
|
||||||
|
|
||||||
scr = &vgascreen[0];
|
scr = &vgascreen[0];
|
||||||
|
if(scr->gscreen == nil || scr->useflush == 0)
|
||||||
|
return;
|
||||||
if(scr->dev && scr->dev->flush){
|
if(scr->dev && scr->dev->flush){
|
||||||
scr->dev->flush(scr, r);
|
scr->dev->flush(scr, r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(scr->gscreen == nil || scr->useflush == 0)
|
|
||||||
return;
|
|
||||||
if(scr->dev == nil || scr->dev->page == nil)
|
if(scr->dev == nil || scr->dev->page == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -185,7 +195,6 @@ flushmemscreen(Rectangle r)
|
||||||
switch(scr->gscreen->depth){
|
switch(scr->gscreen->depth){
|
||||||
default:
|
default:
|
||||||
len = 0;
|
len = 0;
|
||||||
panic("flushmemscreen: depth\n");
|
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
len = Dx(r);
|
len = Dx(r);
|
||||||
|
@ -358,36 +367,31 @@ hwdraw(Memdrawparam *par)
|
||||||
{
|
{
|
||||||
VGAscr *scr;
|
VGAscr *scr;
|
||||||
Memimage *dst, *src, *mask;
|
Memimage *dst, *src, *mask;
|
||||||
|
Memdata *scrd;
|
||||||
int m;
|
int m;
|
||||||
|
|
||||||
if(hwaccel == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
scr = &vgascreen[0];
|
scr = &vgascreen[0];
|
||||||
if((dst=par->dst) == nil || dst->data == nil)
|
scrd = scr->gscreendata;
|
||||||
|
if(scr->gscreen == nil || scrd == nil)
|
||||||
return 0;
|
return 0;
|
||||||
if((src=par->src) == nil || src->data == nil)
|
if((dst = par->dst) == nil || dst->data == nil)
|
||||||
return 0;
|
return 0;
|
||||||
if((mask=par->mask) == nil || mask->data == nil)
|
if((src = par->src) && src->data == nil)
|
||||||
return 0;
|
src = nil;
|
||||||
|
if((mask = par->mask) && mask->data == nil)
|
||||||
|
mask = nil;
|
||||||
if(scr->cur == &swcursor){
|
if(scr->cur == &swcursor){
|
||||||
/*
|
if(dst->data->bdata == scrd->bdata)
|
||||||
* always calling swcursorhide here doesn't cure
|
|
||||||
* leaving cursor tracks nor failing to refresh menus
|
|
||||||
* with the latest libmemdraw/draw.c.
|
|
||||||
*/
|
|
||||||
if(dst->data->bdata == gscreendata.bdata)
|
|
||||||
swcursoravoid(par->r);
|
swcursoravoid(par->r);
|
||||||
if(src->data->bdata == gscreendata.bdata)
|
if(src && src->data->bdata == scrd->bdata)
|
||||||
swcursoravoid(par->sr);
|
swcursoravoid(par->sr);
|
||||||
if(mask->data->bdata == gscreendata.bdata)
|
if(mask && mask->data->bdata == scrd->bdata)
|
||||||
swcursoravoid(par->mr);
|
swcursoravoid(par->mr);
|
||||||
}
|
}
|
||||||
|
if(hwaccel == 0)
|
||||||
if(dst->data->bdata != gscreendata.bdata)
|
return 0;
|
||||||
|
if(dst->data->bdata != scrd->bdata || src == nil || mask == nil)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(scr->fill==nil && scr->scroll==nil)
|
if(scr->fill==nil && scr->scroll==nil)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -607,29 +611,6 @@ swcursordraw(void)
|
||||||
swvisible = 1;
|
swvisible = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Need to lock drawlock for ourselves.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
swenable(VGAscr*)
|
|
||||||
{
|
|
||||||
swenabled = 1;
|
|
||||||
if(canqlock(&drawlock)){
|
|
||||||
swcursordraw();
|
|
||||||
qunlock(&drawlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
swdisable(VGAscr*)
|
|
||||||
{
|
|
||||||
swenabled = 0;
|
|
||||||
if(canqlock(&drawlock)){
|
|
||||||
swcursorhide();
|
|
||||||
qunlock(&drawlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
swload(VGAscr*, Cursor *curs)
|
swload(VGAscr*, Cursor *curs)
|
||||||
{
|
{
|
||||||
|
@ -693,7 +674,7 @@ swcursorclock(void)
|
||||||
void
|
void
|
||||||
swcursorinit(void)
|
swcursorinit(void)
|
||||||
{
|
{
|
||||||
static int init, warned;
|
static int init;
|
||||||
VGAscr *scr;
|
VGAscr *scr;
|
||||||
|
|
||||||
didswcursorinit = 1;
|
didswcursorinit = 1;
|
||||||
|
@ -701,17 +682,10 @@ swcursorinit(void)
|
||||||
init = 1;
|
init = 1;
|
||||||
addclock0link(swcursorclock, 10);
|
addclock0link(swcursorclock, 10);
|
||||||
}
|
}
|
||||||
scr = &vgascreen[0];
|
|
||||||
if(scr==nil || scr->gscreen==nil)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(scr->dev == nil || scr->dev->linear == nil){
|
scr = &vgascreen[0];
|
||||||
if(!warned){
|
if(scr->gscreen==nil)
|
||||||
print("cannot use software cursor on non-linear vga screen\n");
|
|
||||||
warned = 1;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if(swback){
|
if(swback){
|
||||||
freememimage(swback);
|
freememimage(swback);
|
||||||
|
@ -720,23 +694,44 @@ swcursorinit(void)
|
||||||
freememimage(swimg);
|
freememimage(swimg);
|
||||||
freememimage(swimg1);
|
freememimage(swimg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
swback = allocmemimage(Rect(0,0,32,32), gscreen->chan);
|
swback = allocmemimage(Rect(0,0,32,32), gscreen->chan);
|
||||||
swmask = allocmemimage(Rect(0,0,16,16), GREY8);
|
swmask = allocmemimage(Rect(0,0,16,16), GREY8);
|
||||||
swmask1 = allocmemimage(Rect(0,0,16,16), GREY1);
|
swmask1 = allocmemimage(Rect(0,0,16,16), GREY1);
|
||||||
swimg = allocmemimage(Rect(0,0,16,16), GREY8);
|
swimg = allocmemimage(Rect(0,0,16,16), GREY8);
|
||||||
swimg1 = allocmemimage(Rect(0,0,16,16), GREY1);
|
swimg1 = allocmemimage(Rect(0,0,16,16), GREY1);
|
||||||
if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil){
|
if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil)
|
||||||
print("software cursor: allocmemimage fails");
|
print("software cursor: allocmemimage fails");
|
||||||
return;
|
memfillcolor(swback, DTransparent);
|
||||||
}
|
|
||||||
|
|
||||||
memfillcolor(swmask, DOpaque);
|
memfillcolor(swmask, DOpaque);
|
||||||
memfillcolor(swmask1, DOpaque);
|
memfillcolor(swmask1, DOpaque);
|
||||||
memfillcolor(swimg, DBlack);
|
memfillcolor(swimg, DBlack);
|
||||||
memfillcolor(swimg1, DBlack);
|
memfillcolor(swimg1, DBlack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to lock drawlock for ourselves.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
swenable(VGAscr *scr)
|
||||||
|
{
|
||||||
|
swenabled = 1;
|
||||||
|
if(canqlock(&drawlock)){
|
||||||
|
swload(scr, &arrow);
|
||||||
|
swcursordraw();
|
||||||
|
qunlock(&drawlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
swdisable(VGAscr*)
|
||||||
|
{
|
||||||
|
swenabled = 0;
|
||||||
|
if(canqlock(&drawlock)){
|
||||||
|
swcursorhide();
|
||||||
|
qunlock(&drawlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VGAcur swcursor =
|
VGAcur swcursor =
|
||||||
{
|
{
|
||||||
"soft",
|
"soft",
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
#include <cursor.h>
|
#include <cursor.h>
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
static Memimage* back;
|
|
||||||
static Memimage *conscol;
|
static Memimage *conscol;
|
||||||
|
static Memimage *back;
|
||||||
|
|
||||||
static Point curpos;
|
static Point curpos;
|
||||||
static Rectangle window;
|
static Rectangle window;
|
||||||
|
@ -23,25 +23,10 @@ Lock vgascreenlock;
|
||||||
int drawdebug;
|
int drawdebug;
|
||||||
|
|
||||||
void
|
void
|
||||||
vgaimageinit(ulong chan)
|
vgaimageinit(ulong)
|
||||||
{
|
{
|
||||||
if(back == nil){
|
conscol = memblack;
|
||||||
back = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */
|
back = memwhite;
|
||||||
if(back == nil)
|
|
||||||
panic("back alloc"); /* RSC BUG */
|
|
||||||
back->flags |= Frepl;
|
|
||||||
back->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
|
|
||||||
memfillcolor(back, DBlack);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(conscol == nil){
|
|
||||||
conscol = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */
|
|
||||||
if(conscol == nil)
|
|
||||||
panic("conscol alloc"); /* RSC BUG */
|
|
||||||
conscol->flags |= Frepl;
|
|
||||||
conscol->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
|
|
||||||
memfillcolor(conscol, DWhite);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -69,13 +54,11 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
|
||||||
int h, w, pos;
|
int h, w, pos;
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
|
|
||||||
// drawdebug = 1;
|
|
||||||
if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
|
if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
|
||||||
xp = xbuf;
|
xp = xbuf;
|
||||||
|
|
||||||
h = scr->memdefont->height;
|
h = scr->memdefont->height;
|
||||||
switch(buf[0]){
|
switch(buf[0]){
|
||||||
|
|
||||||
case '\n':
|
case '\n':
|
||||||
if(curpos.y+h >= window.max.y){
|
if(curpos.y+h >= window.max.y){
|
||||||
vgascroll(scr);
|
vgascroll(scr);
|
||||||
|
@ -100,7 +83,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
|
||||||
pos = 4-(pos%4);
|
pos = 4-(pos%4);
|
||||||
*xp++ = curpos.x;
|
*xp++ = curpos.x;
|
||||||
r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
|
r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
|
||||||
memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
|
memimagedraw(scr->gscreen, r, back, ZP, nil, ZP, S);
|
||||||
curpos.x += pos*w;
|
curpos.x += pos*w;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -109,7 +92,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
|
||||||
break;
|
break;
|
||||||
xp--;
|
xp--;
|
||||||
r = Rect(*xp, curpos.y, curpos.x, curpos.y+h);
|
r = Rect(*xp, curpos.y, curpos.x, curpos.y+h);
|
||||||
memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP, S);
|
memimagedraw(scr->gscreen, r, back, r.min, nil, ZP, S);
|
||||||
combinerect(flushr, r);
|
combinerect(flushr, r);
|
||||||
curpos.x = *xp;
|
curpos.x = *xp;
|
||||||
break;
|
break;
|
||||||
|
@ -126,12 +109,11 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
|
||||||
|
|
||||||
*xp++ = curpos.x;
|
*xp++ = curpos.x;
|
||||||
r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h);
|
r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h);
|
||||||
memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
|
memimagedraw(scr->gscreen, r, back, r.min, nil, ZP, S);
|
||||||
memimagestring(scr->gscreen, curpos, conscol, ZP, scr->memdefont, buf);
|
memimagestring(scr->gscreen, curpos, conscol, ZP, scr->memdefont, buf);
|
||||||
combinerect(flushr, r);
|
combinerect(flushr, r);
|
||||||
curpos.x += w;
|
curpos.x += w;
|
||||||
}
|
}
|
||||||
// drawdebug = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -184,19 +166,61 @@ vgascreenputs(char* s, int n)
|
||||||
unlock(&vgascreenlock);
|
unlock(&vgascreenlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Memimage*
|
||||||
|
mkcolor(Memimage *screen, ulong color)
|
||||||
|
{
|
||||||
|
Memimage *i;
|
||||||
|
|
||||||
|
if(i = allocmemimage(Rect(0,0,1,1), screen->chan)){
|
||||||
|
i->flags |= Frepl;
|
||||||
|
i->clipr = screen->r;
|
||||||
|
memfillcolor(i, color);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
vgascreenwin(VGAscr* scr)
|
vgascreenwin(VGAscr* scr)
|
||||||
{
|
{
|
||||||
int h, w;
|
Memimage *i;
|
||||||
|
Rectangle r;
|
||||||
|
Point p;
|
||||||
|
int h;
|
||||||
|
|
||||||
|
qlock(&drawlock);
|
||||||
|
|
||||||
h = scr->memdefont->height;
|
h = scr->memdefont->height;
|
||||||
w = scr->memdefont->info[' '].width;
|
r = scr->gscreen->r;
|
||||||
|
|
||||||
window = insetrect(scr->gscreen->r, 48);
|
if(i = mkcolor(scr->gscreen, 0x444488FF)){
|
||||||
window.max.x = window.min.x+((window.max.x-window.min.x)/w)*w;
|
memimagedraw(scr->gscreen, r, i, ZP, nil, ZP, S);
|
||||||
window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
|
freememimage(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
window = insetrect(r, 20);
|
||||||
|
memimagedraw(scr->gscreen, window, conscol, ZP, memopaque, ZP, S);
|
||||||
|
window = insetrect(window, 4);
|
||||||
|
memimagedraw(scr->gscreen, window, back, ZP, memopaque, ZP, S);
|
||||||
|
|
||||||
|
if(i = mkcolor(scr->gscreen, 0xAAAAAAFF)){
|
||||||
|
memimagedraw(scr->gscreen, Rect(window.min.x, window.min.y,
|
||||||
|
window.max.x, window.min.y+h+5+6), i, ZP, nil, ZP, S);
|
||||||
|
freememimage(i);
|
||||||
|
|
||||||
|
window = insetrect(window, 5);
|
||||||
|
p = addpt(window.min, Pt(10, 0));
|
||||||
|
memimagestring(scr->gscreen, p, memblack, ZP, scr->memdefont, " Plan 9 Console ");
|
||||||
|
window.min.y += h+6;
|
||||||
|
} else
|
||||||
|
window = insetrect(window, 5);
|
||||||
|
|
||||||
|
window.max.y = window.min.y+(Dy(window)/h)*h;
|
||||||
curpos = window.min;
|
curpos = window.min;
|
||||||
|
|
||||||
|
flushmemscreen(r);
|
||||||
|
|
||||||
|
qunlock(&drawlock);
|
||||||
|
|
||||||
screenputs = vgascreenputs;
|
screenputs = vgascreenputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,24 +264,3 @@ addvgaseg(char *name, ulong pa, ulong size)
|
||||||
seg.size = size;
|
seg.size = size;
|
||||||
addphysseg(&seg);
|
addphysseg(&seg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
cornerstring(char *s)
|
|
||||||
{
|
|
||||||
int h, w;
|
|
||||||
VGAscr *scr;
|
|
||||||
Rectangle r;
|
|
||||||
Point p;
|
|
||||||
|
|
||||||
scr = &vgascreen[0];
|
|
||||||
if(scr->vaddr == nil || screenputs != vgascreenputs)
|
|
||||||
return;
|
|
||||||
p = memsubfontwidth(scr->memdefont, s);
|
|
||||||
w = p.x;
|
|
||||||
h = scr->memdefont->height;
|
|
||||||
|
|
||||||
r = Rect(0, 0, w, h);
|
|
||||||
memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
|
|
||||||
memimagestring(scr->gscreen, r.min, conscol, ZP, scr->memdefont, s);
|
|
||||||
// flushmemscreen(r);
|
|
||||||
}
|
|
||||||
|
|
|
@ -62,15 +62,19 @@ vbecall(Ureg *u)
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
pa = PADDR(RMBUF);
|
pa = PADDR(RMBUF);
|
||||||
/* TODO: check read and write return values */
|
if(devtab[cmem->type]->write(cmem, modebuf, sizeof(modebuf), pa) != sizeof(modebuf))
|
||||||
devtab[cmem->type]->write(cmem, modebuf, sizeof modebuf, pa);
|
error("write modebuf");
|
||||||
u->trap = 0x10;
|
|
||||||
devtab[creg->type]->write(creg, u, sizeof *u, 0);
|
|
||||||
|
|
||||||
devtab[creg->type]->read(creg, u, sizeof *u, 0);
|
u->trap = 0x10;
|
||||||
|
if(devtab[creg->type]->write(creg, u, sizeof(*u), 0) != sizeof(*u))
|
||||||
|
error("write ureg");
|
||||||
|
if(devtab[creg->type]->read(creg, u, sizeof(*u), 0) != sizeof(*u))
|
||||||
|
error("read ureg");
|
||||||
if((u->ax&0xFFFF) != 0x004F)
|
if((u->ax&0xFFFF) != 0x004F)
|
||||||
error("vesa bios error");
|
error("vesa bios error");
|
||||||
devtab[cmem->type]->read(cmem, modebuf, sizeof modebuf, pa);
|
|
||||||
|
if(devtab[cmem->type]->read(cmem, modebuf, sizeof(modebuf), pa) != sizeof(modebuf))
|
||||||
|
error("read modebuf");
|
||||||
|
|
||||||
poperror();
|
poperror();
|
||||||
cclose(creg);
|
cclose(creg);
|
||||||
|
@ -124,7 +128,7 @@ vesalinear(VGAscr *scr, int, int)
|
||||||
Pcidev *pci;
|
Pcidev *pci;
|
||||||
|
|
||||||
if(hardscreen) {
|
if(hardscreen) {
|
||||||
scr->vaddr = 0;
|
scr->vaddr = hardscreen;
|
||||||
scr->paddr = scr->apsize = 0;
|
scr->paddr = scr->apsize = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +184,6 @@ vesalinear(VGAscr *scr, int, int)
|
||||||
|
|
||||||
if(Usesoftscreen){
|
if(Usesoftscreen){
|
||||||
hardscreen = scr->vaddr;
|
hardscreen = scr->vaddr;
|
||||||
scr->vaddr = 0;
|
|
||||||
scr->paddr = scr->apsize = 0;
|
scr->paddr = scr->apsize = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -365,9 +365,8 @@ addflush(Rectangle r)
|
||||||
int abb, ar, anbb;
|
int abb, ar, anbb;
|
||||||
Rectangle nbb;
|
Rectangle nbb;
|
||||||
|
|
||||||
if(sdraw.softscreen==0 || !rectclip(&r, screenimage->r))
|
if(sdraw.softscreen==0 || screenimage == nil || !rectclip(&r, screenimage->r))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(flushrect.min.x >= flushrect.max.x){
|
if(flushrect.min.x >= flushrect.max.x){
|
||||||
flushrect = r;
|
flushrect = r;
|
||||||
waste = 0;
|
waste = 0;
|
||||||
|
@ -413,13 +412,7 @@ dstflush(int dstid, Memimage *dst, Rectangle r)
|
||||||
combinerect(&flushrect, r);
|
combinerect(&flushrect, r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* how can this happen? -rsc, dec 12 2002 */
|
if(screenimage == nil || dst == nil || (l = dst->layer) == nil)
|
||||||
if(dst == 0){
|
|
||||||
print("nil dstflush\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
l = dst->layer;
|
|
||||||
if(l == nil)
|
|
||||||
return;
|
return;
|
||||||
do{
|
do{
|
||||||
if(l->screen->image->data != screenimage->data)
|
if(l->screen->image->data != screenimage->data)
|
||||||
|
@ -433,7 +426,7 @@ dstflush(int dstid, Memimage *dst, Rectangle r)
|
||||||
void
|
void
|
||||||
drawflush(void)
|
drawflush(void)
|
||||||
{
|
{
|
||||||
if(flushrect.min.x < flushrect.max.x)
|
if(screenimage && flushrect.min.x < flushrect.max.x)
|
||||||
flushmemscreen(flushrect);
|
flushmemscreen(flushrect);
|
||||||
flushrect = Rect(10000, 10000, -10000, -10000);
|
flushrect = Rect(10000, 10000, -10000, -10000);
|
||||||
}
|
}
|
||||||
|
@ -676,12 +669,10 @@ drawfreedimage(DImage *dimage)
|
||||||
drawfreedimage(dimage->fromname);
|
drawfreedimage(dimage->fromname);
|
||||||
goto Return;
|
goto Return;
|
||||||
}
|
}
|
||||||
// if(dimage->image == screenimage) /* don't free the display */
|
|
||||||
// goto Return;
|
|
||||||
ds = dimage->dscreen;
|
ds = dimage->dscreen;
|
||||||
if(ds){
|
if(ds){
|
||||||
l = dimage->image;
|
l = dimage->image;
|
||||||
if(l->data == screenimage->data)
|
if(screenimage && l->data == screenimage->data)
|
||||||
addflush(l->layer->screenr);
|
addflush(l->layer->screenr);
|
||||||
if(l->layer->refreshfn == drawrefresh) /* else true owner will clean up */
|
if(l->layer->refreshfn == drawrefresh) /* else true owner will clean up */
|
||||||
free(l->layer->refreshptr);
|
free(l->layer->refreshptr);
|
||||||
|
@ -929,26 +920,36 @@ makescreenimage(void)
|
||||||
Memdata *md;
|
Memdata *md;
|
||||||
Memimage *i;
|
Memimage *i;
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
|
uchar *data;
|
||||||
|
|
||||||
md = malloc(sizeof *md);
|
if((data = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen)) == nil)
|
||||||
if(md == nil)
|
|
||||||
return nil;
|
|
||||||
md->allocd = 1;
|
|
||||||
md->base = nil;
|
|
||||||
md->bdata = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen);
|
|
||||||
if(md->bdata == nil){
|
|
||||||
free(md);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
md->ref = 1;
|
|
||||||
i = allocmemimaged(r, chan, md);
|
|
||||||
if(i == nil){
|
|
||||||
free(md);
|
|
||||||
return nil;
|
return nil;
|
||||||
|
if(sdraw.softscreen == 0xa110c){
|
||||||
|
/* hack: softscreen is memimage. */
|
||||||
|
md = *((Memdata**)(data - sizeof(ulong) - sizeof(Memdata*)));
|
||||||
|
|
||||||
|
assert(md->bdata == data);
|
||||||
|
assert(md->ref > 1);
|
||||||
|
assert(md->allocd);
|
||||||
|
|
||||||
|
if((i = allocmemimaged(r, chan, md)) == nil){
|
||||||
|
md->ref--;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if((md = malloc(sizeof *md)) == nil)
|
||||||
|
return nil;
|
||||||
|
md->allocd = 1;
|
||||||
|
md->base = nil;
|
||||||
|
md->bdata = data;
|
||||||
|
md->ref = 1;
|
||||||
|
if((i = allocmemimaged(r, chan, md)) == nil){
|
||||||
|
free(md);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i->width = width;
|
i->width = width;
|
||||||
i->clipr = r;
|
i->clipr = r;
|
||||||
|
|
||||||
di = allocdimage(i);
|
di = allocdimage(i);
|
||||||
if(di == nil){
|
if(di == nil){
|
||||||
freememimage(i); /* frees md */
|
freememimage(i); /* frees md */
|
||||||
|
@ -1859,7 +1860,7 @@ drawmesg(Client *client, void *av, int n)
|
||||||
if(pp == nil)
|
if(pp == nil)
|
||||||
error(Enomem);
|
error(Enomem);
|
||||||
doflush = 0;
|
doflush = 0;
|
||||||
if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data))
|
if(dstid==0 || (screenimage && dst->layer && dst->layer->screen->image->data == screenimage->data))
|
||||||
doflush = 1; /* simplify test in loop */
|
doflush = 1; /* simplify test in loop */
|
||||||
ox = oy = 0;
|
ox = oy = 0;
|
||||||
esize = 0;
|
esize = 0;
|
||||||
|
@ -2048,7 +2049,7 @@ drawmesg(Client *client, void *av, int n)
|
||||||
memltofrontn(lp, nw);
|
memltofrontn(lp, nw);
|
||||||
else
|
else
|
||||||
memltorearn(lp, nw);
|
memltorearn(lp, nw);
|
||||||
if(lp[0]->layer->screen->image->data == screenimage->data)
|
if(screenimage && lp[0]->layer->screen->image->data == screenimage->data)
|
||||||
for(j=0; j<nw; j++)
|
for(j=0; j<nw; j++)
|
||||||
addflush(lp[j]->layer->screenr);
|
addflush(lp[j]->layer->screenr);
|
||||||
ll = drawlookup(client, BGLONG(a+1+1+2), 1);
|
ll = drawlookup(client, BGLONG(a+1+1+2), 1);
|
||||||
|
|
|
@ -158,7 +158,7 @@ main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
char *bios, buf[256], sizeb[256], *p, *vsize, *psize;
|
char *bios, buf[256], sizeb[256], *p, *vsize, *psize;
|
||||||
char *type, *vtype;
|
char *type, *vtype;
|
||||||
int fd, virtual, len;
|
int virtual, len;
|
||||||
Ctlr *ctlr;
|
Ctlr *ctlr;
|
||||||
Vga *vga;
|
Vga *vga;
|
||||||
|
|
||||||
|
@ -455,12 +455,6 @@ main(int argc, char** argv)
|
||||||
else
|
else
|
||||||
vgactlw("hwgc", vga->hwgc->name);
|
vgactlw("hwgc", vga->hwgc->name);
|
||||||
|
|
||||||
/* might as well initialize the cursor */
|
|
||||||
if((fd = open("/dev/cursor", OWRITE)) >= 0){
|
|
||||||
write(fd, buf, 0);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(vga->virtx != vga->mode->x || vga->virty != vga->mode->y){
|
if(vga->virtx != vga->mode->x || vga->virty != vga->mode->y){
|
||||||
sprint(buf, "%dx%d", vga->mode->x, vga->mode->y);
|
sprint(buf, "%dx%d", vga->mode->x, vga->mode->y);
|
||||||
vgactlw("actualsize", buf);
|
vgactlw("actualsize", buf);
|
||||||
|
|
|
@ -31,8 +31,8 @@ struct Vbe
|
||||||
|
|
||||||
struct Vmode
|
struct Vmode
|
||||||
{
|
{
|
||||||
char name[32];
|
char size[Namelen+1];
|
||||||
char chan[32];
|
char chan[Namelen+1];
|
||||||
int id;
|
int id;
|
||||||
int attr; /* flags */
|
int attr; /* flags */
|
||||||
int bpl;
|
int bpl;
|
||||||
|
@ -89,7 +89,9 @@ enum {
|
||||||
#define PLONG(p, v) (p)[0] = (v); (p)[1] = (v)>>8; (p)[2] = (v)>>16; (p)[3] = (v)>>24
|
#define PLONG(p, v) (p)[0] = (v); (p)[1] = (v)>>8; (p)[2] = (v)>>16; (p)[3] = (v)>>24
|
||||||
|
|
||||||
static Vbe *vbe;
|
static Vbe *vbe;
|
||||||
static Edid edid;
|
static Edid *edid;
|
||||||
|
|
||||||
|
extern Mode *vesamodes[];
|
||||||
|
|
||||||
Vbe *mkvbe(void);
|
Vbe *mkvbe(void);
|
||||||
int vbecheck(Vbe*);
|
int vbecheck(Vbe*);
|
||||||
|
@ -116,6 +118,7 @@ dbvesa(Vga* vga)
|
||||||
fprint(2, "dbvesa: %r\n");
|
fprint(2, "dbvesa: %r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vga->link = alloc(sizeof(Ctlr));
|
vga->link = alloc(sizeof(Ctlr));
|
||||||
*vga->link = vesa;
|
*vga->link = vesa;
|
||||||
vga->vesa = vga->link;
|
vga->vesa = vga->link;
|
||||||
|
@ -129,32 +132,38 @@ dbvesa(Vga* vga)
|
||||||
}
|
}
|
||||||
|
|
||||||
Mode*
|
Mode*
|
||||||
dbvesamode(char *mode)
|
dbvesamode(char *size)
|
||||||
{
|
{
|
||||||
int i;
|
int i, width;
|
||||||
uchar *p, *ep;
|
uchar *p, *ep;
|
||||||
|
Attr *a;
|
||||||
Vmode vm;
|
Vmode vm;
|
||||||
Mode *m;
|
Mode *m;
|
||||||
|
Modelist *l;
|
||||||
|
|
||||||
if(vbe == nil)
|
if(vbe == nil)
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
p = vbemodes(vbe);
|
if(strncmp(size, "0x", 2) == 0){
|
||||||
if(p == nil)
|
if(vbemodeinfo(vbe, strtol(size+2, nil, 16), &vm) == 0)
|
||||||
return nil;
|
|
||||||
for(ep=p+1024; (p[0]!=0xFF || p[1]!=0xFF) && p<ep; p+=2){
|
|
||||||
if(vbemodeinfo(vbe, WORD(p), &vm) < 0)
|
|
||||||
continue;
|
|
||||||
if(strcmp(vm.name, mode) == 0)
|
|
||||||
goto havemode;
|
goto havemode;
|
||||||
}
|
}else{
|
||||||
if(1){
|
if(p = vbemodes(vbe)){
|
||||||
fprint(2, "warning: scanning for unoffered vesa modes\n");
|
for(ep=p+1024; (p[0]!=0xFF || p[1]!=0xFF) && p<ep; p+=2){
|
||||||
for(i=0x100; i<0x200; i++){
|
if(vbemodeinfo(vbe, WORD(p), &vm) < 0)
|
||||||
if(vbemodeinfo(vbe, i, &vm) < 0)
|
continue;
|
||||||
continue;
|
if(strcmp(vm.size, size) == 0)
|
||||||
if(strcmp(vm.name, mode) == 0)
|
goto havemode;
|
||||||
goto havemode;
|
}
|
||||||
|
}
|
||||||
|
if(1){
|
||||||
|
fprint(2, "warning: scanning for unoffered vesa modes\n");
|
||||||
|
for(i=0x100; i<0x200; i++){
|
||||||
|
if(vbemodeinfo(vbe, i, &vm) < 0)
|
||||||
|
continue;
|
||||||
|
if(strcmp(vm.size, size) == 0)
|
||||||
|
goto havemode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
werrstr("no such vesa mode");
|
werrstr("no such vesa mode");
|
||||||
|
@ -162,13 +171,8 @@ dbvesamode(char *mode)
|
||||||
|
|
||||||
havemode:
|
havemode:
|
||||||
m = alloc(sizeof(Mode));
|
m = alloc(sizeof(Mode));
|
||||||
strcpy(m->type, "vesa");
|
|
||||||
strcpy(m->size, vm.name);
|
|
||||||
strcpy(m->chan, vm.chan);
|
|
||||||
m->frequency = 100;
|
|
||||||
m->x = vm.dx;
|
m->x = vm.dx;
|
||||||
m->y = vm.dy;
|
m->y = vm.dy;
|
||||||
m->z = vm.depth;
|
|
||||||
m->ht = m->x;
|
m->ht = m->x;
|
||||||
m->shb = m->x;
|
m->shb = m->x;
|
||||||
m->ehb = m->x;
|
m->ehb = m->x;
|
||||||
|
@ -177,11 +181,49 @@ havemode:
|
||||||
m->vt = m->y;
|
m->vt = m->y;
|
||||||
m->vrs = m->y;
|
m->vrs = m->y;
|
||||||
m->vre = m->y;
|
m->vre = m->y;
|
||||||
|
m->frequency = m->ht * m->vt * 60;
|
||||||
|
|
||||||
|
/* get default monitor timing */
|
||||||
|
for(i=0; vesamodes[i]; i++){
|
||||||
|
if(vesamodes[i]->x != vm.dx || vesamodes[i]->y != vm.dy)
|
||||||
|
continue;
|
||||||
|
*m = *vesamodes[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(edid){
|
||||||
|
for(l = edid->modelist; l; l = l->next){
|
||||||
|
if(l->x != vm.dx || l->y != vm.dy)
|
||||||
|
continue;
|
||||||
|
*m = *((Mode*)l);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(m->type, "vesa");
|
||||||
|
strcpy(m->size, vm.size);
|
||||||
|
strcpy(m->chan, vm.chan);
|
||||||
|
m->z = vm.depth;
|
||||||
|
|
||||||
|
a = alloc(sizeof(Attr));
|
||||||
|
a->attr = "id";
|
||||||
|
a->val = alloc(32);
|
||||||
|
sprint(a->val, "0x%x", vm.id);
|
||||||
|
|
||||||
|
a->next = nil;
|
||||||
|
m->attr = a;
|
||||||
|
|
||||||
|
/* account for framebuffer stride */
|
||||||
|
width = vm.bpl * 8 / m->z;
|
||||||
|
if(width > m->x){
|
||||||
|
a = alloc(sizeof(Attr));
|
||||||
|
a->attr = "virtx";
|
||||||
|
a->val = alloc(32);
|
||||||
|
sprint(a->val, "%d", width);
|
||||||
|
|
||||||
|
a->next = m->attr;
|
||||||
|
m->attr = a;
|
||||||
|
}
|
||||||
|
|
||||||
m->attr = alloc(sizeof(Attr));
|
|
||||||
m->attr->attr = "id";
|
|
||||||
m->attr->val = alloc(32);
|
|
||||||
sprint(m->attr->val, "0x%x", vm.id);
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +236,20 @@ snarf(Vga* vga, Ctlr* ctlr)
|
||||||
vga->vesa = ctlr;
|
vga->vesa = ctlr;
|
||||||
vbesnarf(vbe, vga);
|
vbesnarf(vbe, vga);
|
||||||
vga->linear = 1;
|
vga->linear = 1;
|
||||||
ctlr->flag |= Hlinear|Ulinear;
|
ctlr->flag |= Hlinear|Ulinear|Fsnarf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
options(Vga *vga, Ctlr *ctlr)
|
||||||
|
{
|
||||||
|
char *v;
|
||||||
|
|
||||||
|
if(v = dbattr(vga->mode->attr, "virtx")){
|
||||||
|
vga->virtx = atoi(v);
|
||||||
|
vga->virty = vga->mode->y;
|
||||||
|
vga->panning = 0;
|
||||||
|
}
|
||||||
|
ctlr->flag |= Foptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -233,18 +288,14 @@ dump(Vga*, Ctlr*)
|
||||||
for(i=0x100; i<0x1FF; i++)
|
for(i=0x100; i<0x1FF; i++)
|
||||||
if(!did[i])
|
if(!did[i])
|
||||||
vbeprintmodeinfo(vbe, i, " (unoffered)");
|
vbeprintmodeinfo(vbe, i, " (unoffered)");
|
||||||
|
if(edid)
|
||||||
|
printedid(edid);
|
||||||
if(vbeddcedid(vbe, &edid) < 0)
|
|
||||||
fprint(2, "warning: reading edid: %r\n");
|
|
||||||
else
|
|
||||||
printedid(&edid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ctlr vesa = {
|
Ctlr vesa = {
|
||||||
"vesa", /* name */
|
"vesa", /* name */
|
||||||
snarf, /* snarf */
|
snarf, /* snarf */
|
||||||
0, /* options */
|
options, /* options */
|
||||||
0, /* init */
|
0, /* init */
|
||||||
load, /* load */
|
load, /* load */
|
||||||
dump, /* dump */
|
dump, /* dump */
|
||||||
|
@ -273,19 +324,34 @@ static Flag capabilityflag[] = {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AttrSupported = 1<<0,
|
||||||
|
AttrTTY = 1<<2,
|
||||||
|
AttrColor = 1<<3,
|
||||||
|
AttrGraphics = 1<<4,
|
||||||
|
AttrNotVGA = 1<<5,
|
||||||
|
AttrNotWinVGA = 1<<6,
|
||||||
|
AttrLinear = 1<<7,
|
||||||
|
AttrDoublescan = 1<<8,
|
||||||
|
AttrInterlace = 1<<9,
|
||||||
|
AttrTriplebuf = 1<<10,
|
||||||
|
AttrStereo = 1<<11,
|
||||||
|
AttrDualAddr = 1<<12,
|
||||||
|
};
|
||||||
|
|
||||||
static Flag modeattributesflags[] = {
|
static Flag modeattributesflags[] = {
|
||||||
1<<0, "supported",
|
AttrSupported, "supported",
|
||||||
1<<2, "tty",
|
AttrTTY, "tty",
|
||||||
1<<3, "color",
|
AttrColor, "color",
|
||||||
1<<4, "graphics",
|
AttrGraphics, "graphics",
|
||||||
1<<5, "not-vga",
|
AttrNotVGA, "not-vga",
|
||||||
1<<6, "no-windowed-vga",
|
AttrNotWinVGA, "no-windowed-vga",
|
||||||
1<<7, "linear",
|
AttrLinear, "linear",
|
||||||
1<<8, "double-scan",
|
AttrDoublescan, "double-scan",
|
||||||
1<<9, "interlace",
|
AttrInterlace, "interlace",
|
||||||
1<<10, "triple-buffer",
|
AttrTriplebuf, "triple-buffer",
|
||||||
1<<11, "stereoscopic",
|
AttrStereo, "stereoscopic",
|
||||||
1<<12, "dual-start-addr",
|
AttrDualAddr, "dual-start-addr",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -302,10 +368,29 @@ static Flag directcolorflags[] = {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *modelstr[] = {
|
enum {
|
||||||
"text", "cga", "hercules", "planar", "packed", "non-chain4", "direct", "YUV"
|
ModText = 0,
|
||||||
|
ModCGA,
|
||||||
|
ModHercules,
|
||||||
|
ModPlanar,
|
||||||
|
ModPacked,
|
||||||
|
ModNonChain4,
|
||||||
|
ModDirect,
|
||||||
|
ModYUV,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char *modelstr[] = {
|
||||||
|
[ModText] "text",
|
||||||
|
[ModCGA] "cga",
|
||||||
|
[ModHercules] "hercules",
|
||||||
|
[ModPlanar] "planar",
|
||||||
|
[ModPacked] "packed",
|
||||||
|
[ModNonChain4] "non-chain4",
|
||||||
|
[ModDirect] "direct",
|
||||||
|
[ModYUV] "YUV",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printflags(Flag *f, int b)
|
printflags(Flag *f, int b)
|
||||||
{
|
{
|
||||||
|
@ -402,8 +487,12 @@ vbecheck(Vbe *vbe)
|
||||||
strcpy((char*)p, "VBE2");
|
strcpy((char*)p, "VBE2");
|
||||||
if(vbecall(vbe, &u) < 0)
|
if(vbecall(vbe, &u) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(memcmp(p, "VESA", 4) != 0 || p[5] < 2){
|
if(memcmp(p, "VESA", 4)){
|
||||||
werrstr("invalid vesa signature %.4H %.4H\n", p, p+4);
|
werrstr("invalid vesa signature %.4H\n", p);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(p[5] < 2){
|
||||||
|
werrstr("invalid vesa version: %.4H\n", p+4);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -422,6 +511,13 @@ vbesnarf(Vbe *vbe, Vga *vga)
|
||||||
if(memcmp(p, "VESA", 4) != 0 || p[5] < 2)
|
if(memcmp(p, "VESA", 4) != 0 || p[5] < 2)
|
||||||
return -1;
|
return -1;
|
||||||
vga->apz = WORD(p+18)*0x10000UL;
|
vga->apz = WORD(p+18)*0x10000UL;
|
||||||
|
if(edid == nil){
|
||||||
|
edid = alloc(sizeof(Edid));
|
||||||
|
if(vbeddcedid(vbe, edid) < 0){
|
||||||
|
free(edid);
|
||||||
|
edid = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,11 +570,9 @@ vbemodes(Vbe *vbe)
|
||||||
int
|
int
|
||||||
vbemodeinfo(Vbe *vbe, int id, Vmode *m)
|
vbemodeinfo(Vbe *vbe, int id, Vmode *m)
|
||||||
{
|
{
|
||||||
int o;
|
|
||||||
ulong d, c, x;
|
|
||||||
uchar *p;
|
uchar *p;
|
||||||
char tmp[sizeof m->chan];
|
|
||||||
Ureg u;
|
Ureg u;
|
||||||
|
int mod;
|
||||||
|
|
||||||
p = vbesetup(vbe, &u, 0x4F01);
|
p = vbesetup(vbe, &u, 0x4F01);
|
||||||
u.cx = id;
|
u.cx = id;
|
||||||
|
@ -487,11 +581,31 @@ vbemodeinfo(Vbe *vbe, int id, Vmode *m)
|
||||||
|
|
||||||
m->id = id;
|
m->id = id;
|
||||||
m->attr = WORD(p);
|
m->attr = WORD(p);
|
||||||
|
if(!(m->attr & AttrSupported))
|
||||||
|
goto Unsupported;
|
||||||
|
if(!(m->attr & AttrGraphics))
|
||||||
|
goto Unsupported;
|
||||||
|
if(!(m->attr & AttrLinear))
|
||||||
|
goto Unsupported;
|
||||||
m->bpl = WORD(p+16);
|
m->bpl = WORD(p+16);
|
||||||
m->dx = WORD(p+18);
|
m->dx = WORD(p+18);
|
||||||
m->dy = WORD(p+20);
|
m->dy = WORD(p+20);
|
||||||
m->depth = p[25];
|
m->depth = p[25];
|
||||||
m->model = p[27] < nelem(modelstr) ? modelstr[p[27]] : "unknown";
|
if((m->dx * m->dy * m->depth) <= 0)
|
||||||
|
goto Unsupported;
|
||||||
|
mod = p[27];
|
||||||
|
switch(mod){
|
||||||
|
default:
|
||||||
|
Unsupported:
|
||||||
|
werrstr("mode unsupported");
|
||||||
|
return -1;
|
||||||
|
case ModCGA:
|
||||||
|
case ModHercules:
|
||||||
|
case ModPacked:
|
||||||
|
case ModDirect:
|
||||||
|
m->model = modelstr[mod];
|
||||||
|
break;
|
||||||
|
}
|
||||||
m->r = p[31];
|
m->r = p[31];
|
||||||
m->g = p[33];
|
m->g = p[33];
|
||||||
m->b = p[35];
|
m->b = p[35];
|
||||||
|
@ -502,44 +616,49 @@ vbemodeinfo(Vbe *vbe, int id, Vmode *m)
|
||||||
m->xo = p[38];
|
m->xo = p[38];
|
||||||
m->directcolor = p[39];
|
m->directcolor = p[39];
|
||||||
m->paddr = LONG(p+40);
|
m->paddr = LONG(p+40);
|
||||||
snprint(m->name, sizeof m->name, "%dx%dx%d",
|
|
||||||
m->dx, m->dy, m->depth);
|
|
||||||
if(m->depth <= 8) {
|
|
||||||
snprint(m->chan, sizeof m->chan, "m%d", m->depth);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
m->xo = m->x = 0;
|
snprint(m->size, sizeof m->size, "%dx%dx%d", m->dx, m->dy, m->depth);
|
||||||
d = 1 << (m->depth - 1);
|
if(m->depth <= 8)
|
||||||
d |= d - 1;
|
snprint(m->chan, sizeof m->chan, "%c%d",
|
||||||
c = ((1<<m->r)-1) << m->ro;
|
(m->attr & AttrColor) ? 'm' : 'k', m->depth);
|
||||||
c |= ((1<<m->g)-1) << m->go;
|
else {
|
||||||
c |= ((1<<m->b)-1) << m->bo;
|
int o;
|
||||||
x = d ^ c;
|
ulong d, c, x;
|
||||||
if(x != 0){
|
|
||||||
for(; (x & 1) == 0; x >>= 1)
|
|
||||||
m->xo++;
|
|
||||||
for(; x & 1; x >>= 1)
|
|
||||||
m->x++;
|
|
||||||
}
|
|
||||||
|
|
||||||
m->chan[0] = o = 0;
|
m->xo = m->x = 0;
|
||||||
while(o < m->depth){
|
d = 1<<m->depth-1;
|
||||||
if(m->r && m->ro == o){
|
d |= d-1;
|
||||||
snprint(tmp, sizeof tmp, "r%d%s", m->r, m->chan);
|
c = ((1<<m->r)-1) << m->ro;
|
||||||
o += m->r;
|
c |= ((1<<m->g)-1) << m->go;
|
||||||
}else if(m->g && m->go == o){
|
c |= ((1<<m->b)-1) << m->bo;
|
||||||
snprint(tmp, sizeof tmp, "g%d%s", m->g, m->chan);
|
if(x = d ^ c){
|
||||||
o += m->g;
|
for(; (x & 1) == 0; x >>= 1)
|
||||||
}else if(m->b && m->bo == o){
|
m->xo++;
|
||||||
snprint(tmp, sizeof tmp, "b%d%s", m->b, m->chan);
|
for(; (x & 1) == 1; x >>= 1)
|
||||||
o += m->b;
|
m->x++;
|
||||||
}else if(m->x && m->xo == o){
|
}
|
||||||
snprint(tmp, sizeof tmp, "x%d%s", m->x, m->chan);
|
|
||||||
o += m->x;
|
o = 0;
|
||||||
}else
|
m->chan[0] = 0;
|
||||||
break;
|
while(o < m->depth){
|
||||||
strncpy(m->chan, tmp, sizeof m->chan);
|
char tmp[sizeof m->chan];
|
||||||
|
|
||||||
|
if(m->r && m->ro == o){
|
||||||
|
snprint(tmp, sizeof tmp, "r%d%s", m->r, m->chan);
|
||||||
|
o += m->r;
|
||||||
|
}else if(m->g && m->go == o){
|
||||||
|
snprint(tmp, sizeof tmp, "g%d%s", m->g, m->chan);
|
||||||
|
o += m->g;
|
||||||
|
}else if(m->b && m->bo == o){
|
||||||
|
snprint(tmp, sizeof tmp, "b%d%s", m->b, m->chan);
|
||||||
|
o += m->b;
|
||||||
|
}else if(m->x && m->xo == o){
|
||||||
|
snprint(tmp, sizeof tmp, "x%d%s", m->x, m->chan);
|
||||||
|
o += m->x;
|
||||||
|
}else
|
||||||
|
break;
|
||||||
|
strncpy(m->chan, tmp, sizeof m->chan);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -549,13 +668,11 @@ vbeprintmodeinfo(Vbe *vbe, int id, char *suffix)
|
||||||
{
|
{
|
||||||
Vmode m;
|
Vmode m;
|
||||||
|
|
||||||
if(vbemodeinfo(vbe, id, &m) < 0){
|
if(vbemodeinfo(vbe, id, &m) < 0)
|
||||||
// Bprint(&stdout, "vesa: cannot get mode 0x%ux: %r\n", id);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
printitem("vesa", "mode");
|
printitem("vesa", "mode");
|
||||||
Bprint(&stdout, "0x%ux %s %s %s%s\n",
|
Bprint(&stdout, "0x%ux %s %s %s%s\n",
|
||||||
m.id, m.name, m.chan, m.model, suffix);
|
m.id, m.size, m.chan, m.model, suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -572,33 +689,12 @@ vbegetmode(Vbe *vbe)
|
||||||
int
|
int
|
||||||
vbesetmode(Vbe *vbe, int id)
|
vbesetmode(Vbe *vbe, int id)
|
||||||
{
|
{
|
||||||
uchar *p;
|
|
||||||
Ureg u;
|
Ureg u;
|
||||||
|
|
||||||
p = vbesetup(vbe, &u, 0x4F02);
|
vbesetup(vbe, &u, 0x4F02);
|
||||||
if(id != 3)
|
|
||||||
id |= 3<<14; /* graphics: use linear, do not clear */
|
|
||||||
u.bx = id;
|
u.bx = id;
|
||||||
USED(p);
|
if(id != 3)
|
||||||
/*
|
u.bx |= 3<<14; /* graphics: use linear, do not clear */
|
||||||
* can set mode specifics (ht hss hse vt vss vse 0 clockhz refreshhz):
|
|
||||||
*
|
|
||||||
u.bx |= 1<<11;
|
|
||||||
n = atoi(argv[2]); PWORD(p, n); p+=2;
|
|
||||||
n = atoi(argv[3]); PWORD(p, n); p+=2;
|
|
||||||
n = atoi(argv[4]); PWORD(p, n); p+=2;
|
|
||||||
n = atoi(argv[5]); PWORD(p, n); p+=2;
|
|
||||||
n = atoi(argv[6]); PWORD(p, n); p+=2;
|
|
||||||
n = atoi(argv[7]); PWORD(p, n); p+=2;
|
|
||||||
*p++ = atoi(argv[8]);
|
|
||||||
n = atoi(argv[9]); PLONG(p, n); p += 4;
|
|
||||||
n = atoi(argv[10]); PWORD(p, n); p += 2;
|
|
||||||
if(p != vbe.buf+19){
|
|
||||||
fprint(2, "prog error\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
return vbecall(vbe, &u);
|
return vbecall(vbe, &u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,8 +775,16 @@ printedid(Edid *e)
|
||||||
|
|
||||||
for(l=e->modelist; l; l=l->next){
|
for(l=e->modelist; l; l=l->next){
|
||||||
printitem("edid", l->name);
|
printitem("edid", l->name);
|
||||||
Bprint(&stdout, "\n\t\tclock=%g\n\t\tshb=%d ehb=%d ht=%d\n\t\tvrs=%d vre=%d vt=%d\n\t\thsync=%c vsync=%c %s\n",
|
Bprint(&stdout, "\n\t\tclock=%g\n"
|
||||||
l->frequency/1.e6, l->shb, l->ehb, l->ht, l->vrs, l->vre, l->vt, l->hsync?l->hsync:'?', l->vsync?l->vsync:'?', l->interlace?"interlace=v" : "");
|
"\t\tshb=%d ehb=%d ht=%d\n"
|
||||||
|
"\t\tvrs=%d vre=%d vt=%d\n"
|
||||||
|
"\t\thsync=%c vsync=%c %s\n",
|
||||||
|
l->frequency/1.e6,
|
||||||
|
l->shb, l->ehb, l->ht,
|
||||||
|
l->vrs, l->vre, l->vt,
|
||||||
|
l->hsync?l->hsync:'?',
|
||||||
|
l->vsync?l->vsync:'?',
|
||||||
|
l->interlace?"interlace=v" : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,9 +794,8 @@ addmode(Modelist *l, Mode m)
|
||||||
int rr;
|
int rr;
|
||||||
Modelist **lp;
|
Modelist **lp;
|
||||||
|
|
||||||
//m.z = 8; // BUG
|
|
||||||
rr = (m.frequency+m.ht*m.vt/2)/(m.ht*m.vt);
|
rr = (m.frequency+m.ht*m.vt/2)/(m.ht*m.vt);
|
||||||
snprint(m.name, sizeof m.name, "%dx%dx%d@%dHz", m.x, m.y, m.z, rr);
|
snprint(m.name, sizeof m.name, "%dx%d@%dHz", m.x, m.y, rr);
|
||||||
|
|
||||||
if(m.shs == 0)
|
if(m.shs == 0)
|
||||||
m.shs = m.shb;
|
m.shs = m.shb;
|
||||||
|
@ -832,8 +935,6 @@ decodedtb(Mode *m, uchar *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern Mode *vesamodes[];
|
|
||||||
|
|
||||||
int
|
int
|
||||||
vesalookup(Mode *m, char *name)
|
vesalookup(Mode *m, char *name)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* this file was automatically generated from vesa.txt */
|
// DO NOT EDIT; this file is automatically generated from vesa.txt
|
||||||
|
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
|
@ -6,16 +6,14 @@
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
|
|
||||||
/*
|
// VESA Monitor Timing Standard mode definitions as per
|
||||||
* VESA Monitor Timing Standard mode definitions as per
|
// VESA and Industry Standards and Guidelines for Computer
|
||||||
* VESA and Industry Standards and Guidelines for Computer
|
// Display Monitor Timing, Version 1.0, Revision 0.8, 17 September 1998.
|
||||||
* Display Monitor Timing, Version 1.0, Revision 0.8, 17 September 1998.
|
//
|
||||||
*
|
// See /lib/vesa/dmtv1r08.pdf.
|
||||||
* See /public/doc/vesa/dmtv1r08.pdf.
|
//
|
||||||
*
|
// This might go back into vgadb at some point. It's here mainly
|
||||||
* This might go back into vgadb at some point. It's here mainly
|
// so that people don't change it, and so that we can run without vgadb.
|
||||||
* so that people don't change it, and so that we can run without vgadb.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static Mode vesa640x480x60 = {
|
static Mode vesa640x480x60 = {
|
||||||
.name = "640x480@60Hz",
|
.name = "640x480@60Hz",
|
||||||
|
|
|
@ -12,22 +12,34 @@ static int tablesbuilt;
|
||||||
#define RGB2K(r,g,b) ((156763*(r)+307758*(g)+59769*(b))>>19)
|
#define RGB2K(r,g,b) ((156763*(r)+307758*(g)+59769*(b))>>19)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* for 0 ≤ x ≤ 255*255, (x*0x0101+0x100)>>16 is a perfect approximation.
|
* For 16-bit values, x / 255 == (t = x+1, (t+(t>>8)) >> 8).
|
||||||
* for 0 ≤ x < (1<<16), x/255 = ((x+1)*0x0101)>>16 is a perfect approximation.
|
* We add another 127 to round to the nearest value rather
|
||||||
* the last one is perfect for all up to 1<<16, avoids a multiply, but requires a rathole.
|
* than truncate.
|
||||||
|
*
|
||||||
|
* CALCxy does x bytewise calculations on y input images (x=1,4; y=1,2).
|
||||||
|
* CALC2x does two parallel 16-bit calculations on y input images (y=1,2).
|
||||||
*/
|
*/
|
||||||
/* #define DIV255(x) (((x)*257+256)>>16) */
|
#define CALC11(a, v, tmp) \
|
||||||
#define DIV255(x) ((((x)+1)*257)>>16)
|
(tmp=(a)*(v)+128, (tmp+(tmp>>8))>>8)
|
||||||
/* #define DIV255(x) (tmp=(x)+1, (tmp+(tmp>>8))>>8) */
|
|
||||||
|
|
||||||
#define MUL(x, y, t) (t = (x)*(y)+128, (t+(t>>8))>>8)
|
#define CALC12(a1, v1, a2, v2, tmp) \
|
||||||
#define MASK13 0xFF00FF00
|
(tmp=(a1)*(v1)+(a2)*(v2)+128, (tmp+(tmp>>8))>>8)
|
||||||
#define MASK02 0x00FF00FF
|
|
||||||
#define MUL13(a, x, t) (t = (a)*(((x)&MASK13)>>8)+128, ((t+((t>>8)&MASK02))>>8)&MASK02)
|
|
||||||
#define MUL02(a, x, t) (t = (a)*(((x)&MASK02)>>0)+128, ((t+((t>>8)&MASK02))>>8)&MASK02)
|
|
||||||
#define MUL0123(a, x, s, t) ((MUL13(a, x, s)<<8)|MUL02(a, x, t))
|
|
||||||
|
|
||||||
#define MUL2(u, v, x, y) (t = (u)*(v)+(x)*(y)+256, (t+(t>>8))>>8)
|
#define MASK 0xFF00FF
|
||||||
|
|
||||||
|
#define CALC21(a, vvuu, tmp) \
|
||||||
|
(tmp=(a)*(vvuu)+0x00800080, ((tmp+((tmp>>8)&MASK))>>8)&MASK)
|
||||||
|
|
||||||
|
#define CALC41(a, rgba, tmp1, tmp2) \
|
||||||
|
(CALC21(a, rgba & MASK, tmp1) | \
|
||||||
|
(CALC21(a, (rgba>>8)&MASK, tmp2)<<8))
|
||||||
|
|
||||||
|
#define CALC22(a1, vvuu1, a2, vvuu2, tmp) \
|
||||||
|
(tmp=(a1)*(vvuu1)+(a2)*(vvuu2)+0x00800080, ((tmp+((tmp>>8)&MASK))>>8)&MASK)
|
||||||
|
|
||||||
|
#define CALC42(a1, rgba1, a2, rgba2, tmp1, tmp2) \
|
||||||
|
(CALC22(a1, rgba1 & MASK, a2, rgba2 & MASK, tmp1) | \
|
||||||
|
(CALC22(a1, (rgba1>>8) & MASK, a2, (rgba2>>8) & MASK, tmp2)<<8))
|
||||||
|
|
||||||
static void mktables(void);
|
static void mktables(void);
|
||||||
typedef int Subdraw(Memdrawparam*);
|
typedef int Subdraw(Memdrawparam*);
|
||||||
|
@ -803,41 +815,85 @@ alphacalc0(Buffer bdst, Buffer b1, Buffer b2, int dx, int grey, int op)
|
||||||
return bdst;
|
return bdst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do the channels in the buffers match enough
|
||||||
|
* that we can do word-at-a-time operations
|
||||||
|
* on the pixels?
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
chanmatch(Buffer *bdst, Buffer *bsrc)
|
||||||
|
{
|
||||||
|
uchar *drgb, *srgb;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* first, r, g, b must be in the same place
|
||||||
|
* in the rgba word.
|
||||||
|
*/
|
||||||
|
drgb = (uchar*)bdst->rgba;
|
||||||
|
srgb = (uchar*)bsrc->rgba;
|
||||||
|
if(bdst->red - drgb != bsrc->red - srgb
|
||||||
|
|| bdst->blu - drgb != bsrc->blu - srgb
|
||||||
|
|| bdst->grn - drgb != bsrc->grn - srgb)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* that implies alpha is in the same place,
|
||||||
|
* if it is there at all (it might be == &ones).
|
||||||
|
* if the destination is &ones, we can scribble
|
||||||
|
* over the rgba slot just fine.
|
||||||
|
*/
|
||||||
|
if(bdst->alpha == &ones)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if the destination is not ones but the src is,
|
||||||
|
* then the simultaneous calculation will use
|
||||||
|
* bogus bytes from the src's rgba. no good.
|
||||||
|
*/
|
||||||
|
if(bsrc->alpha == &ones)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* otherwise, alphas are in the same place.
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static Buffer
|
static Buffer
|
||||||
alphacalc14(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
alphacalc14(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
{
|
{
|
||||||
Buffer obdst;
|
Buffer obdst;
|
||||||
int fd, sadelta;
|
int fd, sadelta;
|
||||||
int i, sa, ma, q;
|
int i, sa, ma, q;
|
||||||
ulong s, t;
|
ulong t, t1;
|
||||||
|
|
||||||
obdst = bdst;
|
obdst = bdst;
|
||||||
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
|
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
|
||||||
q = bsrc.delta == 4 && bdst.delta == 4;
|
q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);
|
||||||
|
|
||||||
for(i=0; i<dx; i++){
|
for(i=0; i<dx; i++){
|
||||||
sa = *bsrc.alpha;
|
sa = *bsrc.alpha;
|
||||||
ma = *bmask.alpha;
|
ma = *bmask.alpha;
|
||||||
fd = MUL(sa, ma, t);
|
fd = CALC11(sa, ma, t);
|
||||||
if(op == DoutS)
|
if(op == DoutS)
|
||||||
fd = 255-fd;
|
fd = 255-fd;
|
||||||
|
|
||||||
if(grey){
|
if(grey){
|
||||||
*bdst.grey = MUL(fd, *bdst.grey, t);
|
*bdst.grey = CALC11(fd, *bdst.grey, t);
|
||||||
bsrc.grey += bsrc.delta;
|
bsrc.grey += bsrc.delta;
|
||||||
bdst.grey += bdst.delta;
|
bdst.grey += bdst.delta;
|
||||||
}else{
|
}else{
|
||||||
if(q){
|
if(q){
|
||||||
*bdst.rgba = MUL0123(fd, *bdst.rgba, s, t);
|
*bdst.rgba = CALC41(fd, *bdst.rgba, t, t1);
|
||||||
bsrc.rgba++;
|
bsrc.rgba++;
|
||||||
bdst.rgba++;
|
bdst.rgba++;
|
||||||
bsrc.alpha += sadelta;
|
bsrc.alpha += sadelta;
|
||||||
bmask.alpha += bmask.delta;
|
bmask.alpha += bmask.delta;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*bdst.red = MUL(fd, *bdst.red, t);
|
*bdst.red = CALC11(fd, *bdst.red, t);
|
||||||
*bdst.grn = MUL(fd, *bdst.grn, t);
|
*bdst.grn = CALC11(fd, *bdst.grn, t);
|
||||||
*bdst.blu = MUL(fd, *bdst.blu, t);
|
*bdst.blu = CALC11(fd, *bdst.blu, t);
|
||||||
bsrc.red += bsrc.delta;
|
bsrc.red += bsrc.delta;
|
||||||
bsrc.blu += bsrc.delta;
|
bsrc.blu += bsrc.delta;
|
||||||
bsrc.grn += bsrc.delta;
|
bsrc.grn += bsrc.delta;
|
||||||
|
@ -846,7 +902,7 @@ alphacalc14(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
bdst.grn += bdst.delta;
|
bdst.grn += bdst.delta;
|
||||||
}
|
}
|
||||||
if(bdst.alpha != &ones){
|
if(bdst.alpha != &ones){
|
||||||
*bdst.alpha = MUL(fd, *bdst.alpha, t);
|
*bdst.alpha = CALC11(fd, *bdst.alpha, t);
|
||||||
bdst.alpha += bdst.delta;
|
bdst.alpha += bdst.delta;
|
||||||
}
|
}
|
||||||
bmask.alpha += bmask.delta;
|
bmask.alpha += bmask.delta;
|
||||||
|
@ -861,11 +917,11 @@ alphacalc2810(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
Buffer obdst;
|
Buffer obdst;
|
||||||
int fs, sadelta;
|
int fs, sadelta;
|
||||||
int i, ma, da, q;
|
int i, ma, da, q;
|
||||||
ulong s, t;
|
ulong t, t1;
|
||||||
|
|
||||||
obdst = bdst;
|
obdst = bdst;
|
||||||
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
|
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
|
||||||
q = bsrc.delta == 4 && bdst.delta == 4;
|
q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);
|
||||||
|
|
||||||
for(i=0; i<dx; i++){
|
for(i=0; i<dx; i++){
|
||||||
ma = *bmask.alpha;
|
ma = *bmask.alpha;
|
||||||
|
@ -874,24 +930,24 @@ alphacalc2810(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
da = 255-da;
|
da = 255-da;
|
||||||
fs = ma;
|
fs = ma;
|
||||||
if(op != S)
|
if(op != S)
|
||||||
fs = MUL(fs, da, t);
|
fs = CALC11(fs, da, t);
|
||||||
|
|
||||||
if(grey){
|
if(grey){
|
||||||
*bdst.grey = MUL(fs, *bsrc.grey, t);
|
*bdst.grey = CALC11(fs, *bsrc.grey, t);
|
||||||
bsrc.grey += bsrc.delta;
|
bsrc.grey += bsrc.delta;
|
||||||
bdst.grey += bdst.delta;
|
bdst.grey += bdst.delta;
|
||||||
}else{
|
}else{
|
||||||
if(q){
|
if(q){
|
||||||
*bdst.rgba = MUL0123(fs, *bsrc.rgba, s, t);
|
*bdst.rgba = CALC41(fs, *bsrc.rgba, t, t1);
|
||||||
bsrc.rgba++;
|
bsrc.rgba++;
|
||||||
bdst.rgba++;
|
bdst.rgba++;
|
||||||
bmask.alpha += bmask.delta;
|
bmask.alpha += bmask.delta;
|
||||||
bdst.alpha += bdst.delta;
|
bdst.alpha += bdst.delta;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*bdst.red = MUL(fs, *bsrc.red, t);
|
*bdst.red = CALC11(fs, *bsrc.red, t);
|
||||||
*bdst.grn = MUL(fs, *bsrc.grn, t);
|
*bdst.grn = CALC11(fs, *bsrc.grn, t);
|
||||||
*bdst.blu = MUL(fs, *bsrc.blu, t);
|
*bdst.blu = CALC11(fs, *bsrc.blu, t);
|
||||||
bsrc.red += bsrc.delta;
|
bsrc.red += bsrc.delta;
|
||||||
bsrc.blu += bsrc.delta;
|
bsrc.blu += bsrc.delta;
|
||||||
bsrc.grn += bsrc.delta;
|
bsrc.grn += bsrc.delta;
|
||||||
|
@ -900,7 +956,7 @@ alphacalc2810(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
bdst.grn += bdst.delta;
|
bdst.grn += bdst.delta;
|
||||||
}
|
}
|
||||||
if(bdst.alpha != &ones){
|
if(bdst.alpha != &ones){
|
||||||
*bdst.alpha = MUL(fs, *bsrc.alpha, t);
|
*bdst.alpha = CALC11(fs, *bsrc.alpha, t);
|
||||||
bdst.alpha += bdst.delta;
|
bdst.alpha += bdst.delta;
|
||||||
}
|
}
|
||||||
bmask.alpha += bmask.delta;
|
bmask.alpha += bmask.delta;
|
||||||
|
@ -915,35 +971,35 @@ alphacalc3679(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
Buffer obdst;
|
Buffer obdst;
|
||||||
int fs, fd, sadelta;
|
int fs, fd, sadelta;
|
||||||
int i, sa, ma, da, q;
|
int i, sa, ma, da, q;
|
||||||
ulong s, t, u, v;
|
ulong t, t1;
|
||||||
|
|
||||||
obdst = bdst;
|
obdst = bdst;
|
||||||
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
|
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
|
||||||
q = bsrc.delta == 4 && bdst.delta == 4;
|
q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);
|
||||||
|
|
||||||
for(i=0; i<dx; i++){
|
for(i=0; i<dx; i++){
|
||||||
sa = *bsrc.alpha;
|
sa = *bsrc.alpha;
|
||||||
ma = *bmask.alpha;
|
ma = *bmask.alpha;
|
||||||
da = *bdst.alpha;
|
da = *bdst.alpha;
|
||||||
if(op == SatopD)
|
if(op == SatopD)
|
||||||
fs = MUL(ma, da, t);
|
fs = CALC11(ma, da, t);
|
||||||
else
|
else
|
||||||
fs = MUL(ma, 255-da, t);
|
fs = CALC11(ma, 255-da, t);
|
||||||
if(op == DoverS)
|
if(op == DoverS)
|
||||||
fd = 255;
|
fd = 255;
|
||||||
else{
|
else{
|
||||||
fd = MUL(sa, ma, t);
|
fd = CALC11(sa, ma, t);
|
||||||
if(op != DatopS)
|
if(op != DatopS)
|
||||||
fd = 255-fd;
|
fd = 255-fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(grey){
|
if(grey){
|
||||||
*bdst.grey = MUL(fs, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);
|
*bdst.grey = CALC12(fs, *bsrc.grey, fd, *bdst.grey, t);
|
||||||
bsrc.grey += bsrc.delta;
|
bsrc.grey += bsrc.delta;
|
||||||
bdst.grey += bdst.delta;
|
bdst.grey += bdst.delta;
|
||||||
}else{
|
}else{
|
||||||
if(q){
|
if(q){
|
||||||
*bdst.rgba = MUL0123(fs, *bsrc.rgba, s, t)+MUL0123(fd, *bdst.rgba, u, v);
|
*bdst.rgba = CALC42(fs, *bsrc.rgba, fd, *bdst.rgba, t, t1);
|
||||||
bsrc.rgba++;
|
bsrc.rgba++;
|
||||||
bdst.rgba++;
|
bdst.rgba++;
|
||||||
bsrc.alpha += sadelta;
|
bsrc.alpha += sadelta;
|
||||||
|
@ -951,9 +1007,9 @@ alphacalc3679(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
bdst.alpha += bdst.delta;
|
bdst.alpha += bdst.delta;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*bdst.red = MUL(fs, *bsrc.red, s)+MUL(fd, *bdst.red, t);
|
*bdst.red = CALC12(fs, *bsrc.red, fd, *bdst.red, t);
|
||||||
*bdst.grn = MUL(fs, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);
|
*bdst.grn = CALC12(fs, *bsrc.grn, fd, *bdst.grn, t);
|
||||||
*bdst.blu = MUL(fs, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);
|
*bdst.blu = CALC12(fs, *bsrc.blu, fd, *bdst.blu, t);
|
||||||
bsrc.red += bsrc.delta;
|
bsrc.red += bsrc.delta;
|
||||||
bsrc.blu += bsrc.delta;
|
bsrc.blu += bsrc.delta;
|
||||||
bsrc.grn += bsrc.delta;
|
bsrc.grn += bsrc.delta;
|
||||||
|
@ -962,7 +1018,7 @@ alphacalc3679(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
bdst.grn += bdst.delta;
|
bdst.grn += bdst.delta;
|
||||||
}
|
}
|
||||||
if(bdst.alpha != &ones){
|
if(bdst.alpha != &ones){
|
||||||
*bdst.alpha = MUL(fs, sa, s)+MUL(fd, da, t);
|
*bdst.alpha = CALC12(fs, sa, fd, da, t);
|
||||||
bdst.alpha += bdst.delta;
|
bdst.alpha += bdst.delta;
|
||||||
}
|
}
|
||||||
bmask.alpha += bmask.delta;
|
bmask.alpha += bmask.delta;
|
||||||
|
@ -988,34 +1044,34 @@ alphacalc11(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
Buffer obdst;
|
Buffer obdst;
|
||||||
int fd, sadelta;
|
int fd, sadelta;
|
||||||
int i, sa, ma, q;
|
int i, sa, ma, q;
|
||||||
ulong s, t, u, v;
|
ulong t, t1;
|
||||||
|
|
||||||
USED(op);
|
USED(op);
|
||||||
obdst = bdst;
|
obdst = bdst;
|
||||||
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
|
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
|
||||||
q = bsrc.delta == 4 && bdst.delta == 4;
|
q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);
|
||||||
|
|
||||||
for(i=0; i<dx; i++){
|
for(i=0; i<dx; i++){
|
||||||
sa = *bsrc.alpha;
|
sa = *bsrc.alpha;
|
||||||
ma = *bmask.alpha;
|
ma = *bmask.alpha;
|
||||||
fd = 255-MUL(sa, ma, t);
|
fd = 255-CALC11(sa, ma, t);
|
||||||
|
|
||||||
if(grey){
|
if(grey){
|
||||||
*bdst.grey = MUL(ma, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);
|
*bdst.grey = CALC12(ma, *bsrc.grey, fd, *bdst.grey, t);
|
||||||
bsrc.grey += bsrc.delta;
|
bsrc.grey += bsrc.delta;
|
||||||
bdst.grey += bdst.delta;
|
bdst.grey += bdst.delta;
|
||||||
}else{
|
}else{
|
||||||
if(q){
|
if(q){
|
||||||
*bdst.rgba = MUL0123(ma, *bsrc.rgba, s, t)+MUL0123(fd, *bdst.rgba, u, v);
|
*bdst.rgba = CALC42(ma, *bsrc.rgba, fd, *bdst.rgba, t, t1);
|
||||||
bsrc.rgba++;
|
bsrc.rgba++;
|
||||||
bdst.rgba++;
|
bdst.rgba++;
|
||||||
bsrc.alpha += sadelta;
|
bsrc.alpha += sadelta;
|
||||||
bmask.alpha += bmask.delta;
|
bmask.alpha += bmask.delta;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*bdst.red = MUL(ma, *bsrc.red, s)+MUL(fd, *bdst.red, t);
|
*bdst.red = CALC12(ma, *bsrc.red, fd, *bdst.red, t);
|
||||||
*bdst.grn = MUL(ma, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);
|
*bdst.grn = CALC12(ma, *bsrc.grn, fd, *bdst.grn, t);
|
||||||
*bdst.blu = MUL(ma, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);
|
*bdst.blu = CALC12(ma, *bsrc.blu, fd, *bdst.blu, t);
|
||||||
bsrc.red += bsrc.delta;
|
bsrc.red += bsrc.delta;
|
||||||
bsrc.blu += bsrc.delta;
|
bsrc.blu += bsrc.delta;
|
||||||
bsrc.grn += bsrc.delta;
|
bsrc.grn += bsrc.delta;
|
||||||
|
@ -1024,7 +1080,7 @@ alphacalc11(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
bdst.grn += bdst.delta;
|
bdst.grn += bdst.delta;
|
||||||
}
|
}
|
||||||
if(bdst.alpha != &ones){
|
if(bdst.alpha != &ones){
|
||||||
*bdst.alpha = MUL(ma, sa, s)+MUL(fd, *bdst.alpha, t);
|
*bdst.alpha = CALC12(ma, sa, fd, *bdst.alpha, t);
|
||||||
bdst.alpha += bdst.delta;
|
bdst.alpha += bdst.delta;
|
||||||
}
|
}
|
||||||
bmask.alpha += bmask.delta;
|
bmask.alpha += bmask.delta;
|
||||||
|
@ -1080,7 +1136,7 @@ alphacalcS(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
Buffer obdst;
|
Buffer obdst;
|
||||||
int fd;
|
int fd;
|
||||||
int i, ma;
|
int i, ma;
|
||||||
ulong s, t;
|
ulong t;
|
||||||
|
|
||||||
USED(op);
|
USED(op);
|
||||||
obdst = bdst;
|
obdst = bdst;
|
||||||
|
@ -1090,13 +1146,13 @@ alphacalcS(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
fd = 255-ma;
|
fd = 255-ma;
|
||||||
|
|
||||||
if(grey){
|
if(grey){
|
||||||
*bdst.grey = MUL(ma, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);
|
*bdst.grey = CALC12(ma, *bsrc.grey, fd, *bdst.grey, t);
|
||||||
bsrc.grey += bsrc.delta;
|
bsrc.grey += bsrc.delta;
|
||||||
bdst.grey += bdst.delta;
|
bdst.grey += bdst.delta;
|
||||||
}else{
|
}else{
|
||||||
*bdst.red = MUL(ma, *bsrc.red, s)+MUL(fd, *bdst.red, t);
|
*bdst.red = CALC12(ma, *bsrc.red, fd, *bdst.red, t);
|
||||||
*bdst.grn = MUL(ma, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);
|
*bdst.grn = CALC12(ma, *bsrc.grn, fd, *bdst.grn, t);
|
||||||
*bdst.blu = MUL(ma, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);
|
*bdst.blu = CALC12(ma, *bsrc.blu, fd, *bdst.blu, t);
|
||||||
bsrc.red += bsrc.delta;
|
bsrc.red += bsrc.delta;
|
||||||
bsrc.blu += bsrc.delta;
|
bsrc.blu += bsrc.delta;
|
||||||
bsrc.grn += bsrc.delta;
|
bsrc.grn += bsrc.delta;
|
||||||
|
@ -1105,7 +1161,7 @@ alphacalcS(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
bdst.grn += bdst.delta;
|
bdst.grn += bdst.delta;
|
||||||
}
|
}
|
||||||
if(bdst.alpha != &ones){
|
if(bdst.alpha != &ones){
|
||||||
*bdst.alpha = ma+MUL(fd, *bdst.alpha, t);
|
*bdst.alpha = ma+CALC11(fd, *bdst.alpha, t);
|
||||||
bdst.alpha += bdst.delta;
|
bdst.alpha += bdst.delta;
|
||||||
}
|
}
|
||||||
bmask.alpha += bmask.delta;
|
bmask.alpha += bmask.delta;
|
||||||
|
@ -1154,7 +1210,7 @@ boolcalc236789(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
Buffer obdst;
|
Buffer obdst;
|
||||||
int fs, fd;
|
int fs, fd;
|
||||||
int i, ma, da, zero;
|
int i, ma, da, zero;
|
||||||
ulong s, t;
|
ulong t;
|
||||||
|
|
||||||
obdst = bdst;
|
obdst = bdst;
|
||||||
zero = !(op&1);
|
zero = !(op&1);
|
||||||
|
@ -1171,16 +1227,16 @@ boolcalc236789(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
|
|
||||||
if(grey){
|
if(grey){
|
||||||
if(ma)
|
if(ma)
|
||||||
*bdst.grey = MUL(fs, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);
|
*bdst.grey = CALC12(fs, *bsrc.grey, fd, *bdst.grey, t);
|
||||||
else if(zero)
|
else if(zero)
|
||||||
*bdst.grey = 0;
|
*bdst.grey = 0;
|
||||||
bsrc.grey += bsrc.delta;
|
bsrc.grey += bsrc.delta;
|
||||||
bdst.grey += bdst.delta;
|
bdst.grey += bdst.delta;
|
||||||
}else{
|
}else{
|
||||||
if(ma){
|
if(ma){
|
||||||
*bdst.red = MUL(fs, *bsrc.red, s)+MUL(fd, *bdst.red, t);
|
*bdst.red = CALC12(fs, *bsrc.red, fd, *bdst.red, t);
|
||||||
*bdst.grn = MUL(fs, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);
|
*bdst.grn = CALC12(fs, *bsrc.grn, fd, *bdst.grn, t);
|
||||||
*bdst.blu = MUL(fs, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);
|
*bdst.blu = CALC12(fs, *bsrc.blu, fd, *bdst.blu, t);
|
||||||
}
|
}
|
||||||
else if(zero)
|
else if(zero)
|
||||||
*bdst.red = *bdst.grn = *bdst.blu = 0;
|
*bdst.red = *bdst.grn = *bdst.blu = 0;
|
||||||
|
@ -1194,7 +1250,7 @@ boolcalc236789(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
|
||||||
bmask.alpha += bmask.delta;
|
bmask.alpha += bmask.delta;
|
||||||
if(bdst.alpha != &ones){
|
if(bdst.alpha != &ones){
|
||||||
if(ma)
|
if(ma)
|
||||||
*bdst.alpha = fs+MUL(fd, da, t);
|
*bdst.alpha = fs+CALC11(fd, da, t);
|
||||||
else if(zero)
|
else if(zero)
|
||||||
*bdst.alpha = 0;
|
*bdst.alpha = 0;
|
||||||
bdst.alpha += bdst.delta;
|
bdst.alpha += bdst.delta;
|
||||||
|
|
|
@ -7,10 +7,17 @@ int
|
||||||
loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata)
|
loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata)
|
||||||
{
|
{
|
||||||
int y, l, lpart, rpart, mx, m, mr;
|
int y, l, lpart, rpart, mx, m, mr;
|
||||||
|
Memdrawparam par;
|
||||||
uchar *q;
|
uchar *q;
|
||||||
|
|
||||||
if(!rectinrect(r, i->r))
|
if(!rectinrect(r, i->r))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
memset(&par, 0, sizeof par);
|
||||||
|
par.dst = i;
|
||||||
|
par.r = r;
|
||||||
|
hwdraw(&par);
|
||||||
|
|
||||||
l = bytesperline(r, i->depth);
|
l = bytesperline(r, i->depth);
|
||||||
if(ndata < l*Dy(r))
|
if(ndata < l*Dy(r))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in a new issue