#include "dat.h"
#include "fns.h"
-#define MOVEIT if(0)
-
enum
{
HiWater = 640000, /* max size of history */
w->cursorp = nil;
w->conswrite = chancreate(sizeof(Conswritemesg), 0);
w->consread = chancreate(sizeof(Consreadmesg), 0);
- w->kbdread = chancreate(sizeof(Kbdreadmesg), 0);
+ w->kbdread = chancreate(sizeof(Consreadmesg), 0);
w->mouseread = chancreate(sizeof(Mousereadmesg), 0);
w->wctlread = chancreate(sizeof(Consreadmesg), 0);
w->complete = chancreate(sizeof(Completion*), 0);
{
Rectangle r;
- freeimage(w->i);
+ wclosewin(w);
w->i = i;
w->mc.image = i;
r = insetrect(i->r, Selborder+1);
wsetselect(w, w->q0, w->q1);
wscrdraw(w);
wborder(w, Selborder);
+ flushimage(display, 1);
wsetname(w);
w->topped = ++topped;
w->resized = TRUE;
void
winctl(void *arg)
{
- Rune *rp, *up;
+ Rune *rp, *up, r;
uint qh, q0;
int nr, nb, c, wid, i, npart, initial, lastb;
char *s, *t, part[3];
Mousestate *mp, m;
enum { WKbd, WKbdread, WMouse, WMouseread, WCtl, WCwrite, WCread, WWread, WComplete, Wgone, NWALT };
Alt alts[NWALT+1];
+ Consreadmesg crm;
Mousereadmesg mrm;
- Kbdreadmesg krm;
Conswritemesg cwm;
- Consreadmesg crm;
- Consreadmesg cwrm;
Stringpair pair;
Wctlmesg wcm;
Completion *cr;
- char *kbdq[8], *kbds;
- int kbdqr, kbdqw;
+ char *kbdq[32], *kbds;
+ uint kbdqr, kbdqw;
w = arg;
threadsetname("winctl-id%d", w->id);
mrm.cm = chancreate(sizeof(Mouse), 0);
- krm.ck = chancreate(sizeof(char*), 0);
- cwm.cw = chancreate(sizeof(Stringpair), 0);
crm.c1 = chancreate(sizeof(Stringpair), 0);
crm.c2 = chancreate(sizeof(Stringpair), 0);
- cwrm.c1 = chancreate(sizeof(Stringpair), 0);
- cwrm.c2 = chancreate(sizeof(Stringpair), 0);
+ cwm.cw = chancreate(sizeof(Stringpair), 0);
alts[WKbd].c = w->ck;
alts[WKbd].v = &kbds;
alts[WKbd].op = CHANRCV;
alts[WKbdread].c = w->kbdread;
- alts[WKbdread].v = &krm;
+ alts[WKbdread].v = &crm;
alts[WKbdread].op = CHANSND;
alts[WMouse].c = w->mc.c;
alts[WMouse].v = &w->mc.Mouse;
alts[WCread].v = &crm;
alts[WCread].op = CHANSND;
alts[WWread].c = w->wctlread;
- alts[WWread].v = &cwrm;
+ alts[WWread].v = &crm;
alts[WWread].op = CHANSND;
alts[WComplete].c = w->complete;
alts[WComplete].v = &cr;
alts[Wgone].op = CHANNOP;
alts[NWALT].op = CHANEND;
- memset(kbdq, 0, sizeof(kbdq));
kbdqr = kbdqw = 0;
npart = 0;
lastb = -1;
}
switch(alt(alts)){
case WKbd:
- if(w->kbdopen){
- i = (kbdqw+1) % nelem(kbdq);
- if(i != kbdqr)
- kbdqw = i;
- } else if(*kbds == 'c'){
- Rune r;
-
- chartorune(&r, kbds+1);
- if(r)
- wkeyctl(w, r);
+ if(kbdqw - kbdqr < nelem(kbdq))
+ kbdq[kbdqw++ % nelem(kbdq)] = kbds;
+ else
+ free(kbds);
+ if(w->kbdopen)
+ continue;
+ while(kbdqr != kbdqw){
+ kbds = kbdq[kbdqr++ % nelem(kbdq)];
+ if(*kbds == 'c'){
+ chartorune(&r, kbds+1);
+ if(r)
+ wkeyctl(w, r);
+ }
+ free(kbds);
}
- free(kbdq[kbdqw]);
- kbdq[kbdqw] = kbds;
break;
-
case WKbdread:
- i = (kbdqr+1) % nelem(kbdq);
- if(kbdqr != kbdqw)
- kbdqr = i;
- if(kbdq[i]){
- sendp(krm.ck, kbdq[i]);
- kbdq[i] = nil;
- }else
- sendp(krm.ck, strdup("K"));
+ recv(crm.c1, &pair);
+ nb = 0;
+ while(kbdqr != kbdqw){
+ kbds = kbdq[kbdqr % nelem(kbdq)];
+ i = strlen(kbds)+1;
+ if(nb+i > pair.ns)
+ break;
+ memmove((char*)pair.s + nb, kbds, i);
+ free(kbds);
+ nb += i;
+ kbdqr++;
+ }
+ pair.ns = nb;
+ send(crm.c2, &pair);
continue;
-
case WMouse:
if(w->mouseopen) {
w->mouse.counter++;
continue;
case WCtl:
if(wctlmesg(w, wcm.type, wcm.r, wcm.p) == Exited){
- for(i=0; i<nelem(kbdq); i++)
- free(kbdq[i]);
+ while(kbdqr != kbdqw)
+ free(kbdq[kbdqr++ % nelem(kbdq)]);
chanfree(crm.c1);
chanfree(crm.c2);
chanfree(mrm.cm);
- chanfree(krm.ck);
chanfree(cwm.cw);
- chanfree(cwrm.c1);
- chanfree(cwrm.c2);
threadexits(nil);
}
continue;
continue;
case WWread:
w->wctlready = 0;
- recv(cwrm.c1, &pair);
+ recv(crm.c1, &pair);
s = Dx(w->screenr) > 0 ? "visible" : "hidden";
t = "notcurrent";
if(w == input)
t = "current";
- pair.ns = snprint(pair.s, pair.ns, "%11d %11d %11d %11d %s %s ",
+ pair.ns = snprint(pair.s, pair.ns, "%11d %11d %11d %11d %11s %11s ",
w->i->r.min.x, w->i->r.min.y, w->i->r.max.x, w->i->r.max.y, t, s);
- send(cwrm.c2, &pair);
+ send(crm.c2, &pair);
continue;
case WComplete:
if(w->i!=nil){
freecompletion(cr);
break;
}
- if(w->i!=nil && Dx(w->screenr) > 0)
+ if(w->i!=nil && Dx(w->screenr) > 0 && display->bufp > display->buf)
flushimage(display, 1);
}
}
--w->holding;
else
w->holding++;
- wsetcursor(w, 0);
+ wsetcursor(w, FALSE);
wrepaint(w);
if(r == Kesc)
return;
m->data = runetobyte(w->r+p0, p1-p0, &m->ndata);
if(plumbsend(fd, m) < 0){
c = lastcursor;
- riosetcursor(&query, 1);
+ riosetcursor(&query);
sleep(300);
- riosetcursor(c, 1);
+ riosetcursor(c);
}
plumbfree(m);
}
wshow(w, i);
}
-int
-winborder(Window *w, Point xy)
-{
- return ptinrect(xy, w->screenr) && !ptinrect(xy, insetrect(w->screenr, Selborder));
-}
-
void
wmousectl(Window *w)
{
if(q0==q1 && selectq==w->q0){
wdoubleclick(w, &q0, &q1);
wsetselect(w, q0, q1);
- flushimage(display, 1);
x = w->mc.xy.x;
y = w->mc.xy.y;
/* stay here until something interesting happens */
}else
clickwin = nil;
wsetselect(w, q0, q1);
- flushimage(display, 1);
while(w->mc.buttons){
w->mc.msec = 0;
b = w->mc.buttons;
}
}
wscrdraw(w);
- flushimage(display, 1);
while(w->mc.buttons == b)
readmouse(&w->mc);
clickwin = nil;
int
wctlmesg(Window *w, int m, Rectangle r, void *p)
{
- char buf[64];
Image *i = p;
switch(m){
break;
}
w->screenr = r;
- strcpy(buf, w->name);
wresize(w, i);
- proccreate(deletetimeoutproc, estrdup(buf), 4096);
- flushimage(display, 1);
if(Dx(r)<=0){ /* window got hidden, if we had the input, drop it */
if(w==input)
input = nil;
wsendctlmesg(oi, Repaint, ZR, nil);
}
wclose(oi);
- } else
+ } else {
input = w;
+ wsetcursor(w, FALSE);
+ }
w->wctlready = 1;
if(m!=Topped && w==input)
break;
case Holdoff:
if(w->i==nil)
break;
- if(w==input)
- wsetcursor(w, 0);
+ wsetcursor(w, FALSE);
wrepaint(w);
flushimage(display, 1);
break;
+ case Truncate:
+ wdelete(w, 0, w->nr);
+ break;
case Deleted:
wclunk(w);
if(w->notefd >= 0)
write(w->notefd, "hangup", 6);
- if(w->i!=nil){
- proccreate(deletetimeoutproc, estrdup(w->name), 4096);
- wclosewin(w);
- }
+ wclosewin(w);
+ flushimage(display, 1);
break;
case Exited:
wclosewin(w);
frclear(w, TRUE);
+ flushimage(display, 1);
if(w->notefd >= 0)
close(w->notefd);
chanfree(w->mc.c);
{
Cursor *p;
- if(w==nil || w->i==nil || Dx(w->screenr)<=0)
+ if(menuing || sweeping || (w!=input && wpointto(mouse->xy)!=w))
+ return;
+ if(w==nil)
p = nil;
- else if(wpointto(mouse->xy) == w){
+ else {
p = w->cursorp;
if(p==nil && w->holding)
p = &whitearrow;
- }else
- p = nil;
- if(!menuing)
- riosetcursor(p, force && !menuing);
+ }
+ if(p && force) /* force cursor reload */
+ lastcursor = nil;
+ riosetcursor(p);
}
void
-riosetcursor(Cursor *p, int force)
+riosetcursor(Cursor *p)
{
- if(!force && p==lastcursor)
+ if(p==lastcursor)
return;
setcursor(mousectl, p);
lastcursor = p;
}
-
void
wtopme(Window *w)
{
w->deleted = TRUE;
if(w == input){
input = nil;
- wsetcursor(w, 0);
+ riosetcursor(nil);
}
if(w == wkeyboard)
wkeyboard = nil;
void
wclosewin(Window *w)
{
- Image *i;
-
- assert(w->deleted==TRUE);
-
- i = w->i;
- if(i){
- w->i = nil;
- /* move it off-screen to hide it, in case client is slow in letting it go */
- MOVEIT originwindow(i, i->r.min, view->r.max);
- freeimage(i);
- }
+ Image *i = w->i;
+ if(i == nil)
+ return;
+ w->i = nil;
+ /* move it off-screen to hide it, in case client is slow in letting it go */
+ originwindow(i, i->r.min, view->r.max);
+ freeimage(i);
}
void