commit 88ed92aa40ab5aa0f563624c488ba2a120990329 from: Russ Cox date: Mon Jan 13 21:46:14 2020 UTC devdraw: move Client into devdraw.h and move global state in commit - 933b98054f40bb224acda134d7bb77a023bcc57f commit + 88ed92aa40ab5aa0f563624c488ba2a120990329 blob - a22dbe2bb4bd0bbe3f9e400b5ffde4c02b69e963 blob + dc0e0b72f9b7202654324c908c4e53a46397753f --- include/memdraw.h +++ include/memdraw.h @@ -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) } blob - 654ab4af6b3967ebd61931292b2c2176dc7c6b12 blob + e83f6f07bc4733dea0559faa404cc0b7f135895c --- src/cmd/devdraw/devdraw.c +++ src/cmd/devdraw/devdraw.c @@ -8,154 +8,32 @@ #include #include #include +#include +#include +#include +#include #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 name */ - 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 @@ -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 @@ -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*2waste*2flushrect, 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 */ @@ -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 @@ -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(; namename, str, n) == 0) return name; @@ -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; @@ -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; } @@ -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; @@ -466,9 +347,9 @@ drawinstallscreen(Client *client, DScreen *d, int id, 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++; @@ -479,18 +360,18 @@ drawinstallscreen(Client *client, DScreen *d, int id, 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; @@ -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 = */ @@ -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; @@ -540,13 +421,13 @@ drawfreedimage(DImage *dimage) return; /* any names? */ - for(i=0; inname; ) + if(client->name[i].dimage == dimage) + drawdelname(client, client->name+i); else i++; if(dimage->fromname){ /* acquired by name; owned by someone else*/ - drawfreedimage(dimage->fromname); + drawfreedimage(client, dimage->fromname); goto Return; } ds = dimage->dscreen; @@ -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 owner will clean up */ 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); @@ -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; } @@ -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; } } @@ -622,14 +503,14 @@ drawaddname(Client *client, DImage *di, int n, char *s DName *name, *ename, *new, *t; char *ns; - name = sdraw.name; - ename = &name[sdraw.nname]; + name = client->name; + ename = &name[client->nname]; for(; namename, 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); @@ -637,16 +518,16 @@ drawaddname(Client *client, DImage *di, int n, char *s *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; } @@ -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; @@ -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; @@ -790,7 +667,6 @@ _drawmsgwrite(void *v, int n) a = v; m = 0; oldn = n; - client = client0; while((n-=m) > 0){ a += m; @@ -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){ @@ -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); @@ -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] */ @@ -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+1, p.y+e1+j+1)); + dstflush(client, dstid, dst, Rect(p.x-e0-j, p.y-e1-j, p.x+e0+j+1, p.y+e1+j+1)); continue; /* free: 'f' id[4] */ @@ -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; @@ -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{ @@ -1102,10 +978,10 @@ _drawmsgwrite(void *v, int n) err = "unknown query"; goto error; case 'd': /* dpi */ - if(forcedpi) - fmtprint(&fmt, "%11d ", forcedpi); + if(client->forcedpi) + fmtprint(&fmt, "%11d ", client->forcedpi); else - fmtprint(&fmt, "%11d ", displaydpi); + fmtprint(&fmt, "%11d ", client->displaydpi); break; } } @@ -1169,7 +1045,7 @@ _drawmsgwrite(void *v, int n) if(dstid==0 || dst->layer!=nil){ /* BUG: this is terribly inefficient: update maximal containing rect*/ r = memlinebbox(p, q, e0, e1, j); - dstflush(dstid, dst, insetrect(r, -(1+1+j))); + dstflush(client, dstid, dst, insetrect(r, -(1+1+j))); } continue; @@ -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); @@ -1239,12 +1115,12 @@ _drawmsgwrite(void *v, int n) if(drawaddname(client, di, j, (char*)a+7, &err) < 0) 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; @@ -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); } @@ -1316,7 +1192,7 @@ _drawmsgwrite(void *v, int n) if(pp == nil) goto Enomem; doflush = 0; - if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data)) + if(dstid==0 || (dst->layer && dst->layer->screen->image->data == client->screenimage->data)) doflush = 1; /* simplify test in loop */ ox = oy = 0; esize = 0; @@ -1353,12 +1229,12 @@ _drawmsgwrite(void *v, int n) combinerect(&r, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1)); } if(rectclip(&r, dst->clipr)) /* should perhaps be an arg to dstflush */ - 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, p.x+esize+1, p.y+esize+1)); + dstflush(client, dstid, dst, Rect(p.x-esize, p.y-esize, p.x+esize+1, p.y+esize+1)); op = drawclientop(client); if(*a == 'p') mempoly(dst, pp, ni, e0, e1, j, src, sp, op); @@ -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->image->r))); + dstflush(client, dstid, dst, Rect(p.x, p.y, q.x, p.y+Dy(font->image->r))); continue; /* use public screen: 'S' id[4] chan[4] */ @@ -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!=client)) goto Enodrawscreen; if(dscrn->screen->image->chan != BGLONG(a+5)){ @@ -1522,9 +1398,9 @@ _drawmsgwrite(void *v, int n) memltofrontn(lp, nw); else memltorearn(lp, nw); - if(lp[0]->layer->screen->image->data == screenimage->data) + if(lp[0]->layer->screen->image->data == client->screenimage->data) for(j=0; jlayer->screenr); + addflush(client, lp[j]->layer->screenr); free(lp); ll = drawlookup(client, BGLONG(a+1+1+2), 1); drawrefreshscreen(ll, client); @@ -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] */ @@ -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; } blob - f768735f541fb5b392b84754a631af43b0b54dc3 blob + 40a2ed4e2d85e21de6c263a683b978ebb4b58333 --- src/cmd/devdraw/devdraw.h +++ src/cmd/devdraw/devdraw.h @@ -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 name */ + 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; blob - b5e3c70107ba82cd2020c2d9137d8d7950f3c519 blob + 7bc0920d8a8df1bfc7ce0191021a42fec1a7243d --- src/cmd/devdraw/mac-screen.h +++ src/cmd/devdraw/mac-screen.h @@ -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*); @@ -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); blob - c115f86787879635bfcc9163d2d8ae5f476dd2cc blob + b71f653d01faceeebe8271ebd89ec3277881a1f6 --- src/cmd/devdraw/mac-screen.m +++ src/cmd/devdraw/mac-screen.m @@ -15,10 +15,13 @@ #include #include #include -#include +#include +#include #include -#include "mac-screen.h" +#include +#include #include "devdraw.h" +#include "mac-screen.h" #include "bigarrow.h" #include "glendapng.h" @@ -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) @@ -48,6 +51,7 @@ usage(void) + (void)callsetcursor:(NSValue *)v; @end @interface DevDrawView : NSView +@property (nonatomic) Client *client; - (void)clearInput; - (void)getmouse:(NSEvent *)e; - (void)sendmouse:(NSUInteger)b; @@ -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{ @@ -113,7 +124,9 @@ callservep9p(void *v) { USED(v); - servep9p(); + client0->rfd = 3; + client0->wfd = 4; + servep9p(client0); [NSApp terminate:myApp]; } @@ -167,6 +180,7 @@ callservep9p(void *v) [win setDelegate:myApp]; myContent = [DevDrawView new]; + myContent.client = client0; [win setContentView:myContent]; [myContent setWantsLayer:YES]; [myContent setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawOnSetNeedsDisplay]; @@ -353,7 +367,7 @@ struct Cursors { - (void)windowDidResize:(NSNotification *)notification { if(![myContent inLiveResize] && img) { - resizeimg(); + resizeimg(myContent.client); } } @@ -463,7 +477,7 @@ struct Cursors { b |= 4; [self sendmouse:b]; }else if(m & ~omod & NSEventModifierFlagOption) - keystroke(Kalt); + keystroke(self.client, Kalt); omod = m; } @@ -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) @@ -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]; } @@ -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 @@ -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 characterAtIndex:i]); } 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, @@ -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); @@ -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); @@ -731,7 +745,7 @@ struct Cursors { k += Kcmd; } if(k>0) - keystroke(k); + keystroke(self.client, k); } // Helper for managing input rect approximately @@ -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); } } @@ -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 @@ -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; @@ -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) @@ -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"); @@ -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]; } blob - b0925eee5d210ea3f97663f77ce1380f1f1edd4d blob + 6727ef6318909fd8b1f28fcb801198665c24c086 --- src/cmd/devdraw/mac-srv.c +++ src/cmd/devdraw/mac-srv.c @@ -7,70 +7,23 @@ #include #include #include +#include #include #include #include #include -#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; +void runmsg(Client*, Wsysmsg*); +void replymsg(Client*, Wsysmsg*); +void matchkbd(Client*); +void matchmouse(Client*); -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); -} - int trace = 0; void -servep9p(void) +servep9p(Client *c) { uchar buf[4], *mbuf; int nmbuf, n, nn; @@ -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); @@ -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"); @@ -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, threadid(), &m); - 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); } /* @@ -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; @@ -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: @@ -166,7 +119,7 @@ runmsg(Wsysmsg *m) setcursor(nil, nil); else setcursor(&m->cursor, nil); - replymsg(m); + replymsg(c, m); break; case Tcursor2: @@ -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; } } @@ -240,7 +193,7 @@ runmsg(Wsysmsg *m) */ QLock replylock; void -replymsg(Wsysmsg *m) +replymsg(Client *c, Wsysmsg *m) { int n; static uchar *mbuf; @@ -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); } @@ -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); } } @@ -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/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' blob - 29f33b7bfbc53e90d61e390d4425e8fa76af9d4f blob + d2dea666953793624f0393be0b04f5f3e137b8c8 --- src/cmd/devdraw/mouseswap.c +++ src/cmd/devdraw/mouseswap.c @@ -2,6 +2,11 @@ #include #include #include +#include +#include +#include +#include +#include #include "devdraw.h" enum blob - 375401bf0812c59c5fca50e519953fcc811841d5 blob + 7d0a7b70ba76dafd132437f0c74821e00c6917b3 --- src/cmd/devdraw/winsize.c +++ src/cmd/devdraw/winsize.c @@ -2,6 +2,11 @@ #include #include #include +#include +#include +#include +#include +#include #include "devdraw.h" int blob - 8935c9d15a1ebad457a251fb41cddbd0d4d4bc92 blob + 4b5b570d240b272f51caa10e0ed88a78a2913a3c --- src/cmd/devdraw/x11-init.c +++ src/cmd/devdraw/x11-init.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -232,7 +233,7 @@ _xattach(char *label, char *winsize) if (XrmGetResource(database, "Xft.dpi", "String", &dpitype, &dpires) == True) { if (dpires.addr) { - displaydpi=atoi(dpires.addr); + client0->displaydpi = atoi(dpires.addr); } } geom = smprint("%s.geometry", label);