X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Fbase%2Flib_newwin.c;h=14beb65ae6855cd033f27faeda9a1290f1737cc4;hp=b0f4603ae7aba1a6b72a40013a83518601d08cd8;hb=8fc9fa113b27e0749e0840fef04c9d4acad4aae7;hpb=e0371a7943009d611a4dc080dcddfcdfba9f589b diff --git a/ncurses/base/lib_newwin.c b/ncurses/base/lib_newwin.c index b0f4603a..14beb65a 100644 --- a/ncurses/base/lib_newwin.c +++ b/ncurses/base/lib_newwin.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * + * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -30,6 +30,7 @@ * Author: Zeyd M. Ben-Halim 1992,1995 * * and: Eric S. Raymond * * and: Thomas E. Dickey 1996-on * + * and: Juergen Pfeifer 2009 * ****************************************************************************/ /* @@ -40,42 +41,51 @@ */ #include +#include -MODULE_ID("$Id: lib_newwin.c,v 1.42 2007/12/22 23:20:18 tom Exp $") +MODULE_ID("$Id: lib_newwin.c,v 1.59 2009/08/30 16:35:23 tom Exp $") -static WINDOW * +#define window_is(name) ((sp)->_##name == win) + +#if USE_REENTRANT +#define remove_window(name) \ + sp->_##name = 0 +#else +#define remove_window(name) \ + sp->_##name = 0; \ + if (win == name) \ + name = 0 +#endif + +static void remove_window_from_screen(WINDOW *win) { - SCREEN **scan = &_nc_screen_chain; - - while (*scan) { - SCREEN *sp = *scan; - if (sp->_curscr == win) { - sp->_curscr = 0; -#if !USE_REENTRANT - if (win == curscr) - curscr = 0; -#endif - } else if (sp->_stdscr == win) { - sp->_stdscr = 0; -#if !USE_REENTRANT - if (win == stdscr) - stdscr = 0; -#endif - } else if (sp->_newscr == win) { - sp->_newscr = 0; -#if !USE_REENTRANT - if (win == newscr) - newscr = 0; -#endif - } else { - scan = &(*scan)->_next_screen; - continue; + SCREEN *sp; + +#ifdef USE_SP_WINDOWLIST + if ((sp = _nc_screen_of(win)) != 0) { + if (window_is(curscr)) { + remove_window(curscr); + } else if (window_is(stdscr)) { + remove_window(stdscr); + } else if (window_is(newscr)) { + remove_window(newscr); } - break; } - - return 0; +#else + for (each_screen(sp)) { + if (window_is(curscr)) { + remove_window(curscr); + break; + } else if (window_is(stdscr)) { + remove_window(stdscr); + break; + } else if (window_is(newscr)) { + remove_window(newscr); + break; + } + } +#endif } NCURSES_EXPORT(int) @@ -84,16 +94,20 @@ _nc_freewin(WINDOW *win) WINDOWLIST *p, *q; int i; int result = ERR; +#ifdef USE_SP_WINDOWLIST + SCREEN *sp = _nc_screen_of(win); /* pretend this is parameter */ +#endif T((T_CALLED("_nc_freewin(%p)"), win)); if (win != 0) { - if (_nc_try_global(windowlist) == 0) { - for (p = _nc_windows, q = 0; p != 0; q = p, p = p->next) { + if (_nc_nonsp_try_global(curses) == 0) { + q = 0; + for (each_window(SP_PARM, p)) { if (&(p->win) == win) { remove_window_from_screen(win); if (q == 0) - _nc_windows = p->next; + WindowList(SP_PARM) = p->next; else q->next = p->next; @@ -108,31 +122,36 @@ _nc_freewin(WINDOW *win) T(("...deleted win=%p", win)); break; } + q = p; } - _nc_unlock_global(windowlist); + _nc_nonsp_unlock_global(curses); } } returnCode(result); } NCURSES_EXPORT(WINDOW *) -newwin(int num_lines, int num_columns, int begy, int begx) +NCURSES_SP_NAME(newwin) (NCURSES_SP_DCLx + int num_lines, int num_columns, int begy, int begx) { WINDOW *win; NCURSES_CH_T *ptr; int i; - T((T_CALLED("newwin(%d,%d,%d,%d)"), num_lines, num_columns, begy, begx)); + T((T_CALLED("newwin(%p, %d,%d,%d,%d)"), SP_PARM, num_lines, num_columns, + begy, begx)); if (begy < 0 || begx < 0 || num_lines < 0 || num_columns < 0) returnWin(0); if (num_lines == 0) - num_lines = SP->_lines_avail - begy; + num_lines = SP_PARM->_lines_avail - begy; if (num_columns == 0) - num_columns = screen_columns - begx; + num_columns = screen_columns(SP_PARM) - begx; - if ((win = _nc_makenew(num_lines, num_columns, begy, begx, 0)) == 0) + win = NCURSES_SP_NAME(_nc_makenew) (NCURSES_SP_ARGx + num_lines, num_columns, begy, begx, 0); + if (win == 0) returnWin(0); for (i = 0; i < num_lines; i++) { @@ -150,12 +169,28 @@ newwin(int num_lines, int num_columns, int begy, int begx) returnWin(win); } +#if NCURSES_SP_FUNCS +NCURSES_EXPORT(WINDOW *) +newwin(int num_lines, int num_columns, int begy, int begx) +{ + WINDOW *win; + _nc_sp_lock_global(curses); + win = NCURSES_SP_NAME(newwin) (CURRENT_SCREEN, + num_lines, num_columns, begy, begx); + _nc_sp_unlock_global(curses); + return (win); +} +#endif + NCURSES_EXPORT(WINDOW *) derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx) { WINDOW *win; int i; int flags = _SUBWIN; +#if NCURSES_SP_FUNCS + SCREEN *sp = _nc_screen_of(orig); +#endif T((T_CALLED("derwin(%p,%d,%d,%d,%d)"), orig, num_lines, num_columns, begy, begx)); @@ -178,8 +213,10 @@ derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx) if (orig->_flags & _ISPAD) flags |= _ISPAD; - if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy, - orig->_begx + begx, flags)) == 0) + win = NCURSES_SP_NAME(_nc_makenew) (NCURSES_SP_ARGx num_lines, num_columns, + orig->_begy + begy, + orig->_begx + begx, flags); + if (win == 0) returnWin(0); win->_pary = begy; @@ -212,16 +249,22 @@ dimension_limit(int value) } NCURSES_EXPORT(WINDOW *) -_nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) +NCURSES_SP_NAME(_nc_makenew) (NCURSES_SP_DCLx + int num_lines, + int num_columns, + int begy, + int begx, + int flags) { int i; WINDOWLIST *wp; WINDOW *win; bool is_pad = (flags & _ISPAD); - T((T_CALLED("_nc_makenew(%d,%d,%d,%d)"), num_lines, num_columns, begy, begx)); + T((T_CALLED("_nc_makenew(%p,%d,%d,%d,%d)"), + SP_PARM, num_lines, num_columns, begy, begx)); - if (SP == 0) + if (SP_PARM == 0) returnWin(0); if (!dimension_limit(num_lines) || !dimension_limit(num_columns)) @@ -230,15 +273,6 @@ _nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) if ((wp = typeCalloc(WINDOWLIST, 1)) == 0) returnWin(0); -#ifdef USE_PTHREADS - { - pthread_mutexattr_t recattr; - memset(&recattr, 0, sizeof(recattr)); - pthread_mutexattr_settype(&recattr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&(wp->mutex_use_window), &recattr); - } -#endif - win = &(wp->win); if ((win->_line = typeCalloc(struct ldat, ((unsigned) num_lines))) == 0) { @@ -246,7 +280,7 @@ _nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) returnWin(0); } - _nc_lock_global(windowlist); + _nc_nonsp_lock_global(curses); win->_curx = 0; win->_cury = 0; @@ -254,14 +288,16 @@ _nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) win->_maxx = num_columns - 1; win->_begy = begy; win->_begx = begx; - win->_yoffset = SP->_topstolen; + win->_yoffset = SP_PARM->_topstolen; win->_flags = flags; WINDOW_ATTRS(win) = A_NORMAL; SetChar(win->_nc_bkgd, BLANK_TEXT, BLANK_ATTR); - win->_clear = is_pad ? FALSE : (num_lines == screen_lines - && num_columns == screen_columns); + win->_clear = (is_pad + ? FALSE + : (num_lines == screen_lines(SP_PARM) + && num_columns == screen_columns(SP_PARM))); win->_idlok = FALSE; win->_idcok = TRUE; win->_scroll = FALSE; @@ -310,21 +346,47 @@ _nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) if_USE_SCROLL_HINTS(win->_line[i].oldindex = i); } - if (!is_pad && (begx + num_columns == screen_columns)) { + if (!is_pad && (begx + num_columns == screen_columns(SP_PARM))) { win->_flags |= _ENDLINE; - if (begx == 0 && num_lines == screen_lines && begy == 0) + if (begx == 0 && num_lines == screen_lines(SP_PARM) && begy == 0) win->_flags |= _FULLWIN; - if (begy + num_lines == screen_lines) + if (begy + num_lines == screen_lines(SP_PARM)) win->_flags |= _SCROLLWIN; } - wp->next = _nc_windows; - _nc_windows = wp; + wp->next = WindowList(SP_PARM); + wp->screen = SP_PARM; + WindowList(SP_PARM) = wp; T((T_CREATE("window %p"), win)); - _nc_unlock_global(windowlist); + _nc_nonsp_unlock_global(curses); returnWin(win); } + +/* + * wgetch() and other functions with a WINDOW* parameter may use a SCREEN* + * internally, and it is useful to allow those to be invoked without switching + * SCREEN's, e.g., for multi-threaded applications. + */ +#if NCURSES_SP_FUNCS +NCURSES_EXPORT(WINDOW *) +_nc_curscr_of(SCREEN *sp) +{ + return sp == 0 ? 0 : sp->_curscr; +} + +NCURSES_EXPORT(WINDOW *) +_nc_newscr_of(SCREEN *sp) +{ + return sp == 0 ? 0 : sp->_newscr; +} + +NCURSES_EXPORT(WINDOW *) +_nc_stdscr_of(SCREEN *sp) +{ + return sp == 0 ? 0 : sp->_stdscr; +} +#endif