diff options
| -rw-r--r-- | sys/src/cmd/rio/dat.h | 2 | ||||
| -rw-r--r-- | sys/src/cmd/rio/fns.h | 2 | ||||
| -rw-r--r-- | sys/src/cmd/rio/rio.c | 170 | ||||
| -rw-r--r-- | sys/src/cmd/rio/wctl.c | 112 | ||||
| -rw-r--r-- | sys/src/cmd/rio/wind.c | 110 |
5 files changed, 218 insertions, 178 deletions
diff --git a/sys/src/cmd/rio/dat.h b/sys/src/cmd/rio/dat.h index 17d0747ae..d74d6e425 100644 --- a/sys/src/cmd/rio/dat.h +++ b/sys/src/cmd/rio/dat.h @@ -67,6 +67,7 @@ enum /* control messages */ Rawoff, Holdon, Holdoff, + Repaint, Deleted, Exited, }; @@ -194,6 +195,7 @@ uint wbacknl(Window*, uint, uint); uint winsert(Window*, Rune*, int, uint); void waddraw(Window*, Rune*, int); void wborder(Window*, int); +void wclunk(Window*); void wclosewin(Window*); void wcurrent(Window*); void wcut(Window*); diff --git a/sys/src/cmd/rio/fns.h b/sys/src/cmd/rio/fns.h index d6e152e35..702eb101e 100644 --- a/sys/src/cmd/rio/fns.h +++ b/sys/src/cmd/rio/fns.h @@ -1,6 +1,6 @@ void keyboardsend(char*, int); int whide(Window*); -int wunhide(int); +int wunhide(Window*); void freescrtemps(void); int parsewctl(char**, Rectangle, Rectangle*, int*, int*, int*, int*, char**, char*, char*); int writewctl(Xfid*, char*); diff --git a/sys/src/cmd/rio/rio.c b/sys/src/cmd/rio/rio.c index 87137e483..98d3dd10b 100644 --- a/sys/src/cmd/rio/rio.c +++ b/sys/src/cmd/rio/rio.c @@ -347,7 +347,7 @@ keyboardthread(void*) while(s = recvp(kbdchan)){ if(*s == 'k' || *s == 'K') shiftdown = utfrune(s+1, Kshift) != nil; - if(input == nil || sendp(input->ck, s) <= 0) + if(input == nil || input->deleted || sendp(input->ck, s) <= 0) free(s); } } @@ -470,7 +470,7 @@ void mousethread(void*) { int sending, inside, scrolling, moving, band; - Window *oin, *w, *winput; + Window *w, *winput; Image *i; Rectangle r; Point xy; @@ -513,7 +513,7 @@ mousethread(void*) wtopme(wkeyboard); winput = wkeyboard; } - if(winput!=nil && winput->i!=nil){ + if(winput!=nil && !winput->deleted && winput->i!=nil){ /* convert to logical coordinates */ xy.x = mouse->xy.x + (winput->i->r.min.x-winput->screenr.min.x); xy.y = mouse->xy.y + (winput->i->r.min.y-winput->screenr.min.y); @@ -555,7 +555,7 @@ mousethread(void*) else riosetcursor(nil, 0); if(moving && (mouse->buttons&7)){ - oin = winput; + incref(winput); band = mouse->buttons & 3; sweeping = 1; if(band) @@ -564,18 +564,19 @@ mousethread(void*) i = drag(winput, &r); sweeping = 0; if(i != nil){ - if(winput == oin){ - if(band) - wsendctlmesg(winput, Reshaped, i->r, i); - else - wsendctlmesg(winput, Moved, r, i); - cornercursor(winput, mouse->xy, 1); - }else - freeimage(i); + if(band) + wsendctlmesg(winput, Reshaped, i->r, i); + else + wsendctlmesg(winput, Moved, r, i); + cornercursor(winput, mouse->xy, 1); + } + if(wclose(winput) == 0) + w = winput; + else { + riosetcursor(nil, 0); + w = nil; } } - if(w != nil) - cornercursor(w, mouse->xy, 0); /* we're not sending the event, but if button is down maybe we should */ if(mouse->buttons){ /* w->topped will be zero or less if window has been bottomed */ @@ -583,8 +584,11 @@ mousethread(void*) if(mouse->buttons & 1){ ; }else if(mouse->buttons & 2){ - if(winput && !winput->mouseopen) + if(winput && !winput->deleted && !winput->mouseopen){ + incref(winput); button2menu(winput); + wclose(winput); + } }else if(mouse->buttons & 4) button3menu(); }else{ @@ -607,11 +611,17 @@ mousethread(void*) } } +int +wtopcmp(void *a, void *b) +{ + return (*(Window**)a)->topped - (*(Window**)b)->topped; +} + void resized(void) { Image *im; - int i, j, ishidden; + int i, j; Rectangle r; Point o, n; Window *w; @@ -627,10 +637,9 @@ resized(void) draw(view, view->r, background, nil, ZP); o = subpt(viewr.max, viewr.min); n = subpt(view->clipr.max, view->clipr.min); + qsort(window, nwindow, sizeof(window[0]), wtopcmp); for(i=0; i<nwindow; i++){ w = window[i]; - if(w->deleted) - continue; r = rectsubpt(w->i->r, viewr.min); r.min.x = (r.min.x*n.x)/o.x; r.min.y = (r.min.y*n.y)/o.y; @@ -639,26 +648,25 @@ resized(void) if(!goodrect(r)) r = rectsubpt(w->i->r, viewr.min); r = rectaddpt(r, screen->clipr.min); - ishidden = 0; for(j=0; j<nhidden; j++) - if(w == hidden[j]){ - ishidden = 1; + if(w == hidden[j]) break; - } - if(ishidden){ + incref(w); + if(j < nhidden){ im = allocimage(display, r, screen->chan, 0, DWhite); r = ZR; - }else + } else im = allocwindow(wscreen, r, Refbackup, DWhite); if(im) wsendctlmesg(w, Reshaped, r, im); + wclose(w); } viewr = screen->r; flushimage(display, 1); } -static int -wcovered(Window *w, Rectangle r, int i) +int +obscured(Window *w, Rectangle r, int i) { Window *t; @@ -668,21 +676,21 @@ wcovered(Window *w, Rectangle r, int i) return 1; for(; i<nwindow; i++){ t = window[i]; - if(t == w || t->topped <= w->topped || t->deleted) + if(t == w || t->topped <= w->topped) continue; if(Dx(t->screenr) == 0 || Dy(t->screenr) == 0 || rectXrect(r, t->screenr) == 0) continue; if(r.min.y < t->screenr.min.y) - if(!wcovered(w, Rect(r.min.x, r.min.y, r.max.x, t->screenr.min.y), i)) + if(!obscured(w, Rect(r.min.x, r.min.y, r.max.x, t->screenr.min.y), i)) return 0; if(r.min.x < t->screenr.min.x) - if(!wcovered(w, Rect(r.min.x, r.min.y, t->screenr.min.x, r.max.y), i)) + if(!obscured(w, Rect(r.min.x, r.min.y, t->screenr.min.x, r.max.y), i)) return 0; if(r.max.y > t->screenr.max.y) - if(!wcovered(w, Rect(r.min.x, t->screenr.max.y, r.max.x, r.max.y), i)) + if(!obscured(w, Rect(r.min.x, t->screenr.max.y, r.max.x, r.max.y), i)) return 0; if(r.max.x > t->screenr.max.x) - if(!wcovered(w, Rect(t->screenr.max.x, r.min.y, r.max.x, r.max.y), i)) + if(!obscured(w, Rect(t->screenr.max.x, r.min.y, r.max.x, r.max.y), i)) return 0; return 1; } @@ -699,13 +707,12 @@ button3menu(void) for(j=0; j<n; j++) if(window[i] == hidden[j]) break; - if(j < n || window[i]->deleted) - continue; - if(wcovered(window[i], window[i]->screenr, 0)){ - hidden[n++] = window[i]; - if(n >= nelem(hidden)) - break; - } + if(j == n) + if(obscured(window[i], window[i]->screenr, 0)){ + hidden[n++] = window[i]; + if(n >= nelem(hidden)) + break; + } } if(n >= nelem(menu3str)-Hidden) n = nelem(menu3str)-Hidden-1; @@ -752,9 +759,6 @@ button3menu(void) void button2menu(Window *w) { - if(w->deleted) - return; - incref(w); if(w->scrolling) menu2str[Scroll] = "noscroll"; else @@ -803,7 +807,6 @@ button2menu(Window *w) wshow(w, w->nr); break; } - wclose(w); wsendctlmesg(w, Wakeup, ZR, nil); flushimage(display, 1); } @@ -1113,9 +1116,13 @@ resize(void) w = pointto(TRUE); if(w == nil) return; + incref(w); i = sweep(); - if(i) + if(i){ wsendctlmesg(w, Reshaped, i->r, i); + wcurrent(w); + } + wclose(w); } void @@ -1128,10 +1135,14 @@ move(void) w = pointto(FALSE); if(w == nil) return; + incref(w); i = drag(w, &r); - if(i) + if(i){ wsendctlmesg(w, Moved, r, i); - cornercursor(input, mouse->xy, 1); + wcurrent(w); + } + cornercursor(w, mouse->xy, 1); + wclose(w); } int @@ -1145,38 +1156,39 @@ whide(Window *w) return -1; if(nhidden >= nelem(hidden)) return 0; + incref(w); i = allocimage(display, w->screenr, w->i->chan, 0, DWhite); if(i){ + if(w == input) + input = nil; hidden[nhidden++] = w; wsendctlmesg(w, Reshaped, ZR, i); - return 1; } - return 0; + wclose(w); + return i!=0; } int -wunhide(int h) +wunhide(Window *w) { + int j; Image *i; - Window *w; - w = hidden[h]; - if(w == nil) - return 0; - if(h >= nhidden){ - wtopme(w); - wcurrent(w); - flushimage(display, 1); - return 1; - } + for(j=0; j<nhidden; j++) + if(hidden[j] == w) + break; + if(j == nhidden) + return -1; /* not hidden */ + incref(w); i = allocwindow(wscreen, w->i->r, Refbackup, DWhite); if(i){ --nhidden; - memmove(hidden+h, hidden+h+1, (nhidden-h)*sizeof(Window*)); + memmove(hidden+j, hidden+j+1, (nhidden-j)*sizeof(Window*)); wsendctlmesg(w, Reshaped, w->i->r, i); - return 1; + wcurrent(w); } - return 0; + wclose(w); + return i!=0; } void @@ -1185,16 +1197,34 @@ hide(void) Window *w; w = pointto(TRUE); - if(w == nil) - return; - whide(w); + if(w) + whide(w); } void -unhide(int h) +unhide(int j) { - if(h >= Hidden) - wunhide(h - Hidden); + Window *w; + + if(j < Hidden) + return; + j -= Hidden; + w = hidden[j]; + if(w == nil) + return; + if(j < nhidden){ + wunhide(w); + return; + } + /* uncover obscured window */ + for(j=0; j<nwindow; j++) + if(window[j] == w){ + incref(w); + wcurrent(w); + wtopme(w); + wclose(w); + return; + } } Window* @@ -1207,6 +1237,10 @@ new(Image *i, int hideit, int scrollit, int pid, char *dir, char *cmd, char **ar if(i == nil) return nil; + if(hideit && nhidden >= nelem(hidden)){ + freeimage(i); + return nil; + } cm = chancreate(sizeof(Mouse), 0); ck = chancreate(sizeof(char*), 0); cctl = chancreate(sizeof(Wctlmesg), 4); @@ -1221,8 +1255,6 @@ new(Image *i, int hideit, int scrollit, int pid, char *dir, char *cmd, char **ar free(mc); /* wmk copies *mc */ window = erealloc(window, ++nwindow*sizeof(Window*)); window[nwindow-1] = w; - if(nhidden >= nelem(hidden)) - hideit = 0; if(hideit){ hidden[nhidden++] = w; w->screenr = ZR; diff --git a/sys/src/cmd/rio/wctl.c b/sys/src/cmd/rio/wctl.c index 2e91b0e7c..557e9e84d 100644 --- a/sys/src/cmd/rio/wctl.c +++ b/sys/src/cmd/rio/wctl.c @@ -346,68 +346,32 @@ wctlnew(Rectangle rect, char *arg, int pid, int hideit, int scrollit, char *dir, } int -writewctl(Xfid *x, char *err) +wctlcmd(Window *w, Rectangle r, int cmd, char *err) { - int cnt, cmd, j, id, hideit, scrollit, pid; Image *i; - char *arg, *dir; - Rectangle rect; - Window *w; - - w = x->f->w; - cnt = x->count; - x->data[cnt] = '\0'; - id = 0; - - rect = rectsubpt(w->screenr, screen->r.min); - cmd = parsewctl(&arg, rect, &rect, &pid, &id, &hideit, &scrollit, &dir, x->data, err); - if(cmd < 0) - return -1; - - if(mouse->buttons!=0 && cmd>=Top){ - strcpy(err, "action disallowed when mouse active"); - return -1; - } - - if(id != 0){ - for(j=0; j<nwindow; j++) - if(window[j]->id == id) - break; - if(j == nwindow){ - strcpy(err, "no such window id"); - return -1; - } - w = window[j]; - if(w->deleted || w->i==nil){ - strcpy(err, "window deleted"); - return -1; - } - } switch(cmd){ - case New: - return wctlnew(rect, arg, pid, hideit, scrollit, dir, err); - case Set: - if(pid > 0) - wsetpid(w, pid, 0); - return 1; case Move: - rect = Rect(rect.min.x, rect.min.y, rect.min.x+Dx(w->screenr), rect.min.y+Dy(w->screenr)); - rect = rectonscreen(rect); + r = Rect(r.min.x, r.min.y, r.min.x+Dx(w->screenr), r.min.y+Dy(w->screenr)); + r = rectonscreen(r); /* fall through */ case Resize: - if(!goodrect(rect)){ + if(!goodrect(r)){ strcpy(err, Ebadwr); return -1; } - if(eqrect(rect, w->screenr)) + if(w != input){ + strcpy(err, "window not current"); + return -1; + } + if(eqrect(r, w->screenr)) return 1; - i = allocwindow(wscreen, rect, Refbackup, DWhite); + i = allocwindow(wscreen, r, Refbackup, DWhite); if(i == nil){ strcpy(err, Ewalloc); return -1; } - border(i, rect, Selborder, red, ZP); + border(i, r, Selborder, red, ZP); wsendctlmesg(w, Reshaped, i->r, i); return 1; case Scroll: @@ -441,26 +405,68 @@ writewctl(Xfid *x, char *err) } return 1; case Unhide: - for(j=0; j<nhidden; j++) - if(hidden[j] == w) - break; - if(j == nhidden){ + switch(wunhide(w)){ + case -1: strcpy(err, "window not hidden"); return -1; - } - if(wunhide(j) == 0){ + case 0: strcpy(err, "hide failed"); return -1; + default: + break; } return 1; case Delete: wsendctlmesg(w, Deleted, ZR, nil); return 1; } + strcpy(err, "invalid wctl message"); return -1; } +int +writewctl(Xfid *x, char *err) +{ + int cnt, cmd, id, hideit, scrollit, pid; + char *arg, *dir; + Rectangle r; + Window *w; + + w = x->f->w; + cnt = x->count; + x->data[cnt] = '\0'; + id = 0; + + r = rectsubpt(w->screenr, screen->r.min); + cmd = parsewctl(&arg, r, &r, &pid, &id, &hideit, &scrollit, &dir, x->data, err); + if(cmd < 0) + return -1; + + if(id != 0){ + w = wlookid(id); + if(w == 0){ + strcpy(err, "no such window id"); + return -1; + } + } + + switch(cmd){ + case New: + return wctlnew(r, arg, pid, hideit, scrollit, dir, err); + case Set: + if(pid > 0) + wsetpid(w, pid, 0); + return 1; + } + + incref(w); + id = wctlcmd(w, r, cmd, err); + wclose(w); + + return id; +} + void wctlthread(void *v) { diff --git a/sys/src/cmd/rio/wind.c b/sys/src/cmd/rio/wind.c index b9c56ab6e..dc7d4a88a 100644 --- a/sys/src/cmd/rio/wind.c +++ b/sys/src/cmd/rio/wind.c @@ -131,7 +131,6 @@ wresize(Window *w, Image *i, int move) draw(i, i->r, w->i, nil, w->i->r.min); freeimage(w->i); w->i = i; - wsetname(w); w->mc.image = i; r = insetrect(i->r, Selborder+1); w->scrollr = r; @@ -151,10 +150,15 @@ wresize(Window *w, Image *i, int move) wsetselect(w, w->q0, w->q1); wscrdraw(w); } - wborder(w, Selborder); + if(w == input) + wborder(w, Selborder); + else + wborder(w, Unselborder); + wsetname(w); w->topped = ++topped; w->resized = TRUE; w->mouse.counter++; + w->wctlready = 1; } void @@ -189,7 +193,7 @@ wclose(Window *w) if(i < 0) error("negative ref count"); if(!w->deleted) - wclosewin(w); + wclunk(w); wsendctlmesg(w, Exited, ZR, nil); return 1; } @@ -1121,24 +1125,16 @@ wctlmesg(Window *w, int m, Rectangle r, Image *i) w->screenr = r; strcpy(buf, w->name); wresize(w, i, m==Moved); - w->wctlready = 1; proccreate(deletetimeoutproc, estrdup(buf), 4096); - if(Dx(r) > 0){ - if(w != input) - wcurrent(w); - }else if(w == input) - wcurrent(nil); - flushimage(display, 1); break; case Refresh: - if(w->deleted || Dx(w->screenr)<=0 || !rectclip(&r, w->i->r)) + if(w->deleted || Dx(w->screenr)<=0 || !rectclip(&r, w->i->r) || w->mouseopen) break; - if(!w->mouseopen) - wrefresh(w, r); + wrefresh(w, r); flushimage(display, 1); break; case Movemouse: - if(sweeping || !ptinrect(r.min, w->i->r)) + if(w->deleted || Dx(w->screenr)<=0 || !ptinrect(r.min, w->i->r)) break; wmovemouse(w, r.min); case Rawon: @@ -1154,6 +1150,7 @@ wctlmesg(Window *w, int m, Rectangle r, Image *i) break; case Holdon: case Holdoff: + case Repaint: if(w->deleted) break; wrepaint(w); @@ -1162,11 +1159,13 @@ wctlmesg(Window *w, int m, Rectangle r, Image *i) case Deleted: if(w->deleted) break; + wclunk(w); write(w->notefd, "hangup", 6); proccreate(deletetimeoutproc, estrdup(w->name), 4096); wclosewin(w); break; case Exited: + wclosewin(w); frclear(w, TRUE); close(w->notefd); chanfree(w->mc.c); @@ -1193,6 +1192,8 @@ wctlmesg(Window *w, int m, Rectangle r, Image *i) void wmovemouse(Window *w, Point p) { + if(w != input || menuing || sweeping) + return; p.x += w->screenr.min.x-w->i->r.min.x; p.y += w->screenr.min.y-w->i->r.min.y; moveto(mousectl, p); @@ -1216,7 +1217,6 @@ wborder(Window *w, int type) else col = lighttitlecol; } - border(w->i, w->i->r, Selborder, col, ZP); } @@ -1230,7 +1230,6 @@ wpointto(Point pt) for(i=0; i<nwindow; i++){ v = window[i]; if(ptinrect(pt, v->screenr)) - if(!v->deleted) if(w==nil || v->topped>w->topped) w = v; } @@ -1246,20 +1245,14 @@ wcurrent(Window *w) return; oi = input; input = w; - if(oi!=w && oi!=nil) - wrepaint(oi); - if(w !=nil){ - wrepaint(w); - wsetcursor(w, 0); - } if(w != oi){ if(oi){ oi->wctlready = 1; - wsendctlmesg(oi, Wakeup, ZR, nil); + wsendctlmesg(oi, Repaint, ZR, nil); } if(w){ w->wctlready = 1; - wsendctlmesg(w, Wakeup, ZR, nil); + wsendctlmesg(w, Repaint, ZR, nil); } } } @@ -1269,7 +1262,7 @@ wsetcursor(Window *w, int force) { Cursor *p; - if(w==nil || /*w!=input || */ w->i==nil || Dx(w->screenr)<=0) + if(w==nil || w->deleted || w->i==nil || Dx(w->screenr)<=0) p = nil; else if(wpointto(mouse->xy) == w){ p = w->cursorp; @@ -1290,30 +1283,14 @@ riosetcursor(Cursor *p, int force) lastcursor = p; } -Window* -wtop(Point pt) -{ - Window *w; - - w = wpointto(pt); - if(w){ - if(w->topped == topped) - return nil; - topwindow(w->i); - wcurrent(w); - flushimage(display, 1); - w->topped = ++topped; - } - return w; -} void wtopme(Window *w) { if(w!=nil && w->i!=nil && !w->deleted && w->topped!=topped){ + w->topped = ++topped; topwindow(w->i); flushimage(display, 1); - w->topped = ++topped; } } @@ -1321,13 +1298,30 @@ void wbottomme(Window *w) { if(w!=nil && w->i!=nil && !w->deleted){ + w->topped = - ++topped; bottomwindow(w->i); flushimage(display, 1); - w->topped = - ++topped; } } Window* +wtop(Point pt) +{ + Window *w; + + w = wpointto(pt); + if(w){ + if(w->topped == topped) + return nil; + incref(w); + wcurrent(w); + wtopme(w); + wclose(w); + } + return w; +} + +Window* wlookid(int id) { int i; @@ -1339,12 +1333,10 @@ wlookid(int id) } void -wclosewin(Window *w) +wclunk(Window *w) { - Rectangle r; int i; - w->deleted = TRUE; if(w == input){ input = nil; wsetcursor(w, 0); @@ -1360,16 +1352,24 @@ wclosewin(Window *w) for(i=0; i<nwindow; i++) if(window[i] == w){ --nwindow; - memmove(window+i, window+i+1, (nwindow-i)*sizeof(Window*)); - w->deleted = TRUE; - r = w->i->r; - /* move it off-screen to hide it, in case client is slow in letting it go */ - MOVEIT originwindow(w->i, r.min, view->r.max); - freeimage(w->i); - w->i = nil; - return; + memmove(window+i, window+i+1, (nwindow-i)*sizeof(window[0])); + break; } - error("unknown window in closewin"); + w->deleted = TRUE; +} + +void +wclosewin(Window *w) +{ + Image *i; + + 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); + } } void |
