1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1995-1998 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* LINTLIBRARY */ 30 31 /* 32 * newwin.c 33 * 34 * XCurses Library 35 * 36 * Copyright 1990, 1995 by Mortice Kern Systems. All rights reserved. 37 * 38 */ 39 40 #ifdef M_RCSID 41 #ifndef lint 42 static char rcsID[] = 43 "$Header: /team/ps/sun_xcurses/archive/local_changes/xcurses/src/lib/" 44 "libxcurses/src/libc/xcurses/rcs/newwin.c 1.11 1998/06/04 14:26:16 " 45 "cbates Exp $"; 46 #endif 47 #endif 48 49 #include <private.h> 50 #include <stdlib.h> 51 52 #undef werase 53 54 /* 55 * Create and return a pointer to a new window or pad. 56 * 57 * For a window, provide the dimensions and location of the upper 58 * left hand corner of the window. If either dimension is zero (0) 59 * then the default sizes will be LINES-begy and COLS-begx. 60 * 61 * For a pad, provide the dimensions and -1 for begy and begx. 62 * If either dimension is zero (0) then the default sizes will be 63 * LINES and COLS. 64 * 65 * If parent is not null, then create a sub-window of the parent 66 * window. 67 */ 68 WINDOW * 69 __m_newwin(WINDOW *parent, 70 int nlines, int ncols, int begy, int begx) 71 { 72 WINDOW *w; 73 int x, y, dx, dy; 74 int isPad; 75 76 isPad = ((begy < 0) && (begx < 0)) || 77 (parent && (parent->_flags & W_IS_PAD)); 78 79 if (parent == NULL) { 80 /* Check for default dimensions. */ 81 if (nlines == 0) { 82 nlines = lines; 83 if (0 <= begy) 84 nlines -= begy; 85 } 86 if (ncols == 0) { 87 ncols = columns; 88 if (0 <= begx) 89 ncols -= begx; 90 } 91 } else { 92 /* 93 * Make sure window dimensions remain within parent's 94 * window so that the new subwindow is a proper subset 95 * of the parent. 96 */ 97 if (begy < parent->_begy || begx < parent->_begx || 98 parent->_maxy < (begy-parent->_begy) + nlines || 99 parent->_maxx < (begx-parent->_begx) + ncols) 100 goto error_1; 101 102 /* 103 * If either dimension is zero (0), use the max size 104 * for the dimension from the parent window less the 105 * subwindow's starting location. 106 */ 107 if (nlines == 0) 108 nlines = parent->_maxy - (begy - parent->_begy); 109 if (ncols == 0) 110 ncols = parent->_maxx - (begx - parent->_begx); 111 } 112 113 if (!isPad) { 114 /* Check that a window fits on the screen. */ 115 if (0 <= begy) { 116 if (lines < begy + nlines) { 117 goto error_1; 118 } 119 } 120 if (0 <= begx) { 121 if (columns < begx + ncols) { 122 goto error_1; 123 } 124 } 125 } 126 127 w = (WINDOW *) calloc(1, sizeof (*w)); 128 if (w == NULL) 129 goto error_1; 130 131 w->_first = (short *) calloc((size_t) (nlines + nlines), 132 sizeof (*w->_first)); 133 if (w->_first == NULL) 134 goto error_2; 135 136 w->_last = &w->_first[nlines]; 137 138 w->_line = (cchar_t **) calloc((size_t) nlines, sizeof (*w->_line)); 139 if (w->_line == NULL) 140 goto error_2; 141 142 /* Window rendition. */ 143 (void) setcchar(&w->_bg, L" ", WA_NORMAL, 0, (void *) 0); 144 (void) setcchar(&w->_fg, L" ", WA_NORMAL, 0, (void *) 0); 145 if (parent == NULL) { 146 w->_base = (cchar_t *) malloc((size_t) (nlines * ncols) * 147 sizeof (*w->_base)); 148 if (w->_base == NULL) 149 goto error_2; 150 151 w->_line[0] = w->_base; 152 for (y = 0; y < nlines; y++) { 153 if (y) 154 w->_line[y] = &w->_line[y-1][ncols]; 155 for (x = 0; x < ncols; ++x) { 156 w->_line[y][x] = w->_bg; 157 } 158 } 159 } else { 160 /* 161 * The new window's origin (0,0) maps to (begy, begx) in the 162 * parent's window. In effect, subwin() is a method by which 163 * a portion of a parent's window can be addressed using a 164 * (0,0) origin. 165 */ 166 dy = begy - parent->_begy; 167 dx = begx - parent->_begx; 168 169 w->_base = NULL; 170 171 for (y = 0; y < nlines; ++y) 172 w->_line[y] = &parent->_line[dy++][dx]; 173 } 174 175 w->_begy = (short) begy; 176 w->_begx = (short) begx; 177 w->_cury = w->_curx = 0; 178 w->_maxy = (short) nlines; 179 w->_maxx = (short) ncols; 180 w->_parent = parent; 181 182 /* Software scroll region. */ 183 w->_top = 0; 184 w->_bottom = (short) nlines; 185 w->_scroll = 0; 186 187 /* Window initially blocks for input. */ 188 w->_vmin = 1; 189 w->_vtime = 0; 190 w->_flags = W_USE_TIMEOUT; 191 192 /* Determine window properties. */ 193 if (isPad) { 194 /* This window is a PAD */ 195 w->_flags |= W_IS_PAD; /* Inherit PAD attribute */ 196 if (((begy < 0) && (begx < 0)) || 197 (parent && !(parent->_flags & W_IS_PAD))) { 198 /* Child of a normal window */ 199 w->_begy = w->_begx = 0; 200 /* 201 * Map to upper left portion of 202 * display by default (???) 203 */ 204 w->_sminy = w->_sminx = 0; 205 w->_smaxx = w->_maxx; 206 w->_smaxy = w->_maxy; 207 } 208 } else if (begx + ncols == columns) { 209 /* Writing to last column should trigger auto-margin wrap. */ 210 w->_flags |= W_END_LINE; 211 212 if (begx == 0) { 213 w->_flags |= W_FULL_LINE; 214 215 if (begy == 0 && nlines == lines) 216 w->_flags |= W_FULL_WINDOW; 217 } 218 219 /* Will writing to bottom-right triggers scroll? */ 220 if (begy + nlines == lines) 221 w->_flags |= W_SCROLL_WINDOW; 222 } 223 224 /* Initial screen clear for full screen windows only. */ 225 if (w->_flags & W_FULL_WINDOW) { 226 w->_flags |= W_CLEAR_WINDOW; 227 /* Reset dirty region markers. */ 228 (void) wtouchln(w, 0, w->_maxy, 0); 229 } else { 230 if (!parent) { 231 /* Do not erase sub windows */ 232 (void) werase(w); 233 } 234 } 235 236 return (w); 237 error_2: 238 (void) delwin(w); 239 error_1: 240 return (NULL); 241 } 242 243 int 244 delwin(WINDOW *w) 245 { 246 if (w == NULL) 247 return (OK); 248 249 250 if (w->_line != NULL) { 251 if (w->_base != NULL) 252 free(w->_base); 253 254 free(w->_line); 255 } 256 257 if (w->_first != NULL) 258 free(w->_first); 259 260 free(w); 261 262 return (OK); 263 } 264 265 WINDOW * 266 derwin(WINDOW *parent, 267 int nlines, int ncols, int begy, int begx) 268 { 269 WINDOW *w; 270 271 if (parent == NULL) 272 return (NULL); 273 274 /* Absolute screen address. */ 275 begy += parent->_begy; 276 begx += parent->_begx; 277 278 w = __m_newwin(parent, nlines, ncols, begy, begx); 279 280 return (w); 281 } 282 283 WINDOW * 284 newwin(int nlines, int ncols, int begy, int begx) 285 { 286 WINDOW *w; 287 288 w = __m_newwin(NULL, nlines, ncols, begy, begx); 289 290 return (w); 291 } 292 293 WINDOW * 294 subwin(WINDOW *parent, int nlines, int ncols, int begy, int begx) 295 { 296 WINDOW *w; 297 298 if (parent == NULL) 299 return (NULL); 300 301 w = __m_newwin(parent, nlines, ncols, begy, begx); 302 303 return (w); 304 } 305