home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / window / win.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-18  |  8.1 KB  |  371 lines

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