void hide(void);
void unhide(int);
void newtile(int);
-Image *sweep(void);
-Image *bandsize(Window*);
-Image* drag(Window*, Rectangle*);
-void refresh(Rectangle);
+Image* sweep(void);
+Image* bandsize(Window*);
+Image* drag(Window*);
void resized(void);
Channel *exitchan; /* chan(int) */
Channel *winclosechan; /* chan(Window*); */
-Channel *kbdchan; /* chan(char*); */
+Channel *kbdchan; /* chan(char*); */
Rectangle viewr;
int threadrforkflag = 0; /* should be RFENVG but that hides rio from plumber */
void mousethread(void*);
void keyboardthread(void*);
-void winclosethread(void*);
-void deletethread(void*);
+void winclosethread(void*);
void initcmd(void*);
Channel* initkbd(void);
char *fontname;
-int mainpid;
-int reverse;
enum
{
Paste,
Snarf,
Plumb,
+ Look,
Send,
Scroll,
};
[Paste] "paste",
[Snarf] "snarf",
[Plumb] "plumb",
+ [Look] "look",
[Send] "send",
[Scroll] "scroll",
nil
threadmain(int argc, char *argv[])
{
char *initstr, *kbdin, *s;
- static void *arg[1];
char buf[256];
Image *i;
Rectangle r;
reverse = ~0xFF;
break;
case 'f':
- fontname = ARGF();
- if(fontname == nil)
- usage();
+ fontname = EARGF(usage());
break;
case 'i':
- initstr = ARGF();
- if(initstr == nil)
- usage();
+ initstr = EARGF(usage());
break;
case 'k':
if(kbdin != nil)
usage();
- kbdin = ARGF();
- if(kbdin == nil)
- usage();
+ kbdin = EARGF(usage());
break;
case 's':
scrolling = TRUE;
break;
+ case 'D':
+ debug++;
+ break;
+ default:
+ usage();
}ARGEND
- mainpid = getpid();
if(getwd(buf, sizeof buf) == nil)
startdir = estrdup(".");
else
exits("display open");
}
iconinit();
+
+ exitchan = chancreate(sizeof(int), 0);
+ winclosechan = chancreate(sizeof(Window*), 0);
+
view = screen;
viewr = view->r;
mousectl = initmouse(nil, screen);
draw(view, viewr, background, nil, ZP);
flushimage(display, 1);
- exitchan = chancreate(sizeof(int), 0);
- winclosechan = chancreate(sizeof(Window*), 0);
- deletechan = chancreate(sizeof(char*), 0);
-
timerinit();
threadcreate(keyboardthread, nil, STACK);
threadcreate(mousethread, nil, STACK);
threadcreate(winclosethread, nil, STACK);
- threadcreate(deletethread, nil, STACK);
filsys = filsysinit(xfidinit());
if(filsys == nil)
if(kbdin){
kbdargv[2] = kbdin;
r = screen->r;
- r.max.x = r.min.x+300;
- r.max.y = r.min.y+80;
- i = allocwindow(wscreen, r, Refbackup, DWhite);
+ r.min.y = r.max.y-Dy(r)/3;
+ i = allocwindow(wscreen, r, Refbackup, DNofill);
wkeyboard = new(i, FALSE, scrolling, 0, nil, "/bin/rc", kbdargv);
if(wkeyboard == nil)
error("can't create keyboard window");
getsnarf(void)
{
int i, n, nb, nulls;
- char *sn, buf[1024];
+ char *s, *sn;
if(snarffd < 0)
return;
sn = nil;
i = 0;
seek(snarffd, 0, 0);
- while((n = read(snarffd, buf, sizeof buf)) > 0){
- sn = erealloc(sn, i+n+1);
- memmove(sn+i, buf, n);
+ for(;;){
+ if(i > MAXSNARF)
+ break;
+ if((s = realloc(sn, i+1024+1)) == nil)
+ break;
+ sn = s;
+ if((n = read(snarffd, sn+i, 1024)) <= 0)
+ break;
i += n;
- sn[i] = 0;
}
- if(i > 0){
- snarf = runerealloc(snarf, i+1);
+ if(i == 0)
+ return;
+ sn[i] = 0;
+ if((snarf = runerealloc(snarf, i+1)) != nil)
cvttorunes(sn, i, snarf, &nb, &nsnarf, &nulls);
- free(sn);
- }
+ free(sn);
}
void
int i;
for(i=0; i<nwindow; i++)
- postnote(PNGROUP, window[i]->pid, "hangup");
+ if(window[i]->notefd >= 0)
+ write(window[i]->notefd, "hangup", 6);
}
void
threadsetname("keyboardthread");
while(s = recvp(kbdchan)){
+ if(*s == 'k' || *s == 'K')
+ shiftdown = utfrune(s+1, Kshift) != nil;
if(input == nil || sendp(input->ck, s) <= 0)
free(s);
}
}
-/*
- * Used by /dev/kbdin
- */
-void
-keyboardsend(char *s, int cnt)
+int
+inborder(Rectangle r, Point xy)
{
- if(cnt <= 0)
- return;
- if(s[cnt-1] == 0)
- chanprint(kbdchan, "%s", s);
- else {
- Rune *r;
- int i, nb, nr;
-
- r = runemalloc(cnt);
- cvttorunes(s, cnt, r, &nb, &nr, nil);
- for(i=0; i<nr; i++){
- if(r[i])
- chanprint(kbdchan, "c%C", r[i]);
- }
- free(r);
+ return ptinrect(xy, r) && !ptinrect(xy, insetrect(r, Selborder));
+}
+
+Rectangle
+whichrect(Rectangle r, Point p, int which)
+{
+ switch(which){
+ case 0: /* top left */
+ r = Rect(p.x, p.y, r.max.x, r.max.y);
+ break;
+ case 2: /* top right */
+ r = Rect(r.min.x, p.y, p.x+1, r.max.y);
+ break;
+ case 6: /* bottom left */
+ r = Rect(p.x, r.min.y, r.max.x, p.y+1);
+ break;
+ case 8: /* bottom right */
+ r = Rect(r.min.x, r.min.y, p.x+1, p.y+1);
+ break;
+ case 1: /* top edge */
+ r = Rect(r.min.x, p.y, r.max.x, r.max.y);
+ break;
+ case 5: /* right edge */
+ r = Rect(r.min.x, r.min.y, p.x+1, r.max.y);
+ break;
+ case 7: /* bottom edge */
+ r = Rect(r.min.x, r.min.y, r.max.x, p.y+1);
+ break;
+ case 3: /* left edge */
+ r = Rect(p.x, r.min.y, r.max.x, r.max.y);
+ break;
}
+ return canonrect(r);
}
int
{
x -= lo;
hi -= lo;
+ if(hi < 20)
+ return x > 0 ? 2 : 0;
if(x < 20)
return 0;
if(x > hi-20)
}
int
-whichcorner(Window *w, Point p)
+whichcorner(Rectangle r, Point p)
{
int i, j;
- i = portion(p.x, w->screenr.min.x, w->screenr.max.x);
- j = portion(p.y, w->screenr.min.y, w->screenr.max.y);
+ i = portion(p.x, r.min.x, r.max.x);
+ j = portion(p.y, r.min.y, r.max.y);
return 3*j+i;
}
-void
-cornercursor(Window *w, Point p, int force)
-{
- if(w!=nil && winborder(w, p))
- riosetcursor(corners[whichcorner(w, p)], force);
- else
- wsetcursor(w, force);
-}
-
/* thread to allow fsysproc to synchronize window closing with main proc */
void
winclosethread(void*)
}
}
-/* thread to make Deleted windows that the client still holds disappear offscreen after an interval */
-void
-deletethread(void*)
-{
- char *s;
- Image *i;
-
- threadsetname("deletethread");
- for(;;){
- s = recvp(deletechan);
- i = namedimage(display, s);
- if(i != nil){
- /* move it off-screen to hide it, since client is slow in letting it go */
- originwindow(i, i->r.min, view->r.max);
- }
- freeimage(i);
- free(s);
- }
-}
-
-void
-deletetimeoutproc(void *v)
-{
- char *s;
-
- s = v;
- sleep(750); /* remove window from screen after 3/4 of a second */
- sendp(deletechan, s);
-}
-
/*
* Button 6 - keyboard toggle - has been pressed.
* Send event to keyboard, wait for button up, send that.
void
mousethread(void*)
{
- int sending, inside, scrolling, moving, band;
- Window *oin, *w, *winput;
+ int sending, inside, scrolling, moving;
+ Window *w, *winput;
Image *i;
- Rectangle r;
Point xy;
Mouse tmp;
enum {
threadsetname("mousethread");
sending = FALSE;
scrolling = FALSE;
- moving = FALSE;
alts[MReshape].c = mousectl->resizec;
alts[MReshape].v = nil;
break;
}
Again:
+ moving = FALSE;
winput = input;
/* override everything for the keyboard window */
if(wkeyboard!=nil && ptinrect(mouse->xy, wkeyboard->screenr)){
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);
else
scrolling = mouse->buttons && ptinrect(xy, winput->scrollr);
/* topped will be zero or less if window has been bottomed */
- if(sending == FALSE && !scrolling && winborder(winput, mouse->xy) && winput->topped>0){
+ if(sending == FALSE && !scrolling && inborder(winput->screenr, mouse->xy) && winput->topped>0)
moving = TRUE;
- }else if(inside && (scrolling || winput->mouseopen || (mouse->buttons&1)))
+ else if(inside && (scrolling || winput->mouseopen || (mouse->buttons&1)))
sending = TRUE;
}else
sending = FALSE;
if(sending){
Sending:
- if(mouse->buttons == 0){
- cornercursor(winput, mouse->xy, 0);
+ wsetcursor(winput, FALSE);
+ if(mouse->buttons == 0)
sending = FALSE;
- }else
- wsetcursor(winput, 0);
tmp = mousectl->Mouse;
tmp.xy = xy;
send(winput->mc.c, &tmp);
continue;
}
- w = wpointto(mouse->xy);
- /* change cursor if over anyone's border */
- if(w != nil)
- cornercursor(w, mouse->xy, 0);
- else
- riosetcursor(nil, 0);
if(moving && (mouse->buttons&7)){
- oin = winput;
- band = mouse->buttons & 3;
- sweeping = 1;
- if(band)
+ incref(winput);
+ sweeping = TRUE;
+ if(mouse->buttons & 3)
i = bandsize(winput);
else
- 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);
- }
+ i = drag(winput);
+ sweeping = FALSE;
+ if(i != nil)
+ wsendctlmesg(winput, Reshaped, i->r, i);
+ wclose(winput);
+ continue;
}
- if(w != nil)
- cornercursor(w, mouse->xy, 0);
+ w = wpointto(mouse->xy);
+ if(w!=nil && inborder(w->screenr, mouse->xy))
+ riosetcursor(corners[whichcorner(w->screenr, mouse->xy)]);
+ else
+ wsetcursor(w, FALSE);
/* 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 */
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{
/* if button 1 event in the window, top the window and wait for button up. */
/* otherwise, top the window and pass the event on */
- if(wtop(mouse->xy) && (mouse->buttons!=1 || winborder(w, mouse->xy)))
+ if(wtop(mouse->xy) && (mouse->buttons!=1 || inborder(w->screenr, mouse->xy)))
goto Again;
goto Drain;
}
}
- moving = FALSE;
break;
Drain:
do
readmouse(mousectl);
while(mousectl->buttons);
- moving = FALSE;
goto Again; /* recalculate mouse position, cursor */
}
}
+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;
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;
r.max.x = (r.max.x*n.x)/o.x;
r.max.y = (r.max.y*n.y)/o.y;
+ r = rectaddpt(r, view->clipr.min);
if(!goodrect(r))
- r = rectsubpt(w->i->r, viewr.min);
- r = rectaddpt(r, screen->clipr.min);
- ishidden = 0;
+ r = rectsubpt(w->i->r, subpt(w->i->r.min, r.min));
for(j=0; j<nhidden; j++)
- if(w == hidden[j]){
- ishidden = 1;
+ if(w == hidden[j])
break;
- }
- if(ishidden){
- im = allocimage(display, r, screen->chan, 0, DWhite);
+ incref(w);
+ if(j < nhidden){
+ im = allocimage(display, r, screen->chan, 0, DNofill);
r = ZR;
- }else
- im = allocwindow(wscreen, r, Refbackup, DWhite);
+ } else
+ im = allocwindow(wscreen, r, Refbackup, DNofill);
if(im)
wsendctlmesg(w, Reshaped, r, im);
+ wclose(w);
}
- viewr = screen->r;
+ viewr = view->r;
flushimage(display, 1);
}
-static int
-wcovered(Window *w, Rectangle r)
+int
+obscured(Window *w, Rectangle r, int i)
{
Window *t;
- int i;
- for(i=0; i<nwindow; i++){
+ if(Dx(r) < font->height || Dy(r) < font->height)
+ return 1;
+ if(!rectclip(&r, screen->r))
+ 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)))
+ 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)))
+ 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)))
+ 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)))
+ if(!obscured(w, Rect(t->screenr.max.x, r.min.y, r.max.x, r.max.y), i))
return 0;
return 1;
}
return 0;
}
+static char*
+shortlabel(char *s)
+{
+ enum { NBUF=60 };
+ static char buf[NBUF*UTFmax];
+ int i, k, l;
+ Rune r;
+
+ l = utflen(s);
+ if(l < NBUF-2)
+ return estrdup(s);
+ k = i = 0;
+ while(i < NBUF/2){
+ k += chartorune(&r, s+k);
+ i++;
+ }
+ strncpy(buf, s, k);
+ strcpy(buf+k, "...");
+ while((l-i) >= NBUF/2-4){
+ k += chartorune(&r, s+k);
+ i++;
+ }
+ strcat(buf, s+k);
+ return estrdup(buf);
+}
+
void
button3menu(void)
{
for(j=0; j<n; j++)
if(window[i] == hidden[j])
break;
- if(i < n || window[i]->deleted)
- continue;
- if(wcovered(window[i], window[i]->screenr)){
- 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;
- for(i=0; i<n; i++)
- menu3str[i+Hidden] = hidden[i]->label;
- menu3str[i+Hidden] = nil;
-
- sweeping = 1;
+ for(i=0; i<n; i++){
+ free(menu3str[i+Hidden]);
+ menu3str[i+Hidden] = shortlabel(hidden[i]->label);
+ }
+ for(i+=Hidden; menu3str[i]; i++){
+ free(menu3str[i]);
+ menu3str[i] = nil;
+ }
+ sweeping = TRUE;
switch(i = menuhit(3, mousectl, &menu3, wscreen)){
case -1:
break;
unhide(i);
break;
}
- sweeping = 0;
+ sweeping = FALSE;
}
void
button2menu(Window *w)
{
- if(w->deleted)
- return;
- incref(w);
if(w->scrolling)
menu2str[Scroll] = "noscroll";
else
wplumb(w);
break;
+ case Look:
+ wlook(w);
+ break;
+
case Send:
getsnarf();
wsnarf(w);
wshow(w, w->nr);
break;
}
- wclose(w);
- wsendctlmesg(w, Wakeup, ZR, nil);
flushimage(display, 1);
+ wsendctlmesg(w, Wakeup, ZR, nil);
}
Point
onscreen(Point p)
{
p.x = max(screen->clipr.min.x, p.x);
- p.x = min(screen->clipr.max.x, p.x);
+ p.x = min(screen->clipr.max.x-1, p.x);
p.y = max(screen->clipr.min.y, p.y);
- p.y = min(screen->clipr.max.y, p.y);
+ p.y = min(screen->clipr.max.y-1, p.y);
return p;
}
i = nil;
menuing = TRUE;
- riosetcursor(&crosscursor, 1);
+ riosetcursor(&crosscursor);
while(mouse->buttons == 0)
readmouse(mousectl);
p0 = onscreen(mouse->xy);
r.max = p;
oi = nil;
while(mouse->buttons == 4){
- readmouse(mousectl);
- if(mouse->buttons != 4 && mouse->buttons != 0)
- break;
if(!eqpt(mouse->xy, p)){
p = onscreen(mouse->xy);
r = canonrect(Rpt(p0, p));
+ r = whichrect(r, p, whichcorner(r, p));
if(Dx(r)>5 && Dy(r)>5){
- i = allocwindow(wscreen, r, Refnone, 0xEEEEEEFF); /* grey */
+ i = allocwindow(wscreen, r, Refnone, DNofill);
freeimage(oi);
if(i == nil)
goto Rescue;
oi = i;
- border(i, r, Selborder, red, ZP);
- flushimage(display, 1);
+ border(i, r, Selborder, sizecol, ZP);
+ draw(i, insetrect(r, Selborder), cols[BACK], nil, ZP);
}
}
+ readmouse(mousectl);
}
if(mouse->buttons != 0)
goto Rescue;
- if(i==nil || Dx(i->r)<100 || Dy(i->r)<3*font->height)
+ if(i==nil || !goodrect(r))
goto Rescue;
oi = i;
- i = allocwindow(wscreen, oi->r, Refbackup, DWhite);
+ i = allocwindow(wscreen, oi->r, Refbackup, DNofill);
freeimage(oi);
if(i == nil)
goto Rescue;
- border(i, r, Selborder, red, ZP);
- cornercursor(input, mouse->xy, 1);
+ riosetcursor(corners[whichcorner(i->r, mouse->xy)]);
goto Return;
Rescue:
+ riosetcursor(nil);
freeimage(i);
i = nil;
- cornercursor(input, mouse->xy, 1);
+ flushimage(display, 1);
while(mouse->buttons)
readmouse(mousectl);
Return:
- moveto(mousectl, mouse->xy); /* force cursor update; ugly */
menuing = FALSE;
return i;
}
originwindow(b, r.min, r.min);
else{
freeimage(b);
- *bp = allocwindow(wscreen, r, Refbackup, DRed);
+ b = allocwindow(wscreen, r, Refbackup, DNofill);
+ if(b != nil) draw(b, r, sizecol, nil, ZP);
+ *bp = b;
}
}
}
Image*
-drag(Window *w, Rectangle *rp)
+drag(Window *w)
{
- Image *i, *ni;
Point p, op, d, dm, om;
Rectangle r;
- i = w->i;
menuing = TRUE;
+ riosetcursor(&boxcursor);
om = mouse->xy;
- riosetcursor(&boxcursor, 1);
- dm = subpt(mouse->xy, w->screenr.min);
- d = subpt(i->r.max, i->r.min);
- op = subpt(mouse->xy, dm);
+ dm = subpt(om, w->screenr.min);
+ d = subpt(w->screenr.max, w->screenr.min);
+ op = subpt(om, dm);
drawborder(Rect(op.x, op.y, op.x+d.x, op.y+d.y), 1);
- flushimage(display, 1);
- while(mouse->buttons == 4){
+ while(mouse->buttons==4){
p = subpt(mouse->xy, dm);
if(!eqpt(p, op)){
drawborder(Rect(p.x, p.y, p.x+d.x, p.y+d.y), 1);
- flushimage(display, 1);
op = p;
}
readmouse(mousectl);
}
r = Rect(op.x, op.y, op.x+d.x, op.y+d.y);
drawborder(r, 0);
- cornercursor(w, mouse->xy, 1);
- moveto(mousectl, mouse->xy); /* force cursor update; ugly */
+ p = mouse->xy;
+ riosetcursor(inborder(r, p) ? corners[whichcorner(r, p)] : nil);
menuing = FALSE;
- flushimage(display, 1);
- if(mouse->buttons!=0 || (ni=allocwindow(wscreen, r, Refbackup, DWhite))==nil){
- moveto(mousectl, om);
+ if(mouse->buttons!=0 || !goodrect(r) || eqrect(r, w->screenr)){
+ flushimage(display, 1);
while(mouse->buttons)
readmouse(mousectl);
- *rp = Rect(0, 0, 0, 0);
return nil;
}
- draw(ni, ni->r, i, nil, i->r.min);
- *rp = r;
- return ni;
-}
-
-Point
-cornerpt(Rectangle r, Point p, int which)
-{
- switch(which){
- case 0: /* top left */
- p = Pt(r.min.x, r.min.y);
- break;
- case 2: /* top right */
- p = Pt(r.max.x,r.min.y);
- break;
- case 6: /* bottom left */
- p = Pt(r.min.x, r.max.y);
- break;
- case 8: /* bottom right */
- p = Pt(r.max.x, r.max.y);
- break;
- case 1: /* top edge */
- p = Pt(p.x,r.min.y);
- break;
- case 5: /* right edge */
- p = Pt(r.max.x, p.y);
- break;
- case 7: /* bottom edge */
- p = Pt(p.x, r.max.y);
- break;
- case 3: /* left edge */
- p = Pt(r.min.x, p.y);
- break;
- }
- return p;
-}
-
-Rectangle
-whichrect(Rectangle r, Point p, int which)
-{
- switch(which){
- case 0: /* top left */
- r = Rect(p.x, p.y, r.max.x, r.max.y);
- break;
- case 2: /* top right */
- r = Rect(r.min.x, p.y, p.x, r.max.y);
- break;
- case 6: /* bottom left */
- r = Rect(p.x, r.min.y, r.max.x, p.y);
- break;
- case 8: /* bottom right */
- r = Rect(r.min.x, r.min.y, p.x, p.y);
- break;
- case 1: /* top edge */
- r = Rect(r.min.x, p.y, r.max.x, r.max.y);
- break;
- case 5: /* right edge */
- r = Rect(r.min.x, r.min.y, p.x, r.max.y);
- break;
- case 7: /* bottom edge */
- r = Rect(r.min.x, r.min.y, r.max.x, p.y);
- break;
- case 3: /* left edge */
- r = Rect(p.x, r.min.y, r.max.x, r.max.y);
- break;
- }
- return canonrect(r);
+ return allocwindow(wscreen, r, Refbackup, DNofill);
}
Image*
bandsize(Window *w)
{
- Image *i;
Rectangle r, or;
Point p, startp;
- int which, but;
+ int which, owhich, but;
- p = mouse->xy;
+ owhich = -1;
+ or = w->screenr;
but = mouse->buttons;
- which = whichcorner(w, p);
- p = cornerpt(w->screenr, p, which);
- wmovemouse(w, p);
- readmouse(mousectl);
- r = whichrect(w->screenr, p, which);
- drawborder(r, 1);
- or = r;
- startp = p;
-
- while(mouse->buttons == but){
+ startp = onscreen(mouse->xy);
+ drawborder(or, 1);
+ while(mouse->buttons == but) {
p = onscreen(mouse->xy);
- r = whichrect(w->screenr, p, which);
+ which = whichcorner(or, p);
+ if(which != owhich && which != 4 && (owhich|~which) & 1){
+ owhich = which;
+ riosetcursor(corners[which]);
+ }
+ r = whichrect(or, p, owhich);
if(!eqrect(r, or) && goodrect(r)){
- drawborder(r, 1);
- flushimage(display, 1);
or = r;
+ drawborder(r, 1);
}
readmouse(mousectl);
}
- p = mouse->xy;
drawborder(or, 0);
- flushimage(display, 1);
- wsetcursor(w, 1);
- if(mouse->buttons!=0 || Dx(or)<100 || Dy(or)<3*font->height){
+ if(mouse->buttons!=0 || !goodrect(or) || eqrect(or, w->screenr)
+ || abs(p.x-startp.x)+abs(p.y-startp.y) <= 1){
+ flushimage(display, 1);
while(mouse->buttons)
readmouse(mousectl);
return nil;
}
- if(abs(p.x-startp.x)+abs(p.y-startp.y) <= 1)
- return nil;
- i = allocwindow(wscreen, or, Refbackup, DWhite);
- if(i == nil)
- return nil;
- border(i, r, Selborder, red, ZP);
- return i;
+ return allocwindow(wscreen, or, Refbackup, DNofill);
}
Window*
Window *w;
menuing = TRUE;
- riosetcursor(&sightcursor, 1);
+ riosetcursor(&sightcursor);
while(mouse->buttons == 0)
readmouse(mousectl);
if(mouse->buttons == 4)
if(wait){
while(mouse->buttons){
if(mouse->buttons!=4 && w !=nil){ /* cancel */
- cornercursor(input, mouse->xy, 0);
+ riosetcursor(nil);
w = nil;
}
readmouse(mousectl);
if(w != nil && wpointto(mouse->xy) != w)
w = nil;
}
- cornercursor(input, mouse->xy, 0);
- moveto(mousectl, mouse->xy); /* force cursor update; ugly */
+ riosetcursor(nil);
menuing = FALSE;
return w;
}
w = pointto(TRUE);
if(w == nil)
return;
+ incref(w);
i = sweep();
if(i)
wsendctlmesg(w, Reshaped, i->r, i);
+ wclose(w);
}
void
{
Window *w;
Image *i;
- Rectangle r;
w = pointto(FALSE);
if(w == nil)
return;
- i = drag(w, &r);
+ incref(w);
+ i = drag(w);
if(i)
- wsendctlmesg(w, Moved, r, i);
- cornercursor(input, mouse->xy, 1);
+ wsendctlmesg(w, Reshaped, i->r, i);
+ wclose(w);
}
int
return -1;
if(nhidden >= nelem(hidden))
return 0;
- i = allocimage(display, w->screenr, w->i->chan, 0, DWhite);
+ incref(w);
+ i = allocimage(display, w->screenr, w->i->chan, 0, DNofill);
if(i){
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;
- }
- i = allocwindow(wscreen, w->i->r, Refbackup, DWhite);
+ 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, DNofill);
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;
}
- return 0;
+ wclose(w);
+ return i!=0;
}
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);
+ wtopme(w);
+ wcurrent(w);
+ wclose(w);
+ return;
+ }
}
Window*
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);
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;
threadcreate(winctl, w, 8192);
if(!hideit)
wcurrent(w);
- flushimage(display, 1);
if(pid == 0){
arg = emalloc(5*sizeof(void*));
arg[0] = w;
if((kfd = open("/dev/kbd", OREAD)) >= 0){
close(fd);
+ /* only serve a kbd file per window when we got one */
+ servekbd = 1;
+
/* read kbd state */
- while((n = read(kfd, buf, sizeof(buf))) > 0)
- chanprint(c, "%.*s", n, buf);
- close(kfd);
+ while((n = read(kfd, buf, sizeof(buf)-1)) > 0){
+ e = buf+n;
+ e[-1] = 0;
+ e[0] = 0;
+ for(p = buf; p < e; p += strlen(p)+1)
+ chanprint(c, "%s", p);
+ }
} else {
/* read single characters */
p = buf;
p = buf + n;
}
}
+ send(exitchan, nil);
}
Channel*
if(e = recvp(c)){
chanfree(c);
c = nil;
- werrstr(e);
+ werrstr("%s", e);
free(e);
}
return c;