xref: /openbsd/lib/libcurses/base/lib_newwin.c (revision c7ef0cfc)
1*c7ef0cfcSnicm /*	$OpenBSD: lib_newwin.c,v 1.7 2023/10/17 09:52:08 nicm Exp $	*/
292dd1ec0Smillert 
392dd1ec0Smillert /****************************************************************************
4*c7ef0cfcSnicm  * Copyright 2020,2021 Thomas E. Dickey                                     *
5*c7ef0cfcSnicm  * Copyright 1998-2016,2017 Free Software Foundation, Inc.                  *
692dd1ec0Smillert  *                                                                          *
792dd1ec0Smillert  * Permission is hereby granted, free of charge, to any person obtaining a  *
892dd1ec0Smillert  * copy of this software and associated documentation files (the            *
992dd1ec0Smillert  * "Software"), to deal in the Software without restriction, including      *
1092dd1ec0Smillert  * without limitation the rights to use, copy, modify, merge, publish,      *
1192dd1ec0Smillert  * distribute, distribute with modifications, sublicense, and/or sell       *
1292dd1ec0Smillert  * copies of the Software, and to permit persons to whom the Software is    *
1392dd1ec0Smillert  * furnished to do so, subject to the following conditions:                 *
1492dd1ec0Smillert  *                                                                          *
1592dd1ec0Smillert  * The above copyright notice and this permission notice shall be included  *
1692dd1ec0Smillert  * in all copies or substantial portions of the Software.                   *
1792dd1ec0Smillert  *                                                                          *
1892dd1ec0Smillert  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1992dd1ec0Smillert  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
2092dd1ec0Smillert  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
2192dd1ec0Smillert  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
2292dd1ec0Smillert  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2392dd1ec0Smillert  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2492dd1ec0Smillert  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2592dd1ec0Smillert  *                                                                          *
2692dd1ec0Smillert  * Except as contained in this notice, the name(s) of the above copyright   *
2792dd1ec0Smillert  * holders shall not be used in advertising or otherwise to promote the     *
2892dd1ec0Smillert  * sale, use or other dealings in this Software without prior written       *
2992dd1ec0Smillert  * authorization.                                                           *
3092dd1ec0Smillert  ****************************************************************************/
3192dd1ec0Smillert 
3292dd1ec0Smillert /****************************************************************************
3392dd1ec0Smillert  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
3492dd1ec0Smillert  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
3581d8c4e1Snicm  *     and: Thomas E. Dickey                        1996-on                 *
36*c7ef0cfcSnicm  *     and: Juergen Pfeifer                         2009                    *
3792dd1ec0Smillert  ****************************************************************************/
3892dd1ec0Smillert 
3992dd1ec0Smillert /*
4092dd1ec0Smillert **	lib_newwin.c
4192dd1ec0Smillert **
4292dd1ec0Smillert **	The routines newwin(), subwin() and their dependent
4392dd1ec0Smillert **
4492dd1ec0Smillert */
4592dd1ec0Smillert 
4692dd1ec0Smillert #include <curses.priv.h>
4781d8c4e1Snicm #include <stddef.h>
4892dd1ec0Smillert 
49*c7ef0cfcSnicm MODULE_ID("$Id: lib_newwin.c,v 1.7 2023/10/17 09:52:08 nicm Exp $")
5081d8c4e1Snicm 
5181d8c4e1Snicm #define window_is(name) ((sp)->_##name == win)
5281d8c4e1Snicm 
5381d8c4e1Snicm #if USE_REENTRANT
5481d8c4e1Snicm #define remove_window(name) \
5581d8c4e1Snicm 		sp->_##name = 0
5681d8c4e1Snicm #else
5781d8c4e1Snicm #define remove_window(name) \
5881d8c4e1Snicm 		sp->_##name = 0; \
5981d8c4e1Snicm 		if (win == name) \
6081d8c4e1Snicm 		    name = 0
6181d8c4e1Snicm #endif
6281d8c4e1Snicm 
6381d8c4e1Snicm static void
remove_window_from_screen(WINDOW * win)6481d8c4e1Snicm remove_window_from_screen(WINDOW *win)
6581d8c4e1Snicm {
6681d8c4e1Snicm     SCREEN *sp;
6781d8c4e1Snicm 
68*c7ef0cfcSnicm #ifdef USE_SP_WINDOWLIST
69*c7ef0cfcSnicm     if ((sp = _nc_screen_of(win)) != 0) {
70*c7ef0cfcSnicm 	if (window_is(curscr)) {
71*c7ef0cfcSnicm 	    remove_window(curscr);
72*c7ef0cfcSnicm 	} else if (window_is(stdscr)) {
73*c7ef0cfcSnicm 	    remove_window(stdscr);
74*c7ef0cfcSnicm 	} else if (window_is(newscr)) {
75*c7ef0cfcSnicm 	    remove_window(newscr);
76*c7ef0cfcSnicm 	}
77*c7ef0cfcSnicm     }
78*c7ef0cfcSnicm #else
7981d8c4e1Snicm     for (each_screen(sp)) {
8081d8c4e1Snicm 	if (window_is(curscr)) {
8181d8c4e1Snicm 	    remove_window(curscr);
8281d8c4e1Snicm 	    break;
8381d8c4e1Snicm 	} else if (window_is(stdscr)) {
8481d8c4e1Snicm 	    remove_window(stdscr);
8581d8c4e1Snicm 	    break;
8681d8c4e1Snicm 	} else if (window_is(newscr)) {
8781d8c4e1Snicm 	    remove_window(newscr);
8881d8c4e1Snicm 	    break;
8981d8c4e1Snicm 	}
9081d8c4e1Snicm     }
91*c7ef0cfcSnicm #endif
9281d8c4e1Snicm }
9392dd1ec0Smillert 
9484af20ceSmillert NCURSES_EXPORT(int)
_nc_freewin(WINDOW * win)951fe33145Smillert _nc_freewin(WINDOW *win)
9692dd1ec0Smillert {
9784af20ceSmillert     int result = ERR;
98*c7ef0cfcSnicm #ifdef USE_SP_WINDOWLIST
99*c7ef0cfcSnicm     SCREEN *sp = _nc_screen_of(win);	/* pretend this is parameter */
100*c7ef0cfcSnicm #endif
10192dd1ec0Smillert 
102*c7ef0cfcSnicm     T((T_CALLED("_nc_freewin(%p)"), (void *) win));
10381d8c4e1Snicm 
10492dd1ec0Smillert     if (win != 0) {
105*c7ef0cfcSnicm 
106*c7ef0cfcSnicm 	if (_nc_nonsp_try_global(curses) == 0) {
107*c7ef0cfcSnicm 	    WINDOWLIST *p, *q;
108*c7ef0cfcSnicm 
10981d8c4e1Snicm 	    q = 0;
110*c7ef0cfcSnicm 	    for (each_window(sp, p)) {
111*c7ef0cfcSnicm 
11281d8c4e1Snicm 		if (&(p->win) == win) {
11381d8c4e1Snicm 		    remove_window_from_screen(win);
11492dd1ec0Smillert 		    if (q == 0)
115*c7ef0cfcSnicm 			WindowList(sp) = p->next;
11692dd1ec0Smillert 		    else
11792dd1ec0Smillert 			q->next = p->next;
11892dd1ec0Smillert 
119*c7ef0cfcSnicm 		    if (!IS_SUBWIN(win)) {
120*c7ef0cfcSnicm 			int i;
121*c7ef0cfcSnicm 
1229ee63291Smillert 			for (i = 0; i <= win->_maxy; i++)
1239ee63291Smillert 			    FreeIfNeeded(win->_line[i].text);
12492dd1ec0Smillert 		    }
12592dd1ec0Smillert 		    free(win->_line);
12681d8c4e1Snicm 		    free(p);
12792dd1ec0Smillert 
12884af20ceSmillert 		    result = OK;
129*c7ef0cfcSnicm 		    T(("...deleted win=%p", (void *) win));
13092dd1ec0Smillert 		    break;
13192dd1ec0Smillert 		}
13281d8c4e1Snicm 		q = p;
13381d8c4e1Snicm 	    }
134*c7ef0cfcSnicm 	    _nc_nonsp_unlock_global(curses);
13592dd1ec0Smillert 	}
13692dd1ec0Smillert     }
13781d8c4e1Snicm     returnCode(result);
13892dd1ec0Smillert }
13992dd1ec0Smillert 
14084af20ceSmillert NCURSES_EXPORT(WINDOW *)
NCURSES_SP_NAME(newwin)141*c7ef0cfcSnicm NCURSES_SP_NAME(newwin) (NCURSES_SP_DCLx
142*c7ef0cfcSnicm 			 int num_lines, int num_columns, int begy, int begx)
14392dd1ec0Smillert {
14492dd1ec0Smillert     WINDOW *win;
14581d8c4e1Snicm     NCURSES_CH_T *ptr;
14692dd1ec0Smillert     int i;
14792dd1ec0Smillert 
148*c7ef0cfcSnicm     T((T_CALLED("newwin(%p, %d,%d,%d,%d)"), (void *) SP_PARM, num_lines, num_columns,
149*c7ef0cfcSnicm        begy, begx));
15092dd1ec0Smillert 
151*c7ef0cfcSnicm     if (begy < 0
152*c7ef0cfcSnicm 	|| begx < 0
153*c7ef0cfcSnicm 	|| num_lines < 0
154*c7ef0cfcSnicm 	|| num_columns < 0
155*c7ef0cfcSnicm 	|| SP_PARM == 0)
15692dd1ec0Smillert 	returnWin(0);
15792dd1ec0Smillert 
15892dd1ec0Smillert     if (num_lines == 0)
159*c7ef0cfcSnicm 	num_lines = SP_PARM->_lines_avail - begy;
16092dd1ec0Smillert     if (num_columns == 0)
161*c7ef0cfcSnicm 	num_columns = screen_columns(SP_PARM) - begx;
16292dd1ec0Smillert 
163*c7ef0cfcSnicm     win = NCURSES_SP_NAME(_nc_makenew) (NCURSES_SP_ARGx
164*c7ef0cfcSnicm 					num_lines, num_columns, begy, begx, 0);
165*c7ef0cfcSnicm     if (win == 0)
16692dd1ec0Smillert 	returnWin(0);
16792dd1ec0Smillert 
16892dd1ec0Smillert     for (i = 0; i < num_lines; i++) {
16981d8c4e1Snicm 	win->_line[i].text = typeCalloc(NCURSES_CH_T, (unsigned) num_columns);
1701fe33145Smillert 	if (win->_line[i].text == 0) {
17184af20ceSmillert 	    (void) _nc_freewin(win);
17292dd1ec0Smillert 	    returnWin(0);
17392dd1ec0Smillert 	}
17481d8c4e1Snicm 	for (ptr = win->_line[i].text;
17581d8c4e1Snicm 	     ptr < win->_line[i].text + num_columns;
17681d8c4e1Snicm 	     ptr++)
17781d8c4e1Snicm 	    SetChar(*ptr, BLANK_TEXT, BLANK_ATTR);
17892dd1ec0Smillert     }
17992dd1ec0Smillert 
18092dd1ec0Smillert     returnWin(win);
18192dd1ec0Smillert }
18292dd1ec0Smillert 
183*c7ef0cfcSnicm #if NCURSES_SP_FUNCS
184*c7ef0cfcSnicm NCURSES_EXPORT(WINDOW *)
newwin(int num_lines,int num_columns,int begy,int begx)185*c7ef0cfcSnicm newwin(int num_lines, int num_columns, int begy, int begx)
186*c7ef0cfcSnicm {
187*c7ef0cfcSnicm     WINDOW *win;
188*c7ef0cfcSnicm     _nc_sp_lock_global(curses);
189*c7ef0cfcSnicm     win = NCURSES_SP_NAME(newwin) (CURRENT_SCREEN,
190*c7ef0cfcSnicm 				   num_lines, num_columns, begy, begx);
191*c7ef0cfcSnicm     _nc_sp_unlock_global(curses);
192*c7ef0cfcSnicm     return (win);
193*c7ef0cfcSnicm }
194*c7ef0cfcSnicm #endif
195*c7ef0cfcSnicm 
19684af20ceSmillert NCURSES_EXPORT(WINDOW *)
derwin(WINDOW * orig,int num_lines,int num_columns,int begy,int begx)19781d8c4e1Snicm derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx)
19892dd1ec0Smillert {
19992dd1ec0Smillert     WINDOW *win;
20092dd1ec0Smillert     int i;
20192dd1ec0Smillert     int flags = _SUBWIN;
202*c7ef0cfcSnicm #if NCURSES_SP_FUNCS
203*c7ef0cfcSnicm     SCREEN *sp = _nc_screen_of(orig);
204*c7ef0cfcSnicm #endif
20592dd1ec0Smillert 
206*c7ef0cfcSnicm     T((T_CALLED("derwin(%p,%d,%d,%d,%d)"), (void *) orig, num_lines, num_columns,
2071fe33145Smillert        begy, begx));
20892dd1ec0Smillert 
20992dd1ec0Smillert     /*
21081d8c4e1Snicm      * make sure window fits inside the original one
21192dd1ec0Smillert      */
21292dd1ec0Smillert     if (begy < 0 || begx < 0 || orig == 0 || num_lines < 0 || num_columns < 0)
21392dd1ec0Smillert 	returnWin(0);
21492dd1ec0Smillert     if (begy + num_lines > orig->_maxy + 1
21592dd1ec0Smillert 	|| begx + num_columns > orig->_maxx + 1)
21692dd1ec0Smillert 	returnWin(0);
21792dd1ec0Smillert 
21892dd1ec0Smillert     if (num_lines == 0)
21992dd1ec0Smillert 	num_lines = orig->_maxy + 1 - begy;
22092dd1ec0Smillert 
22192dd1ec0Smillert     if (num_columns == 0)
22292dd1ec0Smillert 	num_columns = orig->_maxx + 1 - begx;
22392dd1ec0Smillert 
224*c7ef0cfcSnicm     if (IS_PAD(orig))
22592dd1ec0Smillert 	flags |= _ISPAD;
22692dd1ec0Smillert 
227*c7ef0cfcSnicm     win = NCURSES_SP_NAME(_nc_makenew) (NCURSES_SP_ARGx num_lines, num_columns,
228*c7ef0cfcSnicm 					orig->_begy + begy,
229*c7ef0cfcSnicm 					orig->_begx + begx, flags);
230*c7ef0cfcSnicm     if (win == 0)
23192dd1ec0Smillert 	returnWin(0);
23292dd1ec0Smillert 
23392dd1ec0Smillert     win->_pary = begy;
23492dd1ec0Smillert     win->_parx = begx;
23581d8c4e1Snicm     WINDOW_ATTRS(win) = WINDOW_ATTRS(orig);
23681d8c4e1Snicm     win->_nc_bkgd = orig->_nc_bkgd;
23792dd1ec0Smillert 
23892dd1ec0Smillert     for (i = 0; i < num_lines; i++)
23992dd1ec0Smillert 	win->_line[i].text = &orig->_line[begy++].text[begx];
24092dd1ec0Smillert 
24192dd1ec0Smillert     win->_parent = orig;
24292dd1ec0Smillert 
24392dd1ec0Smillert     returnWin(win);
24492dd1ec0Smillert }
24592dd1ec0Smillert 
24684af20ceSmillert NCURSES_EXPORT(WINDOW *)
subwin(WINDOW * w,int l,int c,int y,int x)24781d8c4e1Snicm subwin(WINDOW *w, int l, int c, int y, int x)
24892dd1ec0Smillert {
249*c7ef0cfcSnicm     WINDOW *result = 0;
250*c7ef0cfcSnicm 
251*c7ef0cfcSnicm     T((T_CALLED("subwin(%p, %d, %d, %d, %d)"), (void *) w, l, c, y, x));
252*c7ef0cfcSnicm     if (w != 0) {
25381d8c4e1Snicm 	T(("parent has begy = %ld, begx = %ld", (long) w->_begy, (long) w->_begx));
25492dd1ec0Smillert 
255*c7ef0cfcSnicm 	result = derwin(w, l, c, y - w->_begy, x - w->_begx);
256*c7ef0cfcSnicm     }
257*c7ef0cfcSnicm     returnWin(result);
25892dd1ec0Smillert }
25992dd1ec0Smillert 
2601fe33145Smillert static bool
dimension_limit(int value)2611fe33145Smillert dimension_limit(int value)
2621fe33145Smillert {
263*c7ef0cfcSnicm     NCURSES_SIZE_T test = (NCURSES_SIZE_T) value;
2641fe33145Smillert     return (test == value && value > 0);
2651fe33145Smillert }
2661fe33145Smillert 
26784af20ceSmillert NCURSES_EXPORT(WINDOW *)
NCURSES_SP_NAME(_nc_makenew)268*c7ef0cfcSnicm NCURSES_SP_NAME(_nc_makenew) (NCURSES_SP_DCLx
269*c7ef0cfcSnicm 			      int num_lines,
270*c7ef0cfcSnicm 			      int num_columns,
271*c7ef0cfcSnicm 			      int begy,
272*c7ef0cfcSnicm 			      int begx,
273*c7ef0cfcSnicm 			      int flags)
27492dd1ec0Smillert {
27592dd1ec0Smillert     int i;
27692dd1ec0Smillert     WINDOWLIST *wp;
27792dd1ec0Smillert     WINDOW *win;
278*c7ef0cfcSnicm     bool is_padwin = (flags & _ISPAD);
27992dd1ec0Smillert 
280*c7ef0cfcSnicm     T((T_CALLED("_nc_makenew(%p,%d,%d,%d,%d)"),
281*c7ef0cfcSnicm        (void *) SP_PARM, num_lines, num_columns, begy, begx));
28281d8c4e1Snicm 
283*c7ef0cfcSnicm     if (SP_PARM == 0)
28481d8c4e1Snicm 	returnWin(0);
28592dd1ec0Smillert 
2861fe33145Smillert     if (!dimension_limit(num_lines) || !dimension_limit(num_columns))
28781d8c4e1Snicm 	returnWin(0);
28892dd1ec0Smillert 
28992dd1ec0Smillert     if ((wp = typeCalloc(WINDOWLIST, 1)) == 0)
29081d8c4e1Snicm 	returnWin(0);
29192dd1ec0Smillert 
29281d8c4e1Snicm     win = &(wp->win);
29392dd1ec0Smillert 
29492dd1ec0Smillert     if ((win->_line = typeCalloc(struct ldat, ((unsigned) num_lines))) == 0) {
295b1a67f4cSderaadt 	free(wp);
29681d8c4e1Snicm 	returnWin(0);
29792dd1ec0Smillert     }
29892dd1ec0Smillert 
299*c7ef0cfcSnicm     _nc_nonsp_lock_global(curses);
30081d8c4e1Snicm 
30192dd1ec0Smillert     win->_curx = 0;
30292dd1ec0Smillert     win->_cury = 0;
303*c7ef0cfcSnicm     win->_maxy = (NCURSES_SIZE_T) (num_lines - 1);
304*c7ef0cfcSnicm     win->_maxx = (NCURSES_SIZE_T) (num_columns - 1);
305*c7ef0cfcSnicm     win->_begy = (NCURSES_SIZE_T) begy;
306*c7ef0cfcSnicm     win->_begx = (NCURSES_SIZE_T) begx;
307*c7ef0cfcSnicm     win->_yoffset = SP_PARM->_topstolen;
30892dd1ec0Smillert 
309*c7ef0cfcSnicm     win->_flags = (short) flags;
31081d8c4e1Snicm     WINDOW_ATTRS(win) = A_NORMAL;
31181d8c4e1Snicm     SetChar(win->_nc_bkgd, BLANK_TEXT, BLANK_ATTR);
31292dd1ec0Smillert 
313*c7ef0cfcSnicm     win->_clear = (is_padwin
314*c7ef0cfcSnicm 		   ? FALSE
315*c7ef0cfcSnicm 		   : (num_lines == screen_lines(SP_PARM)
316*c7ef0cfcSnicm 		      && num_columns == screen_columns(SP_PARM)));
31792dd1ec0Smillert     win->_idlok = FALSE;
31892dd1ec0Smillert     win->_idcok = TRUE;
31992dd1ec0Smillert     win->_scroll = FALSE;
32092dd1ec0Smillert     win->_leaveok = FALSE;
32192dd1ec0Smillert     win->_use_keypad = FALSE;
32292dd1ec0Smillert     win->_delay = -1;
32392dd1ec0Smillert     win->_immed = FALSE;
32492dd1ec0Smillert     win->_sync = 0;
32592dd1ec0Smillert     win->_parx = -1;
32692dd1ec0Smillert     win->_pary = -1;
32792dd1ec0Smillert     win->_parent = 0;
32892dd1ec0Smillert 
32992dd1ec0Smillert     win->_regtop = 0;
330*c7ef0cfcSnicm     win->_regbottom = (NCURSES_SIZE_T) (num_lines - 1);
33192dd1ec0Smillert 
33292dd1ec0Smillert     win->_pad._pad_y = -1;
33392dd1ec0Smillert     win->_pad._pad_x = -1;
33492dd1ec0Smillert     win->_pad._pad_top = -1;
33592dd1ec0Smillert     win->_pad._pad_bottom = -1;
33692dd1ec0Smillert     win->_pad._pad_left = -1;
33792dd1ec0Smillert     win->_pad._pad_right = -1;
33892dd1ec0Smillert 
3391fe33145Smillert     for (i = 0; i < num_lines; i++) {
34092dd1ec0Smillert 	/*
34192dd1ec0Smillert 	 * This used to do
34292dd1ec0Smillert 	 *
34392dd1ec0Smillert 	 * win->_line[i].firstchar = win->_line[i].lastchar = _NOCHANGE;
34492dd1ec0Smillert 	 *
34592dd1ec0Smillert 	 * which marks the whole window unchanged.  That's how
34692dd1ec0Smillert 	 * SVr1 curses did it, but SVr4 curses marks the whole new
34792dd1ec0Smillert 	 * window changed.
34892dd1ec0Smillert 	 *
34992dd1ec0Smillert 	 * With the old SVr1-like code, say you have stdscr full of
35092dd1ec0Smillert 	 * characters, then create a new window with newwin(),
35192dd1ec0Smillert 	 * then do a printw(win, "foo        ");, the trailing spaces are
35292dd1ec0Smillert 	 * completely ignored by the following refreshes.  So, you
35392dd1ec0Smillert 	 * get "foojunkjunk" on the screen instead of "foo        " as
35492dd1ec0Smillert 	 * you actually intended.
35592dd1ec0Smillert 	 *
35692dd1ec0Smillert 	 * SVr4 doesn't do this.  Instead the spaces are actually written.
35792dd1ec0Smillert 	 * So that's how we want ncurses to behave.
35892dd1ec0Smillert 	 */
35992dd1ec0Smillert 	win->_line[i].firstchar = 0;
360*c7ef0cfcSnicm 	win->_line[i].lastchar = (NCURSES_SIZE_T) (num_columns - 1);
36192dd1ec0Smillert 
36292dd1ec0Smillert 	if_USE_SCROLL_HINTS(win->_line[i].oldindex = i);
36392dd1ec0Smillert     }
36492dd1ec0Smillert 
365*c7ef0cfcSnicm     if (!is_padwin && (begx + num_columns == screen_columns(SP_PARM))) {
36692dd1ec0Smillert 	win->_flags |= _ENDLINE;
36792dd1ec0Smillert 
368*c7ef0cfcSnicm 	if (begx == 0 && num_lines == screen_lines(SP_PARM) && begy == 0)
36992dd1ec0Smillert 	    win->_flags |= _FULLWIN;
37092dd1ec0Smillert 
371*c7ef0cfcSnicm 	if (begy + num_lines == screen_lines(SP_PARM))
37292dd1ec0Smillert 	    win->_flags |= _SCROLLWIN;
37392dd1ec0Smillert     }
37492dd1ec0Smillert 
375*c7ef0cfcSnicm     wp->next = WindowList(SP_PARM);
376*c7ef0cfcSnicm     wp->screen = SP_PARM;
377*c7ef0cfcSnicm     WindowList(SP_PARM) = wp;
37892dd1ec0Smillert 
379*c7ef0cfcSnicm     T((T_CREATE("window %p"), (void *) win));
38092dd1ec0Smillert 
381*c7ef0cfcSnicm     _nc_nonsp_unlock_global(curses);
38281d8c4e1Snicm     returnWin(win);
38381d8c4e1Snicm }
38481d8c4e1Snicm 
38581d8c4e1Snicm /*
38681d8c4e1Snicm  * wgetch() and other functions with a WINDOW* parameter may use a SCREEN*
38781d8c4e1Snicm  * internally, and it is useful to allow those to be invoked without switching
38881d8c4e1Snicm  * SCREEN's, e.g., for multi-threaded applications.
38981d8c4e1Snicm  */
390*c7ef0cfcSnicm #if NCURSES_SP_FUNCS
391*c7ef0cfcSnicm NCURSES_EXPORT(WINDOW *)
_nc_curscr_of(SCREEN * sp)392*c7ef0cfcSnicm _nc_curscr_of(SCREEN *sp)
39381d8c4e1Snicm {
394*c7ef0cfcSnicm     return (sp == 0) ? NULL : CurScreen(sp);
395*c7ef0cfcSnicm }
39681d8c4e1Snicm 
397*c7ef0cfcSnicm NCURSES_EXPORT(WINDOW *)
_nc_newscr_of(SCREEN * sp)398*c7ef0cfcSnicm _nc_newscr_of(SCREEN *sp)
399*c7ef0cfcSnicm {
400*c7ef0cfcSnicm     return (sp == 0) ? NULL : NewScreen(sp);
40181d8c4e1Snicm }
402*c7ef0cfcSnicm 
403*c7ef0cfcSnicm NCURSES_EXPORT(WINDOW *)
_nc_stdscr_of(SCREEN * sp)404*c7ef0cfcSnicm _nc_stdscr_of(SCREEN *sp)
405*c7ef0cfcSnicm {
406*c7ef0cfcSnicm     return (sp == 0) ? NULL : StdScreen(sp);
40792dd1ec0Smillert }
408*c7ef0cfcSnicm #endif
409