merge
This commit is contained in:
commit
f8f677b48e
9 changed files with 410 additions and 291 deletions
|
@ -524,6 +524,7 @@ allocdimage(Memimage *i)
|
||||||
d->name = 0;
|
d->name = 0;
|
||||||
d->vers = 0;
|
d->vers = 0;
|
||||||
d->image = i;
|
d->image = i;
|
||||||
|
d->dscreen = 0;
|
||||||
d->nfchar = 0;
|
d->nfchar = 0;
|
||||||
d->fchar = 0;
|
d->fchar = 0;
|
||||||
d->fromname = 0;
|
d->fromname = 0;
|
||||||
|
|
|
@ -13,7 +13,6 @@ enum{
|
||||||
Qcons,
|
Qcons,
|
||||||
Qconsctl,
|
Qconsctl,
|
||||||
Qsnarf,
|
Qsnarf,
|
||||||
Qwinname,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static Dirtab consdir[]={
|
static Dirtab consdir[]={
|
||||||
|
@ -21,7 +20,6 @@ static Dirtab consdir[]={
|
||||||
"cons", {Qcons}, 0, 0660,
|
"cons", {Qcons}, 0, 0660,
|
||||||
"consctl", {Qconsctl}, 0, 0220,
|
"consctl", {Qconsctl}, 0, 0220,
|
||||||
"snarf", {Qsnarf}, 0, 0600,
|
"snarf", {Qsnarf}, 0, 0600,
|
||||||
"winname", {Qwinname}, 0, 0000,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static Chan*
|
static Chan*
|
||||||
|
|
|
@ -14,6 +14,7 @@ enum
|
||||||
{
|
{
|
||||||
Qtopdir = 0,
|
Qtopdir = 0,
|
||||||
Qnew,
|
Qnew,
|
||||||
|
Qwinname,
|
||||||
Q3rd,
|
Q3rd,
|
||||||
Q2nd,
|
Q2nd,
|
||||||
Qcolormap,
|
Qcolormap,
|
||||||
|
@ -35,6 +36,7 @@ enum
|
||||||
|
|
||||||
#define NHASH (1<<5)
|
#define NHASH (1<<5)
|
||||||
#define HASHMASK (NHASH-1)
|
#define HASHMASK (NHASH-1)
|
||||||
|
#define IOUNIT (64*1024)
|
||||||
|
|
||||||
typedef struct Client Client;
|
typedef struct Client Client;
|
||||||
typedef struct Draw Draw;
|
typedef struct Draw Draw;
|
||||||
|
@ -46,11 +48,8 @@ typedef struct Refresh Refresh;
|
||||||
typedef struct Refx Refx;
|
typedef struct Refx Refx;
|
||||||
typedef struct DName DName;
|
typedef struct DName DName;
|
||||||
|
|
||||||
ulong blanktime = 30; /* in minutes; a half hour */
|
|
||||||
|
|
||||||
struct Draw
|
struct Draw
|
||||||
{
|
{
|
||||||
QLock;
|
|
||||||
int clientid;
|
int clientid;
|
||||||
int nclient;
|
int nclient;
|
||||||
Client** client;
|
Client** client;
|
||||||
|
@ -58,9 +57,6 @@ struct Draw
|
||||||
DName* name;
|
DName* name;
|
||||||
int vers;
|
int vers;
|
||||||
int softscreen;
|
int softscreen;
|
||||||
int blanked; /* screen turned off */
|
|
||||||
ulong blanktime; /* time of last operation */
|
|
||||||
ulong savemap[3*256];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Client
|
struct Client
|
||||||
|
@ -70,6 +66,7 @@ struct Client
|
||||||
CScreen* cscreen;
|
CScreen* cscreen;
|
||||||
Refresh* refresh;
|
Refresh* refresh;
|
||||||
Rendez refrend;
|
Rendez refrend;
|
||||||
|
QLock refq;
|
||||||
uchar* readdata;
|
uchar* readdata;
|
||||||
int nreaddata;
|
int nreaddata;
|
||||||
int busy;
|
int busy;
|
||||||
|
@ -151,8 +148,13 @@ struct DScreen
|
||||||
};
|
};
|
||||||
|
|
||||||
static Draw sdraw;
|
static Draw sdraw;
|
||||||
|
QLock drawlock;
|
||||||
|
|
||||||
static Memimage *screenimage;
|
static Memimage *screenimage;
|
||||||
static Memdata screendata;
|
static DImage* screendimage;
|
||||||
|
static char screenname[40];
|
||||||
|
static int screennameid;
|
||||||
|
|
||||||
static Rectangle flushrect;
|
static Rectangle flushrect;
|
||||||
static int waste;
|
static int waste;
|
||||||
static DScreen* dscreen;
|
static DScreen* dscreen;
|
||||||
|
@ -161,6 +163,7 @@ extern void flushmemscreen(Rectangle);
|
||||||
void drawuninstall(Client*, int);
|
void drawuninstall(Client*, int);
|
||||||
void drawfreedimage(DImage*);
|
void drawfreedimage(DImage*);
|
||||||
Client* drawclientofpath(ulong);
|
Client* drawclientofpath(ulong);
|
||||||
|
DImage* allocdimage(Memimage*);
|
||||||
|
|
||||||
static char Enodrawimage[] = "unknown id for draw image";
|
static char Enodrawimage[] = "unknown id for draw image";
|
||||||
static char Enodrawscreen[] = "unknown id for draw screen";
|
static char Enodrawscreen[] = "unknown id for draw screen";
|
||||||
|
@ -174,29 +177,28 @@ static char Ewriteoutside[] = "writeimage outside image";
|
||||||
static char Enotfont[] = "image not a font";
|
static char Enotfont[] = "image not a font";
|
||||||
static char Eindex[] = "character index out of range";
|
static char Eindex[] = "character index out of range";
|
||||||
static char Enoclient[] = "no such draw client";
|
static char Enoclient[] = "no such draw client";
|
||||||
static char Edepth[] = "image has bad depth";
|
|
||||||
static char Enameused[] = "image name in use";
|
static char Enameused[] = "image name in use";
|
||||||
static char Enoname[] = "no image with that name";
|
static char Enoname[] = "no image with that name";
|
||||||
static char Eoldname[] = "named image no longer valid";
|
static char Eoldname[] = "named image no longer valid";
|
||||||
static char Enamed[] = "image already has name";
|
static char Enamed[] = "image already has name";
|
||||||
static char Ewrongname[] = "wrong name for image";
|
static char Ewrongname[] = "wrong name for image";
|
||||||
|
|
||||||
void
|
static void
|
||||||
drawlock(void)
|
dlock(void)
|
||||||
{
|
{
|
||||||
qlock(&sdraw);
|
qlock(&drawlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static int
|
||||||
drawunlock(void)
|
candlock(void)
|
||||||
{
|
{
|
||||||
qunlock(&sdraw);
|
return canqlock(&drawlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static void
|
||||||
candrawlock(void)
|
dunlock(void)
|
||||||
{
|
{
|
||||||
return canqlock(&sdraw);
|
qunlock(&drawlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -226,7 +228,7 @@ drawgen(Chan *c, Dirtab*, int, int s, Dir *dp)
|
||||||
devdir(c, q, up->genbuf, 0, eve, 0500, dp);
|
devdir(c, q, up->genbuf, 0, eve, 0500, dp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("drawwalk %#llux", c->qid.path);
|
panic("drawwalk %llux", c->qid.path);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -235,15 +237,17 @@ drawgen(Chan *c, Dirtab*, int, int s, Dir *dp)
|
||||||
* Top level directory contains the name of the device.
|
* Top level directory contains the name of the device.
|
||||||
*/
|
*/
|
||||||
t = QID(c->qid);
|
t = QID(c->qid);
|
||||||
if(t == Qtopdir){
|
if(t == Qtopdir || t == Qwinname){
|
||||||
switch(s){
|
if(s == 1 || t == Qwinname){
|
||||||
case 0:
|
mkqid(&q, Qwinname, 0, QTFILE);
|
||||||
|
devdir(c, q, "winname", 0, eve, 0444, dp);
|
||||||
|
}
|
||||||
|
else if(s == 0){
|
||||||
mkqid(&q, Q2nd, 0, QTDIR);
|
mkqid(&q, Q2nd, 0, QTDIR);
|
||||||
devdir(c, q, "draw", 0, eve, 0555, dp);
|
devdir(c, q, "draw", 0, eve, 0555, dp);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +276,7 @@ drawgen(Chan *c, Dirtab*, int, int s, Dir *dp)
|
||||||
/*
|
/*
|
||||||
* Third level.
|
* Third level.
|
||||||
*/
|
*/
|
||||||
path = c->qid.path&~(((1<<QSHIFT)-1)); /* slot component */
|
path = c->qid.path&~((1<<QSHIFT)-1); /* slot component */
|
||||||
q.vers = c->qid.vers;
|
q.vers = c->qid.vers;
|
||||||
q.type = QTFILE;
|
q.type = QTFILE;
|
||||||
switch(s){
|
switch(s){
|
||||||
|
@ -320,14 +324,13 @@ drawrefreshscreen(DImage *l, Client *client)
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
drawrefresh(Memimage *l, Rectangle r, void *v)
|
drawrefresh(Memimage*, Rectangle r, void *v)
|
||||||
{
|
{
|
||||||
Refx *x;
|
Refx *x;
|
||||||
DImage *d;
|
DImage *d;
|
||||||
Client *c;
|
Client *c;
|
||||||
Refresh *ref;
|
Refresh *ref;
|
||||||
|
|
||||||
USED(l);
|
|
||||||
if(v == 0)
|
if(v == 0)
|
||||||
return;
|
return;
|
||||||
x = v;
|
x = v;
|
||||||
|
@ -353,9 +356,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;
|
||||||
|
@ -393,6 +395,7 @@ addflush(Rectangle r)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* emit current state */
|
/* emit current state */
|
||||||
|
if(flushrect.min.x < flushrect.max.x)
|
||||||
flushmemscreen(flushrect);
|
flushmemscreen(flushrect);
|
||||||
flushrect = r;
|
flushrect = r;
|
||||||
waste = 0;
|
waste = 0;
|
||||||
|
@ -409,8 +412,7 @@ dstflush(int dstid, Memimage *dst, Rectangle r)
|
||||||
addflush(r); // for VNC, see comments in addflush
|
addflush(r); // for VNC, see comments in addflush
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
l = dst->layer;
|
if(screenimage == nil || dst == nil || (l = dst->layer) == nil)
|
||||||
if(l == nil)
|
|
||||||
return;
|
return;
|
||||||
do{
|
do{
|
||||||
if(l->screen->image->data != screenimage->data)
|
if(l->screen->image->data != screenimage->data)
|
||||||
|
@ -421,10 +423,10 @@ dstflush(int dstid, Memimage *dst, Rectangle r)
|
||||||
addflush(r);
|
addflush(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
void
|
void
|
||||||
drawflush(void)
|
drawflush(void)
|
||||||
{
|
{
|
||||||
|
if(screenimage && flushrect.min.x < flushrect.max.x)
|
||||||
flushmemscreen(flushrect);
|
flushmemscreen(flushrect);
|
||||||
flushrect = Rect(10000, 10000, -10000, -10000);
|
flushrect = Rect(10000, 10000, -10000, -10000);
|
||||||
}
|
}
|
||||||
|
@ -517,22 +519,34 @@ drawlookupscreen(Client *client, int id, CScreen **cs)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Memimage*
|
DImage*
|
||||||
drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen)
|
allocdimage(Memimage *i)
|
||||||
{
|
{
|
||||||
DImage *d;
|
DImage *d;
|
||||||
|
|
||||||
d = malloc(sizeof(DImage));
|
d = malloc(sizeof(DImage));
|
||||||
if(d == 0)
|
if(d == 0)
|
||||||
return 0;
|
return 0;
|
||||||
d->id = id;
|
|
||||||
d->ref = 1;
|
d->ref = 1;
|
||||||
d->name = 0;
|
d->name = 0;
|
||||||
d->vers = 0;
|
d->vers = 0;
|
||||||
d->image = i;
|
d->image = i;
|
||||||
|
d->dscreen = 0;
|
||||||
d->nfchar = 0;
|
d->nfchar = 0;
|
||||||
d->fchar = 0;
|
d->fchar = 0;
|
||||||
d->fromname = 0;
|
d->fromname = 0;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
Memimage*
|
||||||
|
drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen)
|
||||||
|
{
|
||||||
|
DImage *d;
|
||||||
|
|
||||||
|
d = allocdimage(i);
|
||||||
|
if(d == 0)
|
||||||
|
return 0;
|
||||||
|
d->id = id;
|
||||||
d->dscreen = dscreen;
|
d->dscreen = dscreen;
|
||||||
d->next = client->dimage[id&HASHMASK];
|
d->next = client->dimage[id&HASHMASK];
|
||||||
client->dimage[id&HASHMASK] = d;
|
client->dimage[id&HASHMASK] = d;
|
||||||
|
@ -595,6 +609,7 @@ drawdelname(DName *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
free(name->name);
|
||||||
i = name-sdraw.name;
|
i = name-sdraw.name;
|
||||||
memmove(name, name+1, (sdraw.nname-(i+1))*sizeof(DName));
|
memmove(name, name+1, (sdraw.nname-(i+1))*sizeof(DName));
|
||||||
sdraw.nname--;
|
sdraw.nname--;
|
||||||
|
@ -656,12 +671,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);
|
||||||
|
@ -856,11 +869,12 @@ drawpoint(Point *p, uchar *a)
|
||||||
}
|
}
|
||||||
|
|
||||||
Point
|
Point
|
||||||
drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int index, int op)
|
drawchar(Memimage *dst, Memimage *rdst, Point p, Memimage *src, Point *sp, DImage *font, int index, int op)
|
||||||
{
|
{
|
||||||
FChar *fc;
|
FChar *fc;
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
Point sp1;
|
Point sp1;
|
||||||
|
static Memimage *tmp;
|
||||||
|
|
||||||
fc = &font->fchar[index];
|
fc = &font->fchar[index];
|
||||||
r.min.x = p.x+fc->left;
|
r.min.x = p.x+fc->left;
|
||||||
|
@ -869,69 +883,143 @@ drawchar(Memimage *dst, Point p, Memimage *src, Point *sp, DImage *font, int ind
|
||||||
r.max.y = r.min.y+(fc->maxy-fc->miny);
|
r.max.y = r.min.y+(fc->maxy-fc->miny);
|
||||||
sp1.x = sp->x+fc->left;
|
sp1.x = sp->x+fc->left;
|
||||||
sp1.y = sp->y+fc->miny;
|
sp1.y = sp->y+fc->miny;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're drawing greyscale fonts onto a VGA screen,
|
||||||
|
* it's very costly to read the screen memory to do the
|
||||||
|
* alpha blending inside memdraw. If this is really a stringbg,
|
||||||
|
* then rdst is the bg image (in main memory) which we can
|
||||||
|
* refer to for the underlying dst pixels instead of reading dst
|
||||||
|
* directly.
|
||||||
|
*/
|
||||||
|
if(ishwimage(dst) && !ishwimage(rdst) && font->image->depth > 1){
|
||||||
|
if(tmp == nil || tmp->chan != dst->chan || Dx(tmp->r) < Dx(r) || Dy(tmp->r) < Dy(r)){
|
||||||
|
if(tmp)
|
||||||
|
freememimage(tmp);
|
||||||
|
tmp = allocmemimage(Rect(0,0,Dx(r),Dy(r)), dst->chan);
|
||||||
|
if(tmp == nil)
|
||||||
|
goto fallback;
|
||||||
|
}
|
||||||
|
memdraw(tmp, Rect(0,0,Dx(r),Dy(r)), rdst, r.min, memopaque, ZP, S);
|
||||||
|
memdraw(tmp, Rect(0,0,Dx(r),Dy(r)), src, sp1, font->image, Pt(fc->minx, fc->miny), op);
|
||||||
|
memdraw(dst, r, tmp, ZP, memopaque, ZP, S);
|
||||||
|
}else{
|
||||||
|
fallback:
|
||||||
memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny), op);
|
memdraw(dst, r, src, sp1, font->image, Pt(fc->minx, fc->miny), op);
|
||||||
|
}
|
||||||
|
|
||||||
p.x += fc->width;
|
p.x += fc->width;
|
||||||
sp->x += fc->width;
|
sp->x += fc->width;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static DImage*
|
||||||
initscreenimage(void)
|
makescreenimage(void)
|
||||||
{
|
{
|
||||||
int width, depth;
|
int width, depth;
|
||||||
ulong chan;
|
ulong chan;
|
||||||
|
DImage *di;
|
||||||
|
Memdata *md;
|
||||||
|
Memimage *i;
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
|
uchar *data;
|
||||||
|
|
||||||
|
if((data = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen)) == 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->clipr = r;
|
||||||
|
di = allocdimage(i);
|
||||||
|
if(di == nil){
|
||||||
|
freememimage(i); /* frees md */
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
if(!waserror()){
|
||||||
|
snprint(screenname, sizeof screenname, "noborder.screen.%d", ++screennameid);
|
||||||
|
drawaddname(nil, di, strlen(screenname), screenname);
|
||||||
|
poperror();
|
||||||
|
}
|
||||||
|
return di;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
initscreenimage(void)
|
||||||
|
{
|
||||||
if(screenimage != nil)
|
if(screenimage != nil)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
screendata.base = nil;
|
screendimage = makescreenimage();
|
||||||
screendata.bdata = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen);
|
if(screendimage == nil)
|
||||||
if(screendata.bdata == nil)
|
|
||||||
{fprint(2, "bad bdata\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
screenimage = screendimage->image;
|
||||||
screendata.ref = 1;
|
// iprint("initscreenimage %p %p\n", screendimage, screenimage);
|
||||||
|
mouseresize();
|
||||||
screenimage = allocmemimaged(r, chan, &screendata);
|
|
||||||
if(screenimage == nil){
|
|
||||||
fprint(2, "bad memimaged: %r\n");
|
|
||||||
/* RSC: BUG: detach screen */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
screenimage->width = width;
|
|
||||||
screenimage->clipr = screenimage->r;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
deletescreenimage(void)
|
deletescreenimage(void)
|
||||||
{
|
{
|
||||||
qlock(&sdraw);
|
dlock();
|
||||||
/* RSC: BUG: detach screen */
|
if(screenimage){
|
||||||
if(screenimage)
|
/* will be freed via screendimage; disable */
|
||||||
freememimage(screenimage);
|
screenimage->clipr = ZR;
|
||||||
screenimage = nil;
|
screenimage = nil;
|
||||||
qunlock(&sdraw);
|
}
|
||||||
|
if(screendimage){
|
||||||
|
drawfreedimage(screendimage);
|
||||||
|
screendimage = nil;
|
||||||
|
}
|
||||||
|
dunlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Chan*
|
void
|
||||||
|
resetscreenimage(void)
|
||||||
|
{
|
||||||
|
dlock();
|
||||||
|
initscreenimage();
|
||||||
|
dunlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Chan*
|
||||||
drawattach(char *spec)
|
drawattach(char *spec)
|
||||||
{
|
{
|
||||||
qlock(&sdraw);
|
dlock();
|
||||||
if(!initscreenimage()){
|
if(!initscreenimage()){
|
||||||
qunlock(&sdraw);
|
dunlock();
|
||||||
error("no frame buffer");
|
error("no frame buffer");
|
||||||
}
|
}
|
||||||
qunlock(&sdraw);
|
dunlock();
|
||||||
return devattach('i', spec);
|
return devattach('i', spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
Walkqid*
|
static Walkqid*
|
||||||
drawwalk(Chan *c, Chan *nc, char **name, int nname)
|
drawwalk(Chan *c, Chan *nc, char **name, int nname)
|
||||||
{
|
{
|
||||||
if(screendata.bdata == nil)
|
if(screenimage == nil)
|
||||||
error("no frame buffer");
|
error("no frame buffer");
|
||||||
return devwalk(c, nc, name, nname, 0, 0, drawgen);
|
return devwalk(c, nc, name, nname, 0, 0, drawgen);
|
||||||
}
|
}
|
||||||
|
@ -946,13 +1034,17 @@ static Chan*
|
||||||
drawopen(Chan *c, int omode)
|
drawopen(Chan *c, int omode)
|
||||||
{
|
{
|
||||||
Client *cl;
|
Client *cl;
|
||||||
|
DName *dn;
|
||||||
|
DImage *di;
|
||||||
|
|
||||||
if(c->qid.type & QTDIR)
|
if(c->qid.type & QTDIR){
|
||||||
return devopen(c, omode, 0, 0, drawgen);
|
c = devopen(c, omode, 0, 0, drawgen);
|
||||||
|
c->iounit = IOUNIT;
|
||||||
|
}
|
||||||
|
|
||||||
qlock(&sdraw);
|
dlock();
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
qunlock(&sdraw);
|
dunlock();
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -964,6 +1056,9 @@ drawopen(Chan *c, int omode)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(QID(c->qid)){
|
switch(QID(c->qid)){
|
||||||
|
case Qwinname:
|
||||||
|
break;
|
||||||
|
|
||||||
case Qnew:
|
case Qnew:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -973,9 +1068,22 @@ drawopen(Chan *c, int omode)
|
||||||
error(Einuse);
|
error(Einuse);
|
||||||
cl->busy = 1;
|
cl->busy = 1;
|
||||||
flushrect = Rect(10000, 10000, -10000, -10000);
|
flushrect = Rect(10000, 10000, -10000, -10000);
|
||||||
drawinstall(cl, 0, screenimage, 0);
|
dn = drawlookupname(strlen(screenname), screenname);
|
||||||
|
if(dn == 0)
|
||||||
|
error("draw: cannot happen 2");
|
||||||
|
if(drawinstall(cl, 0, dn->dimage->image, 0) == 0)
|
||||||
|
error(Edrawmem);
|
||||||
|
di = drawlookup(cl, 0, 0);
|
||||||
|
if(di == 0)
|
||||||
|
error("draw: cannot happen 1");
|
||||||
|
di->vers = dn->vers;
|
||||||
|
di->name = smalloc(strlen(screenname)+1);
|
||||||
|
strcpy(di->name, screenname);
|
||||||
|
di->fromname = dn->dimage;
|
||||||
|
di->fromname->ref++;
|
||||||
incref(&cl->r);
|
incref(&cl->r);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qcolormap:
|
case Qcolormap:
|
||||||
case Qdata:
|
case Qdata:
|
||||||
case Qrefresh:
|
case Qrefresh:
|
||||||
|
@ -983,11 +1091,12 @@ drawopen(Chan *c, int omode)
|
||||||
incref(&cl->r);
|
incref(&cl->r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
qunlock(&sdraw);
|
dunlock();
|
||||||
poperror();
|
poperror();
|
||||||
c->mode = openmode(omode);
|
c->mode = openmode(omode);
|
||||||
c->flag |= COPEN;
|
c->flag |= COPEN;
|
||||||
c->offset = 0;
|
c->offset = 0;
|
||||||
|
c->iounit = IOUNIT;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -999,11 +1108,11 @@ drawclose(Chan *c)
|
||||||
Client *cl;
|
Client *cl;
|
||||||
Refresh *r;
|
Refresh *r;
|
||||||
|
|
||||||
if(c->qid.type & QTDIR)
|
if(QID(c->qid) < Qcolormap) /* Qtopdir, Qnew, Q3rd, Q2nd have no client */
|
||||||
return;
|
return;
|
||||||
qlock(&sdraw);
|
dlock();
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
qunlock(&sdraw);
|
dunlock();
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1036,7 +1145,7 @@ drawclose(Chan *c)
|
||||||
drawflush(); /* to erase visible, now dead windows */
|
drawflush(); /* to erase visible, now dead windows */
|
||||||
free(cl);
|
free(cl);
|
||||||
}
|
}
|
||||||
qunlock(&sdraw);
|
dunlock();
|
||||||
poperror();
|
poperror();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1053,13 +1162,15 @@ drawread(Chan *c, void *a, long n, vlong off)
|
||||||
ulong offset = off;
|
ulong offset = off;
|
||||||
char buf[16];
|
char buf[16];
|
||||||
|
|
||||||
USED(offset);
|
|
||||||
if(c->qid.type & QTDIR)
|
if(c->qid.type & QTDIR)
|
||||||
return devdirread(c, a, n, 0, 0, drawgen);
|
return devdirread(c, a, n, 0, 0, drawgen);
|
||||||
|
if(QID(c->qid) == Qwinname)
|
||||||
|
return readstr(off, a, n, screenname);
|
||||||
|
|
||||||
cl = drawclient(c);
|
cl = drawclient(c);
|
||||||
qlock(&sdraw);
|
dlock();
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
qunlock(&sdraw);
|
dunlock();
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
switch(QID(c->qid)){
|
switch(QID(c->qid)){
|
||||||
|
@ -1078,15 +1189,15 @@ drawread(Chan *c, void *a, long n, vlong off)
|
||||||
error(Enodrawimage);
|
error(Enodrawimage);
|
||||||
i = di->image;
|
i = di->image;
|
||||||
}
|
}
|
||||||
n = sprint(a, "%11d %11d %11s %11d %11d %11d %11d %11d %11d %11d %11d %11d ",
|
n = sprint(a, "%11d %11d %11s %11d %11d %11d %11d %11d %11d %11d %11d %11d",
|
||||||
cl->clientid, cl->infoid, chantostr(buf, i->chan), (i->flags&Frepl)==Frepl,
|
cl->clientid, cl->infoid, chantostr(buf, i->chan), (i->flags&Frepl)==Frepl,
|
||||||
i->r.min.x, i->r.min.y, i->r.max.x, i->r.max.y,
|
i->r.min.x, i->r.min.y, i->r.max.x, i->r.max.y,
|
||||||
i->clipr.min.x, i->clipr.min.y, i->clipr.max.x, i->clipr.max.y);
|
i->clipr.min.x, i->clipr.min.y, i->clipr.max.x, i->clipr.max.y);
|
||||||
|
((char*)a)[n++] = ' ';
|
||||||
cl->infoid = -1;
|
cl->infoid = -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qcolormap:
|
case Qcolormap:
|
||||||
drawactive(1); /* to restore map from backup */
|
|
||||||
p = malloc(4*12*256+1);
|
p = malloc(4*12*256+1);
|
||||||
if(p == 0)
|
if(p == 0)
|
||||||
error(Enomem);
|
error(Enomem);
|
||||||
|
@ -1116,14 +1227,21 @@ drawread(Chan *c, void *a, long n, vlong off)
|
||||||
for(;;){
|
for(;;){
|
||||||
if(cl->refreshme || cl->refresh)
|
if(cl->refreshme || cl->refresh)
|
||||||
break;
|
break;
|
||||||
qunlock(&sdraw);
|
dunlock();
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
qlock(&sdraw); /* restore lock for waserror() above */
|
dlock();
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
qlock(&cl->refq);
|
||||||
|
if(waserror()){
|
||||||
|
qunlock(&cl->refq);
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
rendsleep(&cl->refrend, drawrefactive, cl);
|
rendsleep(&cl->refrend, drawrefactive, cl);
|
||||||
poperror();
|
poperror();
|
||||||
qlock(&sdraw);
|
qunlock(&cl->refq);
|
||||||
|
poperror();
|
||||||
|
dlock();
|
||||||
}
|
}
|
||||||
p = a;
|
p = a;
|
||||||
while(cl->refresh && n>=5*4){
|
while(cl->refresh && n>=5*4){
|
||||||
|
@ -1140,8 +1258,9 @@ drawread(Chan *c, void *a, long n, vlong off)
|
||||||
}
|
}
|
||||||
cl->refreshme = 0;
|
cl->refreshme = 0;
|
||||||
n = p-(uchar*)a;
|
n = p-(uchar*)a;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
qunlock(&sdraw);
|
dunlock();
|
||||||
poperror();
|
poperror();
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -1160,21 +1279,19 @@ drawwakeall(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static long
|
static long
|
||||||
drawwrite(Chan *c, void *a, long n, vlong off)
|
drawwrite(Chan *c, void *a, long n, vlong)
|
||||||
{
|
{
|
||||||
char buf[128], *fields[4], *q;
|
char buf[128], *fields[4], *q;
|
||||||
Client *cl;
|
Client *cl;
|
||||||
int i, m, red, green, blue, x;
|
int i, m, red, green, blue, x;
|
||||||
ulong offset = off;
|
|
||||||
|
|
||||||
USED(offset);
|
|
||||||
if(c->qid.type & QTDIR)
|
if(c->qid.type & QTDIR)
|
||||||
error(Eisdir);
|
error(Eisdir);
|
||||||
cl = drawclient(c);
|
cl = drawclient(c);
|
||||||
qlock(&sdraw);
|
dlock();
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
drawwakeall();
|
drawwakeall();
|
||||||
qunlock(&sdraw);
|
dunlock();
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
switch(QID(c->qid)){
|
switch(QID(c->qid)){
|
||||||
|
@ -1185,7 +1302,6 @@ drawwrite(Chan *c, void *a, long n, vlong off)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qcolormap:
|
case Qcolormap:
|
||||||
drawactive(1); /* to restore map from backup */
|
|
||||||
m = n;
|
m = n;
|
||||||
n = 0;
|
n = 0;
|
||||||
while(m > 0){
|
while(m > 0){
|
||||||
|
@ -1200,7 +1316,7 @@ drawwrite(Chan *c, void *a, long n, vlong off)
|
||||||
a = (char*)a + i;
|
a = (char*)a + i;
|
||||||
m -= i;
|
m -= i;
|
||||||
*q = 0;
|
*q = 0;
|
||||||
if(getfields(buf, fields, nelem(fields), 1, " ") != 4)
|
if(tokenize(buf, fields, nelem(fields)) != 4)
|
||||||
error(Ebadarg);
|
error(Ebadarg);
|
||||||
i = strtoul(fields[0], 0, 0);
|
i = strtoul(fields[0], 0, 0);
|
||||||
red = strtoul(fields[1], 0, 0);
|
red = strtoul(fields[1], 0, 0);
|
||||||
|
@ -1228,7 +1344,7 @@ drawwrite(Chan *c, void *a, long n, vlong off)
|
||||||
default:
|
default:
|
||||||
error(Ebadusefd);
|
error(Ebadusefd);
|
||||||
}
|
}
|
||||||
qunlock(&sdraw);
|
dunlock();
|
||||||
poperror();
|
poperror();
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -1265,7 +1381,7 @@ printmesg(char *fmt, uchar *a, int plsprnt)
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
if(1||plsprnt==0){
|
if(1|| plsprnt==0){
|
||||||
SET(s,q,p);
|
SET(s,q,p);
|
||||||
USED(fmt, a, buf, p, q, s);
|
USED(fmt, a, buf, p, q, s);
|
||||||
return;
|
return;
|
||||||
|
@ -1305,7 +1421,7 @@ printmesg(char *fmt, uchar *a, int plsprnt)
|
||||||
}
|
}
|
||||||
*q++ = '\n';
|
*q++ = '\n';
|
||||||
*q = 0;
|
*q = 0;
|
||||||
fprint(2, "%.*s", (int)(q-buf), buf);
|
// iprint("%.*s", (int)(q-buf), buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1317,7 +1433,7 @@ drawmesg(Client *client, void *av, int n)
|
||||||
ulong value, chan;
|
ulong value, chan;
|
||||||
Rectangle r, clipr;
|
Rectangle r, clipr;
|
||||||
Point p, q, *pp, sp;
|
Point p, q, *pp, sp;
|
||||||
Memimage *i, *dst, *src, *mask;
|
Memimage *i, *bg, *dst, *src, *mask;
|
||||||
Memimage *l, **lp;
|
Memimage *l, **lp;
|
||||||
Memscreen *scrn;
|
Memscreen *scrn;
|
||||||
DImage *font, *ll, *di, *ddst, *dsrc;
|
DImage *font, *ll, *di, *ddst, *dsrc;
|
||||||
|
@ -1333,6 +1449,7 @@ drawmesg(Client *client, void *av, int n)
|
||||||
fmt = nil;
|
fmt = nil;
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
if(fmt) printmesg(fmt, a, 1);
|
if(fmt) printmesg(fmt, a, 1);
|
||||||
|
/* iprint("error: %s\n", up->errstr); */
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
while((n-=m) > 0){
|
while((n-=m) > 0){
|
||||||
|
@ -1445,7 +1562,7 @@ drawmesg(Client *client, void *av, int n)
|
||||||
if(ddst == nil)
|
if(ddst == nil)
|
||||||
error(Enodrawimage);
|
error(Enodrawimage);
|
||||||
if(ddst->name)
|
if(ddst->name)
|
||||||
error("can't change repl/clipr of shared image");
|
error("cannot change repl/clipr of shared image");
|
||||||
dst = ddst->image;
|
dst = ddst->image;
|
||||||
if(a[5])
|
if(a[5])
|
||||||
dst->flags |= Frepl;
|
dst->flags |= Frepl;
|
||||||
|
@ -1543,14 +1660,16 @@ drawmesg(Client *client, void *av, int n)
|
||||||
error(Eshortdraw);
|
error(Eshortdraw);
|
||||||
dstid = BGLONG(a+1);
|
dstid = BGLONG(a+1);
|
||||||
if(dstid == 0)
|
if(dstid == 0)
|
||||||
error("can't use display as font");
|
error("cannot use display as font");
|
||||||
font = drawlookup(client, dstid, 1);
|
font = drawlookup(client, dstid, 1);
|
||||||
if(font == 0)
|
if(font == 0)
|
||||||
error(Enodrawimage);
|
error(Enodrawimage);
|
||||||
if(font->image->layer)
|
if(font->image->layer)
|
||||||
error("can't use window as font");
|
error("cannot use window as font");
|
||||||
free(font->fchar); /* should we complain if non-zero? */
|
|
||||||
ni = BGLONG(a+5);
|
ni = BGLONG(a+5);
|
||||||
|
if(ni<=0 || ni>4096)
|
||||||
|
error("bad font size (4096 chars max)");
|
||||||
|
free(font->fchar); /* should we complain if non-zero? */
|
||||||
font->fchar = malloc(ni*sizeof(FChar));
|
font->fchar = malloc(ni*sizeof(FChar));
|
||||||
if(font->fchar == 0)
|
if(font->fchar == 0)
|
||||||
error("no memory for font");
|
error("no memory for font");
|
||||||
|
@ -1647,7 +1766,7 @@ drawmesg(Client *client, void *av, int n)
|
||||||
error(Edrawmem);
|
error(Edrawmem);
|
||||||
di = drawlookup(client, dstid, 0);
|
di = drawlookup(client, dstid, 0);
|
||||||
if(di == 0)
|
if(di == 0)
|
||||||
error("draw: can't happen");
|
error("draw: cannot happen");
|
||||||
di->vers = dn->vers;
|
di->vers = dn->vers;
|
||||||
di->name = smalloc(j+1);
|
di->name = smalloc(j+1);
|
||||||
di->fromname = dn->dimage;
|
di->fromname = dn->dimage;
|
||||||
|
@ -1748,7 +1867,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;
|
||||||
|
@ -1803,8 +1922,6 @@ drawmesg(Client *client, void *av, int n)
|
||||||
if(n < m)
|
if(n < m)
|
||||||
error(Eshortdraw);
|
error(Eshortdraw);
|
||||||
i = drawimage(client, a+1);
|
i = drawimage(client, a+1);
|
||||||
if(0 && i->layer)
|
|
||||||
error("readimage from window unimplemented");
|
|
||||||
drawrectangle(&r, a+5);
|
drawrectangle(&r, a+5);
|
||||||
if(!rectinrect(r, i->r))
|
if(!rectinrect(r, i->r))
|
||||||
error(Ereadoutside);
|
error(Ereadoutside);
|
||||||
|
@ -1814,7 +1931,7 @@ drawmesg(Client *client, void *av, int n)
|
||||||
client->readdata = mallocz(c, 0);
|
client->readdata = mallocz(c, 0);
|
||||||
if(client->readdata == nil)
|
if(client->readdata == nil)
|
||||||
error("readimage malloc failed");
|
error("readimage malloc failed");
|
||||||
client->nreaddata = unloadmemimage(i, r, client->readdata, c);
|
client->nreaddata = memunload(i, r, client->readdata, c);
|
||||||
if(client->nreaddata < 0){
|
if(client->nreaddata < 0){
|
||||||
free(client->readdata);
|
free(client->readdata);
|
||||||
client->readdata = nil;
|
client->readdata = nil;
|
||||||
|
@ -1852,9 +1969,10 @@ drawmesg(Client *client, void *av, int n)
|
||||||
clipr = dst->clipr;
|
clipr = dst->clipr;
|
||||||
dst->clipr = r;
|
dst->clipr = r;
|
||||||
op = drawclientop(client);
|
op = drawclientop(client);
|
||||||
|
bg = dst;
|
||||||
if(*a == 'x'){
|
if(*a == 'x'){
|
||||||
/* paint background */
|
/* paint background */
|
||||||
l = drawimage(client, a+47);
|
bg = drawimage(client, a+47);
|
||||||
drawpoint(&q, a+51);
|
drawpoint(&q, a+51);
|
||||||
r.min.x = p.x;
|
r.min.x = p.x;
|
||||||
r.min.y = p.y-font->ascent;
|
r.min.y = p.y-font->ascent;
|
||||||
|
@ -1870,7 +1988,7 @@ drawmesg(Client *client, void *av, int n)
|
||||||
r.max.x += font->fchar[ci].width;
|
r.max.x += font->fchar[ci].width;
|
||||||
u += 2;
|
u += 2;
|
||||||
}
|
}
|
||||||
memdraw(dst, r, l, q, memopaque, ZP, op);
|
memdraw(dst, r, bg, q, memopaque, ZP, op);
|
||||||
u -= 2*ni;
|
u -= 2*ni;
|
||||||
}
|
}
|
||||||
q = p;
|
q = p;
|
||||||
|
@ -1880,7 +1998,7 @@ drawmesg(Client *client, void *av, int n)
|
||||||
dst->clipr = clipr;
|
dst->clipr = clipr;
|
||||||
error(Eindex);
|
error(Eindex);
|
||||||
}
|
}
|
||||||
q = drawchar(dst, q, src, &sp, font, ci, op);
|
q = drawchar(dst, bg, q, src, &sp, font, ci, op);
|
||||||
u += 2;
|
u += 2;
|
||||||
}
|
}
|
||||||
dst->clipr = clipr;
|
dst->clipr = clipr;
|
||||||
|
@ -1938,7 +2056,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);
|
||||||
|
@ -2009,7 +2127,6 @@ drawcmap(void)
|
||||||
int num, den;
|
int num, den;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
drawactive(1); /* to restore map from backup */
|
|
||||||
for(r=0,i=0; r!=4; r++)
|
for(r=0,i=0; r!=4; r++)
|
||||||
for(v=0; v!=4; v++,i+=16){
|
for(v=0; v!=4; v++,i+=16){
|
||||||
for(g=0,j=v-r; g!=4; g++)
|
for(g=0,j=v-r; g!=4; g++)
|
||||||
|
@ -2032,53 +2149,3 @@ drawcmap(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
drawblankscreen(int blank)
|
|
||||||
{
|
|
||||||
int i, nc;
|
|
||||||
ulong *p;
|
|
||||||
|
|
||||||
if(blank == sdraw.blanked)
|
|
||||||
return;
|
|
||||||
if(!canqlock(&sdraw))
|
|
||||||
return;
|
|
||||||
if(!initscreenimage()){
|
|
||||||
qunlock(&sdraw);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p = sdraw.savemap;
|
|
||||||
nc = screenimage->depth > 8 ? 256 : 1<<screenimage->depth;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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]);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* record activity on screen, changing blanking as appropriate
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
drawactive(int active)
|
|
||||||
{
|
|
||||||
if(active){
|
|
||||||
drawblankscreen(0);
|
|
||||||
sdraw.blanktime = 0;
|
|
||||||
}else
|
|
||||||
sdraw.blanktime++;
|
|
||||||
}
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ struct Mouseinfo
|
||||||
ulong lastcounter; /* value when /dev/mouse read */
|
ulong lastcounter; /* value when /dev/mouse read */
|
||||||
Rendez r;
|
Rendez r;
|
||||||
Ref;
|
Ref;
|
||||||
|
int resize;
|
||||||
int open;
|
int open;
|
||||||
Mousestate queue[16]; /* circular buffer of click events */
|
Mousestate queue[16]; /* circular buffer of click events */
|
||||||
ulong ri; /* read index into queue */
|
ulong ri; /* read index into queue */
|
||||||
|
@ -195,6 +196,10 @@ mouseread(Chan *c, void *va, long n, vlong off)
|
||||||
m.xy.x, m.xy.y, m.buttons, m.msec);
|
m.xy.x, m.xy.y, m.buttons, m.msec);
|
||||||
|
|
||||||
mouse.lastcounter = m.counter;
|
mouse.lastcounter = m.counter;
|
||||||
|
if(mouse.resize){
|
||||||
|
mouse.resize = 0;
|
||||||
|
buf[0] = 'r';
|
||||||
|
}
|
||||||
|
|
||||||
if(n > 1+4*12)
|
if(n > 1+4*12)
|
||||||
n = 1+4*12;
|
n = 1+4*12;
|
||||||
|
@ -321,7 +326,7 @@ absmousetrack(int x, int y, int b, ulong msec)
|
||||||
int
|
int
|
||||||
mousechanged(void*)
|
mousechanged(void*)
|
||||||
{
|
{
|
||||||
return mouse.lastcounter != mouse.counter;
|
return mouse.lastcounter != mouse.counter || mouse.resize != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point
|
Point
|
||||||
|
@ -329,3 +334,13 @@ mousexy(void)
|
||||||
{
|
{
|
||||||
return mouse.xy;
|
return mouse.xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* notify reader that screen has been resized
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mouseresize(void)
|
||||||
|
{
|
||||||
|
mouse.resize = 1;
|
||||||
|
rendwakeup(&mouse.r);
|
||||||
|
}
|
||||||
|
|
|
@ -260,9 +260,12 @@ dorectangle(Vnc *v)
|
||||||
case EncMouseWarp:
|
case EncMouseWarp:
|
||||||
mousewarp(r.min);
|
mousewarp(r.min);
|
||||||
return;
|
return;
|
||||||
|
case EncDesktopSize:
|
||||||
|
v->canresize |= 1;
|
||||||
|
vncsetdim(v, r);
|
||||||
|
return;
|
||||||
case EncXDesktopSize:
|
case EncXDesktopSize:
|
||||||
v->canresize = 1;
|
v->canresize |= 2;
|
||||||
n = vncrdlong(v)>>24;
|
n = vncrdlong(v)>>24;
|
||||||
if(n <= 0)
|
if(n <= 0)
|
||||||
break;
|
break;
|
||||||
|
@ -274,9 +277,7 @@ dorectangle(Vnc *v)
|
||||||
vncrdrect(v);
|
vncrdrect(v);
|
||||||
vncrdlong(v);
|
vncrdlong(v);
|
||||||
}
|
}
|
||||||
/* wet floor */
|
vncsetdim(v, v->screen[0].rect);
|
||||||
case EncDesktopSize:
|
|
||||||
vncsetdim(v, r);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,10 +42,7 @@ static Cursor screencursor;
|
||||||
void
|
void
|
||||||
screeninit(int x, int y, char *chanstr)
|
screeninit(int x, int y, char *chanstr)
|
||||||
{
|
{
|
||||||
Point p, q;
|
|
||||||
char *greet;
|
|
||||||
char buf[128];
|
char buf[128];
|
||||||
Memimage *grey;
|
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
int chan;
|
int chan;
|
||||||
|
|
||||||
|
@ -78,31 +75,33 @@ screeninit(int x, int y, char *chanstr)
|
||||||
error(buf);
|
error(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawlock();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* set up goo for screenputs
|
|
||||||
*/
|
|
||||||
memdefont = getmemdefont();
|
|
||||||
|
|
||||||
back = memwhite;
|
|
||||||
conscol = memblack;
|
|
||||||
|
|
||||||
/* a lot of work to get a grey color */
|
/* a lot of work to get a grey color */
|
||||||
curscol = allocmemimage(Rect(0,0,1,1), RGBA32);
|
curscol = allocmemimage(Rect(0,0,1,1), RGBA32);
|
||||||
curscol->flags |= Frepl;
|
curscol->flags |= Frepl;
|
||||||
curscol->clipr = gscreen->r;
|
curscol->clipr = gscreen->r;
|
||||||
memfillcolor(curscol, 0xff0000ff);
|
memfillcolor(curscol, 0xff0000ff);
|
||||||
|
|
||||||
memfillcolor(gscreen, 0x444488FF);
|
screenwin();
|
||||||
|
|
||||||
w = memdefont->info[' '].width;
|
setcursor(&arrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
screenwin(void)
|
||||||
|
{
|
||||||
|
Point p;
|
||||||
|
char *greet;
|
||||||
|
Memimage *grey;
|
||||||
|
|
||||||
|
qlock(&drawlock);
|
||||||
|
back = memwhite;
|
||||||
|
conscol = memblack;
|
||||||
|
memfillcolor(gscreen, 0x888844FF);
|
||||||
|
|
||||||
|
memdefont = getmemdefont();
|
||||||
h = memdefont->height;
|
h = memdefont->height;
|
||||||
|
|
||||||
window.min = addpt(gscreen->r.min, Pt(20,20));
|
window = insetrect(gscreen->clipr, 20);
|
||||||
window.max.x = window.min.x + Dx(gscreen->r)*3/4-40;
|
|
||||||
window.max.y = window.min.y + Dy(gscreen->r)*3/4-100;
|
|
||||||
|
|
||||||
memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
|
memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S);
|
||||||
window = insetrect(window, 4);
|
window = insetrect(window, 4);
|
||||||
memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
|
memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
|
||||||
|
@ -119,22 +118,18 @@ screeninit(int x, int y, char *chanstr)
|
||||||
|
|
||||||
greet = " Plan 9 Console ";
|
greet = " Plan 9 Console ";
|
||||||
p = addpt(window.min, Pt(10, 0));
|
p = addpt(window.min, Pt(10, 0));
|
||||||
q = memsubfontwidth(memdefont, greet);
|
|
||||||
memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
|
memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
|
||||||
window.min.y += h+6;
|
window.min.y += h+6;
|
||||||
curpos = window.min;
|
curpos = window.min;
|
||||||
window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
|
window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
|
||||||
flushmemscreen(gscreen->r);
|
flushmemscreen(gscreen->r);
|
||||||
|
qunlock(&drawlock);
|
||||||
drawunlock();
|
|
||||||
|
|
||||||
setcursor(&arrow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar*
|
uchar*
|
||||||
attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen)
|
attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen)
|
||||||
{
|
{
|
||||||
*r = gscreen->r;
|
*r = gscreen->clipr;
|
||||||
*d = gscreen->depth;
|
*d = gscreen->depth;
|
||||||
*chan = gscreen->chan;
|
*chan = gscreen->chan;
|
||||||
*width = gscreen->width;
|
*width = gscreen->width;
|
||||||
|
@ -263,7 +258,7 @@ scroll(void)
|
||||||
memimagedraw(gscreen, r, gscreen, p, nil, p, S);
|
memimagedraw(gscreen, r, gscreen, p, nil, p, S);
|
||||||
r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
|
r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
|
||||||
memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
|
memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
|
||||||
flushmemscreen(gscreen->r);
|
flushmemscreen(gscreen->clipr);
|
||||||
|
|
||||||
curpos.y -= o;
|
curpos.y -= o;
|
||||||
}
|
}
|
||||||
|
@ -336,7 +331,7 @@ screenputs(char *s, int n)
|
||||||
static int nrb;
|
static int nrb;
|
||||||
char *e;
|
char *e;
|
||||||
|
|
||||||
drawlock();
|
qlock(&drawlock);
|
||||||
e = s + n;
|
e = s + n;
|
||||||
while(s < e){
|
while(s < e){
|
||||||
rb[nrb++] = *s++;
|
rb[nrb++] = *s++;
|
||||||
|
@ -347,5 +342,5 @@ screenputs(char *s, int n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
screenflush();
|
screenflush();
|
||||||
drawunlock();
|
qunlock(&drawlock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ extern Memimage *gscreen;
|
||||||
extern int cursorver;
|
extern int cursorver;
|
||||||
extern Point cursorpos;
|
extern Point cursorpos;
|
||||||
|
|
||||||
|
void mouseresize(void);
|
||||||
Point mousexy(void);
|
Point mousexy(void);
|
||||||
void cursoron(void);
|
void cursoron(void);
|
||||||
void cursoroff(void);
|
void cursoroff(void);
|
||||||
|
@ -19,16 +20,18 @@ void flushmemscreen(Rectangle r);
|
||||||
Rectangle cursorrect(void);
|
Rectangle cursorrect(void);
|
||||||
void cursordraw(Memimage *dst, Rectangle r);
|
void cursordraw(Memimage *dst, Rectangle r);
|
||||||
|
|
||||||
|
extern QLock drawlock;
|
||||||
void drawactive(int);
|
void drawactive(int);
|
||||||
void drawlock(void);
|
|
||||||
void drawunlock(void);
|
|
||||||
int candrawlock(void);
|
|
||||||
void getcolor(ulong, ulong*, ulong*, ulong*);
|
void getcolor(ulong, ulong*, ulong*, ulong*);
|
||||||
int setcolor(ulong, ulong, ulong, ulong);
|
int setcolor(ulong, ulong, ulong, ulong);
|
||||||
#define TK2SEC(x) 0
|
#define TK2SEC(x) 0
|
||||||
extern void blankscreen(int);
|
extern void blankscreen(int);
|
||||||
void screeninit(int x, int y, char *chanstr);
|
void screeninit(int x, int y, char *chanstr);
|
||||||
|
void screenwin(void);
|
||||||
void absmousetrack(int x, int y, int b, ulong msec);
|
void absmousetrack(int x, int y, int b, ulong msec);
|
||||||
uchar *attachscreen(Rectangle*, ulong*, int*, int*, int*);
|
uchar *attachscreen(Rectangle*, ulong*, int*, int*, int*);
|
||||||
|
void deletescreenimage(void);
|
||||||
|
void resetscreenimage(void);
|
||||||
|
|
||||||
void fsinit(char *mntpt, int x, int y, char *chanstr);
|
void fsinit(char *mntpt, int x, int y, char *chanstr);
|
||||||
|
#define ishwimage(i) 0
|
||||||
|
|
|
@ -571,7 +571,7 @@ vncaccept(Vncs *v)
|
||||||
if(!shared)
|
if(!shared)
|
||||||
killclients(v);
|
killclients(v);
|
||||||
|
|
||||||
v->dim = rectsubpt(gscreen->r, gscreen->r.min);
|
v->dim = rectsubpt(gscreen->clipr, gscreen->clipr.min);
|
||||||
vncwrpoint(v, v->dim.max);
|
vncwrpoint(v, v->dim.max);
|
||||||
if(verbose)
|
if(verbose)
|
||||||
fprint(2, "%V: send screen size %R\n", v, v->dim);
|
fprint(2, "%V: send screen size %R\n", v, v->dim);
|
||||||
|
@ -592,6 +592,8 @@ vncaccept(Vncs *v)
|
||||||
if(verbose)
|
if(verbose)
|
||||||
fprint(2, "%V: handshaking done\n", v);
|
fprint(2, "%V: handshaking done\n", v);
|
||||||
|
|
||||||
|
v->updatereq = 0;
|
||||||
|
|
||||||
switch(rfork(RFPROC|RFMEM)){
|
switch(rfork(RFPROC|RFMEM)){
|
||||||
case -1:
|
case -1:
|
||||||
fprint(2, "%V: cannot fork: %r; hanging up\n", v);
|
fprint(2, "%V: cannot fork: %r; hanging up\n", v);
|
||||||
|
@ -674,7 +676,10 @@ setencoding(Vncs *v)
|
||||||
v->canwarp = 1;
|
v->canwarp = 1;
|
||||||
continue;
|
continue;
|
||||||
case EncDesktopSize:
|
case EncDesktopSize:
|
||||||
|
v->canresize |= 1;
|
||||||
|
continue;
|
||||||
case EncXDesktopSize:
|
case EncXDesktopSize:
|
||||||
|
v->canresize |= 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(v->countrect != nil)
|
if(v->countrect != nil)
|
||||||
|
@ -710,9 +715,10 @@ setencoding(Vncs *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(verbose)
|
if(verbose)
|
||||||
fprint(2, "Encoding with %s%s%s\n", v->encname,
|
fprint(2, "Encoding with %s%s%s%s\n", v->encname,
|
||||||
v->copyrect ? ", copyrect" : "",
|
v->copyrect ? ", copyrect" : "",
|
||||||
v->canwarp ? ", canwarp" : "");
|
v->canwarp ? ", canwarp" : "",
|
||||||
|
v->canresize ? ", resize" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -755,18 +761,40 @@ clientreadproc(Vncs *v)
|
||||||
case MFrameReq:
|
case MFrameReq:
|
||||||
incremental = vncrdchar(v);
|
incremental = vncrdchar(v);
|
||||||
r = vncrdrect(v);
|
r = vncrdrect(v);
|
||||||
if(incremental){
|
if(!incremental){
|
||||||
vnclock(v);
|
qlock(&drawlock); /* protects rlist */
|
||||||
v->updaterequest = 1;
|
|
||||||
vncunlock(v);
|
|
||||||
}else{
|
|
||||||
drawlock(); /* protects rlist */
|
|
||||||
vnclock(v); /* protects updaterequest */
|
|
||||||
v->updaterequest = 1;
|
|
||||||
addtorlist(&v->rlist, r);
|
addtorlist(&v->rlist, r);
|
||||||
vncunlock(v);
|
qunlock(&drawlock);
|
||||||
drawunlock();
|
|
||||||
}
|
}
|
||||||
|
v->updatereq++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSetDesktopSize:
|
||||||
|
vncrdchar(v);
|
||||||
|
vncrdpoint(v); // desktop size
|
||||||
|
n = vncrdchar(v);
|
||||||
|
vncrdchar(v);
|
||||||
|
if(n == 0)
|
||||||
|
break;
|
||||||
|
vncrdlong(v); // id
|
||||||
|
r = vncrdrect(v);
|
||||||
|
vncrdlong(v); // flags
|
||||||
|
while(--n > 0){
|
||||||
|
vncrdlong(v);
|
||||||
|
vncrdrect(v);
|
||||||
|
vncrdlong(v);
|
||||||
|
}
|
||||||
|
qlock(&drawlock);
|
||||||
|
if(!rectclip(&r, gscreen->r)){
|
||||||
|
qunlock(&drawlock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gscreen->clipr = r;
|
||||||
|
qunlock(&drawlock);
|
||||||
|
|
||||||
|
screenwin();
|
||||||
|
deletescreenimage();
|
||||||
|
resetscreenimage();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* send keystroke */
|
/* send keystroke */
|
||||||
|
@ -905,7 +933,7 @@ flushmemscreen(Rectangle r)
|
||||||
{
|
{
|
||||||
Vncs *v;
|
Vncs *v;
|
||||||
|
|
||||||
if(!rectclip(&r, gscreen->r))
|
if(!rectclip(&r, gscreen->clipr))
|
||||||
return;
|
return;
|
||||||
qlock(&clients);
|
qlock(&clients);
|
||||||
for(v=clients.head; v; v=v->next)
|
for(v=clients.head; v; v=v->next)
|
||||||
|
@ -925,7 +953,7 @@ mousewarpnote(Point p)
|
||||||
for(v=clients.head; v; v=v->next){
|
for(v=clients.head; v; v=v->next){
|
||||||
if(v->canwarp){
|
if(v->canwarp){
|
||||||
vnclock(v);
|
vnclock(v);
|
||||||
v->needwarp = 1;
|
v->dowarp = 1;
|
||||||
v->warppt = p;
|
v->warppt = p;
|
||||||
vncunlock(v);
|
vncunlock(v);
|
||||||
}
|
}
|
||||||
|
@ -940,7 +968,7 @@ mousewarpnote(Point p)
|
||||||
static int
|
static int
|
||||||
updateimage(Vncs *v)
|
updateimage(Vncs *v)
|
||||||
{
|
{
|
||||||
int i, ncount, nsend, docursor, needwarp;
|
int i, j, ncount, nsend, docursor, dowarp, doresize;
|
||||||
vlong ooffset;
|
vlong ooffset;
|
||||||
Point warppt;
|
Point warppt;
|
||||||
Rectangle cr;
|
Rectangle cr;
|
||||||
|
@ -949,20 +977,37 @@ updateimage(Vncs *v)
|
||||||
int (*count)(Vncs*, Rectangle);
|
int (*count)(Vncs*, Rectangle);
|
||||||
int (*send)(Vncs*, Rectangle);
|
int (*send)(Vncs*, Rectangle);
|
||||||
|
|
||||||
if(v->image == nil)
|
vnclock(v);
|
||||||
return 0;
|
dowarp = v->canwarp && v->dowarp;
|
||||||
|
|
||||||
/* warping info and unlock v so that updates can proceed */
|
|
||||||
needwarp = v->canwarp && v->needwarp;
|
|
||||||
warppt = v->warppt;
|
warppt = v->warppt;
|
||||||
v->needwarp = 0;
|
v->dowarp = 0;
|
||||||
vncunlock(v);
|
vncunlock(v);
|
||||||
|
|
||||||
/* copy the screen bits and then unlock the screen so updates can proceed */
|
/* copy the screen bits and then unlock the screen so updates can proceed */
|
||||||
drawlock();
|
qlock(&drawlock);
|
||||||
rlist = v->rlist;
|
rlist = v->rlist;
|
||||||
memset(&v->rlist, 0, sizeof v->rlist);
|
memset(&v->rlist, 0, sizeof v->rlist);
|
||||||
|
|
||||||
|
if(v->canresize && !eqrect(v->screen[0].rect, gscreen->clipr)){
|
||||||
|
v->screen[0].rect = gscreen->clipr;
|
||||||
|
v->dim = rectsubpt(gscreen->clipr, gscreen->clipr.min);
|
||||||
|
doresize = 1;
|
||||||
|
} else
|
||||||
|
doresize = 0;
|
||||||
|
|
||||||
|
if(doresize
|
||||||
|
|| (v->image == nil && v->imagechan != 0)
|
||||||
|
|| (v->image != nil && v->image->chan != v->imagechan)){
|
||||||
|
if(v->image)
|
||||||
|
freememimage(v->image);
|
||||||
|
v->image = allocmemimage(v->dim, v->imagechan);
|
||||||
|
if(v->image == nil){
|
||||||
|
fprint(2, "%V: allocmemimage: %r; hanging up\n", v);
|
||||||
|
qlock(&drawlock);
|
||||||
|
vnchungup(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* if the cursor has moved or changed shape, we need to redraw its square */
|
/* if the cursor has moved or changed shape, we need to redraw its square */
|
||||||
lock(&cursor);
|
lock(&cursor);
|
||||||
if(v->cursorver != cursorver || !eqpt(v->cursorpos, cursorpos)){
|
if(v->cursorver != cursorver || !eqpt(v->cursorpos, cursorpos)){
|
||||||
|
@ -978,7 +1023,7 @@ updateimage(Vncs *v)
|
||||||
|
|
||||||
if(docursor){
|
if(docursor){
|
||||||
addtorlist(&rlist, v->cursorr);
|
addtorlist(&rlist, v->cursorr);
|
||||||
if(!rectclip(&cr, gscreen->r))
|
if(!rectclip(&cr, gscreen->clipr))
|
||||||
cr.max = cr.min;
|
cr.max = cr.min;
|
||||||
addtorlist(&rlist, cr);
|
addtorlist(&rlist, cr);
|
||||||
}
|
}
|
||||||
|
@ -996,15 +1041,7 @@ updateimage(Vncs *v)
|
||||||
v->cursorr = cr;
|
v->cursorr = cr;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawunlock();
|
qunlock(&drawlock);
|
||||||
|
|
||||||
ooffset = Boffset(&v->out);
|
|
||||||
/* no more locks are held; talk to the client */
|
|
||||||
|
|
||||||
if(rlist.nrect == 0 && needwarp == 0){
|
|
||||||
vnclock(v);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = v->countrect;
|
count = v->countrect;
|
||||||
send = v->sendrect;
|
send = v->sendrect;
|
||||||
|
@ -1014,16 +1051,45 @@ updateimage(Vncs *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
ncount = 0;
|
ncount = 0;
|
||||||
for(i=0; i<rlist.nrect; i++)
|
for(i=j=0; i<rlist.nrect; i++){
|
||||||
ncount += (*count)(v, rlist.rect[i]);
|
if(j < i)
|
||||||
|
rlist.rect[j] = rlist.rect[i];
|
||||||
|
if(rectclip(&rlist.rect[j], v->dim))
|
||||||
|
ncount += (*count)(v, rlist.rect[j++]);
|
||||||
|
}
|
||||||
|
rlist.nrect = j;
|
||||||
|
|
||||||
if(verbose > 1)
|
if(doresize == 0 && ncount == 0 && dowarp == 0)
|
||||||
fprint(2, "sendupdate: rlist.nrect=%d, ncount=%d", rlist.nrect, ncount);
|
return 0;
|
||||||
|
|
||||||
|
if(verbose > 1){
|
||||||
|
fprint(2, "sendupdate: rlist.nrect=%d, ncount=%d\n", rlist.nrect, ncount);
|
||||||
t1 = nsec();
|
t1 = nsec();
|
||||||
|
ooffset = Boffset(&v->out);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(doresize && v->canresize == 1){
|
||||||
|
doresize = 0;
|
||||||
|
|
||||||
vncwrchar(v, MFrameUpdate);
|
vncwrchar(v, MFrameUpdate);
|
||||||
vncwrchar(v, 0);
|
vncwrchar(v, 0);
|
||||||
vncwrshort(v, ncount+needwarp);
|
vncwrshort(v, 1);
|
||||||
|
vncwrrect(v, v->dim);
|
||||||
|
vncwrlong(v, EncDesktopSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
vncwrchar(v, MFrameUpdate);
|
||||||
|
vncwrchar(v, 0);
|
||||||
|
vncwrshort(v, doresize+ncount+dowarp);
|
||||||
|
|
||||||
|
if(doresize){
|
||||||
|
vncwrrect(v, gscreen->r);
|
||||||
|
vncwrlong(v, EncXDesktopSize);
|
||||||
|
vncwrlong(v, 1<<24);
|
||||||
|
vncwrlong(v, v->screen[0].id);
|
||||||
|
vncwrrect(v, v->screen[0].rect);
|
||||||
|
vncwrlong(v, v->screen[0].flags);
|
||||||
|
}
|
||||||
|
|
||||||
nsend = 0;
|
nsend = 0;
|
||||||
for(i=0; i<rlist.nrect; i++)
|
for(i=0; i<rlist.nrect; i++)
|
||||||
|
@ -1034,17 +1100,17 @@ updateimage(Vncs *v)
|
||||||
vnchungup(v);
|
vnchungup(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(needwarp){
|
if(dowarp){
|
||||||
vncwrrect(v, Rect(warppt.x, warppt.y, warppt.x+1, warppt.y+1));
|
vncwrrect(v, Rect(warppt.x, warppt.y, warppt.x+1, warppt.y+1));
|
||||||
vncwrlong(v, EncMouseWarp);
|
vncwrlong(v, EncMouseWarp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(verbose > 1){
|
||||||
t1 = nsec() - t1;
|
t1 = nsec() - t1;
|
||||||
if(verbose > 1)
|
|
||||||
fprint(2, " in %lldms, %lld bytes\n", t1/1000000, Boffset(&v->out) - ooffset);
|
fprint(2, " in %lldms, %lld bytes\n", t1/1000000, Boffset(&v->out) - ooffset);
|
||||||
|
}
|
||||||
|
|
||||||
freerlist(&rlist);
|
freerlist(&rlist);
|
||||||
vnclock(v);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1059,13 +1125,11 @@ updatesnarf(Vncs *v)
|
||||||
|
|
||||||
if(v->snarfvers == snarf.vers)
|
if(v->snarfvers == snarf.vers)
|
||||||
return;
|
return;
|
||||||
vncunlock(v);
|
|
||||||
qlock(&snarf);
|
qlock(&snarf);
|
||||||
len = snarf.n;
|
len = snarf.n;
|
||||||
buf = malloc(len);
|
buf = malloc(len);
|
||||||
if(buf == nil){
|
if(buf == nil){
|
||||||
qunlock(&snarf);
|
qunlock(&snarf);
|
||||||
vnclock(v);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memmove(buf, snarf.buf, len);
|
memmove(buf, snarf.buf, len);
|
||||||
|
@ -1077,7 +1141,6 @@ updatesnarf(Vncs *v)
|
||||||
vncwrlong(v, len);
|
vncwrlong(v, len);
|
||||||
vncwrbytes(v, buf, len);
|
vncwrbytes(v, buf, len);
|
||||||
free(buf);
|
free(buf);
|
||||||
vnclock(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1086,41 +1149,16 @@ updatesnarf(Vncs *v)
|
||||||
static void
|
static void
|
||||||
clientwriteproc(Vncs *v)
|
clientwriteproc(Vncs *v)
|
||||||
{
|
{
|
||||||
char buf[32], buf2[32];
|
ulong last = 0;
|
||||||
int sent;
|
|
||||||
|
|
||||||
vncname("write %V", v);
|
vncname("write %V", v);
|
||||||
for(;;){
|
while(!v->ndead){
|
||||||
vnclock(v);
|
|
||||||
if(v->ndead)
|
|
||||||
break;
|
|
||||||
if((v->image == nil && v->imagechan!=0)
|
|
||||||
|| (v->image && v->image->chan != v->imagechan)){
|
|
||||||
if(v->image)
|
|
||||||
freememimage(v->image);
|
|
||||||
v->image = allocmemimage(v->dim, v->imagechan);
|
|
||||||
if(v->image == nil){
|
|
||||||
fprint(2, "%V: allocmemimage: %r; hanging up\n", v);
|
|
||||||
vnchungup(v);
|
|
||||||
}
|
|
||||||
if(verbose)
|
|
||||||
fprint(2, "%V: translating image from chan=%s to chan=%s\n",
|
|
||||||
v, chantostr(buf, gscreen->chan), chantostr(buf2, v->imagechan));
|
|
||||||
}
|
|
||||||
sent = 0;
|
|
||||||
if(v->updaterequest){
|
|
||||||
v->updaterequest = 0;
|
|
||||||
updatesnarf(v);
|
|
||||||
sent = updateimage(v);
|
|
||||||
if(!sent)
|
|
||||||
v->updaterequest = 1;
|
|
||||||
}
|
|
||||||
vncunlock(v);
|
|
||||||
vncflush(v);
|
|
||||||
if(!sent)
|
|
||||||
sleep(sleeptime);
|
sleep(sleeptime);
|
||||||
|
updatesnarf(v);
|
||||||
|
if(v->updatereq != last && updateimage(v))
|
||||||
|
last++;
|
||||||
|
vncflush(v);
|
||||||
}
|
}
|
||||||
vncunlock(v);
|
|
||||||
vnchungup(v);
|
vnchungup(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,11 @@ struct Vncs
|
||||||
int (*sendrect)(Vncs*, Rectangle);
|
int (*sendrect)(Vncs*, Rectangle);
|
||||||
int copyrect;
|
int copyrect;
|
||||||
int canwarp;
|
int canwarp;
|
||||||
int needwarp;
|
int dowarp;
|
||||||
Point warppt;
|
Point warppt;
|
||||||
|
|
||||||
int updaterequest;
|
ulong updatereq;
|
||||||
|
|
||||||
Rlist rlist;
|
Rlist rlist;
|
||||||
int ndead;
|
int ndead;
|
||||||
int nproc;
|
int nproc;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue