| @@ -15,6 +15,7 @@ enum · 14 unmodified lines |
| 15 | 15 | { |
| 16 | 16 | Qtopdir = 0, |
| 17 | 17 | Qnew, |
| 18 | + Qwinname, |
| 18 | 19 | Q3rd, |
| 19 | 20 | Q2nd, |
| 20 | 21 | Qcolormap, |
| @@ -36,7 +37,7 @@ enum · 15 unmodified lines |
| 36 | 37 | |
| 37 | 38 | #define NHASH (1<<5) |
| 38 | 39 | #define HASHMASK (NHASH-1) |
| 39 | | −#define IOUNIT (64*1024) |
| 40 | +#define IOUNIT (64*1024) |
| 40 | 41 | |
| 41 | 42 | typedef struct Client Client; |
| 42 | 43 | typedef struct Draw Draw; |
| @@ -52,17 +53,15 @@ ulong blanktime = 30; /* in minutes; a half hour */ · 9 unmodified lines |
| 52 | 53 | |
| 53 | 54 | struct Draw |
| 54 | 55 | { |
| 55 | | − QLock lk; |
| 56 | 56 | int clientid; |
| 57 | 57 | int nclient; |
| 58 | 58 | Client** client; |
| 59 | 59 | int nname; |
| 60 | | − DName* name; |
| 60 | + DName* name; |
| 61 | 61 | int vers; |
| 62 | 62 | int softscreen; |
| 63 | 63 | int blanked; /* screen turned off */ |
| 64 | 64 | ulong blanktime; /* time of last operation */ |
| 65 | | − ulong savemap[3*256]; |
| 66 | 65 | }; |
| 67 | 66 | |
| 68 | 67 | struct Client |
| @@ -72,6 +71,7 @@ struct Client · 3 unmodified lines |
| 72 | 71 | CScreen* cscreen; |
| 73 | 72 | Refresh* refresh; |
| 74 | 73 | Rendez refrend; |
| 74 | + QLock refq; |
| 75 | 75 | uchar* readdata; |
| 76 | 76 | int nreaddata; |
| 77 | 77 | int busy; |
| @@ -97,10 +97,10 @@ struct Refx · 19 unmodified lines |
| 97 | 97 | |
| 98 | 98 | struct DName |
| 99 | 99 | { |
| 100 | | − char *name; |
| 101 | | − Client *client; |
| 100 | + char *name; |
| 101 | + Client *client; |
| 102 | 102 | DImage* dimage; |
| 103 | | − int vers; |
| 103 | + int vers; |
| 104 | 104 | }; |
| 105 | 105 | |
| 106 | 106 | struct FChar |
| @@ -130,7 +130,7 @@ struct DImage · 23 unmodified lines |
| 130 | 130 | int nfchar; |
| 131 | 131 | FChar* fchar; |
| 132 | 132 | DScreen* dscreen; /* 0 if not a window */ |
| 133 | | − DImage* fromname; /* image this one is derived from, by name */ |
| 133 | + DImage* fromname; /* image this one is derived from, by name */ |
| 134 | 134 | DImage* next; |
| 135 | 135 | }; |
| 136 | 136 | |
| @@ -145,16 +145,21 @@ struct DScreen · 8 unmodified lines |
| 145 | 145 | int id; |
| 146 | 146 | int public; |
| 147 | 147 | int ref; |
| 148 | | − DImage *dimage; |
| 149 | | − DImage *dfill; |
| 148 | + DImage *dimage; |
| 149 | + DImage *dfill; |
| 150 | 150 | Memscreen* screen; |
| 151 | 151 | Client* owner; |
| 152 | 152 | DScreen* next; |
| 153 | 153 | }; |
| 154 | 154 | |
| 155 | 155 | static Draw sdraw; |
| 156 | + QLock drawlock; |
| 157 | + |
| 156 | 158 | static Memimage *screenimage; |
| 157 | | −static Memdata screendata; |
| 159 | +static DImage* screendimage; |
| 160 | +static char screenname[40]; |
| 161 | +static int screennameid; |
| 162 | + |
| 158 | 163 | static Rectangle flushrect; |
| 159 | 164 | static int waste; |
| 160 | 165 | static DScreen* dscreen; |
| @@ -163,6 +168,7 @@ extern void flushmemscreen(Rectangle); · 2 unmodified lines |
| 163 | 168 | void drawuninstall(Client*, int); |
| 164 | 169 | void drawfreedimage(DImage*); |
| 165 | 170 | Client* drawclientofpath(ulong); |
| 171 | + DImage* allocdimage(Memimage*); |
| 166 | 172 | |
| 167 | 173 | static char Enodrawimage[] = "unknown id for draw image"; |
| 168 | 174 | static char Enodrawscreen[] = "unknown id for draw screen"; |
| @@ -176,42 +182,35 @@ static char Ewriteoutside[] = "writeimage outside image"; · 7 unmodified lines |
| 176 | 182 | static char Enotfont[] = "image not a font"; |
| 177 | 183 | static char Eindex[] = "character index out of range"; |
| 178 | 184 | static char Enoclient[] = "no such draw client"; |
| 179 | | −/* static char Edepth[] = "image has bad depth"; */ |
| 180 | 185 | static char Enameused[] = "image name in use"; |
| 181 | 186 | static char Enoname[] = "no image with that name"; |
| 182 | 187 | static char Eoldname[] = "named image no longer valid"; |
| 183 | 188 | static char Enamed[] = "image already has name"; |
| 184 | 189 | static char Ewrongname[] = "wrong name for image"; |
| 185 | 190 | |
| 186 | | −int |
| 187 | | −drawcanqlock(void) |
| 188 | | −{ |
| 189 | | − return canqlock(&sdraw.lk); |
| 190 | | −} |
| 191 | | − |
| 192 | | −void |
| 193 | | −drawqlock(void) |
| 191 | +static void |
| 192 | +dlock(void) |
| 194 | 193 | { |
| 195 | | − qlock(&sdraw.lk); |
| 194 | + qlock(&drawlock); |
| 196 | 195 | } |
| 197 | 196 | |
| 198 | | −void |
| 199 | | −drawqunlock(void) |
| 197 | +static void |
| 198 | +dunlock(void) |
| 200 | 199 | { |
| 201 | | − qunlock(&sdraw.lk); |
| 200 | + qunlock(&drawlock); |
| 202 | 201 | } |
| 203 | 202 | |
| 204 | 203 | static int |
| 205 | | −drawgen(Chan *c, char *name, Dirtab *dt, int ndt, int s, Dir *dp) |
| 204 | +drawgen(Chan *c, char *n, Dirtab *d, int nd, int s, Dir *dp) |
| 206 | 205 | { |
| 207 | 206 | int t; |
| 208 | 207 | Qid q; |
| 209 | 208 | ulong path; |
| 210 | 209 | Client *cl; |
| 211 | 210 | |
| 212 | | − USED(name); |
| 213 | | − USED(dt); |
| 214 | | − USED(ndt); |
| 211 | + USED(n); |
| 212 | + USED(d); |
| 213 | + USED(nd); |
| 215 | 214 | |
| 216 | 215 | q.vers = 0; |
| 217 | 216 | |
| @@ -241,15 +240,17 @@ drawgen(Chan *c, char *name, Dirtab *dt, int ndt, int s, Dir *dp) · 23 unmodified lines |
| 241 | 240 | * Top level directory contains the name of the device. |
| 242 | 241 | */ |
| 243 | 242 | t = QID(c->qid); |
| 244 | | − if(t == Qtopdir){ |
| 245 | | − switch(s){ |
| 246 | | − case 0: |
| 243 | + if(t == Qtopdir || t == Qwinname){ |
| 244 | + if(s == 1 || t == Qwinname){ |
| 245 | + mkqid(&q, Qwinname, 0, QTFILE); |
| 246 | + devdir(c, q, "winname", 0, eve, 0444, dp); |
| 247 | + } |
| 248 | + else if(s == 0){ |
| 247 | 249 | mkqid(&q, Q2nd, 0, QTDIR); |
| 248 | 250 | devdir(c, q, "draw", 0, eve, 0555, dp); |
| 249 | | − break; |
| 250 | | − default: |
| 251 | | − return -1; |
| 252 | 251 | } |
| 252 | + else |
| 253 | + return -1; |
| 253 | 254 | return 1; |
| 254 | 255 | } |
| 255 | 256 | |
| @@ -326,14 +327,14 @@ drawrefreshscreen(DImage *l, Client *client) · 70 unmodified lines |
| 326 | 327 | |
| 327 | 328 | static |
| 328 | 329 | void |
| 329 | | −drawrefresh(Memimage *m, Rectangle r, void *v) |
| 330 | +drawrefresh(Memimage *i, Rectangle r, void *v) |
| 330 | 331 | { |
| 331 | 332 | Refx *x; |
| 332 | 333 | DImage *d; |
| 333 | 334 | Client *c; |
| 334 | 335 | Refresh *ref; |
| 335 | 336 | |
| 336 | | − USED(m); |
| 337 | + USED(i); |
| 337 | 338 | |
| 338 | 339 | if(v == 0) |
| 339 | 340 | return; |
| @@ -360,9 +361,8 @@ addflush(Rectangle r) · 20 unmodified lines |
| 360 | 361 | int abb, ar, anbb; |
| 361 | 362 | Rectangle nbb; |
| 362 | 363 | |
| 363 | | − if(sdraw.softscreen==0 || !rectclip(&r, screenimage->r)) |
| 364 | + if(sdraw.softscreen==0 || screenimage == nil || !rectclip(&r, screenimage->r)) |
| 364 | 365 | return; |
| 365 | | − |
| 366 | 366 | if(flushrect.min.x >= flushrect.max.x){ |
| 367 | 367 | flushrect = r; |
| 368 | 368 | waste = 0; |
| @@ -408,13 +408,7 @@ dstflush(int dstid, Memimage *dst, Rectangle r) · 39 unmodified lines |
| 408 | 408 | combinerect(&flushrect, r); |
| 409 | 409 | return; |
| 410 | 410 | } |
| 411 | | − /* how can this happen? -rsc, dec 12 2002 */ |
| 412 | | − if(dst == 0){ |
| 413 | | − print("nil dstflush\n"); |
| 414 | | − return; |
| 415 | | − } |
| 416 | | − l = dst->layer; |
| 417 | | − if(l == nil) |
| 411 | + if(screenimage == nil || dst == nil || (l = dst->layer) == nil) |
| 418 | 412 | return; |
| 419 | 413 | do{ |
| 420 | 414 | if(l->screen->image->data != screenimage->data) |
| @@ -428,20 +422,11 @@ dstflush(int dstid, Memimage *dst, Rectangle r) · 7 unmodified lines |
| 428 | 422 | void |
| 429 | 423 | drawflush(void) |
| 430 | 424 | { |
| 431 | | − if(flushrect.min.x < flushrect.max.x) |
| 425 | + if(screenimage && flushrect.min.x < flushrect.max.x) |
| 432 | 426 | flushmemscreen(flushrect); |
| 433 | 427 | flushrect = Rect(10000, 10000, -10000, -10000); |
| 434 | 428 | } |
| 435 | 429 | |
| 436 | | −void |
| 437 | | −drawflushr(Rectangle r) |
| 438 | | −{ |
| 439 | | − qlock(&sdraw.lk); |
| 440 | | − flushmemscreen(r); |
| 441 | | − qunlock(&sdraw.lk); |
| 442 | | −} |
| 443 | | − |
| 444 | | −static |
| 445 | 430 | int |
| 446 | 431 | drawcmp(char *a, char *b, int n) |
| 447 | 432 | { |
| @@ -529,15 +514,14 @@ drawlookupscreen(Client *client, int id, CScreen **cs) · 81 unmodified lines |
| 529 | 514 | return 0; |
| 530 | 515 | } |
| 531 | 516 | |
| 532 | | −Memimage* |
| 533 | | −drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen) |
| 517 | +DImage* |
| 518 | +allocdimage(Memimage *i) |
| 534 | 519 | { |
| 535 | 520 | DImage *d; |
| 536 | 521 | |
| 537 | 522 | d = malloc(sizeof(DImage)); |
| 538 | 523 | if(d == 0) |
| 539 | 524 | return 0; |
| 540 | | − d->id = id; |
| 541 | 525 | d->ref = 1; |
| 542 | 526 | d->name = 0; |
| 543 | 527 | d->vers = 0; |
| @@ -545,6 +529,18 @@ drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen) · 1 unmodified line |
| 545 | 529 | d->nfchar = 0; |
| 546 | 530 | d->fchar = 0; |
| 547 | 531 | d->fromname = 0; |
| 532 | + return d; |
| 533 | +} |
| 534 | + |
| 535 | +Memimage* |
| 536 | +drawinstall(Client *client, int id, Memimage *i, DScreen *dscreen) |
| 537 | +{ |
| 538 | + DImage *d; |
| 539 | + |
| 540 | + d = allocdimage(i); |
| 541 | + if(d == 0) |
| 542 | + return 0; |
| 543 | + d->id = id; |
| 548 | 544 | d->dscreen = dscreen; |
| 549 | 545 | d->next = client->dimage[id&HASHMASK]; |
| 550 | 546 | client->dimage[id&HASHMASK] = d; |
| @@ -607,6 +603,7 @@ drawdelname(DName *name) · 56 unmodified lines |
| 607 | 603 | { |
| 608 | 604 | int i; |
| 609 | 605 | |
| 606 | + free(name->name); |
| 610 | 607 | i = name-sdraw.name; |
| 611 | 608 | memmove(name, name+1, (sdraw.nname-(i+1))*sizeof(DName)); |
| 612 | 609 | sdraw.nname--; |
| @@ -627,7 +624,7 @@ drawfreedscreen(DScreen *this) · 14 unmodified lines |
| 627 | 624 | dscreen = this->next; |
| 628 | 625 | goto Found; |
| 629 | 626 | } |
| 630 | | − while((next = ds->next)){ /* assign = */ |
| 627 | + while(next = ds->next){ /* assign = */ |
| 631 | 628 | if(next == this){ |
| 632 | 629 | ds->next = this->next; |
| 633 | 630 | goto Found; |
| @@ -668,12 +665,10 @@ drawfreedimage(DImage *dimage) · 34 unmodified lines |
| 668 | 665 | drawfreedimage(dimage->fromname); |
| 669 | 666 | goto Return; |
| 670 | 667 | } |
| 671 | | − if(dimage->image == screenimage) /* don't free the display */ |
| 672 | | − goto Return; |
| 673 | 668 | ds = dimage->dscreen; |
| 674 | 669 | if(ds){ |
| 675 | 670 | l = dimage->image; |
| 676 | | − if(l->data == screenimage->data) |
| 671 | + if(screenimage && l->data == screenimage->data) |
| 677 | 672 | addflush(l->layer->screenr); |
| 678 | 673 | if(l->layer->refreshfn == drawrefresh) /* else true owner will clean up */ |
| 679 | 674 | free(l->layer->refreshptr); |
| @@ -702,7 +697,7 @@ drawuninstallscreen(Client *client, CScreen *this) · 22 unmodified lines |
| 702 | 697 | free(this); |
| 703 | 698 | return; |
| 704 | 699 | } |
| 705 | | − while((next = cs->next)){ /* assign = */ |
| 700 | + while(next = cs->next){ /* assign = */ |
| 706 | 701 | if(next == this){ |
| 707 | 702 | cs->next = this->next; |
| 708 | 703 | drawfreedscreen(this->dscreen); |
| @@ -726,7 +721,7 @@ drawuninstall(Client *client, int id) · 17 unmodified lines |
| 726 | 721 | drawfreedimage(d); |
| 727 | 722 | return; |
| 728 | 723 | } |
| 729 | | − while((next = d->next)){ /* assign = */ |
| 724 | + while(next = d->next){ /* assign = */ |
| 730 | 725 | if(next->id == id){ |
| 731 | 726 | d->next = next->next; |
| 732 | 727 | drawfreedimage(next); |
| @@ -867,12 +862,8 @@ drawpoint(Point *p, uchar *a) · 134 unmodified lines |
| 867 | 862 | p->y = BGLONG(a+1*4); |
| 868 | 863 | } |
| 869 | 864 | |
| 870 | | −#define isvgascreen(dst) 1 |
| 871 | | − |
| 872 | | − |
| 873 | 865 | Point |
| 874 | | −drawchar(Memimage *dst, Memimage *rdst, Point p, |
| 875 | | − Memimage *src, Point *sp, DImage *font, int index, int op) |
| 866 | +drawchar(Memimage *dst, Memimage *rdst, Point p, Memimage *src, Point *sp, DImage *font, int index, int op) |
| 876 | 867 | { |
| 877 | 868 | FChar *fc; |
| 878 | 869 | Rectangle r; |
| @@ -886,7 +877,7 @@ drawchar(Memimage *dst, Memimage *rdst, Point p, · 7 unmodified lines |
| 886 | 877 | r.max.y = r.min.y+(fc->maxy-fc->miny); |
| 887 | 878 | sp1.x = sp->x+fc->left; |
| 888 | 879 | sp1.y = sp->y+fc->miny; |
| 889 | | − |
| 880 | + |
| 890 | 881 | /* |
| 891 | 882 | * If we're drawing greyscale fonts onto a VGA screen, |
| 892 | 883 | * it's very costly to read the screen memory to do the |
| @@ -895,7 +886,7 @@ drawchar(Memimage *dst, Memimage *rdst, Point p, · 2 unmodified lines |
| 895 | 886 | * refer to for the underlying dst pixels instead of reading dst |
| 896 | 887 | * directly. |
| 897 | 888 | */ |
| 898 | | − if(1 || (isvgascreen(dst) && !isvgascreen(rdst) /*&& font->image->depth > 1*/)){ |
| 889 | + if(ishwimage(dst) && !ishwimage(rdst) && font->image->depth > 1){ |
| 899 | 890 | if(tmp == nil || tmp->chan != dst->chan || Dx(tmp->r) < Dx(r) || Dy(tmp->r) < Dy(r)){ |
| 900 | 891 | if(tmp) |
| 901 | 892 | freememimage(tmp); |
| @@ -916,60 +907,112 @@ drawchar(Memimage *dst, Memimage *rdst, Point p, · 14 unmodified lines |
| 916 | 907 | return p; |
| 917 | 908 | } |
| 918 | 909 | |
| 919 | | −static int |
| 920 | | −initscreenimage(void) |
| 910 | +static DImage* |
| 911 | +makescreenimage(void) |
| 921 | 912 | { |
| 922 | 913 | int width, depth; |
| 923 | 914 | ulong chan; |
| 915 | + DImage *di; |
| 916 | + Memdata *md; |
| 917 | + Memimage *i; |
| 924 | 918 | Rectangle r; |
| 919 | + uchar *data; |
| 925 | 920 | |
| 926 | | − if(screenimage != nil) |
| 927 | | − return 1; |
| 921 | + if((data = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen)) == nil) |
| 922 | + return nil; |
| 923 | + if(sdraw.softscreen == 0xa110c){ |
| 924 | + /* hack: softscreen is memimage. */ |
| 925 | + md = *((Memdata**)(data - sizeof(ulong) - sizeof(Memdata*))); |
| 928 | 926 | |
| 929 | | − screendata.base = nil; |
| 930 | | − screendata.bdata = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen); |
| 931 | | − if(screendata.bdata == nil) |
| 932 | | − return 0; |
| 933 | | − screendata.ref = 1; |
| 927 | + assert(md->bdata == data); |
| 928 | + assert(md->ref > 1); |
| 929 | + assert(md->allocd); |
| 934 | 930 | |
| 935 | | − screenimage = allocmemimaged(r, chan, &screendata); |
| 936 | | − if(screenimage == nil){ |
| 937 | | − /* RSC: BUG: detach screen */ |
| 938 | | − return 0; |
| 931 | + if((i = allocmemimaged(r, chan, md)) == nil){ |
| 932 | + md->ref--; |
| 933 | + return nil; |
| 934 | + } |
| 935 | + }else{ |
| 936 | + if((md = malloc(sizeof *md)) == nil) |
| 937 | + return nil; |
| 938 | + md->allocd = 1; |
| 939 | + md->base = nil; |
| 940 | + md->bdata = data; |
| 941 | + md->ref = 1; |
| 942 | + if((i = allocmemimaged(r, chan, md)) == nil){ |
| 943 | + free(md); |
| 944 | + return nil; |
| 945 | + } |
| 946 | + } |
| 947 | + i->width = width; |
| 948 | + i->clipr = r; |
| 949 | + di = allocdimage(i); |
| 950 | + if(di == nil){ |
| 951 | + freememimage(i); /* frees md */ |
| 952 | + return nil; |
| 953 | + } |
| 954 | + if(!waserror()){ |
| 955 | + snprint(screenname, sizeof screenname, "noborder.screen.%d", ++screennameid); |
| 956 | + drawaddname(nil, di, strlen(screenname), screenname); |
| 957 | + poperror(); |
| 939 | 958 | } |
| 959 | + return di; |
| 960 | +} |
| 940 | 961 | |
| 941 | | − screenimage->width = width; |
| 942 | | − screenimage->clipr = r; |
| 962 | +static int |
| 963 | +initscreenimage(void) |
| 964 | +{ |
| 965 | + if(screenimage != nil) |
| 966 | + return 1; |
| 967 | + |
| 968 | + screendimage = makescreenimage(); |
| 969 | + if(screendimage == nil) |
| 970 | + return 0; |
| 971 | + screenimage = screendimage->image; |
| 972 | +// iprint("initscreenimage %p %p\n", screendimage, screenimage); |
| 943 | 973 | return 1; |
| 944 | 974 | } |
| 945 | 975 | |
| 946 | 976 | void |
| 947 | 977 | deletescreenimage(void) |
| 948 | 978 | { |
| 949 | | − qlock(&sdraw.lk); |
| 950 | | − /* RSC: BUG: detach screen */ |
| 951 | | − if(screenimage) |
| 952 | | − freememimage(screenimage); |
| 953 | | − screenimage = nil; |
| 954 | | − qunlock(&sdraw.lk); |
| 979 | + dlock(); |
| 980 | + if(screenimage){ |
| 981 | + /* will be freed via screendimage; disable */ |
| 982 | + screenimage->clipr = ZR; |
| 983 | + screenimage = nil; |
| 984 | + } |
| 985 | + if(screendimage){ |
| 986 | + drawfreedimage(screendimage); |
| 987 | + screendimage = nil; |
| 988 | + } |
| 989 | + dunlock(); |
| 990 | +} |
| 991 | + |
| 992 | +void |
| 993 | +resetscreenimage(void) |
| 994 | +{ |
| 995 | + dlock(); |
| 996 | + initscreenimage(); |
| 997 | + dunlock(); |
| 955 | 998 | } |
| 956 | 999 | |
| 957 | 1000 | static Chan* |
| 958 | 1001 | drawattach(char *spec) |
| 959 | 1002 | { |
| 960 | | − qlock(&sdraw.lk); |
| 1003 | + dlock(); |
| 961 | 1004 | if(!initscreenimage()){ |
| 962 | | − qunlock(&sdraw.lk); |
| 1005 | + dunlock(); |
| 963 | 1006 | error("no frame buffer"); |
| 964 | 1007 | } |
| 965 | | − qunlock(&sdraw.lk); |
| 1008 | + dunlock(); |
| 966 | 1009 | return devattach('i', spec); |
| 967 | 1010 | } |
| 968 | 1011 | |
| 969 | 1012 | static Walkqid* |
| 970 | 1013 | drawwalk(Chan *c, Chan *nc, char **name, int nname) |
| 971 | 1014 | { |
| 972 | | − if(screendata.bdata == nil) |
| 1015 | + if(screenimage == nil) |
| 973 | 1016 | error("no frame buffer"); |
| 974 | 1017 | return devwalk(c, nc, name, nname, 0, 0, drawgen); |
| 975 | 1018 | } |
| @@ -984,15 +1027,17 @@ static Chan* · 8 unmodified lines |
| 984 | 1027 | drawopen(Chan *c, int omode) |
| 985 | 1028 | { |
| 986 | 1029 | Client *cl; |
| 1030 | + DName *dn; |
| 1031 | + DImage *di; |
| 987 | 1032 | |
| 988 | 1033 | if(c->qid.type & QTDIR){ |
| 989 | 1034 | c = devopen(c, omode, 0, 0, drawgen); |
| 990 | 1035 | c->iounit = IOUNIT; |
| 991 | 1036 | } |
| 992 | 1037 | |
| 993 | | − qlock(&sdraw.lk); |
| 1038 | + dlock(); |
| 994 | 1039 | if(waserror()){ |
| 995 | | − qunlock(&sdraw.lk); |
| 1040 | + dunlock(); |
| 996 | 1041 | nexterror(); |
| 997 | 1042 | } |
| 998 | 1043 | |
| @@ -1004,6 +1049,9 @@ drawopen(Chan *c, int omode) · 5 unmodified lines |
| 1004 | 1049 | } |
| 1005 | 1050 | |
| 1006 | 1051 | switch(QID(c->qid)){ |
| 1052 | + case Qwinname: |
| 1053 | + break; |
| 1054 | + |
| 1007 | 1055 | case Qnew: |
| 1008 | 1056 | break; |
| 1009 | 1057 | |
| @@ -1013,9 +1061,22 @@ drawopen(Chan *c, int omode) · 3 unmodified lines |
| 1013 | 1061 | error(Einuse); |
| 1014 | 1062 | cl->busy = 1; |
| 1015 | 1063 | flushrect = Rect(10000, 10000, -10000, -10000); |
| 1016 | | − drawinstall(cl, 0, screenimage, 0); |
| 1064 | + dn = drawlookupname(strlen(screenname), screenname); |
| 1065 | + if(dn == 0) |
| 1066 | + error("draw: cannot happen 2"); |
| 1067 | + if(drawinstall(cl, 0, dn->dimage->image, 0) == 0) |
| 1068 | + error(Edrawmem); |
| 1069 | + di = drawlookup(cl, 0, 0); |
| 1070 | + if(di == 0) |
| 1071 | + error("draw: cannot happen 1"); |
| 1072 | + di->vers = dn->vers; |
| 1073 | + di->name = smalloc(strlen(screenname)+1); |
| 1074 | + strcpy(di->name, screenname); |
| 1075 | + di->fromname = dn->dimage; |
| 1076 | + di->fromname->ref++; |
| 1017 | 1077 | incref(&cl->r); |
| 1018 | 1078 | break; |
| 1079 | + |
| 1019 | 1080 | case Qcolormap: |
| 1020 | 1081 | case Qdata: |
| 1021 | 1082 | case Qrefresh: |
| @@ -1023,7 +1084,7 @@ drawopen(Chan *c, int omode) · 1 unmodified line |
| 1023 | 1084 | incref(&cl->r); |
| 1024 | 1085 | break; |
| 1025 | 1086 | } |
| 1026 | | − qunlock(&sdraw.lk); |
| 1087 | + dunlock(); |
| 1027 | 1088 | poperror(); |
| 1028 | 1089 | c->mode = openmode(omode); |
| 1029 | 1090 | c->flag |= COPEN; |
| @@ -1042,9 +1103,9 @@ drawclose(Chan *c) · 12 unmodified lines |
| 1042 | 1103 | |
| 1043 | 1104 | if(QID(c->qid) < Qcolormap) /* Qtopdir, Qnew, Q3rd, Q2nd have no client */ |
| 1044 | 1105 | return; |
| 1045 | | − qlock(&sdraw.lk); |
| 1106 | + dlock(); |
| 1046 | 1107 | if(waserror()){ |
| 1047 | | − qunlock(&sdraw.lk); |
| 1108 | + dunlock(); |
| 1048 | 1109 | nexterror(); |
| 1049 | 1110 | } |
| 1050 | 1111 | |
| @@ -1052,7 +1113,7 @@ drawclose(Chan *c) · 1 unmodified line |
| 1052 | 1113 | if(QID(c->qid) == Qctl) |
| 1053 | 1114 | cl->busy = 0; |
| 1054 | 1115 | if((c->flag&COPEN) && (decref(&cl->r)==0)){ |
| 1055 | | − while((r = cl->refresh)){ /* assign = */ |
| 1116 | + while(r = cl->refresh){ /* assign = */ |
| 1056 | 1117 | cl->refresh = r->next; |
| 1057 | 1118 | free(r); |
| 1058 | 1119 | } |
| @@ -1077,7 +1138,7 @@ drawclose(Chan *c) · 18 unmodified lines |
| 1077 | 1138 | drawflush(); /* to erase visible, now dead windows */ |
| 1078 | 1139 | free(cl); |
| 1079 | 1140 | } |
| 1080 | | − qunlock(&sdraw.lk); |
| 1141 | + dunlock(); |
| 1081 | 1142 | poperror(); |
| 1082 | 1143 | } |
| 1083 | 1144 | |
| @@ -1096,10 +1157,13 @@ drawread(Chan *c, void *a, long n, vlong off) · 12 unmodified lines |
| 1096 | 1157 | |
| 1097 | 1158 | if(c->qid.type & QTDIR) |
| 1098 | 1159 | return devdirread(c, a, n, 0, 0, drawgen); |
| 1160 | + if(QID(c->qid) == Qwinname) |
| 1161 | + return readstr(off, a, n, screenname); |
| 1162 | + |
| 1099 | 1163 | cl = drawclient(c); |
| 1100 | | − qlock(&sdraw.lk); |
| 1164 | + dlock(); |
| 1101 | 1165 | if(waserror()){ |
| 1102 | | − qunlock(&sdraw.lk); |
| 1166 | + dunlock(); |
| 1103 | 1167 | nexterror(); |
| 1104 | 1168 | } |
| 1105 | 1169 | switch(QID(c->qid)){ |
| @@ -1118,15 +1182,15 @@ drawread(Chan *c, void *a, long n, vlong off) · 12 unmodified lines |
| 1118 | 1182 | error(Enodrawimage); |
| 1119 | 1183 | i = di->image; |
| 1120 | 1184 | } |
| 1121 | | − n = sprint(a, "%11d %11d %11s %11d %11d %11d %11d %11d %11d %11d %11d %11d ", |
| 1185 | + n = sprint(a, "%11d %11d %11s %11d %11d %11d %11d %11d %11d %11d %11d %11d", |
| 1122 | 1186 | cl->clientid, cl->infoid, chantostr(buf, i->chan), (i->flags&Frepl)==Frepl, |
| 1123 | 1187 | i->r.min.x, i->r.min.y, i->r.max.x, i->r.max.y, |
| 1124 | 1188 | i->clipr.min.x, i->clipr.min.y, i->clipr.max.x, i->clipr.max.y); |
| 1189 | + ((char*)a)[n++] = ' '; |
| 1125 | 1190 | cl->infoid = -1; |
| 1126 | 1191 | break; |
| 1127 | 1192 | |
| 1128 | 1193 | case Qcolormap: |
| 1129 | | − drawactive(1); /* to restore map from backup */ |
| 1130 | 1194 | p = malloc(4*12*256+1); |
| 1131 | 1195 | if(p == 0) |
| 1132 | 1196 | error(Enomem); |
| @@ -1156,14 +1220,21 @@ drawread(Chan *c, void *a, long n, vlong off) · 23 unmodified lines |
| 1156 | 1220 | for(;;){ |
| 1157 | 1221 | if(cl->refreshme || cl->refresh) |
| 1158 | 1222 | break; |
| 1159 | | − qunlock(&sdraw.lk); |
| 1223 | + dunlock(); |
| 1160 | 1224 | if(waserror()){ |
| 1161 | | − qlock(&sdraw.lk); /* restore lock for waserror() above */ |
| 1225 | + dlock(); |
| 1226 | + nexterror(); |
| 1227 | + } |
| 1228 | + qlock(&cl->refq); |
| 1229 | + if(waserror()){ |
| 1230 | + qunlock(&cl->refq); |
| 1162 | 1231 | nexterror(); |
| 1163 | 1232 | } |
| 1164 | 1233 | sleep(&cl->refrend, drawrefactive, cl); |
| 1165 | 1234 | poperror(); |
| 1166 | | − qlock(&sdraw.lk); |
| 1235 | + qunlock(&cl->refq); |
| 1236 | + poperror(); |
| 1237 | + dlock(); |
| 1167 | 1238 | } |
| 1168 | 1239 | p = a; |
| 1169 | 1240 | while(cl->refresh && n>=5*4){ |
| @@ -1180,8 +1251,9 @@ drawread(Chan *c, void *a, long n, vlong off) · 10 unmodified lines |
| 1180 | 1251 | } |
| 1181 | 1252 | cl->refreshme = 0; |
| 1182 | 1253 | n = p-(uchar*)a; |
| 1254 | + break; |
| 1183 | 1255 | } |
| 1184 | | − qunlock(&sdraw.lk); |
| 1256 | + dunlock(); |
| 1185 | 1257 | poperror(); |
| 1186 | 1258 | return n; |
| 1187 | 1259 | } |
| @@ -1200,21 +1272,21 @@ drawwakeall(void) · 12 unmodified lines |
| 1200 | 1272 | } |
| 1201 | 1273 | |
| 1202 | 1274 | static long |
| 1203 | | −drawwrite(Chan *c, void *a, long n, vlong offset) |
| 1275 | +drawwrite(Chan *c, void *a, long n, vlong off) |
| 1204 | 1276 | { |
| 1205 | 1277 | char buf[128], *fields[4], *q; |
| 1206 | 1278 | Client *cl; |
| 1207 | 1279 | int i, m, red, green, blue, x; |
| 1208 | 1280 | |
| 1209 | | − USED(offset); |
| 1281 | + USED(off); |
| 1210 | 1282 | |
| 1211 | 1283 | if(c->qid.type & QTDIR) |
| 1212 | 1284 | error(Eisdir); |
| 1213 | 1285 | cl = drawclient(c); |
| 1214 | | − qlock(&sdraw.lk); |
| 1286 | + dlock(); |
| 1215 | 1287 | if(waserror()){ |
| 1216 | 1288 | drawwakeall(); |
| 1217 | | − qunlock(&sdraw.lk); |
| 1289 | + dunlock(); |
| 1218 | 1290 | nexterror(); |
| 1219 | 1291 | } |
| 1220 | 1292 | switch(QID(c->qid)){ |
| @@ -1225,7 +1297,6 @@ drawwrite(Chan *c, void *a, long n, vlong offset) · 4 unmodified lines |
| 1225 | 1297 | break; |
| 1226 | 1298 | |
| 1227 | 1299 | case Qcolormap: |
| 1228 | | − drawactive(1); /* to restore map from backup */ |
| 1229 | 1300 | m = n; |
| 1230 | 1301 | n = 0; |
| 1231 | 1302 | while(m > 0){ |
| @@ -1268,7 +1339,7 @@ drawwrite(Chan *c, void *a, long n, vlong offset) · 36 unmodified lines |
| 1268 | 1339 | default: |
| 1269 | 1340 | error(Ebadusefd); |
| 1270 | 1341 | } |
| 1271 | | − qunlock(&sdraw.lk); |
| 1342 | + dunlock(); |
| 1272 | 1343 | poperror(); |
| 1273 | 1344 | return n; |
| 1274 | 1345 | } |
| @@ -1306,14 +1377,6 @@ printmesg(char *fmt, uchar *a, int plsprnt) · 31 unmodified lines |
| 1306 | 1377 | int s; |
| 1307 | 1378 | |
| 1308 | 1379 | if(1|| plsprnt==0){ |
| 1309 | | − SET(s); |
| 1310 | | − SET(q); |
| 1311 | | − SET(p); |
| 1312 | | − USED(fmt); |
| 1313 | | − USED(a); |
| 1314 | | − p = buf; |
| 1315 | | − USED(p); |
| 1316 | | − USED(q); |
| 1317 | 1380 | USED(s); |
| 1318 | 1381 | return; |
| 1319 | 1382 | } |
| @@ -1364,7 +1427,7 @@ drawmesg(Client *client, void *av, int n) · 44 unmodified lines |
| 1364 | 1427 | ulong value, chan; |
| 1365 | 1428 | Rectangle r, clipr; |
| 1366 | 1429 | Point p, q, *pp, sp; |
| 1367 | | − Memimage *i, *dst, *src, *mask; |
| 1430 | + Memimage *i, *bg, *dst, *src, *mask; |
| 1368 | 1431 | Memimage *l, **lp; |
| 1369 | 1432 | Memscreen *scrn; |
| 1370 | 1433 | DImage *font, *ll, *di, *ddst, *dsrc; |
| @@ -1396,7 +1459,7 @@ drawmesg(Client *client, void *av, int n) · 25 unmodified lines |
| 1396 | 1459 | if(n < m) |
| 1397 | 1460 | error(Eshortdraw); |
| 1398 | 1461 | dstid = BGLONG(a+1); |
| 1399 | | − scrnid = BGSHORT(a+5); |
| 1462 | + scrnid = BGLONG(a+5); |
| 1400 | 1463 | refresh = a[9]; |
| 1401 | 1464 | chan = BGLONG(a+10); |
| 1402 | 1465 | repl = a[14]; |
| @@ -1410,7 +1473,7 @@ drawmesg(Client *client, void *av, int n) · 7 unmodified lines |
| 1410 | 1473 | scrn = dscrn->screen; |
| 1411 | 1474 | if(repl || chan!=scrn->image->chan) |
| 1412 | 1475 | error("image parameters incompatible with screen"); |
| 1413 | | − reffn = 0; |
| 1476 | + reffn = nil; |
| 1414 | 1477 | switch(refresh){ |
| 1415 | 1478 | case Refbackup: |
| 1416 | 1479 | break; |
| @@ -1493,7 +1556,7 @@ drawmesg(Client *client, void *av, int n) · 76 unmodified lines |
| 1493 | 1556 | if(ddst == nil) |
| 1494 | 1557 | error(Enodrawimage); |
| 1495 | 1558 | if(ddst->name) |
| 1496 | | − error("can't change repl/clipr of shared image"); |
| 1559 | + error("cannot change repl/clipr of shared image"); |
| 1497 | 1560 | dst = ddst->image; |
| 1498 | 1561 | if(a[5]) |
| 1499 | 1562 | dst->flags |= Frepl; |
| @@ -1553,9 +1616,9 @@ drawmesg(Client *client, void *av, int n) · 53 unmodified lines |
| 1553 | 1616 | oy = BGLONG(a+41); |
| 1554 | 1617 | op = drawclientop(client); |
| 1555 | 1618 | /* high bit indicates arc angles are present */ |
| 1556 | | − if(ox & (1U<<31)){ |
| 1619 | + if(ox & (1<<31)){ |
| 1557 | 1620 | if((ox & (1<<30)) == 0) |
| 1558 | | − ox &= ~(1U<<31); |
| 1621 | + ox &= ~(1<<31); |
| 1559 | 1622 | memarc(dst, p, e0, e1, c, src, sp, ox, oy, op); |
| 1560 | 1623 | }else |
| 1561 | 1624 | memellipse(dst, p, e0, e1, c, src, sp, op); |
| @@ -1592,12 +1655,12 @@ drawmesg(Client *client, void *av, int n) · 30 unmodified lines |
| 1592 | 1655 | error(Eshortdraw); |
| 1593 | 1656 | dstid = BGLONG(a+1); |
| 1594 | 1657 | if(dstid == 0) |
| 1595 | | − error("can't use display as font"); |
| 1658 | + error("cannot use display as font"); |
| 1596 | 1659 | font = drawlookup(client, dstid, 1); |
| 1597 | 1660 | if(font == 0) |
| 1598 | 1661 | error(Enodrawimage); |
| 1599 | 1662 | if(font->image->layer) |
| 1600 | | − error("can't use window as font"); |
| 1663 | + error("cannot use window as font"); |
| 1601 | 1664 | ni = BGLONG(a+5); |
| 1602 | 1665 | if(ni<=0 || ni>4096) |
| 1603 | 1666 | error("bad font size (4096 chars max)"); |
| @@ -1698,7 +1761,7 @@ drawmesg(Client *client, void *av, int n) · 94 unmodified lines |
| 1698 | 1761 | error(Edrawmem); |
| 1699 | 1762 | di = drawlookup(client, dstid, 0); |
| 1700 | 1763 | if(di == 0) |
| 1701 | | − error("draw: can't happen"); |
| 1764 | + error("draw: cannot happen"); |
| 1702 | 1765 | di->vers = dn->vers; |
| 1703 | 1766 | di->name = smalloc(j+1); |
| 1704 | 1767 | di->fromname = dn->dimage; |
| @@ -1799,7 +1862,7 @@ drawmesg(Client *client, void *av, int n) · 94 unmodified lines |
| 1799 | 1862 | if(pp == nil) |
| 1800 | 1863 | error(Enomem); |
| 1801 | 1864 | doflush = 0; |
| 1802 | | − if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data)) |
| 1865 | + if(dstid==0 || (screenimage && dst->layer && dst->layer->screen->image->data == screenimage->data)) |
| 1803 | 1866 | doflush = 1; /* simplify test in loop */ |
| 1804 | 1867 | ox = oy = 0; |
| 1805 | 1868 | esize = 0; |
| @@ -1901,10 +1964,10 @@ drawmesg(Client *client, void *av, int n) · 95 unmodified lines |
| 1901 | 1964 | clipr = dst->clipr; |
| 1902 | 1965 | dst->clipr = r; |
| 1903 | 1966 | op = drawclientop(client); |
| 1904 | | − l = dst; |
| 1967 | + bg = dst; |
| 1905 | 1968 | if(*a == 'x'){ |
| 1906 | 1969 | /* paint background */ |
| 1907 | | − l = drawimage(client, a+47); |
| 1970 | + bg = drawimage(client, a+47); |
| 1908 | 1971 | drawpoint(&q, a+51); |
| 1909 | 1972 | r.min.x = p.x; |
| 1910 | 1973 | r.min.y = p.y-font->ascent; |
| @@ -1920,7 +1983,7 @@ drawmesg(Client *client, void *av, int n) · 9 unmodified lines |
| 1920 | 1983 | r.max.x += font->fchar[ci].width; |
| 1921 | 1984 | u += 2; |
| 1922 | 1985 | } |
| 1923 | | − memdraw(dst, r, l, q, memopaque, ZP, op); |
| 1986 | + memdraw(dst, r, bg, q, memopaque, ZP, op); |
| 1924 | 1987 | u -= 2*ni; |
| 1925 | 1988 | } |
| 1926 | 1989 | q = p; |
| @@ -1930,7 +1993,7 @@ drawmesg(Client *client, void *av, int n) · 3 unmodified lines |
| 1930 | 1993 | dst->clipr = clipr; |
| 1931 | 1994 | error(Eindex); |
| 1932 | 1995 | } |
| 1933 | | − q = drawchar(dst, l, q, src, &sp, font, ci, op); |
| 1996 | + q = drawchar(dst, bg, q, src, &sp, font, ci, op); |
| 1934 | 1997 | u += 2; |
| 1935 | 1998 | } |
| 1936 | 1999 | dst->clipr = clipr; |
| @@ -1988,7 +2051,7 @@ drawmesg(Client *client, void *av, int n) · 51 unmodified lines |
| 1988 | 2051 | memltofrontn(lp, nw); |
| 1989 | 2052 | else |
| 1990 | 2053 | memltorearn(lp, nw); |
| 1991 | | − if(lp[0]->layer->screen->image->data == screenimage->data) |
| 2054 | + if(screenimage && lp[0]->layer->screen->image->data == screenimage->data) |
| 1992 | 2055 | for(j=0; j<nw; j++) |
| 1993 | 2056 | addflush(lp[j]->layer->screenr); |
| 1994 | 2057 | ll = drawlookup(client, BGLONG(a+1+1+2), 1); |
| @@ -2060,7 +2123,6 @@ drawcmap(void) · 65 unmodified lines |
| 2060 | 2123 | int num, den; |
| 2061 | 2124 | int i, j; |
| 2062 | 2125 | |
| 2063 | | − drawactive(1); /* to restore map from backup */ |
| 2064 | 2126 | for(r=0,i=0; r!=4; r++) |
| 2065 | 2127 | for(v=0; v!=4; v++,i+=16){ |
| 2066 | 2128 | for(g=0,j=v-r; g!=4; g++) |
| @@ -2083,65 +2145,3 @@ drawcmap(void) · 16 unmodified lines |
| 2083 | 2145 | } |
| 2084 | 2146 | } |
| 2085 | 2147 | } |
| 2086 | | − |
| 2087 | | −void |
| 2088 | | −drawblankscreen(int blank) |
| 2089 | | −{ |
| 2090 | | − int i, nc; |
| 2091 | | − ulong *p; |
| 2092 | | − |
| 2093 | | − if(blank == sdraw.blanked) |
| 2094 | | − return; |
| 2095 | | − if(!canqlock(&sdraw.lk)) |
| 2096 | | − return; |
| 2097 | | − if(!initscreenimage()){ |
| 2098 | | − qunlock(&sdraw.lk); |
| 2099 | | − return; |
| 2100 | | − } |
| 2101 | | − p = sdraw.savemap; |
| 2102 | | − nc = screenimage->depth > 8 ? 256 : 1<<screenimage->depth; |
| 2103 | | − |
| 2104 | | − /* |
| 2105 | | − * blankscreen uses the hardware to blank the screen |
| 2106 | | − * when possible. to help in cases when it is not possible, |
| 2107 | | − * we set the color map to be all black. |
| 2108 | | − */ |
| 2109 | | − if(blank == 0){ /* turn screen on */ |
| 2110 | | − for(i=0; i<nc; i++, p+=3) |
| 2111 | | − setcolor(i, p[0], p[1], p[2]); |
| 2112 | | − // blankscreen(0); |
| 2113 | | − }else{ /* turn screen off */ |
| 2114 | | − // blankscreen(1); |
| 2115 | | − for(i=0; i<nc; i++, p+=3){ |
| 2116 | | − getcolor(i, &p[0], &p[1], &p[2]); |
| 2117 | | − setcolor(i, 0, 0, 0); |
| 2118 | | − } |
| 2119 | | − } |
| 2120 | | − sdraw.blanked = blank; |
| 2121 | | − qunlock(&sdraw.lk); |
| 2122 | | −} |
| 2123 | | − |
| 2124 | | −/* |
| 2125 | | − * record activity on screen, changing blanking as appropriate |
| 2126 | | − */ |
| 2127 | | −void |
| 2128 | | −drawactive(int active) |
| 2129 | | −{ |
| 2130 | | −/* |
| 2131 | | − if(active){ |
| 2132 | | − drawblankscreen(0); |
| 2133 | | − sdraw.blanktime = MACHP(0)->ticks; |
| 2134 | | − }else{ |
| 2135 | | − if(blanktime && sdraw.blanktime && TK2SEC(MACHP(0)->ticks - sdraw.blanktime)/60 >= blanktime) |
| 2136 | | − drawblankscreen(1); |
| 2137 | | − } |
| 2138 | | −*/ |
| 2139 | | −} |
| 2140 | | − |
| 2141 | | −int |
| 2142 | | −drawidletime(void) |
| 2143 | | −{ |
| 2144 | | − return 0; |
| 2145 | | −/* return TK2SEC(MACHP(0)->ticks - sdraw.blanktime)/60; */ |
| 2146 | | −} |
| 2147 | | − |