1/**************************************************************************** 2 * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. * 3 * * 4 * Permission is hereby granted, free of charge, to any person obtaining a * 5 * copy of this software and associated documentation files (the * 6 * "Software"), to deal in the Software without restriction, including * 7 * without limitation the rights to use, copy, modify, merge, publish, * 8 * distribute, distribute with modifications, sublicense, and/or sell * 9 * copies of the Software, and to permit persons to whom the Software is * 10 * furnished to do so, subject to the following conditions: * 11 * * 12 * The above copyright notice and this permission notice shall be included * 13 * in all copies or substantial portions of the Software. * 14 * * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22 * * 23 * Except as contained in this notice, the name(s) of the above copyright * 24 * holders shall not be used in advertising or otherwise to promote the * 25 * sale, use or other dealings in this Software without prior written * 26 * authorization. * 27 ****************************************************************************/ 28 29/**************************************************************************** 30 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 31 * and: Eric S. Raymond <esr@snark.thyrsus.com> * 32 * and: Thomas E. Dickey 1996-on * 33 ****************************************************************************/ 34 35/* 36** lib_newwin.c 37** 38** The routines newwin(), subwin() and their dependent 39** 40*/ 41 42#include <curses.priv.h> 43 44MODULE_ID("$Id: lib_newwin.c,v 1.36 2005/04/09 15:23:04 tom Exp $") 45 46static WINDOW * 47remove_window_from_screen(WINDOW *win) 48{ 49 SCREEN **scan = &_nc_screen_chain; 50 51 while (*scan) { 52 SCREEN *sp = *scan; 53 if (sp->_curscr == win) { 54 sp->_curscr = 0; 55 if (win == curscr) 56 curscr = 0; 57 } else if (sp->_stdscr == win) { 58 sp->_stdscr = 0; 59 if (win == stdscr) 60 stdscr = 0; 61 } else if (sp->_newscr == win) { 62 sp->_newscr = 0; 63 if (win == newscr) 64 newscr = 0; 65 } else { 66 scan = &(*scan)->_next_screen; 67 continue; 68 } 69 break; 70 } 71 72 return 0; 73} 74 75NCURSES_EXPORT(int) 76_nc_freewin(WINDOW *win) 77{ 78 WINDOWLIST *p, *q; 79 int i; 80 int result = ERR; 81 82 if (win != 0) { 83 for (p = _nc_windows, q = 0; p != 0; q = p, p = p->next) { 84 if (&(p->win) == win) { 85 remove_window_from_screen(win); 86 if (q == 0) 87 _nc_windows = p->next; 88 else 89 q->next = p->next; 90 91 if (!(win->_flags & _SUBWIN)) { 92 for (i = 0; i <= win->_maxy; i++) 93 FreeIfNeeded(win->_line[i].text); 94 } 95 free(win->_line); 96 free(p); 97 98 result = OK; 99 T(("...deleted win=%p", win)); 100 break; 101 } 102 } 103 } 104 return result; 105} 106 107NCURSES_EXPORT(WINDOW *) 108newwin(int num_lines, int num_columns, int begy, int begx) 109{ 110 WINDOW *win; 111 NCURSES_CH_T *ptr; 112 int i; 113 114 T((T_CALLED("newwin(%d,%d,%d,%d)"), num_lines, num_columns, begy, begx)); 115 116 if (begy < 0 || begx < 0 || num_lines < 0 || num_columns < 0) 117 returnWin(0); 118 119 if (num_lines == 0) 120 num_lines = SP->_lines_avail - begy; 121 if (num_columns == 0) 122 num_columns = screen_columns - begx; 123 124 if ((win = _nc_makenew(num_lines, num_columns, begy, begx, 0)) == 0) 125 returnWin(0); 126 127 for (i = 0; i < num_lines; i++) { 128 win->_line[i].text = typeCalloc(NCURSES_CH_T, (unsigned) num_columns); 129 if (win->_line[i].text == 0) { 130 (void) _nc_freewin(win); 131 returnWin(0); 132 } 133 for (ptr = win->_line[i].text; 134 ptr < win->_line[i].text + num_columns; 135 ptr++) 136 SetChar(*ptr, BLANK_TEXT, BLANK_ATTR); 137 } 138 139 returnWin(win); 140} 141 142NCURSES_EXPORT(WINDOW *) 143derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx) 144{ 145 WINDOW *win; 146 int i; 147 int flags = _SUBWIN; 148 149 T((T_CALLED("derwin(%p,%d,%d,%d,%d)"), orig, num_lines, num_columns, 150 begy, begx)); 151 152 /* 153 * make sure window fits inside the original one 154 */ 155 if (begy < 0 || begx < 0 || orig == 0 || num_lines < 0 || num_columns < 0) 156 returnWin(0); 157 if (begy + num_lines > orig->_maxy + 1 158 || begx + num_columns > orig->_maxx + 1) 159 returnWin(0); 160 161 if (num_lines == 0) 162 num_lines = orig->_maxy + 1 - begy; 163 164 if (num_columns == 0) 165 num_columns = orig->_maxx + 1 - begx; 166 167 if (orig->_flags & _ISPAD) 168 flags |= _ISPAD; 169 170 if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy, 171 orig->_begx + begx, flags)) == 0) 172 returnWin(0); 173 174 win->_pary = begy; 175 win->_parx = begx; 176 win->_attrs = orig->_attrs; 177 win->_nc_bkgd = orig->_nc_bkgd; 178 179 for (i = 0; i < num_lines; i++) 180 win->_line[i].text = &orig->_line[begy++].text[begx]; 181 182 win->_parent = orig; 183 184 returnWin(win); 185} 186 187NCURSES_EXPORT(WINDOW *) 188subwin(WINDOW *w, int l, int c, int y, int x) 189{ 190 T((T_CALLED("subwin(%p, %d, %d, %d, %d)"), w, l, c, y, x)); 191 T(("parent has begy = %d, begx = %d", w->_begy, w->_begx)); 192 193 returnWin(derwin(w, l, c, y - w->_begy, x - w->_begx)); 194} 195 196static bool 197dimension_limit(int value) 198{ 199 NCURSES_SIZE_T test = value; 200 return (test == value && value > 0); 201} 202 203NCURSES_EXPORT(WINDOW *) 204_nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) 205{ 206 int i; 207 WINDOWLIST *wp; 208 WINDOW *win; 209 bool is_pad = (flags & _ISPAD); 210 211 T(("_nc_makenew(%d,%d,%d,%d)", num_lines, num_columns, begy, begx)); 212 213 if (SP == 0) 214 return 0; 215 216 if (!dimension_limit(num_lines) || !dimension_limit(num_columns)) 217 return 0; 218 219 if ((wp = typeCalloc(WINDOWLIST, 1)) == 0) 220 return 0; 221 222 win = &(wp->win); 223 224 if ((win->_line = typeCalloc(struct ldat, ((unsigned) num_lines))) == 0) { 225 free(win); 226 return 0; 227 } 228 229 win->_curx = 0; 230 win->_cury = 0; 231 win->_maxy = num_lines - 1; 232 win->_maxx = num_columns - 1; 233 win->_begy = begy; 234 win->_begx = begx; 235 win->_yoffset = SP->_topstolen; 236 237 win->_flags = flags; 238 win->_attrs = A_NORMAL; 239 SetChar(win->_nc_bkgd, BLANK_TEXT, BLANK_ATTR); 240 241 win->_clear = is_pad ? FALSE : (num_lines == screen_lines 242 && num_columns == screen_columns); 243 win->_idlok = FALSE; 244 win->_idcok = TRUE; 245 win->_scroll = FALSE; 246 win->_leaveok = FALSE; 247 win->_use_keypad = FALSE; 248 win->_delay = -1; 249 win->_immed = FALSE; 250 win->_sync = 0; 251 win->_parx = -1; 252 win->_pary = -1; 253 win->_parent = 0; 254 255 win->_regtop = 0; 256 win->_regbottom = num_lines - 1; 257 258 win->_pad._pad_y = -1; 259 win->_pad._pad_x = -1; 260 win->_pad._pad_top = -1; 261 win->_pad._pad_bottom = -1; 262 win->_pad._pad_left = -1; 263 win->_pad._pad_right = -1; 264 265 for (i = 0; i < num_lines; i++) { 266 /* 267 * This used to do 268 * 269 * win->_line[i].firstchar = win->_line[i].lastchar = _NOCHANGE; 270 * 271 * which marks the whole window unchanged. That's how 272 * SVr1 curses did it, but SVr4 curses marks the whole new 273 * window changed. 274 * 275 * With the old SVr1-like code, say you have stdscr full of 276 * characters, then create a new window with newwin(), 277 * then do a printw(win, "foo ");, the trailing spaces are 278 * completely ignored by the following refreshes. So, you 279 * get "foojunkjunk" on the screen instead of "foo " as 280 * you actually intended. 281 * 282 * SVr4 doesn't do this. Instead the spaces are actually written. 283 * So that's how we want ncurses to behave. 284 */ 285 win->_line[i].firstchar = 0; 286 win->_line[i].lastchar = num_columns - 1; 287 288 if_USE_SCROLL_HINTS(win->_line[i].oldindex = i); 289 } 290 291 if (!is_pad && (begx + num_columns == screen_columns)) { 292 win->_flags |= _ENDLINE; 293 294 if (begx == 0 && num_lines == screen_lines && begy == 0) 295 win->_flags |= _FULLWIN; 296 297 if (begy + num_lines == screen_lines) 298 win->_flags |= _SCROLLWIN; 299 } 300 301 wp->next = _nc_windows; 302 _nc_windows = wp; 303 304 T((T_CREATE("window %p"), win)); 305 306 return (win); 307} 308