summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/cmd/rio/dat.h2
-rw-r--r--sys/src/cmd/rio/fns.h2
-rw-r--r--sys/src/cmd/rio/rio.c170
-rw-r--r--sys/src/cmd/rio/wctl.c112
-rw-r--r--sys/src/cmd/rio/wind.c110
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