17dd7cddfSDavid du Colombier #include <u.h> 27dd7cddfSDavid du Colombier #include <libc.h> 37dd7cddfSDavid du Colombier #include <draw.h> 47dd7cddfSDavid du Colombier #include <thread.h> 59a747e4fSDavid 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 int winid; 157dd7cddfSDavid du Colombier 167dd7cddfSDavid du Colombier void 177dd7cddfSDavid du Colombier wininit(Window *w, Window *clone, Rectangle r) 187dd7cddfSDavid du Colombier { 197dd7cddfSDavid du Colombier Rectangle r1, br; 207dd7cddfSDavid du Colombier File *f; 217dd7cddfSDavid du Colombier Reffont *rf; 227dd7cddfSDavid du Colombier Rune *rp; 237dd7cddfSDavid du Colombier int nc; 247dd7cddfSDavid du Colombier 257dd7cddfSDavid du Colombier w->tag.w = w; 267dd7cddfSDavid du Colombier w->body.w = w; 277dd7cddfSDavid du Colombier w->id = ++winid; 287dd7cddfSDavid du Colombier incref(w); 2906300895SDavid du Colombier if(globalincref) 3006300895SDavid du Colombier incref(w); 317dd7cddfSDavid du Colombier w->ctlfid = ~0; 327dd7cddfSDavid du Colombier w->utflastqid = -1; 337dd7cddfSDavid du Colombier r1 = r; 347dd7cddfSDavid du Colombier r1.max.y = r1.min.y + font->height; 357dd7cddfSDavid du Colombier incref(&reffont); 367dd7cddfSDavid du Colombier f = fileaddtext(nil, &w->tag); 377dd7cddfSDavid du Colombier textinit(&w->tag, f, r1, &reffont, tagcols); 387dd7cddfSDavid du Colombier w->tag.what = Tag; 397dd7cddfSDavid du Colombier /* tag is a copy of the contents, not a tracked image */ 407dd7cddfSDavid du Colombier if(clone){ 417dd7cddfSDavid du Colombier textdelete(&w->tag, 0, w->tag.file->nc, TRUE); 427dd7cddfSDavid du Colombier nc = clone->tag.file->nc; 437dd7cddfSDavid du Colombier rp = runemalloc(nc); 447dd7cddfSDavid du Colombier bufread(clone->tag.file, 0, rp, nc); 457dd7cddfSDavid du Colombier textinsert(&w->tag, 0, rp, nc, TRUE); 467dd7cddfSDavid du Colombier free(rp); 477dd7cddfSDavid du Colombier filereset(w->tag.file); 487dd7cddfSDavid du Colombier textsetselect(&w->tag, nc, nc); 497dd7cddfSDavid du Colombier } 507dd7cddfSDavid du Colombier r1 = r; 517dd7cddfSDavid du Colombier r1.min.y += font->height + 1; 527dd7cddfSDavid du Colombier if(r1.max.y < r1.min.y) 537dd7cddfSDavid du Colombier r1.max.y = r1.min.y; 547dd7cddfSDavid du Colombier f = nil; 557dd7cddfSDavid du Colombier if(clone){ 567dd7cddfSDavid du Colombier f = clone->body.file; 577dd7cddfSDavid du Colombier w->body.org = clone->body.org; 587dd7cddfSDavid du Colombier w->isscratch = clone->isscratch; 597dd7cddfSDavid du Colombier rf = rfget(FALSE, FALSE, FALSE, clone->body.reffont->f->name); 607dd7cddfSDavid du Colombier }else 617dd7cddfSDavid du Colombier rf = rfget(FALSE, FALSE, FALSE, nil); 627dd7cddfSDavid du Colombier f = fileaddtext(f, &w->body); 637dd7cddfSDavid du Colombier w->body.what = Body; 647dd7cddfSDavid du Colombier textinit(&w->body, f, r1, rf, textcols); 657dd7cddfSDavid du Colombier r1.min.y -= 1; 667dd7cddfSDavid du Colombier r1.max.y = r1.min.y+1; 677dd7cddfSDavid du Colombier draw(screen, r1, tagcols[BORD], nil, ZP); 687dd7cddfSDavid du Colombier textscrdraw(&w->body); 697dd7cddfSDavid du Colombier w->r = r; 707dd7cddfSDavid du Colombier w->r.max.y = w->body.r.max.y; 717dd7cddfSDavid du Colombier br.min = w->tag.scrollr.min; 727dd7cddfSDavid du Colombier br.max.x = br.min.x + Dx(button->r); 737dd7cddfSDavid du Colombier br.max.y = br.min.y + Dy(button->r); 747dd7cddfSDavid du Colombier draw(screen, br, button, nil, button->r.min); 757dd7cddfSDavid du Colombier w->filemenu = TRUE; 767dd7cddfSDavid du Colombier w->maxlines = w->body.maxlines; 77*a30303efSDavid du Colombier w->autoindent = globalautoindent; 787dd7cddfSDavid du Colombier if(clone){ 797dd7cddfSDavid du Colombier w->dirty = clone->dirty; 807dd7cddfSDavid du Colombier textsetselect(&w->body, clone->body.q0, clone->body.q1); 817dd7cddfSDavid du Colombier winsettag(w); 82*a30303efSDavid du Colombier w->autoindent = clone->autoindent; 837dd7cddfSDavid du Colombier } 847dd7cddfSDavid du Colombier } 857dd7cddfSDavid du Colombier 867dd7cddfSDavid du Colombier int 877dd7cddfSDavid du Colombier winresize(Window *w, Rectangle r, int safe) 887dd7cddfSDavid du Colombier { 897dd7cddfSDavid du Colombier Rectangle r1; 907dd7cddfSDavid du Colombier int y; 917dd7cddfSDavid du Colombier Image *b; 927dd7cddfSDavid du Colombier Rectangle br; 937dd7cddfSDavid du Colombier 947dd7cddfSDavid du Colombier r1 = r; 957dd7cddfSDavid du Colombier r1.max.y = r1.min.y + font->height; 967dd7cddfSDavid du Colombier y = r1.max.y; 977dd7cddfSDavid du Colombier if(!safe || !eqrect(w->tag.r, r1)){ 987dd7cddfSDavid du Colombier y = textresize(&w->tag, r1); 997dd7cddfSDavid du Colombier b = button; 1007dd7cddfSDavid du Colombier if(w->body.file->mod && !w->isdir && !w->isscratch) 1017dd7cddfSDavid du Colombier b = modbutton; 1027dd7cddfSDavid du Colombier br.min = w->tag.scrollr.min; 1037dd7cddfSDavid du Colombier br.max.x = br.min.x + Dx(b->r); 1047dd7cddfSDavid du Colombier br.max.y = br.min.y + Dy(b->r); 1057dd7cddfSDavid du Colombier draw(screen, br, b, nil, b->r.min); 1067dd7cddfSDavid du Colombier } 1077dd7cddfSDavid du Colombier if(!safe || !eqrect(w->body.r, r1)){ 1087dd7cddfSDavid du Colombier if(y+1+font->height > r.max.y){ /* no body */ 1097dd7cddfSDavid du Colombier r1.min.y = y; 1107dd7cddfSDavid du Colombier r1.max.y = y; 1117dd7cddfSDavid du Colombier textresize(&w->body, r1); 1127dd7cddfSDavid du Colombier w->r = r; 1137dd7cddfSDavid du Colombier w->r.max.y = y; 1147dd7cddfSDavid du Colombier return y; 1157dd7cddfSDavid du Colombier } 1167dd7cddfSDavid du Colombier r1 = r; 1177dd7cddfSDavid du Colombier r1.min.y = y; 1187dd7cddfSDavid du Colombier r1.max.y = y + 1; 1197dd7cddfSDavid du Colombier draw(screen, r1, tagcols[BORD], nil, ZP); 1207dd7cddfSDavid du Colombier r1.min.y = y + 1; 1217dd7cddfSDavid du Colombier r1.max.y = r.max.y; 1227dd7cddfSDavid du Colombier y = textresize(&w->body, r1); 1237dd7cddfSDavid du Colombier w->r = r; 1247dd7cddfSDavid du Colombier w->r.max.y = y; 1257dd7cddfSDavid du Colombier textscrdraw(&w->body); 1267dd7cddfSDavid du Colombier } 1277dd7cddfSDavid du Colombier w->maxlines = min(w->body.nlines, max(w->maxlines, w->body.maxlines)); 1287dd7cddfSDavid du Colombier return w->r.max.y; 1297dd7cddfSDavid du Colombier } 1307dd7cddfSDavid du Colombier 1317dd7cddfSDavid du Colombier void 1327dd7cddfSDavid du Colombier winlock1(Window *w, int owner) 1337dd7cddfSDavid du Colombier { 1347dd7cddfSDavid du Colombier incref(w); 1357dd7cddfSDavid du Colombier qlock(w); 1367dd7cddfSDavid du Colombier w->owner = owner; 1377dd7cddfSDavid du Colombier } 1387dd7cddfSDavid du Colombier 1397dd7cddfSDavid du Colombier void 1407dd7cddfSDavid du Colombier winlock(Window *w, int owner) 1417dd7cddfSDavid du Colombier { 1427dd7cddfSDavid du Colombier int i; 1437dd7cddfSDavid du Colombier File *f; 1447dd7cddfSDavid du Colombier 1457dd7cddfSDavid du Colombier f = w->body.file; 1467dd7cddfSDavid du Colombier for(i=0; i<f->ntext; i++) 1477dd7cddfSDavid du Colombier winlock1(f->text[i]->w, owner); 1487dd7cddfSDavid du Colombier } 1497dd7cddfSDavid du Colombier 1507dd7cddfSDavid du Colombier void 1517dd7cddfSDavid du Colombier winunlock(Window *w) 1527dd7cddfSDavid du Colombier { 1537dd7cddfSDavid du Colombier int i; 1547dd7cddfSDavid du Colombier File *f; 1557dd7cddfSDavid du Colombier 1567dd7cddfSDavid du Colombier f = w->body.file; 1577dd7cddfSDavid du Colombier for(i=0; i<f->ntext; i++){ 1587dd7cddfSDavid du Colombier w = f->text[i]->w; 1597dd7cddfSDavid du Colombier w->owner = 0; 1607dd7cddfSDavid du Colombier qunlock(w); 1617dd7cddfSDavid du Colombier winclose(w); 1627dd7cddfSDavid du Colombier /* winclose() can change up f->text; beware */ 1637dd7cddfSDavid du Colombier if(f->ntext>0 && w != f->text[i]->w) 1647dd7cddfSDavid du Colombier --i; /* winclose() deleted window */ 1657dd7cddfSDavid du Colombier } 1667dd7cddfSDavid du Colombier } 1677dd7cddfSDavid du Colombier 1687dd7cddfSDavid du Colombier void 1697dd7cddfSDavid du Colombier winmousebut(Window *w) 1707dd7cddfSDavid du Colombier { 1717dd7cddfSDavid du Colombier moveto(mousectl, divpt(addpt(w->tag.scrollr.min, w->tag.scrollr.max), 2)); 1727dd7cddfSDavid du Colombier } 1737dd7cddfSDavid du Colombier 1747dd7cddfSDavid du Colombier void 1757dd7cddfSDavid du Colombier windirfree(Window *w) 1767dd7cddfSDavid du Colombier { 1777dd7cddfSDavid du Colombier int i; 1787dd7cddfSDavid du Colombier Dirlist *dl; 1797dd7cddfSDavid du Colombier 1807dd7cddfSDavid du Colombier if(w->isdir){ 1817dd7cddfSDavid du Colombier for(i=0; i<w->ndl; i++){ 1827dd7cddfSDavid du Colombier dl = w->dlp[i]; 1837dd7cddfSDavid du Colombier free(dl->r); 1847dd7cddfSDavid du Colombier free(dl); 1857dd7cddfSDavid du Colombier } 1867dd7cddfSDavid du Colombier free(w->dlp); 1877dd7cddfSDavid du Colombier } 1887dd7cddfSDavid du Colombier w->dlp = nil; 1897dd7cddfSDavid du Colombier w->ndl = 0; 1907dd7cddfSDavid du Colombier } 1917dd7cddfSDavid du Colombier 1927dd7cddfSDavid du Colombier void 1937dd7cddfSDavid du Colombier winclose(Window *w) 1947dd7cddfSDavid du Colombier { 1957dd7cddfSDavid du Colombier int i; 1967dd7cddfSDavid du Colombier 1977dd7cddfSDavid du Colombier if(decref(w) == 0){ 1987dd7cddfSDavid du Colombier windirfree(w); 1997dd7cddfSDavid du Colombier textclose(&w->tag); 2007dd7cddfSDavid du Colombier textclose(&w->body); 2017dd7cddfSDavid du Colombier if(activewin == w) 2027dd7cddfSDavid du Colombier activewin = nil; 2037dd7cddfSDavid du Colombier for(i=0; i<w->nincl; i++) 2047dd7cddfSDavid du Colombier free(w->incl[i]); 2057dd7cddfSDavid du Colombier free(w->incl); 2067dd7cddfSDavid du Colombier free(w->events); 2077dd7cddfSDavid du Colombier free(w); 2087dd7cddfSDavid du Colombier } 2097dd7cddfSDavid du Colombier } 2107dd7cddfSDavid du Colombier 2117dd7cddfSDavid du Colombier void 2127dd7cddfSDavid du Colombier windelete(Window *w) 2137dd7cddfSDavid du Colombier { 2147dd7cddfSDavid du Colombier Xfid *x; 2157dd7cddfSDavid du Colombier 2167dd7cddfSDavid du Colombier x = w->eventx; 2177dd7cddfSDavid du Colombier if(x){ 2187dd7cddfSDavid du Colombier w->nevents = 0; 2197dd7cddfSDavid du Colombier free(w->events); 2207dd7cddfSDavid du Colombier w->events = nil; 2217dd7cddfSDavid du Colombier w->eventx = nil; 2227dd7cddfSDavid du Colombier sendp(x->c, nil); /* wake him up */ 2237dd7cddfSDavid du Colombier } 2247dd7cddfSDavid du Colombier } 2257dd7cddfSDavid du Colombier 2267dd7cddfSDavid du Colombier void 2277dd7cddfSDavid du Colombier winundo(Window *w, int isundo) 2287dd7cddfSDavid du Colombier { 2297dd7cddfSDavid du Colombier Text *body; 2307dd7cddfSDavid du Colombier int i; 2317dd7cddfSDavid du Colombier File *f; 2327dd7cddfSDavid du Colombier Window *v; 2337dd7cddfSDavid du Colombier 2347dd7cddfSDavid du Colombier w->utflastqid = -1; 2357dd7cddfSDavid du Colombier body = &w->body; 2367dd7cddfSDavid du Colombier fileundo(body->file, isundo, &body->q0, &body->q1); 2379a747e4fSDavid du Colombier textshow(body, body->q0, body->q1, 1); 2387dd7cddfSDavid du Colombier f = body->file; 2397dd7cddfSDavid du Colombier for(i=0; i<f->ntext; i++){ 2407dd7cddfSDavid du Colombier v = f->text[i]->w; 2417dd7cddfSDavid du Colombier v->dirty = (f->seq != v->putseq); 2427dd7cddfSDavid du Colombier if(v != w){ 2437dd7cddfSDavid du Colombier v->body.q0 = v->body.p0+v->body.org; 2447dd7cddfSDavid du Colombier v->body.q1 = v->body.p1+v->body.org; 2457dd7cddfSDavid du Colombier } 2467dd7cddfSDavid du Colombier } 2477dd7cddfSDavid du Colombier winsettag(w); 2487dd7cddfSDavid du Colombier } 2497dd7cddfSDavid du Colombier 2507dd7cddfSDavid du Colombier void 2517dd7cddfSDavid du Colombier winsetname(Window *w, Rune *name, int n) 2527dd7cddfSDavid du Colombier { 2537dd7cddfSDavid du Colombier Text *t; 2547dd7cddfSDavid du Colombier Window *v; 2557dd7cddfSDavid du Colombier int i; 2567dd7cddfSDavid du Colombier 2577dd7cddfSDavid du Colombier t = &w->body; 2587dd7cddfSDavid du Colombier if(runeeq(t->file->name, t->file->nname, name, n) == TRUE) 2597dd7cddfSDavid du Colombier return; 2607dd7cddfSDavid du Colombier w->isscratch = FALSE; 2617dd7cddfSDavid du Colombier if(n>=6 && runeeq(L"/guide", 6, name+(n-6), 6)) 2627dd7cddfSDavid du Colombier w->isscratch = TRUE; 2637dd7cddfSDavid du Colombier else if(n>=7 && runeeq(L"+Errors", 7, name+(n-7), 7)) 2647dd7cddfSDavid du Colombier w->isscratch = TRUE; 2657dd7cddfSDavid du Colombier filesetname(t->file, name, n); 2667dd7cddfSDavid du Colombier for(i=0; i<t->file->ntext; i++){ 2677dd7cddfSDavid du Colombier v = t->file->text[i]->w; 2687dd7cddfSDavid du Colombier winsettag(v); 2697dd7cddfSDavid du Colombier v->isscratch = w->isscratch; 2707dd7cddfSDavid du Colombier } 2717dd7cddfSDavid du Colombier } 2727dd7cddfSDavid du Colombier 2737dd7cddfSDavid du Colombier void 2747dd7cddfSDavid du Colombier wintype(Window *w, Text *t, Rune r) 2757dd7cddfSDavid du Colombier { 2767dd7cddfSDavid du Colombier int i; 2777dd7cddfSDavid du Colombier 2787dd7cddfSDavid du Colombier texttype(t, r); 2797dd7cddfSDavid du Colombier if(t->what == Body) 2807dd7cddfSDavid du Colombier for(i=0; i<t->file->ntext; i++) 2817dd7cddfSDavid du Colombier textscrdraw(t->file->text[i]); 2827dd7cddfSDavid du Colombier winsettag(w); 2837dd7cddfSDavid du Colombier } 2847dd7cddfSDavid du Colombier 2857dd7cddfSDavid du Colombier void 2867dd7cddfSDavid du Colombier wincleartag(Window *w) 2877dd7cddfSDavid du Colombier { 2887dd7cddfSDavid du Colombier int i, n; 2897dd7cddfSDavid du Colombier Rune *r; 2907dd7cddfSDavid du Colombier 2917dd7cddfSDavid du Colombier /* w must be committed */ 2927dd7cddfSDavid du Colombier n = w->tag.file->nc; 2937dd7cddfSDavid du Colombier r = runemalloc(n); 2947dd7cddfSDavid du Colombier bufread(w->tag.file, 0, r, n); 2957dd7cddfSDavid du Colombier for(i=0; i<n; i++) 2967dd7cddfSDavid du Colombier if(r[i]==' ' || r[i]=='\t') 2977dd7cddfSDavid du Colombier break; 2987dd7cddfSDavid du Colombier for(; i<n; i++) 2997dd7cddfSDavid du Colombier if(r[i] == '|') 3007dd7cddfSDavid du Colombier break; 3017dd7cddfSDavid du Colombier if(i == n) 3027dd7cddfSDavid du Colombier return; 3037dd7cddfSDavid du Colombier i++; 3047dd7cddfSDavid du Colombier textdelete(&w->tag, i, n, TRUE); 3057dd7cddfSDavid du Colombier free(r); 3067dd7cddfSDavid du Colombier w->tag.file->mod = FALSE; 3077dd7cddfSDavid du Colombier if(w->tag.q0 > i) 3087dd7cddfSDavid du Colombier w->tag.q0 = i; 3097dd7cddfSDavid du Colombier if(w->tag.q1 > i) 3107dd7cddfSDavid du Colombier w->tag.q1 = i; 3117dd7cddfSDavid du Colombier textsetselect(&w->tag, w->tag.q0, w->tag.q1); 3127dd7cddfSDavid du Colombier } 3137dd7cddfSDavid du Colombier 3147dd7cddfSDavid du Colombier void 3157dd7cddfSDavid du Colombier winsettag1(Window *w) 3167dd7cddfSDavid du Colombier { 3177dd7cddfSDavid du Colombier int i, j, k, n, bar, dirty; 3187dd7cddfSDavid du Colombier Rune *new, *old, *r; 3197dd7cddfSDavid du Colombier Image *b; 3207dd7cddfSDavid du Colombier uint q0, q1; 3217dd7cddfSDavid du Colombier Rectangle br; 3227dd7cddfSDavid du Colombier 3237dd7cddfSDavid du Colombier /* there are races that get us here with stuff in the tag cache, so we take extra care to sync it */ 3247dd7cddfSDavid du Colombier if(w->tag.ncache!=0 || w->tag.file->mod) 3257dd7cddfSDavid du Colombier wincommit(w, &w->tag); /* check file name; also guarantees we can modify tag contents */ 3267dd7cddfSDavid du Colombier old = runemalloc(w->tag.file->nc+1); 3277dd7cddfSDavid du Colombier bufread(w->tag.file, 0, old, w->tag.file->nc); 3287dd7cddfSDavid du Colombier old[w->tag.file->nc] = '\0'; 3297dd7cddfSDavid du Colombier for(i=0; i<w->tag.file->nc; i++) 3307dd7cddfSDavid du Colombier if(old[i]==' ' || old[i]=='\t') 3317dd7cddfSDavid du Colombier break; 3327dd7cddfSDavid du Colombier if(runeeq(old, i, w->body.file->name, w->body.file->nname) == FALSE){ 3337dd7cddfSDavid du Colombier textdelete(&w->tag, 0, i, TRUE); 3347dd7cddfSDavid du Colombier textinsert(&w->tag, 0, w->body.file->name, w->body.file->nname, TRUE); 3357dd7cddfSDavid du Colombier free(old); 3367dd7cddfSDavid du Colombier old = runemalloc(w->tag.file->nc+1); 3377dd7cddfSDavid du Colombier bufread(w->tag.file, 0, old, w->tag.file->nc); 3387dd7cddfSDavid du Colombier old[w->tag.file->nc] = '\0'; 3397dd7cddfSDavid du Colombier } 3407dd7cddfSDavid du Colombier new = runemalloc(w->body.file->nname+100); 3417dd7cddfSDavid du Colombier i = 0; 3427dd7cddfSDavid du Colombier runemove(new+i, w->body.file->name, w->body.file->nname); 3437dd7cddfSDavid du Colombier i += w->body.file->nname; 3447dd7cddfSDavid du Colombier runemove(new+i, L" Del Snarf", 10); 3457dd7cddfSDavid du Colombier i += 10; 3467dd7cddfSDavid du Colombier if(w->filemenu){ 3477dd7cddfSDavid du Colombier if(w->body.file->delta.nc>0 || w->body.ncache){ 3487dd7cddfSDavid du Colombier runemove(new+i, L" Undo", 5); 3497dd7cddfSDavid du Colombier i += 5; 3507dd7cddfSDavid du Colombier } 3517dd7cddfSDavid du Colombier if(w->body.file->epsilon.nc > 0){ 3527dd7cddfSDavid du Colombier runemove(new+i, L" Redo", 5); 3537dd7cddfSDavid du Colombier i += 5; 3547dd7cddfSDavid du Colombier } 3557dd7cddfSDavid du Colombier dirty = w->body.file->nname && (w->body.ncache || w->body.file->seq!=w->putseq); 3567dd7cddfSDavid du Colombier if(!w->isdir && dirty){ 3577dd7cddfSDavid du Colombier runemove(new+i, L" Put", 4); 3587dd7cddfSDavid du Colombier i += 4; 3597dd7cddfSDavid du Colombier } 3607dd7cddfSDavid du Colombier } 3617dd7cddfSDavid du Colombier if(w->isdir){ 3627dd7cddfSDavid du Colombier runemove(new+i, L" Get", 4); 3637dd7cddfSDavid du Colombier i += 4; 3647dd7cddfSDavid du Colombier } 3657dd7cddfSDavid du Colombier runemove(new+i, L" |", 2); 3667dd7cddfSDavid du Colombier i += 2; 36759cc4ca5SDavid du Colombier r = runestrchr(old, '|'); 3687dd7cddfSDavid du Colombier if(r) 3697dd7cddfSDavid du Colombier k = r-old+1; 3707dd7cddfSDavid du Colombier else{ 3717dd7cddfSDavid du Colombier k = w->tag.file->nc; 3727dd7cddfSDavid du Colombier if(w->body.file->seq == 0){ 3737dd7cddfSDavid du Colombier runemove(new+i, L" Look ", 6); 3747dd7cddfSDavid du Colombier i += 6; 3757dd7cddfSDavid du Colombier } 3767dd7cddfSDavid du Colombier } 3777dd7cddfSDavid du Colombier if(runeeq(new, i, old, k) == FALSE){ 3787dd7cddfSDavid du Colombier n = k; 3797dd7cddfSDavid du Colombier if(n > i) 3807dd7cddfSDavid du Colombier n = i; 3817dd7cddfSDavid du Colombier for(j=0; j<n; j++) 3827dd7cddfSDavid du Colombier if(old[j] != new[j]) 3837dd7cddfSDavid du Colombier break; 3847dd7cddfSDavid du Colombier q0 = w->tag.q0; 3857dd7cddfSDavid du Colombier q1 = w->tag.q1; 3867dd7cddfSDavid du Colombier textdelete(&w->tag, j, k, TRUE); 3877dd7cddfSDavid du Colombier textinsert(&w->tag, j, new+j, i-j, TRUE); 3887dd7cddfSDavid du Colombier /* try to preserve user selection */ 38959cc4ca5SDavid du Colombier r = runestrchr(old, '|'); 3907dd7cddfSDavid du Colombier if(r){ 3917dd7cddfSDavid du Colombier bar = r-old; 3927dd7cddfSDavid du Colombier if(q0 > bar){ 39359cc4ca5SDavid du Colombier bar = (runestrchr(new, '|')-new)-bar; 3947dd7cddfSDavid du Colombier w->tag.q0 = q0+bar; 3957dd7cddfSDavid du Colombier w->tag.q1 = q1+bar; 3967dd7cddfSDavid du Colombier } 3977dd7cddfSDavid du Colombier } 3987dd7cddfSDavid du Colombier } 3997dd7cddfSDavid du Colombier free(old); 4007dd7cddfSDavid du Colombier free(new); 4017dd7cddfSDavid du Colombier w->tag.file->mod = FALSE; 4027dd7cddfSDavid du Colombier n = w->tag.file->nc+w->tag.ncache; 4037dd7cddfSDavid du Colombier if(w->tag.q0 > n) 4047dd7cddfSDavid du Colombier w->tag.q0 = n; 4057dd7cddfSDavid du Colombier if(w->tag.q1 > n) 4067dd7cddfSDavid du Colombier w->tag.q1 = n; 4077dd7cddfSDavid du Colombier textsetselect(&w->tag, w->tag.q0, w->tag.q1); 4087dd7cddfSDavid du Colombier b = button; 4097dd7cddfSDavid du Colombier if(!w->isdir && !w->isscratch && (w->body.file->mod || w->body.ncache)) 4107dd7cddfSDavid du Colombier b = modbutton; 4117dd7cddfSDavid du Colombier br.min = w->tag.scrollr.min; 4127dd7cddfSDavid du Colombier br.max.x = br.min.x + Dx(b->r); 4137dd7cddfSDavid du Colombier br.max.y = br.min.y + Dy(b->r); 4147dd7cddfSDavid du Colombier draw(screen, br, b, nil, b->r.min); 4157dd7cddfSDavid du Colombier } 4167dd7cddfSDavid du Colombier 4177dd7cddfSDavid du Colombier void 4187dd7cddfSDavid du Colombier winsettag(Window *w) 4197dd7cddfSDavid du Colombier { 4207dd7cddfSDavid du Colombier int i; 4217dd7cddfSDavid du Colombier File *f; 4227dd7cddfSDavid du Colombier Window *v; 4237dd7cddfSDavid du Colombier 4247dd7cddfSDavid du Colombier f = w->body.file; 4257dd7cddfSDavid du Colombier for(i=0; i<f->ntext; i++){ 4267dd7cddfSDavid du Colombier v = f->text[i]->w; 4277dd7cddfSDavid du Colombier if(v->col->safe || v->body.maxlines>0) 4287dd7cddfSDavid du Colombier winsettag1(v); 4297dd7cddfSDavid du Colombier } 4307dd7cddfSDavid du Colombier } 4317dd7cddfSDavid du Colombier 4327dd7cddfSDavid du Colombier void 4337dd7cddfSDavid du Colombier wincommit(Window *w, Text *t) 4347dd7cddfSDavid du Colombier { 4357dd7cddfSDavid du Colombier Rune *r; 4367dd7cddfSDavid du Colombier int i; 4377dd7cddfSDavid du Colombier File *f; 4387dd7cddfSDavid du Colombier 4397dd7cddfSDavid du Colombier textcommit(t, TRUE); 4407dd7cddfSDavid du Colombier f = t->file; 4417dd7cddfSDavid du Colombier if(f->ntext > 1) 4427dd7cddfSDavid du Colombier for(i=0; i<f->ntext; i++) 4437dd7cddfSDavid du Colombier textcommit(f->text[i], FALSE); /* no-op for t */ 4447dd7cddfSDavid du Colombier if(t->what == Body) 4457dd7cddfSDavid du Colombier return; 4467dd7cddfSDavid du Colombier r = runemalloc(w->tag.file->nc); 4477dd7cddfSDavid du Colombier bufread(w->tag.file, 0, r, w->tag.file->nc); 4487dd7cddfSDavid du Colombier for(i=0; i<w->tag.file->nc; i++) 4497dd7cddfSDavid du Colombier if(r[i]==' ' || r[i]=='\t') 4507dd7cddfSDavid du Colombier break; 4517dd7cddfSDavid du Colombier if(runeeq(r, i, w->body.file->name, w->body.file->nname) == FALSE){ 4527dd7cddfSDavid du Colombier seq++; 4537dd7cddfSDavid du Colombier filemark(w->body.file); 4547dd7cddfSDavid du Colombier w->body.file->mod = TRUE; 4557dd7cddfSDavid du Colombier w->dirty = TRUE; 4567dd7cddfSDavid du Colombier winsetname(w, r, i); 4577dd7cddfSDavid du Colombier winsettag(w); 4587dd7cddfSDavid du Colombier } 4597dd7cddfSDavid du Colombier free(r); 4607dd7cddfSDavid du Colombier } 4617dd7cddfSDavid du Colombier 4627dd7cddfSDavid du Colombier void 4637dd7cddfSDavid du Colombier winaddincl(Window *w, Rune *r, int n) 4647dd7cddfSDavid du Colombier { 4657dd7cddfSDavid du Colombier char *a; 4669a747e4fSDavid du Colombier Dir *d; 4677dd7cddfSDavid du Colombier Runestr rs; 4687dd7cddfSDavid du Colombier 4697dd7cddfSDavid du Colombier a = runetobyte(r, n); 4709a747e4fSDavid du Colombier d = dirstat(a); 4719a747e4fSDavid du Colombier if(d == nil){ 4727dd7cddfSDavid du Colombier if(a[0] == '/') 4737dd7cddfSDavid du Colombier goto Rescue; 4747dd7cddfSDavid du Colombier rs = dirname(&w->body, r, n); 4757dd7cddfSDavid du Colombier r = rs.r; 4767dd7cddfSDavid du Colombier n = rs.nr; 4777dd7cddfSDavid du Colombier free(a); 4787dd7cddfSDavid du Colombier a = runetobyte(r, n); 4799a747e4fSDavid du Colombier d = dirstat(a); 4809a747e4fSDavid du Colombier if(d == nil) 4817dd7cddfSDavid du Colombier goto Rescue; 4827dd7cddfSDavid du Colombier r = runerealloc(r, n+1); 4837dd7cddfSDavid du Colombier r[n] = 0; 4847dd7cddfSDavid du Colombier } 4857dd7cddfSDavid du Colombier free(a); 4869a747e4fSDavid du Colombier if((d->qid.type&QTDIR) == 0){ 4879a747e4fSDavid du Colombier free(d); 4887dd7cddfSDavid du Colombier warning(nil, "%s: not a directory\n", a); 4897dd7cddfSDavid du Colombier free(r); 4907dd7cddfSDavid du Colombier return; 4917dd7cddfSDavid du Colombier } 4929a747e4fSDavid du Colombier free(d); 4937dd7cddfSDavid du Colombier w->nincl++; 4947dd7cddfSDavid du Colombier w->incl = realloc(w->incl, w->nincl*sizeof(Rune*)); 4957dd7cddfSDavid du Colombier memmove(w->incl+1, w->incl, (w->nincl-1)*sizeof(Rune*)); 4967dd7cddfSDavid du Colombier w->incl[0] = runemalloc(n+1); 4977dd7cddfSDavid du Colombier runemove(w->incl[0], r, n); 4987dd7cddfSDavid du Colombier free(r); 4997dd7cddfSDavid du Colombier return; 5007dd7cddfSDavid du Colombier 5017dd7cddfSDavid du Colombier Rescue: 5027dd7cddfSDavid du Colombier warning(nil, "%s: %r\n", a); 5037dd7cddfSDavid du Colombier free(r); 5047dd7cddfSDavid du Colombier free(a); 5057dd7cddfSDavid du Colombier return; 5067dd7cddfSDavid du Colombier } 5077dd7cddfSDavid du Colombier 5087dd7cddfSDavid du Colombier int 5097dd7cddfSDavid du Colombier winclean(Window *w, int conservative) /* as it stands, conservative is always TRUE */ 5107dd7cddfSDavid du Colombier { 5117dd7cddfSDavid du Colombier if(w->isscratch || w->isdir) /* don't whine if it's a guide file, error window, etc. */ 5127dd7cddfSDavid du Colombier return TRUE; 5137dd7cddfSDavid du Colombier if(!conservative && w->nopen[QWevent]>0) 5147dd7cddfSDavid du Colombier return TRUE; 5157dd7cddfSDavid du Colombier if(w->dirty){ 5167dd7cddfSDavid du Colombier if(w->body.file->nname) 5177dd7cddfSDavid du Colombier warning(nil, "%.*S modified\n", w->body.file->nname, w->body.file->name); 5187dd7cddfSDavid du Colombier else{ 5197dd7cddfSDavid du Colombier if(w->body.file->nc < 100) /* don't whine if it's too small */ 5207dd7cddfSDavid du Colombier return TRUE; 5217dd7cddfSDavid du Colombier warning(nil, "unnamed file modified\n"); 5227dd7cddfSDavid du Colombier } 5237dd7cddfSDavid du Colombier w->dirty = FALSE; 5247dd7cddfSDavid du Colombier return FALSE; 5257dd7cddfSDavid du Colombier } 5267dd7cddfSDavid du Colombier return TRUE; 5277dd7cddfSDavid du Colombier } 5287dd7cddfSDavid du Colombier 5297dd7cddfSDavid du Colombier void 5309a747e4fSDavid du Colombier winctlprint(Window *w, char *buf, int fonts) 5317dd7cddfSDavid du Colombier { 5329a747e4fSDavid du Colombier int n; 5339a747e4fSDavid du Colombier 5349a747e4fSDavid du Colombier n = sprint(buf, "%11d %11d %11d %11d %11d ", w->id, w->tag.file->nc, 5357dd7cddfSDavid du Colombier w->body.file->nc, w->isdir, w->dirty); 5369a747e4fSDavid du Colombier if(fonts) 537b8661318SDavid du Colombier sprint(buf+n, "%11d %q %11d" , Dx(w->body.r), w->body.reffont->f->name, w->body.maxtab); 5387dd7cddfSDavid du Colombier } 5397dd7cddfSDavid du Colombier 5407dd7cddfSDavid du Colombier void 5417dd7cddfSDavid du Colombier winevent(Window *w, char *fmt, ...) 5427dd7cddfSDavid du Colombier { 5437dd7cddfSDavid du Colombier int n; 5447dd7cddfSDavid du Colombier char *b; 5457dd7cddfSDavid du Colombier Xfid *x; 5467dd7cddfSDavid du Colombier va_list arg; 5477dd7cddfSDavid du Colombier 5487dd7cddfSDavid du Colombier if(w->nopen[QWevent] == 0) 5497dd7cddfSDavid du Colombier return; 5507dd7cddfSDavid du Colombier if(w->owner == 0) 5517dd7cddfSDavid du Colombier error("no window owner"); 5527dd7cddfSDavid du Colombier va_start(arg, fmt); 5539a747e4fSDavid du Colombier b = vsmprint(fmt, arg); 5547dd7cddfSDavid du Colombier va_end(arg); 5559a747e4fSDavid du Colombier if(b == nil) 5569a747e4fSDavid du Colombier error("vsmprint failed"); 5579a747e4fSDavid du Colombier n = strlen(b); 5587dd7cddfSDavid du Colombier w->events = realloc(w->events, w->nevents+1+n); 5597dd7cddfSDavid du Colombier w->events[w->nevents++] = w->owner; 5607dd7cddfSDavid du Colombier memmove(w->events+w->nevents, b, n); 5619a747e4fSDavid du Colombier free(b); 5627dd7cddfSDavid du Colombier w->nevents += n; 5637dd7cddfSDavid du Colombier x = w->eventx; 5647dd7cddfSDavid du Colombier if(x){ 5657dd7cddfSDavid du Colombier w->eventx = nil; 5667dd7cddfSDavid du Colombier sendp(x->c, nil); 5677dd7cddfSDavid du Colombier } 5687dd7cddfSDavid du Colombier } 569