Annotation of 43BSD/contrib/jove/wind.c, revision 1.1.1.1

1.1       root        1: /*************************************************************************
                      2:  * This program is copyright (C) 1985, 1986 by Jonathan Payne.  It is    *
                      3:  * provided to you without charge for use only on a licensed Unix        *
                      4:  * system.  You may copy JOVE provided that this notice is included with *
                      5:  * the copy.  You may not sell copies of this program or versions        *
                      6:  * modified for use on microcomputer systems, unless the copies are      *
                      7:  * included with a Unix system distribution and the source is provided.  *
                      8:  *************************************************************************/
                      9: 
                     10: /* This creates/deletes/divides/grows/shrinks windows.  */
                     11: 
                     12: #include "jove.h"
                     13: #include "termcap.h"
                     14: 
                     15: static char    onlyone[] = "You only have one window!",
                     16:                toosmall[] = "Resulting window would be too small.";
                     17: 
                     18: Window *curwind,
                     19:        *fwind = 0;
                     20: 
                     21: /* First line in a Window */
                     22: 
                     23: FLine(w)
                     24: register Window        *w;
                     25: {
                     26:        register Window *wp = fwind;
                     27:        register int    lineno = -1;
                     28: 
                     29:        do {
                     30:                if (wp == w)
                     31:                        return lineno + 1;
                     32:                lineno += wp->w_height;
                     33:                wp = wp->w_next;
                     34:        } while (wp != fwind);
                     35:        complain("window?");
                     36:        /* NOTREACHED */
                     37: }
                     38: 
                     39: /* Delete `wp' from the screen.  If it is the only window left
                     40:    on the screen, then complain.  It gives its body
                     41:    to the next window if there is one, otherwise the previous
                     42:    window gets the body.  */
                     43: 
                     44: del_wind(wp)
                     45: register Window        *wp;
                     46: {
                     47:        register Window *prev = wp->w_prev;
                     48: 
                     49:        if (one_windp())
                     50:                complain(onlyone);
                     51: 
                     52:        wp->w_prev->w_next = wp->w_next;
                     53:        wp->w_next->w_prev = wp->w_prev;
                     54:        
                     55:        if (fwind == wp) {
                     56:                fwind = wp->w_next;
                     57:                fwind->w_height += wp->w_height;
                     58:                /* Here try to do something intelligent for redisplay() */
                     59:                SetTop(fwind, prev_line(fwind->w_top, wp->w_height));
                     60:                if (curwind == wp)
                     61:                        SetWind(fwind);
                     62:        } else {
                     63:                prev->w_height += wp->w_height;
                     64:                if (curwind == wp)
                     65:                        SetWind(prev);
                     66:        }
                     67:        free((char *) wp);
                     68: }
                     69: 
                     70: /* Divide the window WP N times, or at least once.  Complains if WP is too
                     71:    small to be split into that many pieces.  It returns the new window. */
                     72: 
                     73: Window *
                     74: div_wind(wp, n)
                     75: register Window        *wp;
                     76: {
                     77:        register Window *new;
                     78:        int     amt;
                     79: 
                     80:        if (n < 1)
                     81:                n = 1;
                     82:        amt = wp->w_height / (n + 1);
                     83:        if (amt < 2)
                     84:                complain(toosmall);
                     85: 
                     86:        while (--n >= 0) {
                     87:                new = (Window *) emalloc(sizeof (Window));
                     88:                new->w_visspace = new->w_numlines = 0;
                     89: 
                     90:                new->w_height = amt;
                     91:                wp->w_height -= amt;
                     92: 
                     93:                /* set the lines such that w_line is the center in
                     94:                   each Window */
                     95:                new->w_line = wp->w_line;
                     96:                new->w_char = wp->w_char;
                     97:                new->w_bufp = wp->w_bufp;
                     98:                new->w_top = prev_line(new->w_line, HALF(new));
                     99: 
                    100:                /* Link the new window into the list */
                    101:                new->w_prev = wp;
                    102:                new->w_next = wp->w_next;
                    103:                new->w_next->w_prev = new;
                    104:                wp->w_next = new;
                    105:        }
                    106:        return new;
                    107: }
                    108: 
                    109: /* Initialze the first window setting the bounds to the size of the
                    110:    screen.  There is no buffer with this window.  See parse for the
                    111:    setting of this window. */
                    112: 
                    113: winit()
                    114: {
                    115:        register Window *w;
                    116: 
                    117:        w = curwind = fwind = (Window *) emalloc(sizeof (Window));
                    118:        w->w_line = w->w_top = 0;
                    119:        w->w_visspace = w->w_numlines = 0;
                    120:        w->w_char = 0;
                    121:        w->w_next = w->w_prev = fwind;
                    122:        w->w_height = ILI;
                    123: }
                    124: 
                    125: /* Change to previous window. */
                    126: 
                    127: PrevWindow()
                    128: {
                    129:        register Window *new = curwind->w_prev;
                    130: 
                    131:        if (one_windp())
                    132:                complain(onlyone);
                    133:        SetWind(new);
                    134: }
                    135: 
                    136: /* Make NEW the current Window */
                    137: 
                    138: SetWind(new)
                    139: register Window        *new;
                    140: {
                    141:        if (!Asking){           /* can you say kludge? */
                    142:                curwind->w_line = curline;
                    143:                curwind->w_char = curchar;
                    144:                curwind->w_bufp = curbuf;
                    145:        }
                    146:        if (new == curwind)
                    147:                return;
                    148:        SetBuf(new->w_bufp);
                    149:        if (!inlist(new->w_bufp->b_first, new->w_line)) {
                    150:                new->w_line = curline;
                    151:                new->w_char = curchar;
                    152:        }
                    153:        DotTo(new->w_line, new->w_char);
                    154:        if (curchar > strlen(linebuf))
                    155:                new->w_char = curchar = strlen(linebuf);
                    156:        curwind = new;
                    157: }
                    158: 
                    159: /* Delete the current window if it isn't the only one left */
                    160: 
                    161: DelCurWindow()
                    162: {
                    163:        del_wind(curwind);
                    164: }
                    165: 
                    166: /* Put the current line of `w' in the middle of the window */
                    167: 
                    168: CentWind(w)
                    169: register Window        *w;
                    170: {
                    171:        SetTop(w, prev_line(w->w_line, HALF(w)));
                    172: }
                    173: 
                    174: int    ScrollStep = 0;         /* Full scrolling */
                    175: 
                    176: /* Calculate the new topline of the screen.  If ScrollStep == 0
                    177:    it means we should center the current line in the window. */
                    178: 
                    179: CalcWind(w)
                    180: register Window        *w;
                    181: {
                    182:        register int    up;
                    183:        Line    *newtop;
                    184: 
                    185:        if (ScrollStep == 0)    /* Means just center it */
                    186:                CentWind(w);
                    187:        else {
                    188:                up = inorder(w->w_line, 0, w->w_top, 0);
                    189:                if (up == -1) {
                    190:                        CentWind(w);
                    191:                        return;
                    192:                }
                    193:                if (up)         /* Dot is above the screen */
                    194:                        newtop = prev_line(w->w_line, min(ScrollStep - 1, HALF(w)));
                    195:                else
                    196:                        newtop = prev_line(w->w_line, (SIZE(w) - 1) -
                    197:                                                min(ScrollStep - 1, HALF(w)));
                    198:                if (LineDist(newtop, w->w_top) >= SIZE(w) - 1)
                    199:                        CentWind(w);
                    200:                else
                    201:                        SetTop(w, newtop);
                    202:        }
                    203: }
                    204: 
                    205: WindFind()
                    206: {
                    207:        register Buffer *savebuf = curbuf;
                    208:        Bufpos  savedot;
                    209:        extern int
                    210:                FindTag(),
                    211:                BufSelect(),
                    212:                FindFile();
                    213: 
                    214:        DOTsave(&savedot);
                    215: 
                    216:        switch (waitchar()) {
                    217:        case 't':
                    218:        case 'T':
                    219:                ExecCmd((data_obj *) FindCmd(FindTag));
                    220:                break;
                    221: 
                    222:        case 'b':
                    223:        case 'B':
                    224:                ExecCmd((data_obj *) FindCmd(BufSelect));
                    225:                break;
                    226: 
                    227:        case 'f':
                    228:        case 'F':
                    229:                ExecCmd((data_obj *) FindCmd(FindFile));
                    230:                break;
                    231: 
                    232:        default:
                    233:                complain("T: find-tag, F: find-file, B: select-buffer.");
                    234:        }
                    235: 
                    236:        if (one_windp())
                    237:                (void) div_wind(curwind, 1);
                    238: 
                    239:        tiewind(curwind->w_next, curbuf);
                    240:        SetBuf(savebuf);        /* Back to original buffer */
                    241:        SetDot(&savedot);       /* in original position */
                    242:        tiewind(curwind, curbuf);
                    243:        SetWind(curwind->w_next);
                    244: }
                    245: 
                    246: /* Go into one window mode by deleting all the other windows */
                    247: 
                    248: OneWindow()
                    249: {
                    250:        while (curwind->w_next != curwind)
                    251:                del_wind(curwind->w_next);
                    252: }
                    253: 
                    254: Window *
                    255: windbp(bp)
                    256: register Buffer        *bp;
                    257: {
                    258: 
                    259:        register Window *wp = fwind;
                    260: 
                    261:        if (bp == 0)
                    262:                return 0;
                    263:        do {
                    264:                if (wp->w_bufp == bp)
                    265:                        return wp;
                    266:                wp = wp->w_next;
                    267:        } while (wp != fwind);
                    268:        return 0;
                    269: }
                    270: 
                    271: /* Look for a window containing a buffer whose name is `name' */
                    272: 
                    273: Window *
                    274: windlook(name)
                    275: register char  *name;
                    276: {
                    277:        return windbp(buf_exists(name));
                    278: }
                    279: 
                    280: /* Change window into the next window.  Curwind becomes the new window. */
                    281: 
                    282: NextWindow()
                    283: {
                    284:        register Window *new = curwind->w_next;
                    285: 
                    286:        if (one_windp())
                    287:                complain(onlyone);
                    288:        SetWind(new);
                    289: }
                    290: 
                    291: /* Scroll the next Window */
                    292: 
                    293: PageNWind()
                    294: {
                    295:        if (one_windp())
                    296:                complain(onlyone);
                    297:        NextWindow();
                    298:        NextPage();
                    299:        PrevWindow();
                    300: }
                    301: 
                    302: Window *
                    303: w_nam_typ(name, type)
                    304: register char  *name;
                    305: {
                    306:        register Window *w;
                    307:        register Buffer *b;
                    308: 
                    309:        b = buf_exists(name);
                    310:        w = fwind;
                    311:        if (b) do {
                    312:                if (w->w_bufp == b)
                    313:                        return w;
                    314:        } while ((w = w->w_next) != fwind);
                    315: 
                    316:        w = fwind;
                    317:        do {
                    318:                if (w->w_bufp->b_type == type)
                    319:                        return w;
                    320:        } while ((w = w->w_next) != fwind);
                    321: 
                    322:        return 0;
                    323: }
                    324: 
                    325: /* Put a window with the buffer `name' in it.  Erase the buffer if
                    326:    `clobber' is non-zero. */
                    327: 
                    328: pop_wind(name, clobber, btype)
                    329: register char  *name;
                    330: {
                    331:        register Window *wp;
                    332:        register Buffer *newb;
                    333: 
                    334:        if ((wp = w_nam_typ(name, btype)) == 0) {
                    335:                if (one_windp())
                    336:                        SetWind(div_wind(curwind, 1));
                    337:                else
                    338:                        PrevWindow();
                    339:        } else
                    340:                SetWind(wp);
                    341: 
                    342:        newb = do_select((Window *) 0, name);
                    343:        if (clobber)
                    344:                initlist(newb);
                    345:        tiewind(curwind, newb);
                    346: #ifdef IPROCS
                    347:        if (newb->b_type != B_IPROCESS && btype != -1)
                    348: #else
                    349:        if (btype != -1)
                    350: #endif
                    351:                newb->b_type = btype;
                    352:        SetBuf(newb);
                    353: }
                    354: 
                    355: GrowWindow()
                    356: {
                    357:        WindSize(curwind, abs(exp));
                    358: }
                    359: 
                    360: ShrWindow()
                    361: {
                    362:        WindSize(curwind, -abs(exp));
                    363: }
                    364: 
                    365: /* Change the size of the window by inc.  First arg is the window,
                    366:    second is the increment. */
                    367: 
                    368: WindSize(w, inc)
                    369: register Window        *w;
                    370: register int   inc;
                    371: {
                    372:        if (one_windp())
                    373:                complain(onlyone);
                    374: 
                    375:        if (inc == 0)
                    376:                return;
                    377:        else if (inc < 0) {     /* Shrinking this Window. */
                    378:                if (w->w_height + inc < 2)
                    379:                        complain(toosmall);
                    380:                w->w_height += inc;
                    381:                w->w_prev->w_height -= inc;
                    382:        } else                  /* Growing the window. */
                    383:                WindSize(w->w_next, -inc);
                    384: }
                    385: 
                    386: /* Set the topline of the window, calculating its number in the buffer.
                    387:    This is for numbering the lines only. */
                    388: 
                    389: SetTop(w, line)
                    390: Window *w;
                    391: register Line  *line;
                    392: {
                    393:        register Line   *lp = w->w_bufp->b_first;
                    394:        register int    num = 0;
                    395: 
                    396:        w->w_top = line;
                    397:        if (w->w_numlines) {
                    398:                while (lp) {
                    399:                        num++;
                    400:                        if (line == lp)
                    401:                                break;
                    402:                        lp = lp->l_next;
                    403:                }
                    404:                w->w_topnum = num;
                    405:        }
                    406: }
                    407: 
                    408: WNumLines()
                    409: {
                    410:        curwind->w_numlines = !curwind->w_numlines;
                    411:        SetTop(curwind, curwind->w_top);
                    412: }
                    413: 
                    414: WVisSpace()
                    415: {
                    416:        curwind->w_visspace = !curwind->w_visspace;
                    417:        ClAndRedraw();
                    418: }
                    419: 
                    420: /* Return the line number that `line' occupies in `windes' */
                    421: 
                    422: in_window(windes, line)
                    423: register Window        *windes;
                    424: register Line  *line;
                    425: {
                    426:        register int    i;
                    427:        register Line   *top = windes->w_top;
                    428: 
                    429:        for (i = 0; top && i < windes->w_height - 1; i++, top = top->l_next)
                    430:                if (top == line)
                    431:                        return FLine(windes) + i;
                    432:        return -1;
                    433: }
                    434: 
                    435: SplitWind()
                    436: {
                    437:        SetWind(div_wind(curwind, exp_p ? (exp - 1) : 1));
                    438: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.