17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <thread.h>
57dd7cddfSDavid du Colombier #include <cursor.h>
67dd7cddfSDavid du Colombier #include <mouse.h>
77dd7cddfSDavid du Colombier #include <keyboard.h>
87dd7cddfSDavid du Colombier #include <frame.h>
97dd7cddfSDavid du Colombier #include <fcall.h>
107dd7cddfSDavid du Colombier #include <plumb.h>
117dd7cddfSDavid du Colombier #include "dat.h"
127dd7cddfSDavid du Colombier #include "fns.h"
137dd7cddfSDavid du Colombier
147dd7cddfSDavid du Colombier void
colinit(Column * c,Rectangle r)157dd7cddfSDavid du Colombier colinit(Column *c, Rectangle r)
167dd7cddfSDavid du Colombier {
177dd7cddfSDavid du Colombier Rectangle r1;
187dd7cddfSDavid du Colombier Text *t;
197dd7cddfSDavid du Colombier
207dd7cddfSDavid du Colombier draw(screen, r, display->white, nil, ZP);
217dd7cddfSDavid du Colombier c->r = r;
227dd7cddfSDavid du Colombier c->w = nil;
237dd7cddfSDavid du Colombier c->nw = 0;
247dd7cddfSDavid du Colombier t = &c->tag;
257dd7cddfSDavid du Colombier t->w = nil;
267dd7cddfSDavid du Colombier t->col = c;
277dd7cddfSDavid du Colombier r1 = r;
287dd7cddfSDavid du Colombier r1.max.y = r1.min.y + font->height;
297dd7cddfSDavid du Colombier textinit(t, fileaddtext(nil, t), r1, &reffont, tagcols);
307dd7cddfSDavid du Colombier t->what = Columntag;
317dd7cddfSDavid du Colombier r1.min.y = r1.max.y;
327dd7cddfSDavid du Colombier r1.max.y += Border;
337dd7cddfSDavid du Colombier draw(screen, r1, display->black, nil, ZP);
347dd7cddfSDavid du Colombier textinsert(t, 0, L"New Cut Paste Snarf Sort Zerox Delcol ", 38, TRUE);
357dd7cddfSDavid du Colombier textsetselect(t, t->file->nc, t->file->nc);
367dd7cddfSDavid du Colombier draw(screen, t->scrollr, colbutton, nil, colbutton->r.min);
377dd7cddfSDavid du Colombier c->safe = TRUE;
387dd7cddfSDavid du Colombier }
397dd7cddfSDavid du Colombier
407dd7cddfSDavid du Colombier Window*
coladd(Column * c,Window * w,Window * clone,int y)417dd7cddfSDavid du Colombier coladd(Column *c, Window *w, Window *clone, int y)
427dd7cddfSDavid du Colombier {
437dd7cddfSDavid du Colombier Rectangle r, r1;
447dd7cddfSDavid du Colombier Window *v;
457dd7cddfSDavid du Colombier int i, t;
467dd7cddfSDavid du Colombier
477dd7cddfSDavid du Colombier v = nil;
487dd7cddfSDavid du Colombier r = c->r;
497dd7cddfSDavid du Colombier r.min.y = c->tag.r.max.y+Border;
507dd7cddfSDavid du Colombier if(y<r.min.y && c->nw>0){ /* steal half of last window by default */
517dd7cddfSDavid du Colombier v = c->w[c->nw-1];
527dd7cddfSDavid du Colombier y = v->body.r.min.y+Dy(v->body.r)/2;
537dd7cddfSDavid du Colombier }
547dd7cddfSDavid du Colombier /* look for window we'll land on */
557dd7cddfSDavid du Colombier for(i=0; i<c->nw; i++){
567dd7cddfSDavid du Colombier v = c->w[i];
577dd7cddfSDavid du Colombier if(y < v->r.max.y)
587dd7cddfSDavid du Colombier break;
597dd7cddfSDavid du Colombier }
607dd7cddfSDavid du Colombier if(c->nw > 0){
617dd7cddfSDavid du Colombier if(i < c->nw)
627dd7cddfSDavid du Colombier i++; /* new window will go after v */
637dd7cddfSDavid du Colombier /*
647dd7cddfSDavid du Colombier * if v's too small, grow it first.
657dd7cddfSDavid du Colombier */
667dd7cddfSDavid du Colombier if(!c->safe || v->body.maxlines<=3){
677dd7cddfSDavid du Colombier colgrow(c, v, 1);
687dd7cddfSDavid du Colombier y = v->body.r.min.y+Dy(v->body.r)/2;
697dd7cddfSDavid du Colombier }
707dd7cddfSDavid du Colombier r = v->r;
717dd7cddfSDavid du Colombier if(i == c->nw)
727dd7cddfSDavid du Colombier t = c->r.max.y;
737dd7cddfSDavid du Colombier else
747dd7cddfSDavid du Colombier t = c->w[i]->r.min.y-Border;
757dd7cddfSDavid du Colombier r.max.y = t;
767dd7cddfSDavid du Colombier draw(screen, r, textcols[BACK], nil, ZP);
777dd7cddfSDavid du Colombier r1 = r;
787dd7cddfSDavid du Colombier y = min(y, t-(v->tag.font->height+v->body.font->height+Border+1));
797dd7cddfSDavid du Colombier r1.max.y = min(y, v->body.r.min.y+v->body.nlines*v->body.font->height);
807dd7cddfSDavid du Colombier r1.min.y = winresize(v, r1, FALSE);
817dd7cddfSDavid du Colombier r1.max.y = r1.min.y+Border;
827dd7cddfSDavid du Colombier draw(screen, r1, display->black, nil, ZP);
837dd7cddfSDavid du Colombier r.min.y = r1.max.y;
847dd7cddfSDavid du Colombier }
857dd7cddfSDavid du Colombier if(w == nil){
867dd7cddfSDavid du Colombier w = emalloc(sizeof(Window));
877dd7cddfSDavid du Colombier w->col = c;
887dd7cddfSDavid du Colombier draw(screen, r, textcols[BACK], nil, ZP);
897dd7cddfSDavid du Colombier wininit(w, clone, r);
907dd7cddfSDavid du Colombier }else{
917dd7cddfSDavid du Colombier w->col = c;
927dd7cddfSDavid du Colombier winresize(w, r, FALSE);
937dd7cddfSDavid du Colombier }
947dd7cddfSDavid du Colombier w->tag.col = c;
957dd7cddfSDavid du Colombier w->tag.row = c->row;
967dd7cddfSDavid du Colombier w->body.col = c;
977dd7cddfSDavid du Colombier w->body.row = c->row;
987dd7cddfSDavid du Colombier c->w = realloc(c->w, (c->nw+1)*sizeof(Window*));
997dd7cddfSDavid du Colombier memmove(c->w+i+1, c->w+i, (c->nw-i)*sizeof(Window*));
1007dd7cddfSDavid du Colombier c->nw++;
1017dd7cddfSDavid du Colombier c->w[i] = w;
1027dd7cddfSDavid du Colombier savemouse(w);
1037dd7cddfSDavid du Colombier /* near but not on the button */
1047dd7cddfSDavid du Colombier moveto(mousectl, addpt(w->tag.scrollr.max, Pt(3, 3)));
1057dd7cddfSDavid du Colombier barttext = &w->body;
1067dd7cddfSDavid du Colombier c->safe = TRUE;
1077dd7cddfSDavid du Colombier return w;
1087dd7cddfSDavid du Colombier }
1097dd7cddfSDavid du Colombier
1107dd7cddfSDavid du Colombier void
colclose(Column * c,Window * w,int dofree)1117dd7cddfSDavid du Colombier colclose(Column *c, Window *w, int dofree)
1127dd7cddfSDavid du Colombier {
1137dd7cddfSDavid du Colombier Rectangle r;
114*588d0145SDavid du Colombier int i, didmouse, up;
1157dd7cddfSDavid du Colombier
1167dd7cddfSDavid du Colombier /* w is locked */
1177dd7cddfSDavid du Colombier if(!c->safe)
1187dd7cddfSDavid du Colombier colgrow(c, w, 1);
1197dd7cddfSDavid du Colombier for(i=0; i<c->nw; i++)
1207dd7cddfSDavid du Colombier if(c->w[i] == w)
1217dd7cddfSDavid du Colombier goto Found;
1227dd7cddfSDavid du Colombier error("can't find window");
1237dd7cddfSDavid du Colombier Found:
1247dd7cddfSDavid du Colombier r = w->r;
1257dd7cddfSDavid du Colombier w->tag.col = nil;
1267dd7cddfSDavid du Colombier w->body.col = nil;
1277dd7cddfSDavid du Colombier w->col = nil;
128*588d0145SDavid du Colombier didmouse = restoremouse(w);
1297dd7cddfSDavid du Colombier if(dofree){
1307dd7cddfSDavid du Colombier windelete(w);
1317dd7cddfSDavid du Colombier winclose(w);
1327dd7cddfSDavid du Colombier }
1337dd7cddfSDavid du Colombier memmove(c->w+i, c->w+i+1, (c->nw-i)*sizeof(Window*));
1347dd7cddfSDavid du Colombier c->nw--;
1357dd7cddfSDavid du Colombier c->w = realloc(c->w, c->nw*sizeof(Window*));
1367dd7cddfSDavid du Colombier if(c->nw == 0){
1377dd7cddfSDavid du Colombier draw(screen, r, display->white, nil, ZP);
1387dd7cddfSDavid du Colombier return;
1397dd7cddfSDavid du Colombier }
140*588d0145SDavid du Colombier up = 0;
1417dd7cddfSDavid du Colombier if(i == c->nw){ /* extend last window down */
1427dd7cddfSDavid du Colombier w = c->w[i-1];
1437dd7cddfSDavid du Colombier r.min.y = w->r.min.y;
1447dd7cddfSDavid du Colombier r.max.y = c->r.max.y;
1457dd7cddfSDavid du Colombier }else{ /* extend next window up */
1467dd7cddfSDavid du Colombier w = c->w[i];
1477dd7cddfSDavid du Colombier r.max.y = w->r.max.y;
148*588d0145SDavid du Colombier up = 1;
1497dd7cddfSDavid du Colombier }
1507dd7cddfSDavid du Colombier draw(screen, r, textcols[BACK], nil, ZP);
151*588d0145SDavid du Colombier if(c->safe){
1527dd7cddfSDavid du Colombier winresize(w, r, FALSE);
153*588d0145SDavid du Colombier USED(up);
154*588d0145SDavid du Colombier if(!didmouse)
155*588d0145SDavid du Colombier movetodel(w);
156*588d0145SDavid du Colombier }
1577dd7cddfSDavid du Colombier }
1587dd7cddfSDavid du Colombier
1597dd7cddfSDavid du Colombier void
colcloseall(Column * c)1607dd7cddfSDavid du Colombier colcloseall(Column *c)
1617dd7cddfSDavid du Colombier {
1627dd7cddfSDavid du Colombier int i;
1637dd7cddfSDavid du Colombier Window *w;
1647dd7cddfSDavid du Colombier
1657dd7cddfSDavid du Colombier if(c == activecol)
1667dd7cddfSDavid du Colombier activecol = nil;
1677dd7cddfSDavid du Colombier textclose(&c->tag);
1687dd7cddfSDavid du Colombier for(i=0; i<c->nw; i++){
1697dd7cddfSDavid du Colombier w = c->w[i];
1707dd7cddfSDavid du Colombier winclose(w);
1717dd7cddfSDavid du Colombier }
1727dd7cddfSDavid du Colombier c->nw = 0;
1737dd7cddfSDavid du Colombier free(c->w);
1747dd7cddfSDavid du Colombier free(c);
1757dd7cddfSDavid du Colombier clearmouse();
1767dd7cddfSDavid du Colombier }
1777dd7cddfSDavid du Colombier
1787dd7cddfSDavid du Colombier void
colmousebut(Column * c)1797dd7cddfSDavid du Colombier colmousebut(Column *c)
1807dd7cddfSDavid du Colombier {
1817dd7cddfSDavid du Colombier moveto(mousectl, divpt(addpt(c->tag.scrollr.min, c->tag.scrollr.max), 2));
1827dd7cddfSDavid du Colombier }
1837dd7cddfSDavid du Colombier
1847dd7cddfSDavid du Colombier void
colresize(Column * c,Rectangle r)1857dd7cddfSDavid du Colombier colresize(Column *c, Rectangle r)
1867dd7cddfSDavid du Colombier {
1877dd7cddfSDavid du Colombier int i;
1887dd7cddfSDavid du Colombier Rectangle r1, r2;
1897dd7cddfSDavid du Colombier Window *w;
1907dd7cddfSDavid du Colombier
1917dd7cddfSDavid du Colombier clearmouse();
1927dd7cddfSDavid du Colombier r1 = r;
1937dd7cddfSDavid du Colombier r1.max.y = r1.min.y + c->tag.font->height;
1947dd7cddfSDavid du Colombier textresize(&c->tag, r1);
1957dd7cddfSDavid du Colombier draw(screen, c->tag.scrollr, colbutton, nil, colbutton->r.min);
1967dd7cddfSDavid du Colombier r1.min.y = r1.max.y;
1977dd7cddfSDavid du Colombier r1.max.y += Border;
1987dd7cddfSDavid du Colombier draw(screen, r1, display->black, nil, ZP);
1997dd7cddfSDavid du Colombier r1.max.y = r.max.y;
2007dd7cddfSDavid du Colombier for(i=0; i<c->nw; i++){
2017dd7cddfSDavid du Colombier w = c->w[i];
2027dd7cddfSDavid du Colombier w->maxlines = 0;
2037dd7cddfSDavid du Colombier if(i == c->nw-1)
2047dd7cddfSDavid du Colombier r1.max.y = r.max.y;
2057dd7cddfSDavid du Colombier else
2067dd7cddfSDavid du Colombier r1.max.y = r1.min.y+(Dy(w->r)+Border)*Dy(r)/Dy(c->r);
2077dd7cddfSDavid du Colombier r2 = r1;
2087dd7cddfSDavid du Colombier r2.max.y = r2.min.y+Border;
2097dd7cddfSDavid du Colombier draw(screen, r2, display->black, nil, ZP);
2107dd7cddfSDavid du Colombier r1.min.y = r2.max.y;
2117dd7cddfSDavid du Colombier r1.min.y = winresize(w, r1, FALSE);
2127dd7cddfSDavid du Colombier }
2137dd7cddfSDavid du Colombier c->r = r;
2147dd7cddfSDavid du Colombier }
2157dd7cddfSDavid du Colombier
2167dd7cddfSDavid du Colombier static
2177dd7cddfSDavid du Colombier int
colcmp(void * a,void * b)2187dd7cddfSDavid du Colombier colcmp(void *a, void *b)
2197dd7cddfSDavid du Colombier {
2207dd7cddfSDavid du Colombier Rune *r1, *r2;
2217dd7cddfSDavid du Colombier int i, nr1, nr2;
2227dd7cddfSDavid du Colombier
2237dd7cddfSDavid du Colombier r1 = (*(Window**)a)->body.file->name;
2247dd7cddfSDavid du Colombier nr1 = (*(Window**)a)->body.file->nname;
2257dd7cddfSDavid du Colombier r2 = (*(Window**)b)->body.file->name;
2267dd7cddfSDavid du Colombier nr2 = (*(Window**)b)->body.file->nname;
2277dd7cddfSDavid du Colombier for(i=0; i<nr1 && i<nr2; i++){
2287dd7cddfSDavid du Colombier if(*r1 != *r2)
2297dd7cddfSDavid du Colombier return *r1-*r2;
2307dd7cddfSDavid du Colombier r1++;
2317dd7cddfSDavid du Colombier r2++;
2327dd7cddfSDavid du Colombier }
2337dd7cddfSDavid du Colombier return nr1-nr2;
2347dd7cddfSDavid du Colombier }
2357dd7cddfSDavid du Colombier
2367dd7cddfSDavid du Colombier void
colsort(Column * c)2377dd7cddfSDavid du Colombier colsort(Column *c)
2387dd7cddfSDavid du Colombier {
2397dd7cddfSDavid du Colombier int i, y;
2407dd7cddfSDavid du Colombier Rectangle r, r1, *rp;
2417dd7cddfSDavid du Colombier Window **wp, *w;
2427dd7cddfSDavid du Colombier
2437dd7cddfSDavid du Colombier if(c->nw == 0)
2447dd7cddfSDavid du Colombier return;
2457dd7cddfSDavid du Colombier clearmouse();
2467dd7cddfSDavid du Colombier rp = emalloc(c->nw*sizeof(Rectangle));
2477dd7cddfSDavid du Colombier wp = emalloc(c->nw*sizeof(Window*));
2487dd7cddfSDavid du Colombier memmove(wp, c->w, c->nw*sizeof(Window*));
2497dd7cddfSDavid du Colombier qsort(wp, c->nw, sizeof(Window*), colcmp);
2507dd7cddfSDavid du Colombier for(i=0; i<c->nw; i++)
2517dd7cddfSDavid du Colombier rp[i] = wp[i]->r;
2527dd7cddfSDavid du Colombier r = c->r;
2537dd7cddfSDavid du Colombier r.min.y = c->tag.r.max.y;
2547dd7cddfSDavid du Colombier draw(screen, r, textcols[BACK], nil, ZP);
2557dd7cddfSDavid du Colombier y = r.min.y;
2567dd7cddfSDavid du Colombier for(i=0; i<c->nw; i++){
2577dd7cddfSDavid du Colombier w = wp[i];
2587dd7cddfSDavid du Colombier r.min.y = y;
2597dd7cddfSDavid du Colombier if(i == c->nw-1)
2607dd7cddfSDavid du Colombier r.max.y = c->r.max.y;
2617dd7cddfSDavid du Colombier else
2627dd7cddfSDavid du Colombier r.max.y = r.min.y+Dy(w->r)+Border;
2637dd7cddfSDavid du Colombier r1 = r;
2647dd7cddfSDavid du Colombier r1.max.y = r1.min.y+Border;
2657dd7cddfSDavid du Colombier draw(screen, r1, display->black, nil, ZP);
2667dd7cddfSDavid du Colombier r.min.y = r1.max.y;
2677dd7cddfSDavid du Colombier y = winresize(w, r, FALSE);
2687dd7cddfSDavid du Colombier }
2697dd7cddfSDavid du Colombier free(rp);
2707dd7cddfSDavid du Colombier free(c->w);
2717dd7cddfSDavid du Colombier c->w = wp;
2727dd7cddfSDavid du Colombier }
2737dd7cddfSDavid du Colombier
2747dd7cddfSDavid du Colombier void
colgrow(Column * c,Window * w,int but)2757dd7cddfSDavid du Colombier colgrow(Column *c, Window *w, int but)
2767dd7cddfSDavid du Colombier {
2777dd7cddfSDavid du Colombier Rectangle r, cr;
2787dd7cddfSDavid du Colombier int i, j, k, l, y1, y2, *nl, *ny, tot, nnl, onl, dnl, h;
2797dd7cddfSDavid du Colombier Window *v;
2807dd7cddfSDavid du Colombier
2817dd7cddfSDavid du Colombier for(i=0; i<c->nw; i++)
2827dd7cddfSDavid du Colombier if(c->w[i] == w)
2837dd7cddfSDavid du Colombier goto Found;
2847dd7cddfSDavid du Colombier error("can't find window");
2857dd7cddfSDavid du Colombier
2867dd7cddfSDavid du Colombier Found:
2877dd7cddfSDavid du Colombier cr = c->r;
2887dd7cddfSDavid du Colombier if(but < 0){ /* make sure window fills its own space properly */
2897dd7cddfSDavid du Colombier r = w->r;
2903ff48bf5SDavid du Colombier if(i==c->nw-1 || c->safe==FALSE)
2917dd7cddfSDavid du Colombier r.max.y = cr.max.y;
2927dd7cddfSDavid du Colombier else
2937dd7cddfSDavid du Colombier r.max.y = c->w[i+1]->r.min.y;
2947dd7cddfSDavid du Colombier winresize(w, r, FALSE);
2957dd7cddfSDavid du Colombier return;
2967dd7cddfSDavid du Colombier }
2977dd7cddfSDavid du Colombier cr.min.y = c->w[0]->r.min.y;
2987dd7cddfSDavid du Colombier if(but == 3){ /* full size */
2997dd7cddfSDavid du Colombier if(i != 0){
3007dd7cddfSDavid du Colombier v = c->w[0];
3017dd7cddfSDavid du Colombier c->w[0] = w;
3027dd7cddfSDavid du Colombier c->w[i] = v;
3037dd7cddfSDavid du Colombier }
3047dd7cddfSDavid du Colombier draw(screen, cr, textcols[BACK], nil, ZP);
3057dd7cddfSDavid du Colombier winresize(w, cr, FALSE);
3067dd7cddfSDavid du Colombier for(i=1; i<c->nw; i++)
3077dd7cddfSDavid du Colombier c->w[i]->body.maxlines = 0;
3087dd7cddfSDavid du Colombier c->safe = FALSE;
3097dd7cddfSDavid du Colombier return;
3107dd7cddfSDavid du Colombier }
3117dd7cddfSDavid du Colombier /* store old #lines for each window */
3127dd7cddfSDavid du Colombier onl = w->body.maxlines;
3137dd7cddfSDavid du Colombier nl = emalloc(c->nw * sizeof(int));
3147dd7cddfSDavid du Colombier ny = emalloc(c->nw * sizeof(int));
3157dd7cddfSDavid du Colombier tot = 0;
3167dd7cddfSDavid du Colombier for(j=0; j<c->nw; j++){
3177dd7cddfSDavid du Colombier l = c->w[j]->body.maxlines;
3187dd7cddfSDavid du Colombier nl[j] = l;
3197dd7cddfSDavid du Colombier tot += l;
3207dd7cddfSDavid du Colombier }
3217dd7cddfSDavid du Colombier /* approximate new #lines for this window */
3227dd7cddfSDavid du Colombier if(but == 2){ /* as big as can be */
3237dd7cddfSDavid du Colombier memset(nl, 0, c->nw * sizeof(int));
3247dd7cddfSDavid du Colombier goto Pack;
3257dd7cddfSDavid du Colombier }
3267dd7cddfSDavid du Colombier nnl = min(onl + max(min(5, w->maxlines), onl/2), tot);
3277dd7cddfSDavid du Colombier if(nnl < w->maxlines)
3287dd7cddfSDavid du Colombier nnl = (w->maxlines+nnl)/2;
3297dd7cddfSDavid du Colombier if(nnl == 0)
3307dd7cddfSDavid du Colombier nnl = 2;
3317dd7cddfSDavid du Colombier dnl = nnl - onl;
3327dd7cddfSDavid du Colombier /* compute new #lines for each window */
3337dd7cddfSDavid du Colombier for(k=1; k<c->nw; k++){
3347dd7cddfSDavid du Colombier /* prune from later window */
3357dd7cddfSDavid du Colombier j = i+k;
3367dd7cddfSDavid du Colombier if(j<c->nw && nl[j]){
3377dd7cddfSDavid du Colombier l = min(dnl, max(1, nl[j]/2));
3387dd7cddfSDavid du Colombier nl[j] -= l;
3397dd7cddfSDavid du Colombier nl[i] += l;
3407dd7cddfSDavid du Colombier dnl -= l;
3417dd7cddfSDavid du Colombier }
3427dd7cddfSDavid du Colombier /* prune from earlier window */
3437dd7cddfSDavid du Colombier j = i-k;
3447dd7cddfSDavid du Colombier if(j>=0 && nl[j]){
3457dd7cddfSDavid du Colombier l = min(dnl, max(1, nl[j]/2));
3467dd7cddfSDavid du Colombier nl[j] -= l;
3477dd7cddfSDavid du Colombier nl[i] += l;
3487dd7cddfSDavid du Colombier dnl -= l;
3497dd7cddfSDavid du Colombier }
3507dd7cddfSDavid du Colombier }
3517dd7cddfSDavid du Colombier Pack:
3527dd7cddfSDavid du Colombier /* pack everyone above */
3537dd7cddfSDavid du Colombier y1 = cr.min.y;
3547dd7cddfSDavid du Colombier for(j=0; j<i; j++){
3557dd7cddfSDavid du Colombier v = c->w[j];
3567dd7cddfSDavid du Colombier r = v->r;
3577dd7cddfSDavid du Colombier r.min.y = y1;
3587dd7cddfSDavid du Colombier r.max.y = y1+Dy(v->tag.all);
3597dd7cddfSDavid du Colombier if(nl[j])
3607dd7cddfSDavid du Colombier r.max.y += 1 + nl[j]*v->body.font->height;
3617dd7cddfSDavid du Colombier if(!c->safe || !eqrect(v->r, r)){
3627dd7cddfSDavid du Colombier draw(screen, r, textcols[BACK], nil, ZP);
3637dd7cddfSDavid du Colombier winresize(v, r, c->safe);
3647dd7cddfSDavid du Colombier }
3657dd7cddfSDavid du Colombier r.min.y = v->r.max.y;
3667dd7cddfSDavid du Colombier r.max.y += Border;
3677dd7cddfSDavid du Colombier draw(screen, r, display->black, nil, ZP);
3687dd7cddfSDavid du Colombier y1 = r.max.y;
3697dd7cddfSDavid du Colombier }
3707dd7cddfSDavid du Colombier /* scan to see new size of everyone below */
3717dd7cddfSDavid du Colombier y2 = c->r.max.y;
3727dd7cddfSDavid du Colombier for(j=c->nw-1; j>i; j--){
3737dd7cddfSDavid du Colombier v = c->w[j];
3747dd7cddfSDavid du Colombier r = v->r;
3757dd7cddfSDavid du Colombier r.min.y = y2-Dy(v->tag.all);
3767dd7cddfSDavid du Colombier if(nl[j])
3777dd7cddfSDavid du Colombier r.min.y -= 1 + nl[j]*v->body.font->height;
3787dd7cddfSDavid du Colombier r.min.y -= Border;
3797dd7cddfSDavid du Colombier ny[j] = r.min.y;
3807dd7cddfSDavid du Colombier y2 = r.min.y;
3817dd7cddfSDavid du Colombier }
3827dd7cddfSDavid du Colombier /* compute new size of window */
3837dd7cddfSDavid du Colombier r = w->r;
3847dd7cddfSDavid du Colombier r.min.y = y1;
3857dd7cddfSDavid du Colombier r.max.y = r.min.y+Dy(w->tag.all);
3867dd7cddfSDavid du Colombier h = w->body.font->height;
3877dd7cddfSDavid du Colombier if(y2-r.max.y >= 1+h+Border){
3887dd7cddfSDavid du Colombier r.max.y += 1;
3897dd7cddfSDavid du Colombier r.max.y += h*((y2-r.max.y)/h);
3907dd7cddfSDavid du Colombier }
3917dd7cddfSDavid du Colombier /* draw window */
3927dd7cddfSDavid du Colombier if(!c->safe || !eqrect(w->r, r)){
3937dd7cddfSDavid du Colombier draw(screen, r, textcols[BACK], nil, ZP);
3947dd7cddfSDavid du Colombier winresize(w, r, c->safe);
3957dd7cddfSDavid du Colombier }
3967dd7cddfSDavid du Colombier if(i < c->nw-1){
3977dd7cddfSDavid du Colombier r.min.y = r.max.y;
3987dd7cddfSDavid du Colombier r.max.y += Border;
3997dd7cddfSDavid du Colombier draw(screen, r, display->black, nil, ZP);
4007dd7cddfSDavid du Colombier for(j=i+1; j<c->nw; j++)
4017dd7cddfSDavid du Colombier ny[j] -= (y2-r.max.y);
4027dd7cddfSDavid du Colombier }
4037dd7cddfSDavid du Colombier /* pack everyone below */
4047dd7cddfSDavid du Colombier y1 = r.max.y;
4057dd7cddfSDavid du Colombier for(j=i+1; j<c->nw; j++){
4067dd7cddfSDavid du Colombier v = c->w[j];
4077dd7cddfSDavid du Colombier r = v->r;
4087dd7cddfSDavid du Colombier r.min.y = y1;
4097dd7cddfSDavid du Colombier r.max.y = y1+Dy(v->tag.all);
4107dd7cddfSDavid du Colombier if(nl[j])
4117dd7cddfSDavid du Colombier r.max.y += 1 + nl[j]*v->body.font->height;
4127dd7cddfSDavid du Colombier if(!c->safe || !eqrect(v->r, r)){
4137dd7cddfSDavid du Colombier draw(screen, r, textcols[BACK], nil, ZP);
4147dd7cddfSDavid du Colombier winresize(v, r, c->safe);
4157dd7cddfSDavid du Colombier }
4167dd7cddfSDavid du Colombier if(j < c->nw-1){ /* no border on last window */
4177dd7cddfSDavid du Colombier r.min.y = v->r.max.y;
4187dd7cddfSDavid du Colombier r.max.y += Border;
4197dd7cddfSDavid du Colombier draw(screen, r, display->black, nil, ZP);
4207dd7cddfSDavid du Colombier }
4217dd7cddfSDavid du Colombier y1 = r.max.y;
4227dd7cddfSDavid du Colombier }
4237dd7cddfSDavid du Colombier r = w->r;
4247dd7cddfSDavid du Colombier r.min.y = y1;
4257dd7cddfSDavid du Colombier r.max.y = c->r.max.y;
4267dd7cddfSDavid du Colombier draw(screen, r, textcols[BACK], nil, ZP);
4277dd7cddfSDavid du Colombier free(nl);
4287dd7cddfSDavid du Colombier free(ny);
4297dd7cddfSDavid du Colombier c->safe = TRUE;
4307dd7cddfSDavid du Colombier winmousebut(w);
4317dd7cddfSDavid du Colombier }
4327dd7cddfSDavid du Colombier
4337dd7cddfSDavid du Colombier void
coldragwin(Column * c,Window * w,int but)4347dd7cddfSDavid du Colombier coldragwin(Column *c, Window *w, int but)
4357dd7cddfSDavid du Colombier {
4367dd7cddfSDavid du Colombier Rectangle r;
4377dd7cddfSDavid du Colombier int i, b;
4387dd7cddfSDavid du Colombier Point p, op;
4397dd7cddfSDavid du Colombier Window *v;
4407dd7cddfSDavid du Colombier Column *nc;
4417dd7cddfSDavid du Colombier
4427dd7cddfSDavid du Colombier clearmouse();
4437dd7cddfSDavid du Colombier setcursor(mousectl, &boxcursor);
4447dd7cddfSDavid du Colombier b = mouse->buttons;
4457dd7cddfSDavid du Colombier op = mouse->xy;
4467dd7cddfSDavid du Colombier while(mouse->buttons == b)
4477dd7cddfSDavid du Colombier readmouse(mousectl);
4487dd7cddfSDavid du Colombier setcursor(mousectl, nil);
4497dd7cddfSDavid du Colombier if(mouse->buttons){
4507dd7cddfSDavid du Colombier while(mouse->buttons)
4517dd7cddfSDavid du Colombier readmouse(mousectl);
4527dd7cddfSDavid du Colombier return;
4537dd7cddfSDavid du Colombier }
4547dd7cddfSDavid du Colombier
4557dd7cddfSDavid du Colombier for(i=0; i<c->nw; i++)
4567dd7cddfSDavid du Colombier if(c->w[i] == w)
4577dd7cddfSDavid du Colombier goto Found;
4587dd7cddfSDavid du Colombier error("can't find window");
4597dd7cddfSDavid du Colombier
4607dd7cddfSDavid du Colombier Found:
4617dd7cddfSDavid du Colombier p = mouse->xy;
4627dd7cddfSDavid du Colombier if(abs(p.x-op.x)<5 && abs(p.y-op.y)<5){
4637dd7cddfSDavid du Colombier colgrow(c, w, but);
4647dd7cddfSDavid du Colombier winmousebut(w);
4657dd7cddfSDavid du Colombier return;
4667dd7cddfSDavid du Colombier }
4677dd7cddfSDavid du Colombier /* is it a flick to the right? */
4683ff48bf5SDavid du Colombier if(abs(p.y-op.y)<10 && p.x>op.x+30 && rowwhichcol(c->row, p)==c)
4693df12bc6SDavid du Colombier p.x = op.x+Dx(w->r); /* yes: toss to next column */
4707dd7cddfSDavid du Colombier nc = rowwhichcol(c->row, p);
4717dd7cddfSDavid du Colombier if(nc!=nil && nc!=c){
4727dd7cddfSDavid du Colombier colclose(c, w, FALSE);
4737dd7cddfSDavid du Colombier coladd(nc, w, nil, p.y);
4747dd7cddfSDavid du Colombier winmousebut(w);
4757dd7cddfSDavid du Colombier return;
4767dd7cddfSDavid du Colombier }
4777dd7cddfSDavid du Colombier if(i==0 && c->nw==1)
4787dd7cddfSDavid du Colombier return; /* can't do it */
4797dd7cddfSDavid du Colombier if((i>0 && p.y<c->w[i-1]->r.min.y) || (i<c->nw-1 && p.y>w->r.max.y)
4807dd7cddfSDavid du Colombier || (i==0 && p.y>w->r.max.y)){
4817dd7cddfSDavid du Colombier /* shuffle */
4827dd7cddfSDavid du Colombier colclose(c, w, FALSE);
4837dd7cddfSDavid du Colombier coladd(c, w, nil, p.y);
4847dd7cddfSDavid du Colombier winmousebut(w);
4857dd7cddfSDavid du Colombier return;
4867dd7cddfSDavid du Colombier }
4877dd7cddfSDavid du Colombier if(i == 0)
4887dd7cddfSDavid du Colombier return;
4897dd7cddfSDavid du Colombier v = c->w[i-1];
4907dd7cddfSDavid du Colombier if(p.y < v->tag.all.max.y)
4917dd7cddfSDavid du Colombier p.y = v->tag.all.max.y;
4927dd7cddfSDavid du Colombier if(p.y > w->r.max.y-Dy(w->tag.all)-Border)
4937dd7cddfSDavid du Colombier p.y = w->r.max.y-Dy(w->tag.all)-Border;
4947dd7cddfSDavid du Colombier r = v->r;
4957dd7cddfSDavid du Colombier r.max.y = p.y;
4967dd7cddfSDavid du Colombier if(r.max.y > v->body.r.min.y){
4977dd7cddfSDavid du Colombier r.max.y -= (r.max.y-v->body.r.min.y)%v->body.font->height;
4987dd7cddfSDavid du Colombier if(v->body.r.min.y == v->body.r.max.y)
4997dd7cddfSDavid du Colombier r.max.y++;
5007dd7cddfSDavid du Colombier }
5017dd7cddfSDavid du Colombier if(!eqrect(v->r, r)){
5027dd7cddfSDavid du Colombier draw(screen, r, textcols[BACK], nil, ZP);
5037dd7cddfSDavid du Colombier winresize(v, r, c->safe);
5047dd7cddfSDavid du Colombier }
5057dd7cddfSDavid du Colombier r.min.y = v->r.max.y;
5067dd7cddfSDavid du Colombier r.max.y = r.min.y+Border;
5077dd7cddfSDavid du Colombier draw(screen, r, display->black, nil, ZP);
5087dd7cddfSDavid du Colombier r.min.y = r.max.y;
5097dd7cddfSDavid du Colombier if(i == c->nw-1)
5107dd7cddfSDavid du Colombier r.max.y = c->r.max.y;
5117dd7cddfSDavid du Colombier else
5127dd7cddfSDavid du Colombier r.max.y = c->w[i+1]->r.min.y-Border;
5137dd7cddfSDavid du Colombier if(!eqrect(w->r, r)){
5147dd7cddfSDavid du Colombier draw(screen, r, textcols[BACK], nil, ZP);
5157dd7cddfSDavid du Colombier winresize(w, r, c->safe);
5167dd7cddfSDavid du Colombier }
5177dd7cddfSDavid du Colombier c->safe = TRUE;
5187dd7cddfSDavid du Colombier winmousebut(w);
5197dd7cddfSDavid du Colombier }
5207dd7cddfSDavid du Colombier
5217dd7cddfSDavid du Colombier Text*
colwhich(Column * c,Point p)5227dd7cddfSDavid du Colombier colwhich(Column *c, Point p)
5237dd7cddfSDavid du Colombier {
5247dd7cddfSDavid du Colombier int i;
5257dd7cddfSDavid du Colombier Window *w;
5267dd7cddfSDavid du Colombier
5277dd7cddfSDavid du Colombier if(!ptinrect(p, c->r))
5287dd7cddfSDavid du Colombier return nil;
5297dd7cddfSDavid du Colombier if(ptinrect(p, c->tag.all))
5307dd7cddfSDavid du Colombier return &c->tag;
5317dd7cddfSDavid du Colombier for(i=0; i<c->nw; i++){
5327dd7cddfSDavid du Colombier w = c->w[i];
5337dd7cddfSDavid du Colombier if(ptinrect(p, w->r)){
5347dd7cddfSDavid du Colombier if(ptinrect(p, w->tag.all))
5357dd7cddfSDavid du Colombier return &w->tag;
5367dd7cddfSDavid du Colombier return &w->body;
5377dd7cddfSDavid du Colombier }
538ded93d44SDavid du Colombier /* scrollr drops below w->r on low windows */
539ded93d44SDavid du Colombier if(ptinrect(p, w->body.scrollr))
540ded93d44SDavid du Colombier return &w->body;
5417dd7cddfSDavid du Colombier }
5427dd7cddfSDavid du Colombier return nil;
5437dd7cddfSDavid du Colombier }
5447dd7cddfSDavid du Colombier
5457dd7cddfSDavid du Colombier int
colclean(Column * c)5467dd7cddfSDavid du Colombier colclean(Column *c)
5477dd7cddfSDavid du Colombier {
5487dd7cddfSDavid du Colombier int i, clean;
5497dd7cddfSDavid du Colombier
5507dd7cddfSDavid du Colombier clean = TRUE;
5517dd7cddfSDavid du Colombier for(i=0; i<c->nw; i++)
5527dd7cddfSDavid du Colombier clean &= winclean(c->w[i], TRUE);
5537dd7cddfSDavid du Colombier return clean;
5547dd7cddfSDavid du Colombier }
555