[BACK]Return to win.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / window

Annotation of src/usr.bin/window/win.c, Revision 1.5

1.5     ! downsj      1: /*     $OpenBSD$       */
1.3       niklas      2: /*     $NetBSD: win.c,v 1.8 1996/02/08 21:07:57 mycroft Exp $  */
1.1       deraadt     3:
                      4: /*
                      5:  * Copyright (c) 1983, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to Berkeley by
                      9:  * Edward Wang at The University of California, Berkeley.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by the University of
                     22:  *     California, Berkeley and its contributors.
                     23:  * 4. Neither the name of the University nor the names of its contributors
                     24:  *    may be used to endorse or promote products derived from this software
                     25:  *    without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     28:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     29:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     30:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     31:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     32:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     33:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     34:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     35:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     36:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     37:  * SUCH DAMAGE.
                     38:  */
                     39:
                     40: #ifndef lint
                     41: #if 0
                     42: static char sccsid[] = "@(#)win.c      8.1 (Berkeley) 6/6/93";
                     43: #else
1.5     ! downsj     44: static char rcsid[] = "$OpenBSD$";
1.1       deraadt    45: #endif
                     46: #endif /* not lint */
                     47:
                     48: #include "defs.h"
                     49: #include "char.h"
                     50: #include <string.h>
                     51:
                     52: /*
                     53:  * Higher level routines for dealing with windows.
                     54:  *
                     55:  * There are two types of windows: user window, and information window.
                     56:  * User windows are the ones with a pty and shell.  Information windows
                     57:  * are for displaying error messages, and other information.
                     58:  *
                     59:  * The windows are doubly linked in overlapping order and divided into
                     60:  * two groups: foreground and normal.  Information
                     61:  * windows are always foreground.  User windows can be either.
                     62:  * Addwin() adds a window to the list at the top of one of the two groups.
                     63:  * Deletewin() deletes a window.  Front() moves a window to the front
                     64:  * of its group.  Wwopen(), wwadd(), and wwdelete() should never be called
                     65:  * directly.
                     66:  */
                     67:
                     68: /*
                     69:  * Open a user window.
                     70:  */
                     71: struct ww *
1.3       niklas     72: openwin(id, row, col, nrow, ncol, nline, label, type, uflags, shf, sh)
1.1       deraadt    73: char *label;
                     74: char *shf, **sh;
                     75: {
                     76:        register struct ww *w;
                     77:
                     78:        if (id < 0 && (id = findid()) < 0)
                     79:                return 0;
                     80:        if (row + nrow <= 0 || row > wwnrow - 1
                     81:            || col + ncol <= 0 || col > wwncol - 1) {
                     82:                error("Illegal window position.");
                     83:                return 0;
                     84:        }
1.3       niklas     85:        w = wwopen(type, 0, nrow, ncol, row, col, nline);
1.1       deraadt    86:        if (w == 0) {
                     87:                error("Can't open window: %s.", wwerror());
                     88:                return 0;
                     89:        }
                     90:        w->ww_id = id;
                     91:        window[id] = w;
1.3       niklas     92:        CLR(w->ww_uflags, WWU_ALLFLAGS);
                     93:        SET(w->ww_uflags, uflags);
1.1       deraadt    94:        w->ww_alt = w->ww_w;
                     95:        if (label != 0 && setlabel(w, label) < 0)
                     96:                error("No memory for label.");
                     97:        wwcursor(w, 1);
                     98:        /*
                     99:         * We have to do this little maneuver to make sure
                    100:         * addwin() puts w at the top, so we don't waste an
                    101:         * insert and delete operation.
                    102:         */
                    103:        setselwin((struct ww *)0);
                    104:        addwin(w, 0);
                    105:        setselwin(w);
                    106:        if (wwspawn(w, shf, sh) < 0) {
                    107:                error("Can't execute %s: %s.", shf, wwerror());
                    108:                closewin(w);
                    109:                return 0;
                    110:        }
                    111:        return w;
                    112: }
                    113:
                    114: findid()
                    115: {
                    116:        register i;
                    117:
                    118:        for (i = 0; i < NWINDOW && window[i] != 0; i++)
                    119:                ;
                    120:        if (i >= NWINDOW) {
                    121:                error("Too many windows.");
                    122:                return -1;
                    123:        }
                    124:        return i;
                    125: }
                    126:
                    127: struct ww *
                    128: findselwin()
                    129: {
                    130:        register struct ww *w, *s = 0;
                    131:        register i;
                    132:
                    133:        for (i = 0; i < NWINDOW; i++)
                    134:                if ((w = window[i]) != 0 && w != selwin &&
                    135:                    (s == 0 ||
                    136:                     !isfg(w) && (w->ww_order < s->ww_order || isfg(s))))
                    137:                        s = w;
                    138:        return s;
                    139: }
                    140:
                    141: /*
                    142:  * Close a user window.  Close all if w == 0.
                    143:  */
                    144: closewin(w)
                    145: register struct ww *w;
                    146: {
                    147:        char didit = 0;
                    148:        register i;
                    149:
                    150:        if (w != 0) {
                    151:                closewin1(w);
                    152:                didit++;
                    153:        } else
                    154:                for (i = 0; i < NWINDOW; i++) {
                    155:                        if ((w = window[i]) == 0)
                    156:                                continue;
                    157:                        closewin1(w);
                    158:                        didit++;
                    159:                }
                    160:        if (didit) {
                    161:                if (selwin == 0)
                    162:                        if (lastselwin != 0) {
                    163:                                setselwin(lastselwin);
                    164:                                lastselwin = 0;
                    165:                        } else if (w = findselwin())
                    166:                                setselwin(w);
                    167:                if (lastselwin == 0 && selwin)
                    168:                        if (w = findselwin())
                    169:                                lastselwin = w;
                    170:                reframe();
                    171:        }
                    172: }
                    173:
                    174: /*
                    175:  * Open an information (display) window.
                    176:  */
                    177: struct ww *
                    178: openiwin(nrow, label)
                    179: char *label;
                    180: {
                    181:        register struct ww *w;
                    182:
1.2       deraadt   183:        if ((w = wwopen(WWT_INTERNAL, 0, nrow, wwncol, 2, 0, 0)) == 0)
1.1       deraadt   184:                return 0;
1.3       niklas    185:        SET(w->ww_wflags, WWW_MAPNL | WWW_NOINTR | WWW_NOUPDATE | WWW_UNCTRL);
                    186:        SET(w->ww_uflags, WWU_HASFRAME | WWU_CENTER);
1.1       deraadt   187:        w->ww_id = -1;
                    188:        (void) setlabel(w, label);
                    189:        addwin(w, 1);
                    190:        reframe();
                    191:        return w;
                    192: }
                    193:
                    194: /*
                    195:  * Close an information window.
                    196:  */
                    197: closeiwin(w)
                    198: struct ww *w;
                    199: {
                    200:        closewin1(w);
                    201:        reframe();
                    202: }
                    203:
                    204: closewin1(w)
                    205: register struct ww *w;
                    206: {
                    207:        if (w == selwin)
                    208:                selwin = 0;
                    209:        if (w == lastselwin)
                    210:                lastselwin = 0;
                    211:        if (w->ww_id >= 0 && w->ww_id < NWINDOW)
                    212:                window[w->ww_id] = 0;
                    213:        if (w->ww_label)
                    214:                str_free(w->ww_label);
                    215:        deletewin(w);
                    216:        wwclose(w);
                    217: }
                    218:
                    219: /*
                    220:  * Move the window to the top of its group.
                    221:  * Don't do it if already fully visible.
                    222:  * Wwvisible() doesn't work for tinted windows.
                    223:  * But anything to make it faster.
                    224:  * Always reframe() if doreframe is true.
                    225:  */
                    226: front(w, doreframe)
                    227: register struct ww *w;
                    228: char doreframe;
                    229: {
                    230:        if (w->ww_back != (isfg(w) ? framewin : fgwin) && !wwvisible(w)) {
                    231:                deletewin(w);
                    232:                addwin(w, isfg(w));
                    233:                doreframe = 1;
                    234:        }
                    235:        if (doreframe)
                    236:                reframe();
                    237: }
                    238:
                    239: /*
                    240:  * Add a window at the top of normal windows or foreground windows.
                    241:  * For normal windows, we put it behind the current window.
                    242:  */
                    243: addwin(w, fg)
                    244: register struct ww *w;
                    245: char fg;
                    246: {
                    247:        if (fg) {
                    248:                wwadd(w, framewin);
                    249:                if (fgwin == framewin)
                    250:                        fgwin = w;
                    251:        } else
                    252:                wwadd(w, selwin != 0 && selwin != w && !isfg(selwin)
                    253:                                ? selwin : fgwin);
                    254: }
                    255:
                    256: /*
                    257:  * Delete a window.
                    258:  */
                    259: deletewin(w)
                    260: register struct ww *w;
                    261: {
                    262:        if (fgwin == w)
                    263:                fgwin = w->ww_back;
                    264:        wwdelete(w);
                    265: }
                    266:
                    267: reframe()
                    268: {
                    269:        register struct ww *w;
                    270:
                    271:        wwunframe(framewin);
                    272:        for (w = wwhead.ww_back; w != &wwhead; w = w->ww_back)
1.3       niklas    273:                if (ISSET(w->ww_uflags, WWU_HASFRAME)) {
1.1       deraadt   274:                        wwframe(w, framewin);
                    275:                        labelwin(w);
                    276:                }
                    277: }
                    278:
                    279: labelwin(w)
                    280: register struct ww *w;
                    281: {
                    282:        int mode = w == selwin ? WWM_REV : 0;
                    283:
1.3       niklas    284:        if (!ISSET(w->ww_uflags, WWU_HASFRAME))
1.1       deraadt   285:                return;
                    286:        if (w->ww_id >= 0) {
                    287:                char buf[2];
                    288:
                    289:                buf[0] = w->ww_id + '1';
                    290:                buf[1] = 0;
                    291:                wwlabel(w, framewin, 1, buf, mode);
                    292:        }
                    293:        if (w->ww_label) {
                    294:                int col;
                    295:
1.3       niklas    296:                if (ISSET(w->ww_uflags, WWU_CENTER)) {
1.1       deraadt   297:                        col = (w->ww_w.nc - strlen(w->ww_label)) / 2;
                    298:                        col = MAX(3, col);
                    299:                } else
                    300:                        col = 3;
                    301:                wwlabel(w, framewin, col, w->ww_label, mode);
                    302:        }
                    303: }
                    304:
                    305: stopwin(w)
                    306:        register struct ww *w;
                    307: {
1.2       deraadt   308:        if (w->ww_pty >= 0 && w->ww_type == WWT_PTY && wwstoptty(w->ww_pty) < 0)
1.1       deraadt   309:                error("Can't stop output: %s.", wwerror());
                    310:        else
1.3       niklas    311:                SET(w->ww_pflags, WWP_STOPPED);
1.1       deraadt   312: }
                    313:
                    314: startwin(w)
                    315:        register struct ww *w;
                    316: {
1.2       deraadt   317:        if (w->ww_pty >= 0 && w->ww_type == WWT_PTY && wwstarttty(w->ww_pty) < 0)
1.1       deraadt   318:                error("Can't start output: %s.", wwerror());
                    319:        else
1.3       niklas    320:                CLR(w->ww_pflags, WWP_STOPPED);
1.1       deraadt   321: }
                    322:
                    323: sizewin(w, nrow, ncol)
                    324: register struct ww *w;
                    325: {
                    326:        struct ww *back = w->ww_back;
                    327:
                    328:        w->ww_alt.nr = w->ww_w.nr;
                    329:        w->ww_alt.nc = w->ww_w.nc;
                    330:        wwdelete(w);
                    331:        if (wwsize(w, nrow, ncol) < 0)
                    332:                error("Can't resize window: %s.", wwerror());
                    333:        wwadd(w, back);
                    334:        reframe();
                    335: }
                    336:
                    337: waitnl(w)
                    338: struct ww *w;
                    339: {
                    340:        (void) waitnl1(w, "[Type any key to continue]");
                    341: }
                    342:
                    343: more(w, always)
                    344: register struct ww *w;
                    345: char always;
                    346: {
                    347:        int c;
1.3       niklas    348:        int uc = ISSET(w->ww_wflags, WWW_UNCTRL);
1.1       deraadt   349:
                    350:        if (!always && w->ww_cur.r < w->ww_w.b - 2)
                    351:                return 0;
                    352:        c = waitnl1(w, "[Type escape to abort, any other key to continue]");
1.3       niklas    353:        CLR(w->ww_wflags, WWW_UNCTRL);
1.1       deraadt   354:        wwputs("\033E", w);
1.3       niklas    355:        SET(w->ww_wflags, uc);
1.1       deraadt   356:        return c == ctrl('[') ? 2 : 1;
                    357: }
                    358:
                    359: waitnl1(w, prompt)
                    360: register struct ww *w;
                    361: char *prompt;
                    362: {
1.3       niklas    363:        int uc = ISSET(w->ww_wflags, WWW_UNCTRL);
1.1       deraadt   364:
1.3       niklas    365:        CLR(w->ww_wflags, WWW_UNCTRL);
1.1       deraadt   366:        front(w, 0);
                    367:        wwprintf(w, "\033Y%c%c\033sA%s\033rA ",
                    368:                w->ww_w.nr - 1 + ' ', ' ', prompt);     /* print on last line */
                    369:        wwcurtowin(w);
                    370:        while (wwpeekc() < 0)
                    371:                wwiomux();
1.3       niklas    372:        SET(w->ww_wflags, uc);
1.1       deraadt   373:        return wwgetc();
                    374: }