2 /***************************************************************************
4 ****************************************************************************
5 * ncurses is copyright (C) 1992-1995 *
7 * zmbenhal@netcom.com *
9 * esr@snark.thyrsus.com *
11 * Permission is hereby granted to reproduce and distribute ncurses *
12 * by any means and for any fee, whether alone or as part of a *
13 * larger distribution, in source or in binary form, PROVIDED *
14 * this notice is included with any such distribution, and is not *
15 * removed from any of its header files. Mention of ncurses in any *
16 * applications linked with it is highly appreciated. *
18 * ncurses comes AS IS with no warranty, implied or expressed. *
20 ***************************************************************************/
27 ** The routine set_term().
31 #include <curses.priv.h>
33 #include <term.h> /* cur_term */
35 MODULE_ID("$Id: lib_set_term.c,v 1.17 1997/05/01 23:46:18 Alexander.V.Lukyanov Exp $")
38 * If the output file descriptor is connected to a tty (the typical case) it
39 * will probably be line-buffered. Keith Bostic pointed out that we don't want
40 * this; it hoses people running over networks by forcing out a bunch of small
41 * packets instead of one big one, so screen updates on ptys look jerky.
42 * Restore block buffering to prevent this minor lossage.
44 * The buffer size is a compromise. Ideally we'd like a buffer that can hold
45 * the maximum possible update size (the whole screen plus cup commands to
46 * change lines as it's painted). On a 66-line xterm this can become
47 * excessive. So we min it with the amount of data we think we can get through
48 * two Ethernet packets (maximum packet size - 100 for TCP/IP overhead).
50 * Why two ethernet packets? It used to be one, on the theory that said
51 * packets define the maximum size of atomic update. But that's less than the
52 * 2000 chars on a 25 x 80 screen, and we don't want local updates to flicker
53 * either. Two packet lengths will handle up to a 35 x 80 screen.
55 * The magic '6' is the estimated length of the end-of-line cup sequence to go
56 * to the next line. It's generous. We used to mess with the buffering in
57 * init_mvcur() after cost computation, but that lost the sequences emitted by
58 * init_acs() in setupscreen().
60 * "The setvbuf function may be used only after the stream pointed to by stream
61 * has been associated with an open file and before any other operation is
62 * performed on the stream." (ISO 7.9.5.6.)
66 void _nc_set_buffer(FILE *ofp, bool buffered)
68 /* optional optimization hack -- do before any output to ofp */
69 #if HAVE_SETVBUF || HAVE_SETBUFFER
74 buf_len = min(LINES * (COLS + 6), 2800);
75 buf_ptr = malloc(buf_len);
82 #ifdef SETVBUF_REVERSED /* pre-svr3? */
83 (void) setvbuf(ofp, buf_ptr, buf_len, buf_len ? _IOFBF : _IONBF);
85 (void) setvbuf(ofp, buf_ptr, buf_len ? _IOFBF : _IONBF, buf_len);
88 (void) setbuffer(ofp, buf_ptr, (int)buf_len);
92 FreeIfNeeded(SP->_setbuf);
94 SP->_setbuf = buf_ptr;
96 #endif /* HAVE_SETVBUF || HAVE_SETBUFFER */
99 SCREEN * set_term(SCREEN *screen)
103 T((T_CALLED("set_term(%p)"), screen));
106 _nc_set_screen(screen);
108 cur_term = SP->_term;
109 curscr = SP->_curscr;
110 newscr = SP->_newscr;
111 stdscr = SP->_stdscr;
112 COLORS = SP->_color_count;
113 COLOR_PAIRS = SP->_pair_count;
115 T((T_RETURN("%p"), oldSP));
119 static void _nc_free_keytry(struct tries *kt)
122 _nc_free_keytry(kt->child);
123 _nc_free_keytry(kt->sibling);
129 * Free the storage associated with the given SCREEN sp.
131 void delscreen(SCREEN *sp)
133 T((T_CALLED("delscreen(%p)"), sp));
135 _nc_freewin(sp->_curscr);
136 _nc_freewin(sp->_newscr);
137 _nc_freewin(sp->_stdscr);
138 _nc_free_keytry(sp->_keytry);
140 FreeIfNeeded(sp->_color_table);
141 FreeIfNeeded(sp->_color_pairs);
146 * If this was the current screen, reset everything that the
147 * application might try to use (except cur_term, which may have
148 * multiple references in different screens).
161 ripoff_t rippedoff[5], *rsp = rippedoff;
162 #define N_RIPS (int)(sizeof(rippedoff)/sizeof(rippedoff[0]))
164 int _nc_setupscreen(short slines, short const scolumns, FILE *output)
165 /* OS-independent screen initializations */
167 int bottom_stolen = 0, i;
169 if (!_nc_alloc_screen())
172 _nc_set_buffer(output, TRUE);
173 SP->_term = cur_term;
175 SP->_lines_avail = slines;
176 SP->_columns = scolumns;
179 SP->_keytry = UNINITIALISED;
194 SP->_cursor = -1; /* cannot know real cursor shape */
198 T(("creating newscr"));
199 if ((newscr = newwin(slines, scolumns, 0, 0)) == 0)
202 T(("creating curscr"));
203 if ((curscr = newwin(slines, scolumns, 0, 0)) == 0)
206 SP->_newscr = newscr;
207 SP->_curscr = curscr;
209 newscr->_clear = TRUE;
210 curscr->_clear = FALSE;
212 for (i=0, rsp = rippedoff; rsp->line && (i < N_RIPS); rsp++, i++) {
215 int count = (rsp->line < 0) ? -rsp->line : rsp->line;
218 w = newwin(count,scolumns,SP->_lines_avail - count,0);
221 rsp->hook(w, scolumns);
222 bottom_stolen += count;
227 w = newwin(count,scolumns, 0, 0);
230 rsp->hook(w, scolumns);
231 SP->_topstolen += count;
236 SP->_lines_avail -= count;
240 T(("creating stdscr"));
241 assert ((SP->_lines_avail + SP->_topstolen + bottom_stolen) == slines);
242 if ((stdscr = newwin(LINES = SP->_lines_avail, scolumns, 0, 0)) == 0)
244 SP->_stdscr = stdscr;
252 /* The internal implementation interprets line as the number of
253 lines to rip off from the top or bottom.
256 _nc_ripoffline(int line, int (*init)(WINDOW *,int))
261 if (rsp >= rippedoff + N_RIPS)
273 ripoffline(int line, int (*init)(WINDOW *, int))
275 T((T_CALLED("ripoffline(%d,%p)"), line, init));
280 returnCode(_nc_ripoffline ((line<0) ? -1 : 1, init));