diff options
Diffstat (limited to 'lib/libcurses/lib_newwin.c')
-rw-r--r-- | lib/libcurses/lib_newwin.c | 162 |
1 files changed, 114 insertions, 48 deletions
diff --git a/lib/libcurses/lib_newwin.c b/lib/libcurses/lib_newwin.c index 0fd8d16db36..66269e31638 100644 --- a/lib/libcurses/lib_newwin.c +++ b/lib/libcurses/lib_newwin.c @@ -28,63 +28,94 @@ ** */ -#include "curses.priv.h" -#include <stdlib.h> +#include <curses.priv.h> + +MODULE_ID("Id: lib_newwin.c,v 1.17 1997/02/15 21:46:05 tom Exp $") + +void _nc_freewin(WINDOW *win) +{ +WINDOWLIST *p, *q; +int i; + + if (win != 0) { + for (p = _nc_windows, q = 0; p != 0; q = p, p = p->next) { + if (p->win == win) { + if (q == 0) + _nc_windows = p->next; + else + q->next = p->next; + free(p); + + if (! (win->_flags & _SUBWIN)) { + for (i = 0; i <= win->_maxy && win->_line[i].text; i++) + free(win->_line[i].text); + } + free(win->_line); + free(win); + + if (win == curscr) curscr = 0; + if (win == stdscr) stdscr = 0; + if (win == newscr) newscr = 0; + + T(("...deleted win=%p", win)); + break; + } + } + } +} WINDOW * newwin(int num_lines, int num_columns, int begy, int begx) { WINDOW *win; chtype *ptr; -int i, j; +int i; + + T((T_CALLED("newwin(%d,%d,%d,%d)"), num_lines, num_columns, begy, begx)); - T(("newwin(%d,%d,%d,%d) called", 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 = screen_lines - begy; + num_lines = SP->_lines_avail - begy; if (num_columns == 0) num_columns = screen_columns - begx; - if (num_columns + begx > SP->_columns || num_lines + begy > SP->_lines) - return NULL; + if (num_columns + begx > SP->_columns || num_lines + begy > SP->_lines_avail) + returnWin(0); - if ((win = _nc_makenew(num_lines, num_columns, begy, begx)) == NULL) - return NULL; + if ((win = _nc_makenew(num_lines, num_columns, begy, begx, 0)) == 0) + returnWin(0); for (i = 0; i < num_lines; i++) { - if ((win->_line[i].text = (chtype *) calloc((unsigned)num_columns, sizeof(chtype))) == NULL) { - for (j = 0; j < i; j++) - free(win->_line[j].text); - - free(win->_line); - free(win); - - return NULL; + if ((win->_line[i].text = typeCalloc(chtype, (unsigned)num_columns)) == 0) { + _nc_freewin(win); + returnWin(0); } - else - for (ptr = win->_line[i].text; ptr < win->_line[i].text + num_columns; ) - *ptr++ = ' '; + for (ptr = win->_line[i].text; ptr < win->_line[i].text + num_columns; ) + *ptr++ = ' '; } T(("newwin: returned window is %p", win)); - return(win); + returnWin(win); } WINDOW * derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx) { WINDOW *win; int i; +int flags = _SUBWIN; - T(("derwin(%p, %d,%d,%d,%d) called", orig, num_lines, num_columns, begy, begx)); + T((T_CALLED("derwin(%p,%d,%d,%d,%d)"), orig, num_lines, num_columns, begy, begx)); /* ** make sure window fits inside the original one */ - if ( begy < 0 || begx < 0) - return NULL; + if ( begy < 0 || begx < 0 || orig == 0 || num_lines < 0 || num_columns < 0) + returnWin(0); if ( begy + num_lines > orig->_maxy + 1 || begx + num_columns > orig->_maxx + 1) - return NULL; + returnWin(0); if (num_lines == 0) num_lines = orig->_maxy - begy; @@ -92,8 +123,11 @@ int i; if (num_columns == 0) num_columns = orig->_maxx - begx; - if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy, orig->_begx + begx)) == NULL) - return NULL; + if (orig->_flags & _ISPAD) + flags |= _ISPAD; + + if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy, orig->_begx + begx, flags)) == 0) + returnWin(0); win->_pary = begy; win->_parx = begx; @@ -103,40 +137,44 @@ int i; for (i = 0; i < num_lines; i++) win->_line[i].text = &orig->_line[begy++].text[begx]; - win->_flags = _SUBWIN; win->_parent = orig; T(("derwin: returned window is %p", win)); - return(win); + returnWin(win); } WINDOW *subwin(WINDOW *w, int l, int c, int y, int x) { - T(("subwin(%p, %d, %d, %d, %d) called", w, l, c, y, x)); + T((T_CALLED("subwin(%p, %d, %d, %d, %d)"), w, l, c, y, x)); T(("parent has begy = %d, begx = %d", w->_begy, w->_begx)); - return derwin(w, l, c, y - w->_begy, x - w->_begx); + returnWin(derwin(w, l, c, y - w->_begy, x - w->_begx)); } WINDOW * -_nc_makenew(int num_lines, int num_columns, int begy, int begx) +_nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) { int i; +WINDOWLIST *wp; WINDOW *win; +bool is_pad = (flags & _ISPAD); T(("_nc_makenew(%d,%d,%d,%d)", num_lines, num_columns, begy, begx)); if (num_lines <= 0 || num_columns <= 0) - return NULL; + return 0; - if ((win = (WINDOW *) calloc(1, sizeof(WINDOW))) == NULL) - return NULL; + if ((wp = typeCalloc(WINDOWLIST, 1)) == 0) + return 0; - if ((win->_line = (struct ldat *) calloc((unsigned)num_lines, sizeof (struct ldat))) == NULL) { + if ((win = typeCalloc(WINDOW, 1)) == 0) + return 0; + + if ((win->_line = typeCalloc(struct ldat, ((unsigned)num_lines))) == 0) { free(win); - return NULL; + return 0; } win->_curx = 0; @@ -145,23 +183,24 @@ WINDOW *win; win->_maxx = num_columns - 1; win->_begy = begy; win->_begx = begx; + win->_yoffset = SP->_topstolen; - win->_flags = 0; + win->_flags = flags; win->_attrs = A_NORMAL; - win->_bkgd = A_NORMAL; + win->_bkgd = BLANK; - win->_clear = (num_lines == screen_lines && num_columns == screen_columns); + win->_clear = is_pad ? FALSE : (num_lines == screen_lines && num_columns == screen_columns); win->_idlok = FALSE; win->_idcok = TRUE; win->_scroll = FALSE; win->_leaveok = FALSE; win->_use_keypad = FALSE; - win->_delay = -1; - win->_immed = FALSE; - win->_sync = 0; - win->_parx = -1; - win->_pary = -1; - win->_parent = (WINDOW *)NULL; + win->_delay = -1; + win->_immed = FALSE; + win->_sync = 0; + win->_parx = -1; + win->_pary = -1; + win->_parent = 0; win->_regtop = 0; win->_regbottom = num_lines - 1; @@ -175,11 +214,32 @@ WINDOW *win; for (i = 0; i < num_lines; i++) { - win->_line[i].firstchar = win->_line[i].lastchar = _NOCHANGE; + /* + * This used to do + * + * win->_line[i].firstchar = win->_line[i].lastchar = _NOCHANGE; + * + * which marks the whole window unchanged. That's how + * SVr1 curses did it, but SVr4 curses marks the whole new + * window changed. + * + * With the old SVr1-like code, say you have stdscr full of + * characters, then create a new window with newwin(), + * then do a printw(win, "foo ");, the trailing spaces are + * completely ignored by the following refreshes. So, you + * get "foojunkjunk" on the screen instead of "foo " as + * you actually intended. + * + * SVr4 doesn't do this. Instead the spaces are actually written. + * So that's how we want ncurses to behave. + */ + win->_line[i].firstchar = 0; + win->_line[i].lastchar = num_columns-1; + win->_line[i].oldindex = i; } - if (begx + num_columns == screen_columns) { + if (!is_pad && (begx + num_columns == screen_columns)) { win->_flags |= _ENDLINE; if (begx == 0 && num_lines == screen_lines && begy == 0) @@ -189,5 +249,11 @@ WINDOW *win; win->_flags |= _SCROLLWIN; } + wp->next = _nc_windows; + wp->win = win; + _nc_windows = wp; + + T((T_CREATE("window %p"), win)); + return(win); } |