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 <bio.h>
117dd7cddfSDavid du Colombier #include <plumb.h>
127dd7cddfSDavid du Colombier #include "dat.h"
137dd7cddfSDavid du Colombier #include "fns.h"
147dd7cddfSDavid du Colombier
157dd7cddfSDavid du Colombier void
rowinit(Row * row,Rectangle r)167dd7cddfSDavid du Colombier rowinit(Row *row, Rectangle r)
177dd7cddfSDavid du Colombier {
187dd7cddfSDavid du Colombier Rectangle r1;
197dd7cddfSDavid du Colombier Text *t;
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier draw(screen, r, display->white, nil, ZP);
227dd7cddfSDavid du Colombier row->r = r;
237dd7cddfSDavid du Colombier row->col = nil;
247dd7cddfSDavid du Colombier row->ncol = 0;
257dd7cddfSDavid du Colombier r1 = r;
267dd7cddfSDavid du Colombier r1.max.y = r1.min.y + font->height;
277dd7cddfSDavid du Colombier t = &row->tag;
287dd7cddfSDavid du Colombier textinit(t, fileaddtext(nil, t), r1, rfget(FALSE, FALSE, FALSE, nil), tagcols);
297dd7cddfSDavid du Colombier t->what = Rowtag;
307dd7cddfSDavid du Colombier t->row = row;
317dd7cddfSDavid du Colombier t->w = nil;
327dd7cddfSDavid du Colombier t->col = nil;
337dd7cddfSDavid du Colombier r1.min.y = r1.max.y;
347dd7cddfSDavid du Colombier r1.max.y += Border;
357dd7cddfSDavid du Colombier draw(screen, r1, display->black, nil, ZP);
367dd7cddfSDavid du Colombier textinsert(t, 0, L"Newcol Kill Putall Dump Exit ", 29, TRUE);
377dd7cddfSDavid du Colombier textsetselect(t, t->file->nc, t->file->nc);
387dd7cddfSDavid du Colombier }
397dd7cddfSDavid du Colombier
407dd7cddfSDavid du Colombier Column*
rowadd(Row * row,Column * c,int x)417dd7cddfSDavid du Colombier rowadd(Row *row, Column *c, int x)
427dd7cddfSDavid du Colombier {
437dd7cddfSDavid du Colombier Rectangle r, r1;
447dd7cddfSDavid du Colombier Column *d;
457dd7cddfSDavid du Colombier int i;
467dd7cddfSDavid du Colombier
477dd7cddfSDavid du Colombier d = nil;
487dd7cddfSDavid du Colombier r = row->r;
497dd7cddfSDavid du Colombier r.min.y = row->tag.r.max.y+Border;
507dd7cddfSDavid du Colombier if(x<r.min.x && row->ncol>0){ /*steal 40% of last column by default */
517dd7cddfSDavid du Colombier d = row->col[row->ncol-1];
527dd7cddfSDavid du Colombier x = d->r.min.x + 3*Dx(d->r)/5;
537dd7cddfSDavid du Colombier }
547dd7cddfSDavid du Colombier /* look for column we'll land on */
557dd7cddfSDavid du Colombier for(i=0; i<row->ncol; i++){
567dd7cddfSDavid du Colombier d = row->col[i];
577dd7cddfSDavid du Colombier if(x < d->r.max.x)
587dd7cddfSDavid du Colombier break;
597dd7cddfSDavid du Colombier }
607dd7cddfSDavid du Colombier if(row->ncol > 0){
617dd7cddfSDavid du Colombier if(i < row->ncol)
627dd7cddfSDavid du Colombier i++; /* new column will go after d */
637dd7cddfSDavid du Colombier r = d->r;
647dd7cddfSDavid du Colombier if(Dx(r) < 100)
657dd7cddfSDavid du Colombier return nil;
667dd7cddfSDavid du Colombier draw(screen, r, display->white, nil, ZP);
677dd7cddfSDavid du Colombier r1 = r;
687dd7cddfSDavid du Colombier r1.max.x = min(x, r.max.x-50);
697dd7cddfSDavid du Colombier if(Dx(r1) < 50)
707dd7cddfSDavid du Colombier r1.max.x = r1.min.x+50;
717dd7cddfSDavid du Colombier colresize(d, r1);
727dd7cddfSDavid du Colombier r1.min.x = r1.max.x;
737dd7cddfSDavid du Colombier r1.max.x = r1.min.x+Border;
747dd7cddfSDavid du Colombier draw(screen, r1, display->black, nil, ZP);
757dd7cddfSDavid du Colombier r.min.x = r1.max.x;
767dd7cddfSDavid du Colombier }
777dd7cddfSDavid du Colombier if(c == nil){
787dd7cddfSDavid du Colombier c = emalloc(sizeof(Column));
797dd7cddfSDavid du Colombier colinit(c, r);
807dd7cddfSDavid du Colombier incref(&reffont);
817dd7cddfSDavid du Colombier }else
827dd7cddfSDavid du Colombier colresize(c, r);
837dd7cddfSDavid du Colombier c->row = row;
847dd7cddfSDavid du Colombier c->tag.row = row;
857dd7cddfSDavid du Colombier row->col = realloc(row->col, (row->ncol+1)*sizeof(Column*));
867dd7cddfSDavid du Colombier memmove(row->col+i+1, row->col+i, (row->ncol-i)*sizeof(Column*));
877dd7cddfSDavid du Colombier row->col[i] = c;
887dd7cddfSDavid du Colombier row->ncol++;
897dd7cddfSDavid du Colombier clearmouse();
907dd7cddfSDavid du Colombier return c;
917dd7cddfSDavid du Colombier }
927dd7cddfSDavid du Colombier
937dd7cddfSDavid du Colombier void
rowresize(Row * row,Rectangle r)947dd7cddfSDavid du Colombier rowresize(Row *row, Rectangle r)
957dd7cddfSDavid du Colombier {
967dd7cddfSDavid du Colombier int i, dx, odx;
977dd7cddfSDavid du Colombier Rectangle r1, r2;
987dd7cddfSDavid du Colombier Column *c;
997dd7cddfSDavid du Colombier
1007dd7cddfSDavid du Colombier dx = Dx(r);
1017dd7cddfSDavid du Colombier odx = Dx(row->r);
1027dd7cddfSDavid du Colombier row->r = r;
1037dd7cddfSDavid du Colombier r1 = r;
1047dd7cddfSDavid du Colombier r1.max.y = r1.min.y + font->height;
1057dd7cddfSDavid du Colombier textresize(&row->tag, r1);
1067dd7cddfSDavid du Colombier r1.min.y = r1.max.y;
1077dd7cddfSDavid du Colombier r1.max.y += Border;
1087dd7cddfSDavid du Colombier draw(screen, r1, display->black, nil, ZP);
1097dd7cddfSDavid du Colombier r.min.y = r1.max.y;
1107dd7cddfSDavid du Colombier r1 = r;
1117dd7cddfSDavid du Colombier r1.max.x = r1.min.x;
1127dd7cddfSDavid du Colombier for(i=0; i<row->ncol; i++){
1137dd7cddfSDavid du Colombier c = row->col[i];
1147dd7cddfSDavid du Colombier r1.min.x = r1.max.x;
1157dd7cddfSDavid du Colombier if(i == row->ncol-1)
1167dd7cddfSDavid du Colombier r1.max.x = r.max.x;
1177dd7cddfSDavid du Colombier else
1187dd7cddfSDavid du Colombier r1.max.x = r1.min.x+Dx(c->r)*dx/odx;
1197dd7cddfSDavid du Colombier if(i > 0){
1207dd7cddfSDavid du Colombier r2 = r1;
1217dd7cddfSDavid du Colombier r2.max.x = r2.min.x+Border;
1227dd7cddfSDavid du Colombier draw(screen, r2, display->black, nil, ZP);
1237dd7cddfSDavid du Colombier r1.min.x = r2.max.x;
1247dd7cddfSDavid du Colombier }
1257dd7cddfSDavid du Colombier colresize(c, r1);
1267dd7cddfSDavid du Colombier }
1277dd7cddfSDavid du Colombier }
1287dd7cddfSDavid du Colombier
1297dd7cddfSDavid du Colombier void
rowdragcol(Row * row,Column * c,int)1307dd7cddfSDavid du Colombier rowdragcol(Row *row, Column *c, int)
1317dd7cddfSDavid du Colombier {
1327dd7cddfSDavid du Colombier Rectangle r;
1337dd7cddfSDavid du Colombier int i, b, x;
1347dd7cddfSDavid du Colombier Point p, op;
1357dd7cddfSDavid du Colombier Column *d;
1367dd7cddfSDavid du Colombier
1377dd7cddfSDavid du Colombier clearmouse();
1387dd7cddfSDavid du Colombier setcursor(mousectl, &boxcursor);
1397dd7cddfSDavid du Colombier b = mouse->buttons;
1407dd7cddfSDavid du Colombier op = mouse->xy;
1417dd7cddfSDavid du Colombier while(mouse->buttons == b)
1427dd7cddfSDavid du Colombier readmouse(mousectl);
1437dd7cddfSDavid du Colombier setcursor(mousectl, nil);
1447dd7cddfSDavid du Colombier if(mouse->buttons){
1457dd7cddfSDavid du Colombier while(mouse->buttons)
1467dd7cddfSDavid du Colombier readmouse(mousectl);
1477dd7cddfSDavid du Colombier return;
1487dd7cddfSDavid du Colombier }
1497dd7cddfSDavid du Colombier
1507dd7cddfSDavid du Colombier for(i=0; i<row->ncol; i++)
1517dd7cddfSDavid du Colombier if(row->col[i] == c)
1527dd7cddfSDavid du Colombier goto Found;
1537dd7cddfSDavid du Colombier error("can't find column");
1547dd7cddfSDavid du Colombier
1557dd7cddfSDavid du Colombier Found:
1567dd7cddfSDavid du Colombier p = mouse->xy;
1577dd7cddfSDavid du Colombier if((abs(p.x-op.x)<5 && abs(p.y-op.y)<5))
1587dd7cddfSDavid du Colombier return;
1597dd7cddfSDavid du Colombier if((i>0 && p.x<row->col[i-1]->r.min.x) || (i<row->ncol-1 && p.x>c->r.max.x)){
1607dd7cddfSDavid du Colombier /* shuffle */
1617dd7cddfSDavid du Colombier x = c->r.min.x;
1627dd7cddfSDavid du Colombier rowclose(row, c, FALSE);
1637dd7cddfSDavid du Colombier if(rowadd(row, c, p.x) == nil) /* whoops! */
1647dd7cddfSDavid du Colombier if(rowadd(row, c, x) == nil) /* WHOOPS! */
1657dd7cddfSDavid du Colombier if(rowadd(row, c, -1)==nil){ /* shit! */
1667dd7cddfSDavid du Colombier rowclose(row, c, TRUE);
1677dd7cddfSDavid du Colombier return;
1687dd7cddfSDavid du Colombier }
1697dd7cddfSDavid du Colombier colmousebut(c);
1707dd7cddfSDavid du Colombier return;
1717dd7cddfSDavid du Colombier }
172*348c7de8SDavid du Colombier if(i == 0)
173*348c7de8SDavid du Colombier return;
1747dd7cddfSDavid du Colombier d = row->col[i-1];
1757dd7cddfSDavid du Colombier if(p.x < d->r.min.x+80+Scrollwid)
1767dd7cddfSDavid du Colombier p.x = d->r.min.x+80+Scrollwid;
1777dd7cddfSDavid du Colombier if(p.x > c->r.max.x-80-Scrollwid)
1787dd7cddfSDavid du Colombier p.x = c->r.max.x-80-Scrollwid;
1797dd7cddfSDavid du Colombier r = d->r;
1807dd7cddfSDavid du Colombier r.max.x = c->r.max.x;
1817dd7cddfSDavid du Colombier draw(screen, r, display->white, nil, ZP);
1827dd7cddfSDavid du Colombier r.max.x = p.x;
1837dd7cddfSDavid du Colombier colresize(d, r);
1847dd7cddfSDavid du Colombier r = c->r;
1857dd7cddfSDavid du Colombier r.min.x = p.x;
1867dd7cddfSDavid du Colombier r.max.x = r.min.x;
1877dd7cddfSDavid du Colombier r.max.x += Border;
1887dd7cddfSDavid du Colombier draw(screen, r, display->black, nil, ZP);
1897dd7cddfSDavid du Colombier r.min.x = r.max.x;
1907dd7cddfSDavid du Colombier r.max.x = c->r.max.x;
1917dd7cddfSDavid du Colombier colresize(c, r);
1927dd7cddfSDavid du Colombier colmousebut(c);
1937dd7cddfSDavid du Colombier }
1947dd7cddfSDavid du Colombier
1957dd7cddfSDavid du Colombier void
rowclose(Row * row,Column * c,int dofree)1967dd7cddfSDavid du Colombier rowclose(Row *row, Column *c, int dofree)
1977dd7cddfSDavid du Colombier {
1987dd7cddfSDavid du Colombier Rectangle r;
1997dd7cddfSDavid du Colombier int i;
2007dd7cddfSDavid du Colombier
2017dd7cddfSDavid du Colombier for(i=0; i<row->ncol; i++)
2027dd7cddfSDavid du Colombier if(row->col[i] == c)
2037dd7cddfSDavid du Colombier goto Found;
2047dd7cddfSDavid du Colombier error("can't find column");
2057dd7cddfSDavid du Colombier Found:
2067dd7cddfSDavid du Colombier r = c->r;
2077dd7cddfSDavid du Colombier if(dofree)
2087dd7cddfSDavid du Colombier colcloseall(c);
2097dd7cddfSDavid du Colombier memmove(row->col+i, row->col+i+1, (row->ncol-i)*sizeof(Column*));
2107dd7cddfSDavid du Colombier row->ncol--;
2117dd7cddfSDavid du Colombier row->col = realloc(row->col, row->ncol*sizeof(Column*));
2127dd7cddfSDavid du Colombier if(row->ncol == 0){
2137dd7cddfSDavid du Colombier draw(screen, r, display->white, nil, ZP);
2147dd7cddfSDavid du Colombier return;
2157dd7cddfSDavid du Colombier }
2167dd7cddfSDavid du Colombier if(i == row->ncol){ /* extend last column right */
2177dd7cddfSDavid du Colombier c = row->col[i-1];
2187dd7cddfSDavid du Colombier r.min.x = c->r.min.x;
2197dd7cddfSDavid du Colombier r.max.x = row->r.max.x;
2207dd7cddfSDavid du Colombier }else{ /* extend next window left */
2217dd7cddfSDavid du Colombier c = row->col[i];
2227dd7cddfSDavid du Colombier r.max.x = c->r.max.x;
2237dd7cddfSDavid du Colombier }
2247dd7cddfSDavid du Colombier draw(screen, r, display->white, nil, ZP);
2257dd7cddfSDavid du Colombier colresize(c, r);
2267dd7cddfSDavid du Colombier }
2277dd7cddfSDavid du Colombier
2287dd7cddfSDavid du Colombier Column*
rowwhichcol(Row * row,Point p)2297dd7cddfSDavid du Colombier rowwhichcol(Row *row, Point p)
2307dd7cddfSDavid du Colombier {
2317dd7cddfSDavid du Colombier int i;
2327dd7cddfSDavid du Colombier Column *c;
2337dd7cddfSDavid du Colombier
2347dd7cddfSDavid du Colombier for(i=0; i<row->ncol; i++){
2357dd7cddfSDavid du Colombier c = row->col[i];
2367dd7cddfSDavid du Colombier if(ptinrect(p, c->r))
2377dd7cddfSDavid du Colombier return c;
2387dd7cddfSDavid du Colombier }
2397dd7cddfSDavid du Colombier return nil;
2407dd7cddfSDavid du Colombier }
2417dd7cddfSDavid du Colombier
2427dd7cddfSDavid du Colombier Text*
rowwhich(Row * row,Point p)2437dd7cddfSDavid du Colombier rowwhich(Row *row, Point p)
2447dd7cddfSDavid du Colombier {
2457dd7cddfSDavid du Colombier Column *c;
2467dd7cddfSDavid du Colombier
2477dd7cddfSDavid du Colombier if(ptinrect(p, row->tag.all))
2487dd7cddfSDavid du Colombier return &row->tag;
2497dd7cddfSDavid du Colombier c = rowwhichcol(row, p);
2507dd7cddfSDavid du Colombier if(c)
2517dd7cddfSDavid du Colombier return colwhich(c, p);
2527dd7cddfSDavid du Colombier return nil;
2537dd7cddfSDavid du Colombier }
2547dd7cddfSDavid du Colombier
2557dd7cddfSDavid du Colombier Text*
rowtype(Row * row,Rune r,Point p)2567dd7cddfSDavid du Colombier rowtype(Row *row, Rune r, Point p)
2577dd7cddfSDavid du Colombier {
2587dd7cddfSDavid du Colombier Window *w;
2597dd7cddfSDavid du Colombier Text *t;
2607dd7cddfSDavid du Colombier
2617dd7cddfSDavid du Colombier clearmouse();
2627dd7cddfSDavid du Colombier qlock(row);
2637dd7cddfSDavid du Colombier if(bartflag)
2647dd7cddfSDavid du Colombier t = barttext;
2657dd7cddfSDavid du Colombier else
2667dd7cddfSDavid du Colombier t = rowwhich(row, p);
2677dd7cddfSDavid du Colombier if(t!=nil && !(t->what==Tag && ptinrect(p, t->scrollr))){
2687dd7cddfSDavid du Colombier w = t->w;
2697dd7cddfSDavid du Colombier if(w == nil)
2707dd7cddfSDavid du Colombier texttype(t, r);
2717dd7cddfSDavid du Colombier else{
2727dd7cddfSDavid du Colombier winlock(w, 'K');
2737dd7cddfSDavid du Colombier wintype(w, t, r);
2747dd7cddfSDavid du Colombier winunlock(w);
2757dd7cddfSDavid du Colombier }
2767dd7cddfSDavid du Colombier }
2777dd7cddfSDavid du Colombier qunlock(row);
2787dd7cddfSDavid du Colombier return t;
2797dd7cddfSDavid du Colombier }
2807dd7cddfSDavid du Colombier
2817dd7cddfSDavid du Colombier int
rowclean(Row * row)2827dd7cddfSDavid du Colombier rowclean(Row *row)
2837dd7cddfSDavid du Colombier {
2847dd7cddfSDavid du Colombier int clean;
2857dd7cddfSDavid du Colombier int i;
2867dd7cddfSDavid du Colombier
2877dd7cddfSDavid du Colombier clean = TRUE;
2887dd7cddfSDavid du Colombier for(i=0; i<row->ncol; i++)
2897dd7cddfSDavid du Colombier clean &= colclean(row->col[i]);
2907dd7cddfSDavid du Colombier return clean;
2917dd7cddfSDavid du Colombier }
2927dd7cddfSDavid du Colombier
2937dd7cddfSDavid du Colombier void
rowdump(Row * row,char * file)2947dd7cddfSDavid du Colombier rowdump(Row *row, char *file)
2957dd7cddfSDavid du Colombier {
2967dd7cddfSDavid du Colombier int i, j, fd, m, n, dumped;
2977dd7cddfSDavid du Colombier uint q0, q1;
2987dd7cddfSDavid du Colombier Biobuf *b;
2997dd7cddfSDavid du Colombier char *buf, *a, *fontname;
3007dd7cddfSDavid du Colombier Rune *r;
3017dd7cddfSDavid du Colombier Column *c;
3027dd7cddfSDavid du Colombier Window *w, *w1;
3037dd7cddfSDavid du Colombier Text *t;
3047dd7cddfSDavid du Colombier
3057dd7cddfSDavid du Colombier if(row->ncol == 0)
3067dd7cddfSDavid du Colombier return;
3077dd7cddfSDavid du Colombier buf = fbufalloc();
3087dd7cddfSDavid du Colombier if(file == nil){
3097dd7cddfSDavid du Colombier if(home == nil){
3107dd7cddfSDavid du Colombier warning(nil, "can't find file for dump: $home not defined\n");
3117dd7cddfSDavid du Colombier goto Rescue;
3127dd7cddfSDavid du Colombier }
3137dd7cddfSDavid du Colombier sprint(buf, "%s/acme.dump", home);
3147dd7cddfSDavid du Colombier file = buf;
3157dd7cddfSDavid du Colombier }
3167dd7cddfSDavid du Colombier fd = create(file, OWRITE, 0600);
3177dd7cddfSDavid du Colombier if(fd < 0){
3187dd7cddfSDavid du Colombier warning(nil, "can't open %s: %r\n", file);
3197dd7cddfSDavid du Colombier goto Rescue;
3207dd7cddfSDavid du Colombier }
3217dd7cddfSDavid du Colombier b = emalloc(sizeof(Biobuf));
3227dd7cddfSDavid du Colombier Binit(b, fd, OWRITE);
3237dd7cddfSDavid du Colombier r = fbufalloc();
3247dd7cddfSDavid du Colombier Bprint(b, "%s\n", wdir);
3257dd7cddfSDavid du Colombier Bprint(b, "%s\n", fontnames[0]);
3267dd7cddfSDavid du Colombier Bprint(b, "%s\n", fontnames[1]);
3277dd7cddfSDavid du Colombier for(i=0; i<row->ncol; i++){
3287dd7cddfSDavid du Colombier c = row->col[i];
3297dd7cddfSDavid du Colombier Bprint(b, "%11d", 100*(c->r.min.x-row->r.min.x)/Dx(row->r));
3307dd7cddfSDavid du Colombier if(i == row->ncol-1)
3317dd7cddfSDavid du Colombier Bputc(b, '\n');
3327dd7cddfSDavid du Colombier else
3337dd7cddfSDavid du Colombier Bputc(b, ' ');
3347dd7cddfSDavid du Colombier }
3357dd7cddfSDavid du Colombier for(i=0; i<row->ncol; i++){
3367dd7cddfSDavid du Colombier c = row->col[i];
3377dd7cddfSDavid du Colombier for(j=0; j<c->nw; j++)
3387dd7cddfSDavid du Colombier c->w[j]->body.file->dumpid = 0;
3397dd7cddfSDavid du Colombier }
3407dd7cddfSDavid du Colombier for(i=0; i<row->ncol; i++){
3417dd7cddfSDavid du Colombier c = row->col[i];
3427dd7cddfSDavid du Colombier for(j=0; j<c->nw; j++){
3437dd7cddfSDavid du Colombier w = c->w[j];
3447dd7cddfSDavid du Colombier wincommit(w, &w->tag);
3457dd7cddfSDavid du Colombier t = &w->body;
3467dd7cddfSDavid du Colombier /* windows owned by others get special treatment */
3477dd7cddfSDavid du Colombier if(w->nopen[QWevent] > 0)
3487dd7cddfSDavid du Colombier if(w->dumpstr == nil)
3497dd7cddfSDavid du Colombier continue;
3507dd7cddfSDavid du Colombier /* zeroxes of external windows are tossed */
3517dd7cddfSDavid du Colombier if(t->file->ntext > 1)
3527dd7cddfSDavid du Colombier for(n=0; n<t->file->ntext; n++){
3537dd7cddfSDavid du Colombier w1 = t->file->text[n]->w;
3547dd7cddfSDavid du Colombier if(w == w1)
3557dd7cddfSDavid du Colombier continue;
3567dd7cddfSDavid du Colombier if(w1->nopen[QWevent])
3577dd7cddfSDavid du Colombier goto Continue2;
3587dd7cddfSDavid du Colombier }
3597dd7cddfSDavid du Colombier fontname = "";
3607dd7cddfSDavid du Colombier if(t->reffont->f != font)
3617dd7cddfSDavid du Colombier fontname = t->reffont->f->name;
3627dd7cddfSDavid du Colombier if(t->file->nname)
3637dd7cddfSDavid du Colombier a = runetobyte(t->file->name, t->file->nname);
3647dd7cddfSDavid du Colombier else
3657dd7cddfSDavid du Colombier a = emalloc(1);
3667dd7cddfSDavid du Colombier if(t->file->dumpid){
3677dd7cddfSDavid du Colombier dumped = FALSE;
3687dd7cddfSDavid du Colombier Bprint(b, "x%11d %11d %11d %11d %11d %s\n", i, t->file->dumpid,
3697dd7cddfSDavid du Colombier w->body.q0, w->body.q1,
3707dd7cddfSDavid du Colombier 100*(w->r.min.y-c->r.min.y)/Dy(c->r),
3717dd7cddfSDavid du Colombier fontname);
3727dd7cddfSDavid du Colombier }else if(w->dumpstr){
3737dd7cddfSDavid du Colombier dumped = FALSE;
3747dd7cddfSDavid du Colombier Bprint(b, "e%11d %11d %11d %11d %11d %s\n", i, t->file->dumpid,
3757dd7cddfSDavid du Colombier 0, 0,
3767dd7cddfSDavid du Colombier 100*(w->r.min.y-c->r.min.y)/Dy(c->r),
3777dd7cddfSDavid du Colombier fontname);
3787dd7cddfSDavid du Colombier }else if((w->dirty==FALSE && access(a, 0)==0) || w->isdir){
3797dd7cddfSDavid du Colombier dumped = FALSE;
3807dd7cddfSDavid du Colombier t->file->dumpid = w->id;
3817dd7cddfSDavid du Colombier Bprint(b, "f%11d %11d %11d %11d %11d %s\n", i, w->id,
3827dd7cddfSDavid du Colombier w->body.q0, w->body.q1,
3837dd7cddfSDavid du Colombier 100*(w->r.min.y-c->r.min.y)/Dy(c->r),
3847dd7cddfSDavid du Colombier fontname);
3857dd7cddfSDavid du Colombier }else{
3867dd7cddfSDavid du Colombier dumped = TRUE;
3877dd7cddfSDavid du Colombier t->file->dumpid = w->id;
3887dd7cddfSDavid du Colombier Bprint(b, "F%11d %11d %11d %11d %11d %11d %s\n", i, j,
3897dd7cddfSDavid du Colombier w->body.q0, w->body.q1,
3907dd7cddfSDavid du Colombier 100*(w->r.min.y-c->r.min.y)/Dy(c->r),
3917dd7cddfSDavid du Colombier w->body.file->nc, fontname);
3927dd7cddfSDavid du Colombier }
3937dd7cddfSDavid du Colombier free(a);
3949a747e4fSDavid du Colombier winctlprint(w, buf, 0);
3957dd7cddfSDavid du Colombier Bwrite(b, buf, strlen(buf));
3967dd7cddfSDavid du Colombier m = min(RBUFSIZE, w->tag.file->nc);
3977dd7cddfSDavid du Colombier bufread(w->tag.file, 0, r, m);
3987dd7cddfSDavid du Colombier n = 0;
3997dd7cddfSDavid du Colombier while(n<m && r[n]!='\n')
4007dd7cddfSDavid du Colombier n++;
4017dd7cddfSDavid du Colombier r[n++] = '\n';
4027dd7cddfSDavid du Colombier Bprint(b, "%.*S", n, r);
4037dd7cddfSDavid du Colombier if(dumped){
4047dd7cddfSDavid du Colombier q0 = 0;
4057dd7cddfSDavid du Colombier q1 = t->file->nc;
4067dd7cddfSDavid du Colombier while(q0 < q1){
4077dd7cddfSDavid du Colombier n = q1 - q0;
4087dd7cddfSDavid du Colombier if(n > BUFSIZE/UTFmax)
4097dd7cddfSDavid du Colombier n = BUFSIZE/UTFmax;
4107dd7cddfSDavid du Colombier bufread(t->file, q0, r, n);
4117dd7cddfSDavid du Colombier Bprint(b, "%.*S", n, r);
4127dd7cddfSDavid du Colombier q0 += n;
4137dd7cddfSDavid du Colombier }
4147dd7cddfSDavid du Colombier }
4157dd7cddfSDavid du Colombier if(w->dumpstr){
4167dd7cddfSDavid du Colombier if(w->dumpdir)
4177dd7cddfSDavid du Colombier Bprint(b, "%s\n%s\n", w->dumpdir, w->dumpstr);
4187dd7cddfSDavid du Colombier else
4197dd7cddfSDavid du Colombier Bprint(b, "\n%s\n", w->dumpstr);
4207dd7cddfSDavid du Colombier }
4217dd7cddfSDavid du Colombier Continue2:;
4227dd7cddfSDavid du Colombier }
4237dd7cddfSDavid du Colombier }
4247dd7cddfSDavid du Colombier Bterm(b);
4257dd7cddfSDavid du Colombier close(fd);
4267dd7cddfSDavid du Colombier free(b);
4277dd7cddfSDavid du Colombier fbuffree(r);
4287dd7cddfSDavid du Colombier
4297dd7cddfSDavid du Colombier Rescue:
4307dd7cddfSDavid du Colombier fbuffree(buf);
4317dd7cddfSDavid du Colombier }
4327dd7cddfSDavid du Colombier
4337dd7cddfSDavid du Colombier static
4347dd7cddfSDavid du Colombier char*
rdline(Biobuf * b,int * linep)4357dd7cddfSDavid du Colombier rdline(Biobuf *b, int *linep)
4367dd7cddfSDavid du Colombier {
4377dd7cddfSDavid du Colombier char *l;
4387dd7cddfSDavid du Colombier
4397dd7cddfSDavid du Colombier l = Brdline(b, '\n');
4407dd7cddfSDavid du Colombier if(l)
4417dd7cddfSDavid du Colombier (*linep)++;
4427dd7cddfSDavid du Colombier return l;
4437dd7cddfSDavid du Colombier }
4447dd7cddfSDavid du Colombier
4459a747e4fSDavid du Colombier /*
4469a747e4fSDavid du Colombier * Get font names from load file so we don't load fonts we won't use
4479a747e4fSDavid du Colombier */
4489a747e4fSDavid du Colombier void
rowloadfonts(char * file)4499a747e4fSDavid du Colombier rowloadfonts(char *file)
4509a747e4fSDavid du Colombier {
4519a747e4fSDavid du Colombier int i;
4529a747e4fSDavid du Colombier Biobuf *b;
4539a747e4fSDavid du Colombier char *l;
4549a747e4fSDavid du Colombier
4559a747e4fSDavid du Colombier b = Bopen(file, OREAD);
4569a747e4fSDavid du Colombier if(b == nil)
4579a747e4fSDavid du Colombier return;
4589a747e4fSDavid du Colombier /* current directory */
4599a747e4fSDavid du Colombier l = Brdline(b, '\n');
4609a747e4fSDavid du Colombier if(l == nil)
4619a747e4fSDavid du Colombier goto Return;
4629a747e4fSDavid du Colombier /* global fonts */
4639a747e4fSDavid du Colombier for(i=0; i<2; i++){
4649a747e4fSDavid du Colombier l = Brdline(b, '\n');
4659a747e4fSDavid du Colombier if(l == nil)
4669a747e4fSDavid du Colombier goto Return;
4679a747e4fSDavid du Colombier l[Blinelen(b)-1] = 0;
4686d0d1481SDavid du Colombier if(*l && strcmp(l, fontnames[i])!=0){
4696d0d1481SDavid du Colombier free(fontnames[i]);
4709a747e4fSDavid du Colombier fontnames[i] = estrdup(l);
4719a747e4fSDavid du Colombier }
4726d0d1481SDavid du Colombier }
4739a747e4fSDavid du Colombier Return:
4749a747e4fSDavid du Colombier Bterm(b);
4759a747e4fSDavid du Colombier }
4769a747e4fSDavid du Colombier
4774b30ca09SDavid du Colombier int
rowload(Row * row,char * file,int initing)4787dd7cddfSDavid du Colombier rowload(Row *row, char *file, int initing)
4797dd7cddfSDavid du Colombier {
4807dd7cddfSDavid du Colombier int i, j, line, percent, y, nr, nfontr, n, ns, ndumped, dumpid, x, fd;
4817dd7cddfSDavid du Colombier Biobuf *b, *bout;
4827dd7cddfSDavid du Colombier char *buf, *l, *t, *fontname;
4837dd7cddfSDavid du Colombier Rune *r, rune, *fontr;
4847dd7cddfSDavid du Colombier Column *c, *c1, *c2;
4857dd7cddfSDavid du Colombier uint q0, q1;
4867dd7cddfSDavid du Colombier Rectangle r1, r2;
4877dd7cddfSDavid du Colombier Window *w;
4887dd7cddfSDavid du Colombier
4897dd7cddfSDavid du Colombier buf = fbufalloc();
4907dd7cddfSDavid du Colombier if(file == nil){
4917dd7cddfSDavid du Colombier if(home == nil){
4927dd7cddfSDavid du Colombier warning(nil, "can't find file for load: $home not defined\n");
4937dd7cddfSDavid du Colombier goto Rescue1;
4947dd7cddfSDavid du Colombier }
4957dd7cddfSDavid du Colombier sprint(buf, "%s/acme.dump", home);
4967dd7cddfSDavid du Colombier file = buf;
4977dd7cddfSDavid du Colombier }
4987dd7cddfSDavid du Colombier b = Bopen(file, OREAD);
4997dd7cddfSDavid du Colombier if(b == nil){
5007dd7cddfSDavid du Colombier warning(nil, "can't open load file %s: %r\n", file);
5017dd7cddfSDavid du Colombier goto Rescue1;
5027dd7cddfSDavid du Colombier }
5037dd7cddfSDavid du Colombier /* current directory */
5047dd7cddfSDavid du Colombier line = 0;
5057dd7cddfSDavid du Colombier l = rdline(b, &line);
5067dd7cddfSDavid du Colombier if(l == nil)
5077dd7cddfSDavid du Colombier goto Rescue2;
5087dd7cddfSDavid du Colombier l[Blinelen(b)-1] = 0;
5097dd7cddfSDavid du Colombier if(chdir(l) < 0){
5107dd7cddfSDavid du Colombier warning(nil, "can't chdir %s\n", l);
5117dd7cddfSDavid du Colombier goto Rescue2;
5127dd7cddfSDavid du Colombier }
5137dd7cddfSDavid du Colombier /* global fonts */
5147dd7cddfSDavid du Colombier for(i=0; i<2; i++){
5157dd7cddfSDavid du Colombier l = rdline(b, &line);
5167dd7cddfSDavid du Colombier if(l == nil)
5177dd7cddfSDavid du Colombier goto Rescue2;
5187dd7cddfSDavid du Colombier l[Blinelen(b)-1] = 0;
5197dd7cddfSDavid du Colombier if(*l && strcmp(l, fontnames[i])!=0)
5206d0d1481SDavid du Colombier rfget(i, TRUE, i==0 && initing, l);
5217dd7cddfSDavid du Colombier }
5227dd7cddfSDavid du Colombier if(initing && row->ncol==0)
5237dd7cddfSDavid du Colombier rowinit(row, screen->clipr);
5247dd7cddfSDavid du Colombier l = rdline(b, &line);
5257dd7cddfSDavid du Colombier if(l == nil)
5267dd7cddfSDavid du Colombier goto Rescue2;
5277dd7cddfSDavid du Colombier j = Blinelen(b)/12;
5287dd7cddfSDavid du Colombier if(j<=0 || j>10)
5297dd7cddfSDavid du Colombier goto Rescue2;
5307dd7cddfSDavid du Colombier for(i=0; i<j; i++){
5317dd7cddfSDavid du Colombier percent = atoi(l+i*12);
5327dd7cddfSDavid du Colombier if(percent<0 || percent>=100)
5337dd7cddfSDavid du Colombier goto Rescue2;
5347dd7cddfSDavid du Colombier x = row->r.min.x+percent*Dx(row->r)/100;
5357dd7cddfSDavid du Colombier if(i < row->ncol){
5367dd7cddfSDavid du Colombier if(i == 0)
5377dd7cddfSDavid du Colombier continue;
5387dd7cddfSDavid du Colombier c1 = row->col[i-1];
5397dd7cddfSDavid du Colombier c2 = row->col[i];
5407dd7cddfSDavid du Colombier r1 = c1->r;
5417dd7cddfSDavid du Colombier r2 = c2->r;
5427dd7cddfSDavid du Colombier r1.max.x = x;
5437dd7cddfSDavid du Colombier r2.min.x = x+Border;
5447dd7cddfSDavid du Colombier if(Dx(r1) < 50 || Dx(r2) < 50)
5457dd7cddfSDavid du Colombier continue;
5467dd7cddfSDavid du Colombier draw(screen, Rpt(r1.min, r2.max), display->white, nil, ZP);
5477dd7cddfSDavid du Colombier colresize(c1, r1);
5487dd7cddfSDavid du Colombier colresize(c2, r2);
5497dd7cddfSDavid du Colombier r2.min.x = x;
5507dd7cddfSDavid du Colombier r2.max.x = x+Border;
5517dd7cddfSDavid du Colombier draw(screen, r2, display->black, nil, ZP);
5527dd7cddfSDavid du Colombier }
5537dd7cddfSDavid du Colombier if(i >= row->ncol)
5547dd7cddfSDavid du Colombier rowadd(row, nil, x);
5557dd7cddfSDavid du Colombier }
5567dd7cddfSDavid du Colombier for(;;){
5577dd7cddfSDavid du Colombier l = rdline(b, &line);
5587dd7cddfSDavid du Colombier if(l == nil)
5597dd7cddfSDavid du Colombier break;
5607dd7cddfSDavid du Colombier dumpid = 0;
5617dd7cddfSDavid du Colombier switch(l[0]){
5627dd7cddfSDavid du Colombier case 'e':
5637dd7cddfSDavid du Colombier if(Blinelen(b) < 1+5*12+1)
5647dd7cddfSDavid du Colombier goto Rescue2;
5657dd7cddfSDavid du Colombier l = rdline(b, &line); /* ctl line; ignored */
5667dd7cddfSDavid du Colombier if(l == nil)
5677dd7cddfSDavid du Colombier goto Rescue2;
5687dd7cddfSDavid du Colombier l = rdline(b, &line); /* directory */
5697dd7cddfSDavid du Colombier if(l == nil)
5707dd7cddfSDavid du Colombier goto Rescue2;
5717dd7cddfSDavid du Colombier l[Blinelen(b)-1] = 0;
5727dd7cddfSDavid du Colombier if(*l == '\0'){
5737dd7cddfSDavid du Colombier if(home == nil)
5747dd7cddfSDavid du Colombier r = bytetorune("./", &nr);
5757dd7cddfSDavid du Colombier else{
5767dd7cddfSDavid du Colombier t = emalloc(strlen(home)+1+1);
5777dd7cddfSDavid du Colombier sprint(t, "%s/", home);
5787dd7cddfSDavid du Colombier r = bytetorune(t, &nr);
5797dd7cddfSDavid du Colombier free(t);
5807dd7cddfSDavid du Colombier }
5817dd7cddfSDavid du Colombier }else
5827dd7cddfSDavid du Colombier r = bytetorune(l, &nr);
5837dd7cddfSDavid du Colombier l = rdline(b, &line); /* command */
5847dd7cddfSDavid du Colombier if(l == nil)
5857dd7cddfSDavid du Colombier goto Rescue2;
5867dd7cddfSDavid du Colombier t = emalloc(Blinelen(b)+1);
5877dd7cddfSDavid du Colombier memmove(t, l, Blinelen(b));
58859cc4ca5SDavid du Colombier run(nil, t, r, nr, TRUE, nil, nil, FALSE);
5897dd7cddfSDavid du Colombier /* r is freed in run() */
5907dd7cddfSDavid du Colombier continue;
5917dd7cddfSDavid du Colombier case 'f':
5927dd7cddfSDavid du Colombier if(Blinelen(b) < 1+5*12+1)
5937dd7cddfSDavid du Colombier goto Rescue2;
5947dd7cddfSDavid du Colombier fontname = l+1+5*12;
5957dd7cddfSDavid du Colombier ndumped = -1;
5967dd7cddfSDavid du Colombier break;
5977dd7cddfSDavid du Colombier case 'F':
5987dd7cddfSDavid du Colombier if(Blinelen(b) < 1+6*12+1)
5997dd7cddfSDavid du Colombier goto Rescue2;
6007dd7cddfSDavid du Colombier fontname = l+1+6*12;
6017dd7cddfSDavid du Colombier ndumped = atoi(l+1+5*12+1);
6027dd7cddfSDavid du Colombier break;
6037dd7cddfSDavid du Colombier case 'x':
6047dd7cddfSDavid du Colombier if(Blinelen(b) < 1+5*12+1)
6057dd7cddfSDavid du Colombier goto Rescue2;
6067dd7cddfSDavid du Colombier fontname = l+1+5*12;
6077dd7cddfSDavid du Colombier ndumped = -1;
6087dd7cddfSDavid du Colombier dumpid = atoi(l+1+1*12);
6097dd7cddfSDavid du Colombier break;
6107dd7cddfSDavid du Colombier default:
6117dd7cddfSDavid du Colombier goto Rescue2;
6127dd7cddfSDavid du Colombier }
6137dd7cddfSDavid du Colombier l[Blinelen(b)-1] = 0;
6147dd7cddfSDavid du Colombier fontr = nil;
6157dd7cddfSDavid du Colombier nfontr = 0;
6167dd7cddfSDavid du Colombier if(*fontname)
6177dd7cddfSDavid du Colombier fontr = bytetorune(fontname, &nfontr);
6187dd7cddfSDavid du Colombier i = atoi(l+1+0*12);
6197dd7cddfSDavid du Colombier j = atoi(l+1+1*12);
6207dd7cddfSDavid du Colombier q0 = atoi(l+1+2*12);
6217dd7cddfSDavid du Colombier q1 = atoi(l+1+3*12);
6227dd7cddfSDavid du Colombier percent = atoi(l+1+4*12);
6237dd7cddfSDavid du Colombier if(i<0 || i>10)
6247dd7cddfSDavid du Colombier goto Rescue2;
6257dd7cddfSDavid du Colombier if(i > row->ncol)
6267dd7cddfSDavid du Colombier i = row->ncol;
6277dd7cddfSDavid du Colombier c = row->col[i];
6287dd7cddfSDavid du Colombier y = c->r.min.y+(percent*Dy(c->r))/100;
6297dd7cddfSDavid du Colombier if(y<c->r.min.y || y>=c->r.max.y)
6307dd7cddfSDavid du Colombier y = -1;
6317dd7cddfSDavid du Colombier if(dumpid == 0)
6327dd7cddfSDavid du Colombier w = coladd(c, nil, nil, y);
6337dd7cddfSDavid du Colombier else
6347dd7cddfSDavid du Colombier w = coladd(c, nil, lookid(dumpid, TRUE), y);
6357dd7cddfSDavid du Colombier if(w == nil)
6367dd7cddfSDavid du Colombier continue;
6377dd7cddfSDavid du Colombier w->dumpid = j;
6387dd7cddfSDavid du Colombier l = rdline(b, &line);
6397dd7cddfSDavid du Colombier if(l == nil)
6407dd7cddfSDavid du Colombier goto Rescue2;
6417dd7cddfSDavid du Colombier l[Blinelen(b)-1] = 0;
6427dd7cddfSDavid du Colombier r = bytetorune(l+5*12, &nr);
6437dd7cddfSDavid du Colombier ns = -1;
6447dd7cddfSDavid du Colombier for(n=0; n<nr; n++){
6457dd7cddfSDavid du Colombier if(r[n] == '/')
6467dd7cddfSDavid du Colombier ns = n;
6477dd7cddfSDavid du Colombier if(r[n] == ' ')
6487dd7cddfSDavid du Colombier break;
6497dd7cddfSDavid du Colombier }
6507dd7cddfSDavid du Colombier if(dumpid == 0)
6517dd7cddfSDavid du Colombier winsetname(w, r, n);
6527dd7cddfSDavid du Colombier for(; n<nr; n++)
6537dd7cddfSDavid du Colombier if(r[n] == '|')
6547dd7cddfSDavid du Colombier break;
6557dd7cddfSDavid du Colombier wincleartag(w);
6567dd7cddfSDavid du Colombier textinsert(&w->tag, w->tag.file->nc, r+n+1, nr-(n+1), TRUE);
6577dd7cddfSDavid du Colombier if(ndumped >= 0){
6587dd7cddfSDavid du Colombier /* simplest thing is to put it in a file and load that */
6597dd7cddfSDavid du Colombier sprint(buf, "/tmp/d%d.%.4sacme", getpid(), getuser());
6607dd7cddfSDavid du Colombier fd = create(buf, OWRITE|ORCLOSE, 0600);
6617dd7cddfSDavid du Colombier if(fd < 0){
6622af003dfSDavid du Colombier free(r);
6637dd7cddfSDavid du Colombier warning(nil, "can't create temp file: %r\n");
6647dd7cddfSDavid du Colombier goto Rescue2;
6657dd7cddfSDavid du Colombier }
6667dd7cddfSDavid du Colombier bout = emalloc(sizeof(Biobuf));
6677dd7cddfSDavid du Colombier Binit(bout, fd, OWRITE);
6687dd7cddfSDavid du Colombier for(n=0; n<ndumped; n++){
6697dd7cddfSDavid du Colombier rune = Bgetrune(b);
6707dd7cddfSDavid du Colombier if(rune == '\n')
6717dd7cddfSDavid du Colombier line++;
67229b83c63SDavid du Colombier if(rune == (Rune)Beof){
6732af003dfSDavid du Colombier free(r);
6747dd7cddfSDavid du Colombier Bterm(bout);
6757dd7cddfSDavid du Colombier free(bout);
6767dd7cddfSDavid du Colombier close(fd);
6777dd7cddfSDavid du Colombier goto Rescue2;
6787dd7cddfSDavid du Colombier }
6797dd7cddfSDavid du Colombier Bputrune(bout, rune);
6807dd7cddfSDavid du Colombier }
6817dd7cddfSDavid du Colombier Bterm(bout);
6827dd7cddfSDavid du Colombier free(bout);
6837dd7cddfSDavid du Colombier textload(&w->body, 0, buf, 1);
6847dd7cddfSDavid du Colombier close(fd);
6857dd7cddfSDavid du Colombier w->body.file->mod = TRUE;
6867dd7cddfSDavid du Colombier for(n=0; n<w->body.file->ntext; n++)
6877dd7cddfSDavid du Colombier w->body.file->text[n]->w->dirty = TRUE;
6887dd7cddfSDavid du Colombier winsettag(w);
6897dd7cddfSDavid du Colombier }else if(dumpid==0 && r[ns+1]!='+' && r[ns+1]!='-')
6907dd7cddfSDavid du Colombier get(&w->body, nil, nil, FALSE, XXX, nil, 0);
6917dd7cddfSDavid du Colombier if(fontr){
6927dd7cddfSDavid du Colombier fontx(&w->body, nil, nil, 0, 0, fontr, nfontr);
6937dd7cddfSDavid du Colombier free(fontr);
6947dd7cddfSDavid du Colombier }
6952af003dfSDavid du Colombier free(r);
6967dd7cddfSDavid du Colombier if(q0>w->body.file->nc || q1>w->body.file->nc || q0>q1)
6977dd7cddfSDavid du Colombier q0 = q1 = 0;
6989a747e4fSDavid du Colombier textshow(&w->body, q0, q1, 1);
6997dd7cddfSDavid du Colombier w->maxlines = min(w->body.nlines, max(w->maxlines, w->body.maxlines));
7007dd7cddfSDavid du Colombier }
7017dd7cddfSDavid du Colombier Bterm(b);
7027dd7cddfSDavid du Colombier fbuffree(buf);
7034b30ca09SDavid du Colombier return TRUE;
7047dd7cddfSDavid du Colombier
7057dd7cddfSDavid du Colombier Rescue2:
7067dd7cddfSDavid du Colombier warning(nil, "bad load file %s:%d\n", file, line);
7077dd7cddfSDavid du Colombier Bterm(b);
7084b30ca09SDavid du Colombier Rescue1:
7094b30ca09SDavid du Colombier fbuffree(buf);
7104b30ca09SDavid du Colombier return FALSE;
7117dd7cddfSDavid du Colombier }
71259cc4ca5SDavid du Colombier
71359cc4ca5SDavid du Colombier void
allwindows(void (* f)(Window *,void *),void * arg)71459cc4ca5SDavid du Colombier allwindows(void (*f)(Window*, void*), void *arg)
71559cc4ca5SDavid du Colombier {
71659cc4ca5SDavid du Colombier int i, j;
71759cc4ca5SDavid du Colombier Column *c;
71859cc4ca5SDavid du Colombier
71959cc4ca5SDavid du Colombier for(i=0; i<row.ncol; i++){
72059cc4ca5SDavid du Colombier c = row.col[i];
72159cc4ca5SDavid du Colombier for(j=0; j<c->nw; j++)
72259cc4ca5SDavid du Colombier (*f)(c->w[j], arg);
72359cc4ca5SDavid du Colombier }
72459cc4ca5SDavid du Colombier }
725