tdevdraw: move Client into devdraw.h and move global state in - plan9port - [fo… | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 88ed92aa40ab5aa0f563624c488ba2a120990329 | |
parent 933b98054f40bb224acda134d7bb77a023bcc57f | |
Author: Russ Cox <[email protected]> | |
Date: Wed, 8 Jan 2020 20:28:17 -0500 | |
devdraw: move Client into devdraw.h and move global state in | |
Diffstat: | |
M include/memdraw.h | 1 - | |
M src/cmd/devdraw/devdraw.c | 340 ++++++++++-------------------… | |
M src/cmd/devdraw/devdraw.h | 169 +++++++++++++++++++++++++++++… | |
M src/cmd/devdraw/mac-screen.h | 15 +++++---------- | |
M src/cmd/devdraw/mac-screen.m | 80 +++++++++++++++++------------… | |
M src/cmd/devdraw/mac-srv.c | 309 +++++++++++++----------------… | |
M src/cmd/devdraw/mkfile | 6 +++++- | |
M src/cmd/devdraw/mkwsysrules.sh | 2 ++ | |
M src/cmd/devdraw/mouseswap.c | 5 +++++ | |
M src/cmd/devdraw/winsize.c | 5 +++++ | |
M src/cmd/devdraw/x11-init.c | 3 ++- | |
11 files changed, 470 insertions(+), 465 deletions(-) | |
--- | |
diff --git a/include/memdraw.h b/include/memdraw.h | |
t@@ -216,7 +216,6 @@ extern Memdrawparam* _memimagedrawsetup(Memimage*, | |
Rectangle, Memimage*, Point, Memimage*, | |
Point, int); | |
extern void _memimagedraw(Memdrawparam*); | |
-extern void _drawreplacescreenimage(Memimage*); | |
#if defined(__cplusplus) | |
} | |
diff --git a/src/cmd/devdraw/devdraw.c b/src/cmd/devdraw/devdraw.c | |
t@@ -8,154 +8,32 @@ | |
#include <draw.h> | |
#include <memdraw.h> | |
#include <memlayer.h> | |
+#include <mouse.h> | |
+#include <cursor.h> | |
+#include <keyboard.h> | |
+#include <drawfcall.h> | |
#include "devdraw.h" | |
extern void _flushmemscreen(Rectangle); | |
-int forcedpi = 0; | |
-int displaydpi = 100; | |
- | |
-#define NHASH (1<<5) | |
-#define HASHMASK (NHASH-1) | |
- | |
-typedef struct Client Client; | |
-typedef struct Draw Draw; | |
-typedef struct DImage DImage; | |
-typedef struct DScreen DScreen; | |
-typedef struct CScreen CScreen; | |
-typedef struct FChar FChar; | |
-typedef struct Refresh Refresh; | |
-typedef struct Refx Refx; | |
-typedef struct DName DName; | |
- | |
-struct Draw | |
-{ | |
- QLock lk; | |
- int clientid; | |
- int nclient; | |
- Client* client[1]; | |
- int nname; | |
- DName* name; | |
- int vers; | |
- int softscreen; | |
-}; | |
- | |
-struct Client | |
-{ | |
- /*Ref r;*/ | |
- DImage* dimage[NHASH]; | |
- CScreen* cscreen; | |
- Refresh* refresh; | |
- Rendez refrend; | |
- uchar* readdata; | |
- int nreaddata; | |
- int busy; | |
- int clientid; | |
- int slot; | |
- int refreshme; | |
- int infoid; | |
- int op; | |
-}; | |
- | |
-struct Refresh | |
-{ | |
- DImage* dimage; | |
- Rectangle r; | |
- Refresh* next; | |
-}; | |
- | |
-struct Refx | |
-{ | |
- Client* client; | |
- DImage* dimage; | |
-}; | |
- | |
-struct DName | |
-{ | |
- char *name; | |
- Client *client; | |
- DImage* dimage; | |
- int vers; | |
-}; | |
- | |
-struct FChar | |
-{ | |
- int minx; /* left edge of bits */ | |
- int maxx; /* right edge of bits */ | |
- uchar miny; /* first non-zero scan-line */ | |
- uchar maxy; /* last non-zero scan-line + 1 */ | |
- schar left; /* offset of baseline */ | |
- uchar width; /* width of baseline */ | |
-}; | |
- | |
-/* | |
- * Reference counts in DImages: | |
- * one per open by original client | |
- * one per screen image or fill | |
- * one per image derived from this one by name | |
- */ | |
-struct DImage | |
-{ | |
- int id; | |
- int ref; | |
- char *name; | |
- int vers; | |
- Memimage* image; | |
- int ascent; | |
- int nfchar; | |
- FChar* fchar; | |
- DScreen* dscreen; /* 0 if not a window */ | |
- DImage* fromname; /* image this one is derived from, by … | |
- DImage* next; | |
-}; | |
- | |
-struct CScreen | |
-{ | |
- DScreen* dscreen; | |
- CScreen* next; | |
-}; | |
- | |
-struct DScreen | |
-{ | |
- int id; | |
- int public; | |
- int ref; | |
- DImage *dimage; | |
- DImage *dfill; | |
- Memscreen* screen; | |
- Client* owner; | |
- DScreen* next; | |
-}; | |
static Draw sdraw; | |
-static Client *client0; | |
-static Memimage *screenimage; | |
-static Rectangle flushrect; | |
-static int waste; | |
-static DScreen* dscreen; | |
+Client *client0; | |
static int drawuninstall(Client*, int); | |
static Memimage* drawinstall(Client*, int, Memimage*, DScreen*); | |
-static void drawfreedimage(DImage*); | |
+static void drawfreedimage(Client*, DImage*); | |
void | |
-_initdisplaymemimage(Memimage *m) | |
+_initdisplaymemimage(Client *c, Memimage *m) | |
{ | |
- screenimage = m; | |
+ c->screenimage = m; | |
m->screenref = 1; | |
- client0 = mallocz(sizeof(Client), 1); | |
- if(client0 == nil){ | |
- fprint(2, "initdraw: allocating client0: out of memory"); | |
- abort(); | |
- } | |
- client0->slot = 0; | |
- client0->clientid = ++sdraw.clientid; | |
- client0->op = SoverD; | |
- sdraw.client[0] = client0; | |
- sdraw.nclient = 1; | |
- sdraw.softscreen = 1; | |
+ c->slot = 0; | |
+ c->clientid = 1; | |
+ c->op = SoverD; | |
} | |
void | |
-_drawreplacescreenimage(Memimage *m) | |
+_drawreplacescreenimage(Client *c, Memimage *m) | |
{ | |
/* | |
* Replace the screen image because the screen | |
t@@ -171,14 +49,17 @@ _drawreplacescreenimage(Memimage *m) | |
*/ | |
Memimage *om; | |
+ qlock(&c->inputlk); | |
qlock(&sdraw.lk); | |
- om = screenimage; | |
- screenimage = m; | |
+ om = c->screenimage; | |
+ c->screenimage = m; | |
m->screenref = 1; | |
+ c->mouse.resized = 1; | |
if(om && --om->screenref == 0){ | |
_freememimage(om); | |
} | |
qunlock(&sdraw.lk); | |
+ qunlock(&c->inputlk); | |
} | |
static | |
t@@ -222,57 +103,57 @@ drawrefresh(Memimage *m, Rectangle r, void *v) | |
} | |
static void | |
-addflush(Rectangle r) | |
+addflush(Client *c, Rectangle r) | |
{ | |
int abb, ar, anbb; | |
Rectangle nbb; | |
- if(sdraw.softscreen==0 || !rectclip(&r, screenimage->r)) | |
+ if(/*sdraw.softscreen==0 ||*/ !rectclip(&r, c->screenimage->r)) | |
return; | |
- if(flushrect.min.x >= flushrect.max.x){ | |
- flushrect = r; | |
- waste = 0; | |
+ if(c->flushrect.min.x >= c->flushrect.max.x){ | |
+ c->flushrect = r; | |
+ c->waste = 0; | |
return; | |
} | |
- nbb = flushrect; | |
+ nbb = c->flushrect; | |
combinerect(&nbb, r); | |
ar = Dx(r)*Dy(r); | |
- abb = Dx(flushrect)*Dy(flushrect); | |
+ abb = Dx(c->flushrect)*Dy(c->flushrect); | |
anbb = Dx(nbb)*Dy(nbb); | |
/* | |
* Area of new waste is area of new bb minus area of old bb, | |
* less the area of the new segment, which we assume is not waste. | |
* This could be negative, but that's OK. | |
*/ | |
- waste += anbb-abb - ar; | |
- if(waste < 0) | |
- waste = 0; | |
+ c->waste += anbb-abb - ar; | |
+ if(c->waste < 0) | |
+ c->waste = 0; | |
/* | |
* absorb if: | |
* total area is small | |
* waste is less than half total area | |
* rectangles touch | |
*/ | |
- if(anbb<=1024 || waste*2<anbb || rectXrect(flushrect, r)){ | |
- flushrect = nbb; | |
+ if(anbb<=1024 || c->waste*2<anbb || rectXrect(c->flushrect, r)){ | |
+ c->flushrect = nbb; | |
return; | |
} | |
/* emit current state */ | |
- if(flushrect.min.x < flushrect.max.x) | |
- _flushmemscreen(flushrect); | |
- flushrect = r; | |
- waste = 0; | |
+ if(c->flushrect.min.x < c->flushrect.max.x) | |
+ _flushmemscreen(c->flushrect); | |
+ c->flushrect = r; | |
+ c->waste = 0; | |
} | |
static | |
void | |
-dstflush(int dstid, Memimage *dst, Rectangle r) | |
+dstflush(Client *c, int dstid, Memimage *dst, Rectangle r) | |
{ | |
Memlayer *l; | |
if(dstid == 0){ | |
- combinerect(&flushrect, r); | |
+ combinerect(&c->flushrect, r); | |
return; | |
} | |
/* how can this happen? -rsc, dec 12 2002 */ | |
t@@ -284,21 +165,21 @@ dstflush(int dstid, Memimage *dst, Rectangle r) | |
if(l == nil) | |
return; | |
do{ | |
- if(l->screen->image->data != screenimage->data) | |
+ if(l->screen->image->data != c->screenimage->data) | |
return; | |
r = rectaddpt(r, l->delta); | |
l = l->screen->image->layer; | |
}while(l); | |
- addflush(r); | |
+ addflush(c, r); | |
} | |
static | |
void | |
-drawflush(void) | |
+drawflush(Client *c) | |
{ | |
- if(flushrect.min.x < flushrect.max.x) | |
- _flushmemscreen(flushrect); | |
- flushrect = Rect(10000, 10000, -10000, -10000); | |
+ if(c->flushrect.min.x < c->flushrect.max.x) | |
+ _flushmemscreen(c->flushrect); | |
+ c->flushrect = Rect(10000, 10000, -10000, -10000); | |
} | |
static | |
t@@ -312,12 +193,12 @@ drawcmp(char *a, char *b, int n) | |
static | |
DName* | |
-drawlookupname(int n, char *str) | |
+drawlookupname(Client *client, int n, char *str) | |
{ | |
DName *name, *ename; | |
- name = sdraw.name; | |
- ename = &name[sdraw.nname]; | |
+ name = client->name; | |
+ ename = &name[client->nname]; | |
for(; name<ename; name++) | |
if(drawcmp(name->name, str, n) == 0) | |
return name; | |
t@@ -326,18 +207,18 @@ drawlookupname(int n, char *str) | |
static | |
int | |
-drawgoodname(DImage *d) | |
+drawgoodname(Client *client, DImage *d) | |
{ | |
DName *n; | |
/* if window, validate the screen's own images */ | |
if(d->dscreen) | |
- if(drawgoodname(d->dscreen->dimage) == 0 | |
- || drawgoodname(d->dscreen->dfill) == 0) | |
+ if(drawgoodname(client, d->dscreen->dimage) == 0 | |
+ || drawgoodname(client, d->dscreen->dfill) == 0) | |
return 0; | |
if(d->name == nil) | |
return 1; | |
- n = drawlookupname(strlen(d->name), d->name); | |
+ n = drawlookupname(client, strlen(d->name), d->name); | |
if(n==nil || n->vers!=d->vers) | |
return 0; | |
return 1; | |
t@@ -356,7 +237,7 @@ drawlookup(Client *client, int id, int checkname) | |
* BUG: should error out but too hard. | |
* Return 0 instead. | |
*/ | |
- if(checkname && !drawgoodname(d)) | |
+ if(checkname && !drawgoodname(client, d)) | |
return 0; | |
return d; | |
} | |
t@@ -367,11 +248,11 @@ drawlookup(Client *client, int id, int checkname) | |
static | |
DScreen* | |
-drawlookupdscreen(int id) | |
+drawlookupdscreen(Client *c, int id) | |
{ | |
DScreen *s; | |
- s = dscreen; | |
+ s = c->dscreen; | |
while(s){ | |
if(s->id == id) | |
return s; | |
t@@ -466,9 +347,9 @@ drawinstallscreen(Client *client, DScreen *d, int id, DIma… | |
d->id = id; | |
d->screen = s; | |
d->public = public; | |
- d->next = dscreen; | |
+ d->next = client->dscreen; | |
d->owner = client; | |
- dscreen = d; | |
+ client->dscreen = d; | |
} | |
c->dscreen = d; | |
d->ref++; | |
t@@ -479,18 +360,18 @@ drawinstallscreen(Client *client, DScreen *d, int id, DI… | |
static | |
void | |
-drawdelname(DName *name) | |
+drawdelname(Client *client, DName *name) | |
{ | |
int i; | |
- i = name-sdraw.name; | |
- memmove(name, name+1, (sdraw.nname-(i+1))*sizeof(DName)); | |
- sdraw.nname--; | |
+ i = name-client->name; | |
+ memmove(name, name+1, (client->nname-(i+1))*sizeof(DName)); | |
+ client->nname--; | |
} | |
static | |
void | |
-drawfreedscreen(DScreen *this) | |
+drawfreedscreen(Client *client, DScreen *this) | |
{ | |
DScreen *ds, *next; | |
t@@ -499,9 +380,9 @@ drawfreedscreen(DScreen *this) | |
fprint(2, "negative ref in drawfreedscreen\n"); | |
if(this->ref > 0) | |
return; | |
- ds = dscreen; | |
+ ds = client->dscreen; | |
if(ds == this){ | |
- dscreen = this->next; | |
+ client->dscreen = this->next; | |
goto Found; | |
} | |
while(next = ds->next){ /* assign = */ | |
t@@ -518,16 +399,16 @@ drawfreedscreen(DScreen *this) | |
Found: | |
if(this->dimage) | |
- drawfreedimage(this->dimage); | |
+ drawfreedimage(client, this->dimage); | |
if(this->dfill) | |
- drawfreedimage(this->dfill); | |
+ drawfreedimage(client, this->dfill); | |
free(this->screen); | |
free(this); | |
} | |
static | |
void | |
-drawfreedimage(DImage *dimage) | |
+drawfreedimage(Client *client, DImage *dimage) | |
{ | |
int i; | |
Memimage *l; | |
t@@ -540,13 +421,13 @@ drawfreedimage(DImage *dimage) | |
return; | |
/* any names? */ | |
- for(i=0; i<sdraw.nname; ) | |
- if(sdraw.name[i].dimage == dimage) | |
- drawdelname(sdraw.name+i); | |
+ for(i=0; i<client->nname; ) | |
+ if(client->name[i].dimage == dimage) | |
+ drawdelname(client, client->name+i); | |
else | |
i++; | |
if(dimage->fromname){ /* acquired by name; owned by someone els… | |
- drawfreedimage(dimage->fromname); | |
+ drawfreedimage(client, dimage->fromname); | |
goto Return; | |
} | |
ds = dimage->dscreen; | |
t@@ -554,16 +435,16 @@ drawfreedimage(DImage *dimage) | |
dimage->dscreen = nil; /* paranoia */ | |
dimage->image = nil; | |
if(ds){ | |
- if(l->data == screenimage->data) | |
- addflush(l->layer->screenr); | |
+ if(l->data == client->screenimage->data) | |
+ addflush(client, l->layer->screenr); | |
if(l->layer->refreshfn == drawrefresh) /* else true own… | |
free(l->layer->refreshptr); | |
l->layer->refreshptr = nil; | |
- if(drawgoodname(dimage)) | |
+ if(drawgoodname(client, dimage)) | |
memldelete(l); | |
else | |
memlfree(l); | |
- drawfreedscreen(ds); | |
+ drawfreedscreen(client, ds); | |
}else{ | |
if(l->screenref==0) | |
freememimage(l); | |
t@@ -584,14 +465,14 @@ drawuninstallscreen(Client *client, CScreen *this) | |
cs = client->cscreen; | |
if(cs == this){ | |
client->cscreen = this->next; | |
- drawfreedscreen(this->dscreen); | |
+ drawfreedscreen(client, this->dscreen); | |
free(this); | |
return; | |
} | |
while(next = cs->next){ /* assign = */ | |
if(next == this){ | |
cs->next = this->next; | |
- drawfreedscreen(this->dscreen); | |
+ drawfreedscreen(client, this->dscreen); | |
free(this); | |
return; | |
} | |
t@@ -608,7 +489,7 @@ drawuninstall(Client *client, int id) | |
for(l=&client->dimage[id&HASHMASK]; (d=*l) != nil; l=&d->next){ | |
if(d->id == id){ | |
*l = d->next; | |
- drawfreedimage(d); | |
+ drawfreedimage(client, d); | |
return 0; | |
} | |
} | |
t@@ -622,14 +503,14 @@ drawaddname(Client *client, DImage *di, int n, char *str… | |
DName *name, *ename, *new, *t; | |
char *ns; | |
- name = sdraw.name; | |
- ename = &name[sdraw.nname]; | |
+ name = client->name; | |
+ ename = &name[client->nname]; | |
for(; name<ename; name++) | |
if(drawcmp(name->name, str, n) == 0){ | |
*err = "image name in use"; | |
return -1; | |
} | |
- t = mallocz((sdraw.nname+1)*sizeof(DName), 1); | |
+ t = mallocz((client->nname+1)*sizeof(DName), 1); | |
ns = malloc(n+1); | |
if(t == nil || ns == nil){ | |
free(t); | |
t@@ -637,16 +518,16 @@ drawaddname(Client *client, DImage *di, int n, char *str… | |
*err = "out of memory"; | |
return -1; | |
} | |
- memmove(t, sdraw.name, sdraw.nname*sizeof(DName)); | |
- free(sdraw.name); | |
- sdraw.name = t; | |
- new = &sdraw.name[sdraw.nname++]; | |
+ memmove(t, client->name, client->nname*sizeof(DName)); | |
+ free(client->name); | |
+ client->name = t; | |
+ new = &client->name[client->nname++]; | |
new->name = ns; | |
memmove(new->name, str, n); | |
new->name[n] = 0; | |
new->dimage = di; | |
new->client = client; | |
- new->vers = ++sdraw.vers; | |
+ new->vers = ++client->namevers; | |
return 0; | |
} | |
t@@ -738,12 +619,9 @@ drawcoord(uchar *p, uchar *maxp, int oldx, int *newx) | |
} | |
int | |
-_drawmsgread(void *a, int n) | |
+_drawmsgread(Client *cl, void *a, int n) | |
{ | |
- Client *cl; | |
- | |
qlock(&sdraw.lk); | |
- cl = client0; | |
if(cl->readdata == nil){ | |
werrstr("no draw data"); | |
goto err; | |
t@@ -765,14 +643,13 @@ err: | |
} | |
int | |
-_drawmsgwrite(void *v, int n) | |
+_drawmsgwrite(Client *client, void *v, int n) | |
{ | |
char cbuf[40], *err, ibuf[12*12+1], *s; | |
int c, ci, doflush, dstid, e0, e1, esize, j, m; | |
int ni, nw, oesize, oldn, op, ox, oy, repl, scrnid, y; | |
uchar *a, refresh, *u; | |
u32int chan, value; | |
- Client *client; | |
CScreen *cs; | |
DImage *di, *ddst, *dsrc, *font, *ll; | |
DName *dn; | |
t@@ -790,7 +667,6 @@ _drawmsgwrite(void *v, int n) | |
a = v; | |
m = 0; | |
oldn = n; | |
- client = client0; | |
while((n-=m) > 0){ | |
a += m; | |
t@@ -844,7 +720,7 @@ _drawmsgwrite(void *v, int n) | |
l = memlalloc(scrn, r, reffn, 0, value); | |
if(l == 0) | |
goto Edrawmem; | |
- addflush(l->layer->screenr); | |
+ addflush(client, l->layer->screenr); | |
l->clipr = clipr; | |
rectclip(&l->clipr, r); | |
if(drawinstall(client, dstid, l, dscrn) == 0){ | |
t@@ -891,7 +767,7 @@ _drawmsgwrite(void *v, int n) | |
dstid = BGLONG(a+1); | |
if(dstid == 0) | |
goto Ebadarg; | |
- if(drawlookupdscreen(dstid)) | |
+ if(drawlookupdscreen(client, dstid)) | |
goto Escreenexists; | |
ddst = drawlookup(client, BGLONG(a+5), 1); | |
dsrc = drawlookup(client, BGLONG(a+9), 1); | |
t@@ -935,7 +811,7 @@ _drawmsgwrite(void *v, int n) | |
drawpoint(&q, a+37); | |
op = drawclientop(client); | |
memdraw(dst, r, src, p, mask, q, op); | |
- dstflush(dstid, dst, r); | |
+ dstflush(client, dstid, dst, r); | |
continue; | |
/* toggle debugging: 'D' val[1] */ | |
t@@ -984,7 +860,7 @@ _drawmsgwrite(void *v, int n) | |
memarc(dst, p, e0, e1, c, src, sp, ox, oy, op); | |
}else | |
memellipse(dst, p, e0, e1, c, src, sp, op); | |
- dstflush(dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j… | |
+ dstflush(client, dstid, dst, Rect(p.x-e0-j, p.y-e1-j, … | |
continue; | |
/* free: 'f' id[4] */ | |
t@@ -1049,7 +925,7 @@ _drawmsgwrite(void *v, int n) | |
goto Eshortdraw; | |
if(drawlookup(client, 0, 0)) | |
goto Eimageexists; | |
- drawinstall(client, 0, screenimage, 0); | |
+ drawinstall(client, 0, client->screenimage, 0); | |
client->infoid = 0; | |
continue; | |
t@@ -1061,7 +937,7 @@ _drawmsgwrite(void *v, int n) | |
if(client->infoid < 0) | |
goto Enodrawimage; | |
if(client->infoid == 0){ | |
- i = screenimage; | |
+ i = client->screenimage; | |
if(i == nil) | |
goto Enodrawimage; | |
}else{ | |
t@@ -1102,10 +978,10 @@ _drawmsgwrite(void *v, int n) | |
err = "unknown query"; | |
goto error; | |
case 'd': /* dpi */ | |
- if(forcedpi) | |
- fmtprint(&fmt, "%11d ", forced… | |
+ if(client->forcedpi) | |
+ fmtprint(&fmt, "%11d ", client… | |
else | |
- fmtprint(&fmt, "%11d ", displa… | |
+ fmtprint(&fmt, "%11d ", client… | |
break; | |
} | |
} | |
t@@ -1169,7 +1045,7 @@ _drawmsgwrite(void *v, int n) | |
if(dstid==0 || dst->layer!=nil){ | |
/* BUG: this is terribly inefficient: update m… | |
r = memlinebbox(p, q, e0, e1, j); | |
- dstflush(dstid, dst, insetrect(r, -(1+1+j))); | |
+ dstflush(client, dstid, dst, insetrect(r, -(1+… | |
} | |
continue; | |
t@@ -1198,7 +1074,7 @@ _drawmsgwrite(void *v, int n) | |
dstid = BGLONG(a+1); | |
if(drawlookup(client, dstid, 0)) | |
goto Eimageexists; | |
- dn = drawlookupname(j, (char*)a+6); | |
+ dn = drawlookupname(client, j, (char*)a+6); | |
if(dn == nil) | |
goto Enoname; | |
s = malloc(j+1); | |
t@@ -1239,12 +1115,12 @@ _drawmsgwrite(void *v, int n) | |
if(drawaddname(client, di, j, (char*)a+7, &err… | |
goto error; | |
else{ | |
- dn = drawlookupname(j, (char*)a+7); | |
+ dn = drawlookupname(client, j, (char*)a+7); | |
if(dn == nil) | |
goto Enoname; | |
if(dn->dimage != di) | |
goto Ewrongname; | |
- drawdelname(dn); | |
+ drawdelname(client, dn); | |
} | |
continue; | |
t@@ -1266,8 +1142,8 @@ _drawmsgwrite(void *v, int n) | |
goto error; | |
} | |
if(ni > 0){ | |
- addflush(r); | |
- addflush(dst->layer->screenr); | |
+ addflush(client, r); | |
+ addflush(client, dst->layer->screenr); | |
ll = drawlookup(client, BGLONG(a+1), 1… | |
drawrefreshscreen(ll, client); | |
} | |
t@@ -1316,7 +1192,7 @@ _drawmsgwrite(void *v, int n) | |
if(pp == nil) | |
goto Enomem; | |
doflush = 0; | |
- if(dstid==0 || (dst->layer && dst->layer->screen->imag… | |
+ if(dstid==0 || (dst->layer && dst->layer->screen->imag… | |
doflush = 1; /* simplify test in loop */ | |
ox = oy = 0; | |
esize = 0; | |
t@@ -1353,12 +1229,12 @@ _drawmsgwrite(void *v, int n) | |
combinerect(&r, Rect(p.x-esize… | |
} | |
if(rectclip(&r, dst->clipr)) … | |
- dstflush(dstid, dst, r); | |
+ dstflush(client, dstid, dst, r… | |
} | |
pp[y] = p; | |
} | |
if(y == 1) | |
- dstflush(dstid, dst, Rect(p.x-esize, p.y-esize… | |
+ dstflush(client, dstid, dst, Rect(p.x-esize, p… | |
op = drawclientop(client); | |
if(*a == 'p') | |
mempoly(dst, pp, ni, e0, e1, j, src, sp, op); | |
t@@ -1462,7 +1338,7 @@ _drawmsgwrite(void *v, int n) | |
} | |
dst->clipr = clipr; | |
p.y -= font->ascent; | |
- dstflush(dstid, dst, Rect(p.x, p.y, q.x, p.y+Dy(font->… | |
+ dstflush(client, dstid, dst, Rect(p.x, p.y, q.x, p.y+D… | |
continue; | |
/* use public screen: 'S' id[4] chan[4] */ | |
t@@ -1473,7 +1349,7 @@ _drawmsgwrite(void *v, int n) | |
dstid = BGLONG(a+1); | |
if(dstid == 0) | |
goto Ebadarg; | |
- dscrn = drawlookupdscreen(dstid); | |
+ dscrn = drawlookupdscreen(client, dstid); | |
if(dscrn==0 || (dscrn->public==0 && dscrn->owner!=clie… | |
goto Enodrawscreen; | |
if(dscrn->screen->image->chan != BGLONG(a+5)){ | |
t@@ -1522,9 +1398,9 @@ _drawmsgwrite(void *v, int n) | |
memltofrontn(lp, nw); | |
else | |
memltorearn(lp, nw); | |
- if(lp[0]->layer->screen->image->data == screenimage->d… | |
+ if(lp[0]->layer->screen->image->data == client->screen… | |
for(j=0; j<nw; j++) | |
- addflush(lp[j]->layer->screenr); | |
+ addflush(client, lp[j]->layer->screenr… | |
free(lp); | |
ll = drawlookup(client, BGLONG(a+1+1+2), 1); | |
drawrefreshscreen(ll, client); | |
t@@ -1533,7 +1409,7 @@ _drawmsgwrite(void *v, int n) | |
/* visible: 'v' */ | |
case 'v': | |
m = 1; | |
- drawflush(); | |
+ drawflush(client); | |
continue; | |
/* write: 'y' id[4] R[4*4] data[x*1] */ | |
t@@ -1555,7 +1431,7 @@ _drawmsgwrite(void *v, int n) | |
err = "bad writeimage call"; | |
goto error; | |
} | |
- dstflush(dstid, dst, r); | |
+ dstflush(client, dstid, dst, r); | |
m += y; | |
continue; | |
} | |
diff --git a/src/cmd/devdraw/devdraw.h b/src/cmd/devdraw/devdraw.h | |
t@@ -1,10 +1,167 @@ | |
-int _drawmsgread(void*, int); | |
-int _drawmsgwrite(void*, int); | |
-void _initdisplaymemimage(Memimage*); | |
+ | |
+#define NHASH (1<<5) | |
+#define HASHMASK (NHASH-1) | |
+ | |
+typedef struct Kbdbuf Kbdbuf; | |
+typedef struct Mousebuf Mousebuf; | |
+typedef struct Tagbuf Tagbuf; | |
+ | |
+typedef struct Client Client; | |
+typedef struct Draw Draw; | |
+typedef struct DImage DImage; | |
+typedef struct DScreen DScreen; | |
+typedef struct CScreen CScreen; | |
+typedef struct FChar FChar; | |
+typedef struct Refresh Refresh; | |
+typedef struct Refx Refx; | |
+typedef struct DName DName; | |
+ | |
+struct Draw | |
+{ | |
+ QLock lk; | |
+}; | |
+ | |
+struct Kbdbuf | |
+{ | |
+ Rune r[256]; | |
+ int ri; | |
+ int wi; | |
+ int stall; | |
+ int alting; | |
+}; | |
+ | |
+struct Mousebuf | |
+{ | |
+ Mouse m[256]; | |
+ Mouse last; | |
+ int ri; | |
+ int wi; | |
+ int stall; | |
+ int resized; | |
+}; | |
+ | |
+struct Tagbuf | |
+{ | |
+ int t[256]; | |
+ int ri; | |
+ int wi; | |
+}; | |
+ | |
+struct Client | |
+{ | |
+ /*Ref r;*/ | |
+ DImage* dimage[NHASH]; | |
+ CScreen* cscreen; | |
+ Refresh* refresh; | |
+ Rendez refrend; | |
+ uchar* readdata; | |
+ int nreaddata; | |
+ int busy; | |
+ int clientid; | |
+ int slot; | |
+ int refreshme; | |
+ int infoid; | |
+ int op; | |
+ | |
+ int displaydpi; | |
+ int forcedpi; | |
+ int waste; | |
+ Rectangle flushrect; | |
+ Memimage *screenimage; | |
+ DScreen* dscreen; | |
+ int nname; | |
+ DName* name; | |
+ int namevers; | |
+ | |
+ int rfd; | |
+ int wfd; | |
+ | |
+ QLock inputlk; | |
+ Kbdbuf kbd; | |
+ Mousebuf mouse; | |
+ Tagbuf kbdtags; | |
+ Tagbuf mousetags; | |
+ Rectangle mouserect; | |
+}; | |
+ | |
+struct Refresh | |
+{ | |
+ DImage* dimage; | |
+ Rectangle r; | |
+ Refresh* next; | |
+}; | |
+ | |
+struct Refx | |
+{ | |
+ Client* client; | |
+ DImage* dimage; | |
+}; | |
+ | |
+struct DName | |
+{ | |
+ char *name; | |
+ Client *client; | |
+ DImage* dimage; | |
+ int vers; | |
+}; | |
+ | |
+struct FChar | |
+{ | |
+ int minx; /* left edge of bits */ | |
+ int maxx; /* right edge of bits */ | |
+ uchar miny; /* first non-zero scan-line */ | |
+ uchar maxy; /* last non-zero scan-line + 1 */ | |
+ schar left; /* offset of baseline */ | |
+ uchar width; /* width of baseline */ | |
+}; | |
+ | |
+/* | |
+ * Reference counts in DImages: | |
+ * one per open by original client | |
+ * one per screen image or fill | |
+ * one per image derived from this one by name | |
+ */ | |
+struct DImage | |
+{ | |
+ int id; | |
+ int ref; | |
+ char *name; | |
+ int vers; | |
+ Memimage* image; | |
+ int ascent; | |
+ int nfchar; | |
+ FChar* fchar; | |
+ DScreen* dscreen; /* 0 if not a window */ | |
+ DImage* fromname; /* image this one is derived from, by … | |
+ DImage* next; | |
+}; | |
+ | |
+struct CScreen | |
+{ | |
+ DScreen* dscreen; | |
+ CScreen* next; | |
+}; | |
+ | |
+struct DScreen | |
+{ | |
+ int id; | |
+ int public; | |
+ int ref; | |
+ DImage *dimage; | |
+ DImage *dfill; | |
+ Memscreen* screen; | |
+ Client* owner; | |
+ DScreen* next; | |
+}; | |
+ | |
+int _drawmsgread(Client*, void*, int); | |
+int _drawmsgwrite(Client*, void*, int); | |
+void _initdisplaymemimage(Client*, Memimage*); | |
+void _drawreplacescreenimage(Client*, Memimage*); | |
+ | |
int _latin1(Rune*, int); | |
int parsewinsize(char*, Rectangle*, int*); | |
int mouseswap(int); | |
-void abortcompose(void); | |
+void abortcompose(Client*); | |
-extern int displaydpi; | |
-extern int forcedpi; | |
+extern Client *client0; | |
diff --git a/src/cmd/devdraw/mac-screen.h b/src/cmd/devdraw/mac-screen.h | |
t@@ -1,6 +1,6 @@ | |
#define setcursor dsetcursor | |
-Memimage *attachscreen(char*, char*); | |
+Memimage *attachscreen(Client*, char*, char*); | |
void setmouse(Point); | |
void setcursor(Cursor*, Cursor2*); | |
void setlabel(char*); | |
t@@ -8,17 +8,12 @@ char* getsnarf(void); | |
void putsnarf(char*); | |
void topwin(void); | |
-void mousetrack(int, int, int, uint); | |
-void keystroke(int); | |
+void mousetrack(Client*, int, int, int, uint); | |
+void keystroke(Client*, int); | |
void kicklabel(char*); | |
-void servep9p(void); | |
-void zlock(void); | |
-void zunlock(void); | |
+void servep9p(Client*); | |
-void resizeimg(void); | |
+void resizeimg(Client*); | |
-Rectangle mouserect; | |
- | |
-int mouseresized; | |
void resizewindow(Rectangle); | |
diff --git a/src/cmd/devdraw/mac-screen.m b/src/cmd/devdraw/mac-screen.m | |
t@@ -15,10 +15,13 @@ | |
#include <thread.h> | |
#include <draw.h> | |
#include <memdraw.h> | |
-#include <keyboard.h> | |
+#include <memlayer.h> | |
+#include <mouse.h> | |
#include <cursor.h> | |
-#include "mac-screen.h" | |
+#include <keyboard.h> | |
+#include <drawfcall.h> | |
#include "devdraw.h" | |
+#include "mac-screen.h" | |
#include "bigarrow.h" | |
#include "glendapng.h" | |
t@@ -31,7 +34,7 @@ AUTOFRAMEWORK(QuartzCore) | |
static void setprocname(const char*); | |
static uint keycvt(uint); | |
static uint msec(void); | |
-static Memimage* initimg(void); | |
+static Memimage* initimg(Client*); | |
void | |
usage(void) | |
t@@ -48,6 +51,7 @@ usage(void) | |
+ (void)callsetcursor:(NSValue *)v; | |
@end | |
@interface DevDrawView : NSView<NSTextInputClient> | |
+@property (nonatomic) Client *client; | |
- (void)clearInput; | |
- (void)getmouse:(NSEvent *)e; | |
- (void)sendmouse:(NSUInteger)b; | |
t@@ -96,6 +100,13 @@ threadmain(int argc, char **argv) | |
usage(); | |
}ARGEND | |
+ client0 = mallocz(sizeof(Client), 1); | |
+ client0->displaydpi = 100; | |
+ if(client0 == nil){ | |
+ fprint(2, "initdraw: allocating client0: out of memory"); | |
+ abort(); | |
+ } | |
+ | |
setprocname(argv0); | |
@autoreleasepool{ | |
t@@ -113,7 +124,9 @@ callservep9p(void *v) | |
{ | |
USED(v); | |
- servep9p(); | |
+ client0->rfd = 3; | |
+ client0->wfd = 4; | |
+ servep9p(client0); | |
[NSApp terminate:myApp]; | |
} | |
t@@ -167,6 +180,7 @@ callservep9p(void *v) | |
[win setDelegate:myApp]; | |
myContent = [DevDrawView new]; | |
+ myContent.client = client0; | |
[win setContentView:myContent]; | |
[myContent setWantsLayer:YES]; | |
[myContent setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawOnSet… | |
t@@ -353,7 +367,7 @@ struct Cursors { | |
- (void)windowDidResize:(NSNotification *)notification | |
{ | |
if(![myContent inLiveResize] && img) { | |
- resizeimg(); | |
+ resizeimg(myContent.client); | |
} | |
} | |
t@@ -463,7 +477,7 @@ struct Cursors { | |
b |= 4; | |
[self sendmouse:b]; | |
}else if(m & ~omod & NSEventModifierFlagOption) | |
- keystroke(Kalt); | |
+ keystroke(self.client, Kalt); | |
omod = m; | |
} | |
t@@ -520,7 +534,7 @@ struct Cursors { | |
if(b == 1){ | |
m = [e modifierFlags]; | |
if(m & NSEventModifierFlagOption){ | |
- abortcompose(); | |
+ abortcompose(self.client); | |
b = 2; | |
}else | |
if(m & NSEventModifierFlagCommand) | |
t@@ -535,9 +549,9 @@ struct Cursors { | |
p = [self.window convertPointToBacking: | |
[self.window mouseLocationOutsideOfEventStream]]; | |
- p.y = Dy(mouserect) - p.y; | |
+ p.y = Dy(self.client->mouserect) - p.y; | |
// LOG(@"(%g, %g) <- sendmouse(%d)", p.x, p.y, (uint)b); | |
- mousetrack(p.x, p.y, b, msec()); | |
+ mousetrack(self.client, p.x, p.y, b, msec()); | |
if(b && _lastInputRect.size.width && _lastInputRect.size.height) | |
[self resetLastInputRect]; | |
} | |
t@@ -551,14 +565,14 @@ struct Cursors { | |
{ | |
[super viewDidEndLiveResize]; | |
if(img) | |
- resizeimg(); | |
+ resizeimg(self.client); | |
} | |
- (void)viewDidChangeBackingProperties | |
{ | |
[super viewDidChangeBackingProperties]; | |
if(img) | |
- resizeimg(); | |
+ resizeimg(self.client); | |
} | |
// conforms to protocol NSTextInputClient | |
t@@ -617,24 +631,24 @@ struct Cursors { | |
LOG(@"text length %ld", _tmpText.length); | |
for(i = 0; i <= _tmpText.length; ++i){ | |
if(i == _markedRange.location) | |
- keystroke('['); | |
+ keystroke(self.client, '['); | |
if(_selectedRange.length){ | |
if(i == _selectedRange.location) | |
- keystroke('{'); | |
+ keystroke(self.client, '{'); | |
if(i == NSMaxRange(_selectedRange)) | |
- keystroke('}'); | |
+ keystroke(self.client, '}'); | |
} | |
if(i == NSMaxRange(_markedRange)) | |
- keystroke(']'); | |
+ keystroke(self.client, ']'); | |
if(i < _tmpText.length) | |
- keystroke([_tmpText characterAtIndex:i]); | |
+ keystroke(self.client, [_tmpText characterAtIn… | |
} | |
int l; | |
l = 1 + _tmpText.length - NSMaxRange(_selectedRange) | |
+ (_selectedRange.length > 0); | |
LOG(@"move left %d", l); | |
for(i = 0; i < l; ++i) | |
- keystroke(Kleft); | |
+ keystroke(self.client, Kleft); | |
} | |
LOG(@"text: \"%@\" (%ld,%ld) (%ld,%ld)", _tmpText, | |
t@@ -649,7 +663,7 @@ struct Cursors { | |
LOG(@"unmarkText"); | |
len = [_tmpText length]; | |
//for(i = 0; i < len; ++i) | |
- // keystroke([_tmpText characterAtIndex:i]); | |
+ // keystroke(self.client, [_tmpText characterAtIndex:i]); | |
[_tmpText deleteCharactersInRange:NSMakeRange(0, len)]; | |
_markedRange = NSMakeRange(NSNotFound, 0); | |
_selectedRange = NSMakeRange(0, 0); | |
t@@ -691,7 +705,7 @@ struct Cursors { | |
len = [s length]; | |
for(i = 0; i < len; ++i) | |
- keystroke([s characterAtIndex:i]); | |
+ keystroke(self.client, [s characterAtIndex:i]); | |
[_tmpText deleteCharactersInRange:NSMakeRange(0, _tmpText.length)]; | |
_markedRange = NSMakeRange(NSNotFound, 0); | |
_selectedRange = NSMakeRange(0, 0); | |
t@@ -731,7 +745,7 @@ struct Cursors { | |
k += Kcmd; | |
} | |
if(k>0) | |
- keystroke(k); | |
+ keystroke(self.client, k); | |
} | |
// Helper for managing input rect approximately | |
t@@ -762,11 +776,11 @@ struct Cursors { | |
+ (_selectedRange.length > 0); | |
LOG(@"move right %d", l); | |
for(i = 0; i < l; ++i) | |
- keystroke(Kright); | |
+ keystroke(self.client, Kright); | |
l = _tmpText.length+2+2*(_selectedRange.length > 0); | |
LOG(@"backspace %d", l); | |
for(uint i = 0; i < l; ++i) | |
- keystroke(Kbs); | |
+ keystroke(self.client, Kbs); | |
} | |
} | |
t@@ -915,7 +929,7 @@ keycvt(uint code) | |
} | |
Memimage* | |
-attachscreen(char *label, char *winsize) | |
+attachscreen(Client *c, char *label, char *winsize) | |
{ | |
LOG(@"attachscreen(%s, %s)", label, winsize); | |
[AppDelegate | |
t@@ -924,12 +938,12 @@ attachscreen(char *label, char *winsize) | |
waitUntilDone:YES]; | |
kicklabel(label); | |
setcursor(nil, nil); | |
- mouseresized = 0; | |
- return initimg(); | |
+ c->mouse.resized = 0; | |
+ return initimg(c); | |
} | |
static Memimage* | |
-initimg(void) | |
+initimg(Client *c) | |
{ | |
@autoreleasepool{ | |
CGFloat scale; | |
t@@ -937,11 +951,11 @@ initimg(void) | |
MTLTextureDescriptor *textureDesc; | |
size = [myContent convertSizeToBacking:[myContent bounds].size]; | |
- mouserect = Rect(0, 0, size.width, size.height); | |
+ c->mouserect = Rect(0, 0, size.width, size.height); | |
LOG(@"initimg %.0f %.0f", size.width, size.height); | |
- img = allocmemimage(mouserect, XRGB32); | |
+ img = allocmemimage(c->mouserect, XRGB32); | |
if(img == nil) | |
panic("allocmemimage: %r"); | |
if(img->data == nil) | |
t@@ -966,7 +980,7 @@ initimg(void) | |
// This formula gives us 220 for retina, 110 otherwise. | |
// That's not quite right but it's close to correct. | |
// https://en.wikipedia.org/wiki/Retina_display#Models | |
- displaydpi = scale * 110; | |
+ c->displaydpi = scale * 110; | |
} | |
LOG(@"initimg return"); | |
t@@ -1109,13 +1123,9 @@ topwin(void) | |
} | |
void | |
-resizeimg(void) | |
+resizeimg(Client *c) | |
{ | |
- zlock(); | |
- _drawreplacescreenimage(initimg()); | |
- | |
- mouseresized = 1; | |
- zunlock(); | |
+ _drawreplacescreenimage(c, initimg(c)); | |
[myContent sendmouse:0]; | |
} | |
diff --git a/src/cmd/devdraw/mac-srv.c b/src/cmd/devdraw/mac-srv.c | |
t@@ -7,70 +7,23 @@ | |
#include <thread.h> | |
#include <draw.h> | |
#include <memdraw.h> | |
+#include <memlayer.h> | |
#include <keyboard.h> | |
#include <mouse.h> | |
#include <cursor.h> | |
#include <drawfcall.h> | |
-#include "mac-screen.h" | |
#include "devdraw.h" | |
+#include "mac-screen.h" | |
-typedef struct Kbdbuf Kbdbuf; | |
-typedef struct Mousebuf Mousebuf; | |
-typedef struct Fdbuf Fdbuf; | |
-typedef struct Tagbuf Tagbuf; | |
- | |
-struct Kbdbuf | |
-{ | |
- Rune r[256]; | |
- int ri; | |
- int wi; | |
- int stall; | |
-}; | |
- | |
-struct Mousebuf | |
-{ | |
- Mouse m[256]; | |
- Mouse last; | |
- int ri; | |
- int wi; | |
- int stall; | |
-}; | |
- | |
-struct Tagbuf | |
-{ | |
- int t[256]; | |
- int ri; | |
- int wi; | |
-}; | |
- | |
-Kbdbuf kbd; | |
-Mousebuf mouse; | |
-Tagbuf kbdtags; | |
-Tagbuf mousetags; | |
- | |
-void runmsg(Wsysmsg*); | |
-void replymsg(Wsysmsg*); | |
-void matchkbd(void); | |
-void matchmouse(void); | |
- | |
- | |
-QLock lk; | |
-void | |
-zlock(void) | |
-{ | |
- qlock(&lk); | |
-} | |
- | |
-void | |
-zunlock(void) | |
-{ | |
- qunlock(&lk); | |
-} | |
+void runmsg(Client*, Wsysmsg*); | |
+void replymsg(Client*, Wsysmsg*); | |
+void matchkbd(Client*); | |
+void matchmouse(Client*); | |
int trace = 0; | |
void | |
-servep9p(void) | |
+servep9p(Client *c) | |
{ | |
uchar buf[4], *mbuf; | |
int nmbuf, n, nn; | |
t@@ -80,7 +33,7 @@ servep9p(void) | |
mbuf = nil; | |
nmbuf = 0; | |
- while((n = read(3, buf, 4)) == 4){ | |
+ while((n = read(c->rfd, buf, 4)) == 4){ | |
GET(buf, n); | |
if(n > nmbuf){ | |
free(mbuf); | |
t@@ -90,7 +43,7 @@ servep9p(void) | |
nmbuf = n; | |
} | |
memmove(mbuf, buf, 4); | |
- nn = readn(3, mbuf+4, n-4); | |
+ nn = readn(c->rfd, mbuf+4, n-4); | |
if(nn != n-4) | |
sysfatal("eof during message"); | |
t@@ -98,19 +51,19 @@ servep9p(void) | |
if(convM2W(mbuf, nn+4, &m) <= 0) | |
sysfatal("cannot convert message"); | |
if(trace) fprint(2, "%ud [%d] <- %W\n", nsec()/1000000, thread… | |
- runmsg(&m); | |
+ runmsg(c, &m); | |
} | |
} | |
void | |
-replyerror(Wsysmsg *m) | |
+replyerror(Client *c, Wsysmsg *m) | |
{ | |
char err[256]; | |
rerrstr(err, sizeof err); | |
m->type = Rerror; | |
m->error = err; | |
- replymsg(m); | |
+ replymsg(c, m); | |
} | |
/* | |
t@@ -118,7 +71,7 @@ replyerror(Wsysmsg *m) | |
* Might queue for later (kbd, mouse read) | |
*/ | |
void | |
-runmsg(Wsysmsg *m) | |
+runmsg(Client *c, Wsysmsg *m) | |
{ | |
static uchar buf[65536]; | |
int n; | |
t@@ -127,38 +80,38 @@ runmsg(Wsysmsg *m) | |
switch(m->type){ | |
case Tinit: | |
memimageinit(); | |
- i = attachscreen(m->label, m->winsize); | |
- _initdisplaymemimage(i); | |
- replymsg(m); | |
+ i = attachscreen(c, m->label, m->winsize); | |
+ _initdisplaymemimage(c, i); | |
+ replymsg(c, m); | |
break; | |
case Trdmouse: | |
- zlock(); | |
- mousetags.t[mousetags.wi++] = m->tag; | |
- if(mousetags.wi == nelem(mousetags.t)) | |
- mousetags.wi = 0; | |
- if(mousetags.wi == mousetags.ri) | |
+ qlock(&c->inputlk); | |
+ c->mousetags.t[c->mousetags.wi++] = m->tag; | |
+ if(c->mousetags.wi == nelem(c->mousetags.t)) | |
+ c->mousetags.wi = 0; | |
+ if(c->mousetags.wi == c->mousetags.ri) | |
sysfatal("too many queued mouse reads"); | |
- mouse.stall = 0; | |
- matchmouse(); | |
- zunlock(); | |
+ c->mouse.stall = 0; | |
+ matchmouse(c); | |
+ qunlock(&c->inputlk); | |
break; | |
case Trdkbd: | |
- zlock(); | |
- kbdtags.t[kbdtags.wi++] = m->tag; | |
- if(kbdtags.wi == nelem(kbdtags.t)) | |
- kbdtags.wi = 0; | |
- if(kbdtags.wi == kbdtags.ri) | |
+ qlock(&c->inputlk); | |
+ c->kbdtags.t[c->kbdtags.wi++] = m->tag; | |
+ if(c->kbdtags.wi == nelem(c->kbdtags.t)) | |
+ c->kbdtags.wi = 0; | |
+ if(c->kbdtags.wi == c->kbdtags.ri) | |
sysfatal("too many queued keyboard reads"); | |
- kbd.stall = 0; | |
- matchkbd(); | |
- zunlock(); | |
+ c->kbd.stall = 0; | |
+ matchkbd(c); | |
+ qunlock(&c->inputlk); | |
break; | |
case Tmoveto: | |
setmouse(m->mouse.xy); | |
- replymsg(m); | |
+ replymsg(c, m); | |
break; | |
case Tcursor: | |
t@@ -166,7 +119,7 @@ runmsg(Wsysmsg *m) | |
setcursor(nil, nil); | |
else | |
setcursor(&m->cursor, nil); | |
- replymsg(m); | |
+ replymsg(c, m); | |
break; | |
case Tcursor2: | |
t@@ -174,63 +127,63 @@ runmsg(Wsysmsg *m) | |
setcursor(nil, nil); | |
else | |
setcursor(&m->cursor, &m->cursor2); | |
- replymsg(m); | |
+ replymsg(c, m); | |
break; | |
case Tbouncemouse: | |
// _xbouncemouse(&m->mouse); | |
- replymsg(m); | |
+ replymsg(c, m); | |
break; | |
case Tlabel: | |
kicklabel(m->label); | |
- replymsg(m); | |
+ replymsg(c, m); | |
break; | |
case Trdsnarf: | |
m->snarf = getsnarf(); | |
- replymsg(m); | |
+ replymsg(c, m); | |
free(m->snarf); | |
break; | |
case Twrsnarf: | |
putsnarf(m->snarf); | |
- replymsg(m); | |
+ replymsg(c, m); | |
break; | |
case Trddraw: | |
- zlock(); | |
+ qlock(&c->inputlk); | |
n = m->count; | |
if(n > sizeof buf) | |
n = sizeof buf; | |
- n = _drawmsgread(buf, n); | |
+ n = _drawmsgread(c, buf, n); | |
if(n < 0) | |
- replyerror(m); | |
+ replyerror(c, m); | |
else{ | |
m->count = n; | |
m->data = buf; | |
- replymsg(m); | |
+ replymsg(c, m); | |
} | |
- zunlock(); | |
+ qunlock(&c->inputlk); | |
break; | |
case Twrdraw: | |
- zlock(); | |
- if(_drawmsgwrite(m->data, m->count) < 0) | |
- replyerror(m); | |
+ qlock(&c->inputlk); | |
+ if(_drawmsgwrite(c, m->data, m->count) < 0) | |
+ replyerror(c, m); | |
else | |
- replymsg(m); | |
- zunlock(); | |
+ replymsg(c, m); | |
+ qunlock(&c->inputlk); | |
break; | |
case Ttop: | |
topwin(); | |
- replymsg(m); | |
+ replymsg(c, m); | |
break; | |
case Tresize: | |
resizewindow(m->rect); | |
- replymsg(m); | |
+ replymsg(c, m); | |
break; | |
} | |
} | |
t@@ -240,7 +193,7 @@ runmsg(Wsysmsg *m) | |
*/ | |
QLock replylock; | |
void | |
-replymsg(Wsysmsg *m) | |
+replymsg(Client *c, Wsysmsg *m) | |
{ | |
int n; | |
static uchar *mbuf; | |
t@@ -263,7 +216,7 @@ replymsg(Wsysmsg *m) | |
nmbuf = n; | |
} | |
convW2M(m, mbuf, n); | |
- if(write(4, mbuf, n) != n) | |
+ if(write(c->wfd, mbuf, n) != n) | |
sysfatal("write: %r"); | |
qunlock(&replylock); | |
} | |
t@@ -272,21 +225,21 @@ replymsg(Wsysmsg *m) | |
* Match queued kbd reads with queued kbd characters. | |
*/ | |
void | |
-matchkbd(void) | |
+matchkbd(Client *c) | |
{ | |
Wsysmsg m; | |
- if(kbd.stall) | |
+ if(c->kbd.stall) | |
return; | |
- while(kbd.ri != kbd.wi && kbdtags.ri != kbdtags.wi){ | |
+ while(c->kbd.ri != c->kbd.wi && c->kbdtags.ri != c->kbdtags.wi){ | |
m.type = Rrdkbd; | |
- m.tag = kbdtags.t[kbdtags.ri++]; | |
- if(kbdtags.ri == nelem(kbdtags.t)) | |
- kbdtags.ri = 0; | |
- m.rune = kbd.r[kbd.ri++]; | |
- if(kbd.ri == nelem(kbd.r)) | |
- kbd.ri = 0; | |
- replymsg(&m); | |
+ m.tag = c->kbdtags.t[c->kbdtags.ri++]; | |
+ if(c->kbdtags.ri == nelem(c->kbdtags.t)) | |
+ c->kbdtags.ri = 0; | |
+ m.rune = c->kbd.r[c->kbd.ri++]; | |
+ if(c->kbd.ri == nelem(c->kbd.r)) | |
+ c->kbd.ri = 0; | |
+ replymsg(c, &m); | |
} | |
} | |
t@@ -294,131 +247,129 @@ matchkbd(void) | |
* Match queued mouse reads with queued mouse events. | |
*/ | |
void | |
-matchmouse(void) | |
+matchmouse(Client *c) | |
{ | |
Wsysmsg m; | |
- while(mouse.ri != mouse.wi && mousetags.ri != mousetags.wi){ | |
+ while(c->mouse.ri != c->mouse.wi && c->mousetags.ri != c->mousetags.wi… | |
m.type = Rrdmouse; | |
- m.tag = mousetags.t[mousetags.ri++]; | |
- if(mousetags.ri == nelem(mousetags.t)) | |
- mousetags.ri = 0; | |
- m.mouse = mouse.m[mouse.ri]; | |
- m.resized = mouseresized; | |
- mouseresized = 0; | |
+ m.tag = c->mousetags.t[c->mousetags.ri++]; | |
+ if(c->mousetags.ri == nelem(c->mousetags.t)) | |
+ c->mousetags.ri = 0; | |
+ m.mouse = c->mouse.m[c->mouse.ri]; | |
+ m.resized = c->mouse.resized; | |
+ c->mouse.resized = 0; | |
/* | |
if(m.resized) | |
fprint(2, "sending resize\n"); | |
*/ | |
- mouse.ri++; | |
- if(mouse.ri == nelem(mouse.m)) | |
- mouse.ri = 0; | |
- replymsg(&m); | |
+ c->mouse.ri++; | |
+ if(c->mouse.ri == nelem(c->mouse.m)) | |
+ c->mouse.ri = 0; | |
+ replymsg(c, &m); | |
} | |
} | |
void | |
-mousetrack(int x, int y, int b, uint ms) | |
+mousetrack(Client *c, int x, int y, int b, uint ms) | |
{ | |
Mouse *m; | |
- if(x < mouserect.min.x) | |
- x = mouserect.min.x; | |
- if(x > mouserect.max.x) | |
- x = mouserect.max.x; | |
- if(y < mouserect.min.y) | |
- y = mouserect.min.y; | |
- if(y > mouserect.max.y) | |
- y = mouserect.max.y; | |
+ if(x < c->mouserect.min.x) | |
+ x = c->mouserect.min.x; | |
+ if(x > c->mouserect.max.x) | |
+ x = c->mouserect.max.x; | |
+ if(y < c->mouserect.min.y) | |
+ y = c->mouserect.min.y; | |
+ if(y > c->mouserect.max.y) | |
+ y = c->mouserect.max.y; | |
- zlock(); | |
+ qlock(&c->inputlk); | |
// If reader has stopped reading, don't bother. | |
// If reader is completely caught up, definitely queue. | |
// Otherwise, queue only button change events. | |
- if(!mouse.stall) | |
- if(mouse.wi == mouse.ri || mouse.last.buttons != b){ | |
- m = &mouse.last; | |
+ if(!c->mouse.stall) | |
+ if(c->mouse.wi == c->mouse.ri || c->mouse.last.buttons != b){ | |
+ m = &c->mouse.last; | |
m->xy.x = x; | |
m->xy.y = y; | |
m->buttons = b; | |
m->msec = ms; | |
- mouse.m[mouse.wi] = *m; | |
- if(++mouse.wi == nelem(mouse.m)) | |
- mouse.wi = 0; | |
- if(mouse.wi == mouse.ri){ | |
- mouse.stall = 1; | |
- mouse.ri = 0; | |
- mouse.wi = 1; | |
- mouse.m[0] = *m; | |
+ c->mouse.m[c->mouse.wi] = *m; | |
+ if(++c->mouse.wi == nelem(c->mouse.m)) | |
+ c->mouse.wi = 0; | |
+ if(c->mouse.wi == c->mouse.ri){ | |
+ c->mouse.stall = 1; | |
+ c->mouse.ri = 0; | |
+ c->mouse.wi = 1; | |
+ c->mouse.m[0] = *m; | |
} | |
- matchmouse(); | |
+ matchmouse(c); | |
} | |
- zunlock(); | |
+ qunlock(&c->inputlk); | |
} | |
void | |
-kputc(int c) | |
+kputc(Client *c, int ch) | |
{ | |
- zlock(); | |
- kbd.r[kbd.wi++] = c; | |
- if(kbd.wi == nelem(kbd.r)) | |
- kbd.wi = 0; | |
- if(kbd.ri == kbd.wi) | |
- kbd.stall = 1; | |
- matchkbd(); | |
- zunlock(); | |
+ qlock(&c->inputlk); | |
+ c->kbd.r[c->kbd.wi++] = ch; | |
+ if(c->kbd.wi == nelem(c->kbd.r)) | |
+ c->kbd.wi = 0; | |
+ if(c->kbd.ri == c->kbd.wi) | |
+ c->kbd.stall = 1; | |
+ matchkbd(c); | |
+ qunlock(&c->inputlk); | |
} | |
-static int alting; | |
- | |
void | |
-abortcompose(void) | |
+abortcompose(Client *c) | |
{ | |
- if(alting) | |
- keystroke(Kalt); | |
+ if(c->kbd.alting) | |
+ keystroke(c, Kalt); | |
} | |
void | |
-keystroke(int c) | |
+keystroke(Client *c, int ch) | |
{ | |
static Rune k[10]; | |
static int nk; | |
int i; | |
- if(c == Kalt){ | |
- alting = !alting; | |
+ if(ch == Kalt){ | |
+ c->kbd.alting = !c->kbd.alting; | |
nk = 0; | |
return; | |
} | |
- if(c == Kcmd+'r') { | |
- if(forcedpi) | |
- forcedpi = 0; | |
- else if(displaydpi >= 200) | |
- forcedpi = 100; | |
+ if(ch == Kcmd+'r') { | |
+ if(c->forcedpi) | |
+ c->forcedpi = 0; | |
+ else if(c->displaydpi >= 200) | |
+ c->forcedpi = 100; | |
else | |
- forcedpi = 225; | |
- resizeimg(); | |
+ c->forcedpi = 225; | |
+ resizeimg(c); | |
return; | |
} | |
- if(!alting){ | |
- kputc(c); | |
+ if(!c->kbd.alting){ | |
+ kputc(c, ch); | |
return; | |
} | |
if(nk >= nelem(k)) // should not happen | |
nk = 0; | |
- k[nk++] = c; | |
- c = _latin1(k, nk); | |
- if(c > 0){ | |
- alting = 0; | |
- kputc(c); | |
+ k[nk++] = ch; | |
+ ch = _latin1(k, nk); | |
+ if(ch > 0){ | |
+ c->kbd.alting = 0; | |
+ kputc(c, ch); | |
nk = 0; | |
return; | |
} | |
- if(c == -1){ | |
- alting = 0; | |
+ if(ch == -1){ | |
+ c->kbd.alting = 0; | |
for(i=0; i<nk; i++) | |
- kputc(k[i]); | |
+ kputc(c, k[i]); | |
nk = 0; | |
return; | |
} | |
diff --git a/src/cmd/devdraw/mkfile b/src/cmd/devdraw/mkfile | |
t@@ -16,7 +16,11 @@ WSYSOFILES=\ | |
OFILES=$WSYSOFILES | |
HFILES=\ | |
+ bigarrow.h\ | |
devdraw.h\ | |
+ glendapng.h\ | |
+ latin1.h\ | |
+ $WSYSHFILES\ | |
<$PLAN9/src/mkone | |
t@@ -40,7 +44,7 @@ $O.macargv: $MACARGV | |
%.$O: %.m | |
$CC $CFLAGS $OBJCFLAGS -o $target $stem.m | |
-CLEANFILES=$O.devdraw $O.macargv $O.mklatinkbd latin1.h | |
+CLEANFILES=$O.devdraw $O.macargv $O.drawclient $O.mklatinkbd latin1.h | |
install: mklatinkbd.install | |
install:Q: | |
diff --git a/src/cmd/devdraw/mkwsysrules.sh b/src/cmd/devdraw/mkwsysrules.sh | |
t@@ -51,9 +51,11 @@ if [ $WSYSTYPE = x11 ]; then | |
echo 'HFILES=$HFILES $XHFILES' | |
XO=`ls x11-*.c 2>/dev/null | sed 's/\.c$/.o/'` | |
echo 'WSYSOFILES=$WSYSOFILES '$XO | |
+ echo 'WSYSHFILES=x11-inc.h x11-keysym2ucs.h x11-memdraw.h' | |
elif [ $WSYSTYPE = mac ]; then | |
echo 'OBJCFLAGS=$OBJCFLAGS -fobjc-arc' | |
echo 'WSYSOFILES=$WSYSOFILES mac-draw.o mac-screen.o mac-srv.o' | |
+ echo 'WSYSHFILES=mac-screen.h' | |
echo 'MACARGV=macargv.o' | |
elif [ $WSYSTYPE = nowsys ]; then | |
echo 'WSYSOFILES=nowsys.o' | |
diff --git a/src/cmd/devdraw/mouseswap.c b/src/cmd/devdraw/mouseswap.c | |
t@@ -2,6 +2,11 @@ | |
#include <libc.h> | |
#include <draw.h> | |
#include <memdraw.h> | |
+#include <memlayer.h> | |
+#include <mouse.h> | |
+#include <cursor.h> | |
+#include <keyboard.h> | |
+#include <drawfcall.h> | |
#include "devdraw.h" | |
enum | |
diff --git a/src/cmd/devdraw/winsize.c b/src/cmd/devdraw/winsize.c | |
t@@ -2,6 +2,11 @@ | |
#include <libc.h> | |
#include <draw.h> | |
#include <memdraw.h> | |
+#include <memlayer.h> | |
+#include <mouse.h> | |
+#include <cursor.h> | |
+#include <keyboard.h> | |
+#include <drawfcall.h> | |
#include "devdraw.h" | |
int | |
diff --git a/src/cmd/devdraw/x11-init.c b/src/cmd/devdraw/x11-init.c | |
t@@ -6,6 +6,7 @@ | |
#include <libc.h> | |
#include <draw.h> | |
#include <memdraw.h> | |
+#include <memlayer.h> | |
#include <keyboard.h> | |
#include <mouse.h> | |
#include <cursor.h> | |
t@@ -232,7 +233,7 @@ _xattach(char *label, char *winsize) | |
if (XrmGetResource(database, "Xft.dpi", "String", &dpitype, &d… | |
if (dpires.addr) { | |
- displaydpi=atoi(dpires.addr); | |
+ client0->displaydpi = atoi(dpires.addr); | |
} | |
} | |
geom = smprint("%s.geometry", label); |