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);
+ w->gone = chancreate(sizeof(char*), 0);
w->scrollr = r;
w->scrollr.max.x = r.min.x+Scrollwid;
w->lastsr = ZR;
}
void
-wresize(Window *w, Image *i, int move)
+wresize(Window *w, Image *i)
{
- Rectangle r, or;
+ Rectangle r;
- or = w->i->r;
- if(move || (Dx(or)==Dx(i->r) && Dy(or)==Dy(i->r)))
- draw(i, i->r, w->i, nil, w->i->r.min);
freeimage(w->i);
w->i = i;
w->mc.image = i;
w->scrollr.max.x = r.min.x+Scrollwid;
w->lastsr = ZR;
r.min.x += Scrollwid+Scrollgap;
- if(move)
- frsetrects(w, r, w->i);
- else{
- frclear(w, FALSE);
- frinit(w, r, w->font, w->i, cols);
- wsetcols(w);
- w->maxtab = maxtab*stringwidth(w->font, "0");
- r = insetrect(w->i->r, Selborder);
- draw(w->i, r, cols[BACK], nil, w->entire.min);
- wfill(w);
- wsetselect(w, w->q0, w->q1);
- wscrdraw(w);
- }
+ frclear(w, FALSE);
+ frinit(w, r, w->font, w->i, cols);
+ wsetcols(w, 1);
+ w->maxtab = maxtab*stringwidth(w->font, "0");
+ r = insetrect(w->i->r, Selborder);
+ draw(w->i, r, cols[BACK], nil, w->entire.min);
+ wfill(w);
+ wsetselect(w, w->q0, w->q1);
+ wscrdraw(w);
wborder(w, Selborder);
+ flushimage(display, 1);
wsetname(w);
w->topped = ++topped;
w->resized = TRUE;
}
void
-wrefresh(Window *w, Rectangle r)
+wrefresh(Window *w)
{
- /* BUG: rectangle is ignored */
+ Rectangle r;
+
if(w == input)
wborder(w, Selborder);
else
return 0;
if(i < 0)
error("negative ref count");
- if(!w->deleted)
- wclunk(w);
+ wclunk(w);
wsendctlmesg(w, Exited, ZR, nil);
return 1;
}
+void
+showcandidates(Window *, Completion *);
void
winctl(void *arg)
{
- Rune *rp, *bp, *tp, *up;
- uint qh;
+ Rune *rp, *up, r;
+ uint qh, q0;
int nr, nb, c, wid, i, npart, initial, lastb;
char *s, *t, part[3];
Window *w;
Mousestate *mp, m;
- enum { WKbd, WKbdread, WMouse, WMouseread, WCtl, WCwrite, WCread, WWread, NWALT };
+ 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;
- char buf[4*12+1], *kbdq[8], *kbds;
- int kbdqr, kbdqw;
+ Completion *cr;
+ char *kbdq[32], *kbds;
+ uint kbdqr, kbdqw;
w = arg;
- snprint(buf, sizeof buf, "winctl-id%d", w->id);
- threadsetname(buf);
+ 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[WComplete].op = CHANRCV;
+ alts[Wgone].c = w->gone;
+ alts[Wgone].v = "window deleted";
+ alts[Wgone].op = CHANNOP;
alts[NWALT].op = CHANEND;
- memset(kbdq, 0, sizeof(kbdq));
kbdqr = kbdqw = 0;
npart = 0;
lastb = -1;
for(;;){
- alts[WKbdread].op = (w->kbdopen && kbdqw != kbdqr) ?
- CHANSND : CHANNOP;
- alts[WMouseread].op = (w->mouseopen && w->mouse.counter != w->mouse.lastcounter) ?
- CHANSND : CHANNOP;
- alts[WCwrite].op = (!w->scrolling && !w->mouseopen && w->qh>w->org+w->nchars) ?
- CHANNOP : CHANSND;
- alts[WWread].op = (w->deleted || !w->wctlready) ?
- CHANNOP : CHANSND;
-
- /* this code depends on NL and EOT fitting in a single byte */
- /* kind of expensive for each loop; worth precomputing? */
- if(w->holding)
- alts[WCread].op = CHANNOP;
- else if(npart || (w->rawing && w->nraw>0))
- alts[WCread].op = CHANSND;
- else{
+ if(w->i==nil){
+ /* window deleted */
+ alts[Wgone].op = CHANSND;
+
+ alts[WKbdread].op = CHANNOP;
+ alts[WMouseread].op = CHANNOP;
+ alts[WCwrite].op = CHANNOP;
+ alts[WWread].op = CHANNOP;
alts[WCread].op = CHANNOP;
- for(i=w->qh; i<w->nr; i++){
- c = w->r[i];
- if(c=='\n' || c=='\004'){
- alts[WCread].op = CHANSND;
- break;
+ } else {
+ alts[WKbdread].op = (w->kbdopen && kbdqw != kbdqr) ?
+ CHANSND : CHANNOP;
+ alts[WMouseread].op = (w->mouseopen && w->mouse.counter != w->mouse.lastcounter) ?
+ CHANSND : CHANNOP;
+ alts[WCwrite].op = w->scrolling || w->mouseopen || (w->qh <= w->org+w->nchars) ?
+ CHANSND : CHANNOP;
+ alts[WWread].op = w->wctlready ?
+ CHANSND : CHANNOP;
+ /* this code depends on NL and EOT fitting in a single byte */
+ /* kind of expensive for each loop; worth precomputing? */
+ if(w->holding)
+ alts[WCread].op = CHANNOP;
+ else if(npart || (w->rawing && w->nraw>0))
+ alts[WCread].op = CHANSND;
+ else{
+ alts[WCread].op = CHANNOP;
+ for(i=w->qh; i<w->nr; i++){
+ c = w->r[i];
+ if(c=='\n' || c=='\004'){
+ alts[WCread].op = CHANSND;
+ break;
+ }
}
}
}
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;
recv(cwm.cw, &pair);
rp = pair.s;
nr = pair.ns;
- bp = rp;
for(i=0; i<nr; i++)
- if(*bp++ == '\b'){
- --bp;
+ if(rp[i] == '\b'){
+ up = rp+i;
initial = 0;
- tp = runemalloc(nr);
- runemove(tp, rp, i);
- up = tp+i;
for(; i<nr; i++){
- *up = *bp++;
- if(*up == '\b')
- if(up == tp)
+ if(rp[i] == '\b'){
+ if(up == rp)
initial++;
else
- --up;
- else
- up++;
+ up--;
+ }else
+ *up++ = rp[i];
}
if(initial){
if(initial > w->qh)
wdelete(w, qh, qh+initial);
w->qh = qh;
}
- free(rp);
- rp = tp;
- nr = up-tp;
- rp[nr] = 0;
+ nr = up - rp;
break;
}
w->qh = winsert(w, rp, nr, w->qh)+nr;
continue;
case WWread:
w->wctlready = 0;
- recv(cwrm.c1, &pair);
- if(w->deleted || w->i==nil)
- pair.ns = sprint(pair.s, "");
- else{
- s = "visible";
- for(i=0; i<nhidden; i++)
- if(hidden[i] == w){
- s = "hidden";
- break;
+ 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 ",
+ w->i->r.min.x, w->i->r.min.y, w->i->r.max.x, w->i->r.max.y, t, s);
+ send(crm.c2, &pair);
+ continue;
+ case WComplete:
+ if(w->i!=nil){
+ if(!cr->advance)
+ showcandidates(w, cr);
+ if(cr->advance){
+ rp = runesmprint("%s", cr->string);
+ if(rp){
+ nr = runestrlen(rp);
+ q0 = w->q0;
+ q0 = winsert(w, rp, nr, q0);
+ wshow(w, q0+nr);
+ free(rp);
}
- t = "notcurrent";
- if(w == input)
- t = "current";
- pair.ns = snprint(pair.s, pair.ns, "%11d %11d %11d %11d %s %s ",
- 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);
- continue;
+ freecompletion(cr);
+ break;
}
- if(!w->deleted)
+ if(w->i!=nil && Dx(w->screenr) > 0 && display->bufp > display->buf)
flushimage(display, 1);
}
}
q = q0;
while(q > 0){
r = w->r[q-1];
- if(r<=' ')
+ if(r<=' ' || r=='=' || r=='^' || r=='(' || r=='{')
break;
if(oneelement && r=='/')
break;
int i;
Fmt f;
Rune *rp;
- uint nr, qline, q0;
+ uint nr, qline;
char *s;
runefmtstrinit(&f);
}
fmtprint(&f, "]\n");
}
- /* place text at beginning of line before host point */
- qline = w->qh;
- while(qline>0 && w->r[qline-1] != '\n')
- qline--;
-
rp = runefmtstrflush(&f);
nr = runestrlen(rp);
- q0 = w->q0;
- q0 += winsert(w, rp, runestrlen(rp), qline) - qline;
+ /* place text at beginning of line before cursor and host point */
+ qline = min(w->qh, w->q0);
+ while(qline>0 && w->r[qline-1] != '\n')
+ qline--;
+
+ if(qline == w->qh){
+ /* advance host point to avoid readback */
+ w->qh = winsert(w, rp, nr, qline)+nr;
+ } else {
+ winsert(w, rp, nr, qline);
+ }
free(rp);
- wsetselect(w, q0+nr, q0+nr);
}
-Rune*
+typedef struct Completejob Completejob;
+struct Completejob
+{
+ char *dir;
+ char *str;
+ Window *win;
+};
+
+void
+completeproc(void *arg)
+{
+ Completejob *job;
+ Completion *c;
+
+ job = arg;
+ threadsetname("namecomplete %s", job->dir);
+
+ c = complete(job->dir, job->str);
+ if(c != nil && sendp(job->win->complete, c) <= 0)
+ freecompletion(c);
+
+ wclose(job->win);
+
+ free(job->dir);
+ free(job->str);
+ free(job);
+}
+
+void
namecomplete(Window *w)
{
int nstr, npath;
- Rune *rp, *path, *str;
- Completion *c;
- char *s, *dir, *root;
+ Rune *path, *str;
+ char *dir, *root;
+ Completejob *job;
/* control-f: filename completion; works back to white space or / */
if(w->q0<w->nr && w->r[w->q0]>' ') /* must be at end of word */
- return nil;
+ return;
nstr = windfilewidth(w, w->q0, TRUE);
- str = runemalloc(nstr);
- runemove(str, w->r+(w->q0-nstr), nstr);
+ str = w->r+(w->q0-nstr);
npath = windfilewidth(w, w->q0-nstr, FALSE);
- path = runemalloc(npath);
- runemove(path, w->r+(w->q0-nstr-npath), npath);
- rp = nil;
+ path = w->r+(w->q0-nstr-npath);
/* is path rooted? if not, we need to make it relative to window path */
- if(npath>0 && path[0]=='/'){
- dir = malloc(UTFmax*npath+1);
- sprint(dir, "%.*S", npath, path);
- }else{
+ if(npath>0 && path[0]=='/')
+ dir = runetobyte(path, npath, &npath);
+ else {
if(strcmp(w->dir, "") == 0)
root = ".";
else
root = w->dir;
- dir = malloc(strlen(root)+1+UTFmax*npath+1);
- sprint(dir, "%s/%.*S", root, npath, path);
+ dir = smprint("%s/%.*S", root, npath, path);
}
- dir = cleanname(dir);
-
- s = smprint("%.*S", nstr, str);
- c = complete(dir, s);
- free(s);
- if(c == nil)
- goto Return;
-
- if(!c->advance)
- showcandidates(w, c);
-
- if(c->advance)
- rp = runesmprint("%s", c->string);
+ if(dir == nil)
+ return;
- Return:
- freecompletion(c);
- free(dir);
- free(path);
- free(str);
- return rp;
+ /* run in background, winctl will collect the result on w->complete chan */
+ job = emalloc(sizeof *job);
+ job->str = runetobyte(str, nstr, &nstr);
+ job->dir = cleanname(dir);
+ job->win = w;
+ incref(w);
+ proccreate(completeproc, job, STACK);
}
void
wkeyctl(Window *w, Rune r)
{
uint q0 ,q1;
- int n, nb, nr;
- Rune *rp;
+ int n, nb;
int *notefd;
switch(r){
return;
}
- if(w->deleted)
+ if(w->i==nil)
return;
/* navigation keys work only when mouse and kbd is not open */
if(!w->mouseopen)
wsetselect(w, q0, q0);
wshow(w, w->q0);
return;
+ case Kstx: /* ^B: output point */
+ wsetselect(w, w->qh, w->qh);
+ wshow(w, w->q0);
+ return;
}
if(w->rawing && (w->q0==w->nr || w->mouseopen)){
waddraw(w, &r, 1);
--w->holding;
else
w->holding++;
- wsetcursor(w, 0);
+ wsetcursor(w, FALSE);
wrepaint(w);
if(r == Kesc)
return;
case Kdel: /* send interrupt */
w->qh = w->nr;
wshow(w, w->qh);
+ if(w->notefd < 0)
+ return;
notefd = emalloc(sizeof(int));
*notefd = dup(w->notefd, -1);
proccreate(interruptproc, notefd, 4096);
return;
case Kack: /* ^F: file name completion */
case Kins: /* Insert: file name completion */
- rp = namecomplete(w);
- if(rp == nil)
- return;
- nr = runestrlen(rp);
- q0 = w->q0;
- q0 = winsert(w, rp, nr, q0);
- wshow(w, q0+nr);
- free(rp);
+ namecomplete(w);
return;
case Kbs: /* ^H: erase character */
case Knack: /* ^U: erase line */
}
void
-wsetcols(Window *w)
+wsetcols(Window *w, int topped)
{
if(w->holding)
- if(w == input)
- w->cols[TEXT] = w->cols[HTEXT] = holdcol;
+ if(topped)
+ w->cols[TEXT] = holdcol;
else
- w->cols[TEXT] = w->cols[HTEXT] = lightholdcol;
+ w->cols[TEXT] = lightholdcol;
else
- if(w == input)
- w->cols[TEXT] = w->cols[HTEXT] = cols[TEXT];
+ if(topped)
+ w->cols[TEXT] = cols[TEXT];
else
- w->cols[TEXT] = w->cols[HTEXT] = paletextcol;
+ w->cols[TEXT] = paletextcol;
}
void
wrepaint(Window *w)
{
- wsetcols(w);
+ wsetcols(w, w == input);
if(!w->mouseopen)
frredraw(w);
if(w == input)
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);
}
-int
-winborder(Window *w, Point xy)
+void
+wlook(Window *w)
{
- return ptinrect(xy, w->screenr) && !ptinrect(xy, insetrect(w->screenr, Selborder));
+ int i, n, e;
+
+ i = w->q1;
+ n = i - w->q0;
+ e = w->nr - n;
+ if(n <= 0 || e < n)
+ return;
+
+ if(i > e)
+ i = 0;
+
+ while(runestrncmp(w->r+w->q0, w->r+i, n) != 0){
+ if(i < e)
+ i++;
+ else
+ i = 0;
+ }
+
+ wsetselect(w, i, i+n);
+ wshow(w, i);
}
void
{
int but;
- if(w->mc.buttons == 1)
- but = 1;
- else if(w->mc.buttons == 2)
- but = 2;
- else if(w->mc.buttons == 4)
- but = 3;
- else{
- if(w->mc.buttons == 8)
- wkeyctl(w, Kscrolloneup);
- if(w->mc.buttons == 16)
- wkeyctl(w, Kscrollonedown);
- return;
+ for(but=1;; but++){
+ if(but > 5)
+ return;
+ if(w->mc.buttons == 1<<(but-1))
+ break;
}
incref(w); /* hold up window while we track */
- if(w->deleted)
- goto Return;
- if(ptinrect(w->mc.xy, w->scrollr)){
- if(but)
+ if(w->i != nil){
+ if(shiftdown && but > 3)
+ wkeyctl(w, but == 4 ? Kscrolloneup : Kscrollonedown);
+ else if(ptinrect(w->mc.xy, w->scrollr) || (but > 3))
wscroll(w, but);
- goto Return;
+ else if(but == 1)
+ wselect(w);
}
- if(but == 1)
- wselect(w);
- /* else all is handled by main process */
- Return:
wclose(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;
if(p!=nil)
sendp((Channel*)p, w);
break;
- case Moved:
case Reshaped:
if(w->deleted){
freeimage(i);
}
w->screenr = r;
strcpy(buf, w->name);
- wresize(w, i, m==Moved);
+ 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;
break;
/* fall thrugh for redraw after input change */
case Repaint:
- if(w->deleted || Dx(w->screenr)<=0)
+ if(w->i==nil || Dx(w->screenr)<=0)
break;
wrepaint(w);
flushimage(display, 1);
break;
case Refresh:
- if(w->deleted || Dx(w->screenr)<=0 || !rectclip(&r, w->i->r) || w->mouseopen)
+ if(w->i==nil || Dx(w->screenr)<=0 || w->mouseopen)
break;
- wrefresh(w, r);
+ wrefresh(w);
flushimage(display, 1);
break;
case Movemouse:
- if(w->deleted || Dx(w->screenr)<=0 || !ptinrect(r.min, w->i->r))
+ if(w->i==nil || Dx(w->screenr)<=0 || !ptinrect(r.min, w->i->r))
break;
wmovemouse(w, r.min);
case Rawon:
break;
case Rawoff:
- if(w->deleted)
- break;
while(w->nraw > 0){
wkeyctl(w, w->raw[0]);
--w->nraw;
break;
case Holdon:
case Holdoff:
- if(w->deleted)
+ if(w->i==nil)
break;
if(w==input)
- wsetcursor(w, 0);
+ wsetcursor(w, FALSE);
wrepaint(w);
flushimage(display, 1);
break;
case Deleted:
- if(w->deleted)
- break;
wclunk(w);
- write(w->notefd, "hangup", 6);
- proccreate(deletetimeoutproc, estrdup(w->name), 4096);
- wclosewin(w);
+ if(w->notefd >= 0)
+ write(w->notefd, "hangup", 6);
+ if(w->i!=nil){
+ proccreate(deletetimeoutproc, estrdup(w->name), 4096);
+ wclosewin(w);
+ }
break;
case Exited:
wclosewin(w);
frclear(w, TRUE);
- close(w->notefd);
+ if(w->notefd >= 0)
+ close(w->notefd);
chanfree(w->mc.c);
chanfree(w->ck);
chanfree(w->cctl);
chanfree(w->mouseread);
chanfree(w->wctlread);
chanfree(w->kbdread);
+ chanfree(w->complete);
+ chanfree(w->gone);
free(w->raw);
free(w->r);
free(w->dir);
{
Cursor *p;
- if(w==nil || w->deleted || w->i==nil || Dx(w->screenr)<=0)
+ if(menuing || sweeping)
+ return;
+ if(w==nil || w->i==nil || Dx(w->screenr)<=0)
p = nil;
else if(wpointto(mouse->xy) == w){
p = w->cursorp;
p = &whitearrow;
}else
p = nil;
- if(!menuing)
- riosetcursor(p, force && !menuing);
+ if(force) /* force cursor reload */
+ lastcursor = (void*)~0;
+ 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)
{
- if(w!=nil && w->i!=nil && !w->deleted && w->topped!=topped){
+ if(w!=nil && w->i!=nil && w->topped!=topped){
w->topped = ++topped;
topwindow(w->i);
flushimage(display, 1);
void
wbottomme(Window *w)
{
- if(w!=nil && w->i!=nil && !w->deleted){
+ if(w!=nil && w->i!=nil){
w->topped = - ++topped;
bottomwindow(w->i);
flushimage(display, 1);
{
int i;
+ if(w->deleted)
+ return;
+ w->deleted = TRUE;
if(w == input){
input = nil;
- wsetcursor(w, 0);
+ wsetcursor(w, FALSE);
}
if(w == wkeyboard)
wkeyboard = nil;
memmove(window+i, window+i+1, (nwindow-i)*sizeof(window[0]));
break;
}
- w->deleted = TRUE;
}
void
{
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);
+ flushimage(display, 1);
}
}
fixup = 1; /* frdelete can leave end of last line in wrong selection mode; it doesn't know what follows */
}else if(a<0 && -a<w->nchars){
n = w->org - org;
- r = runemalloc(n);
- runemove(r, w->r+org, n);
+ r = w->r+org;
frinsert(w, r, r+n, 0);
- free(r);
}else
frdelete(w, 0, w->nchars);
w->org = org;
Rune *rp;
int i, n, m, nl;
- if(w->lastlinefull)
- return;
- rp = malloc(messagesize);
- do{
+ while(w->lastlinefull == FALSE){
n = w->nr-(w->org+w->nchars);
if(n == 0)
break;
if(n > 2000) /* educated guess at reasonable amount */
n = 2000;
- runemove(rp, w->r+(w->org+w->nchars), n);
+ rp = w->r+(w->org+w->nchars);
+
/*
* it's expensive to frinsert more than we need, so
* count newlines.
}
}
frinsert(w, rp, rp+i, w->nchars);
- }while(w->lastlinefull == FALSE);
- free(rp);
+ }
}
char*