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, by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * newwin.c 31 * 32 * XCurses Library 33 * 34 * Copyright 1990, 1995 by Mortice Kern Systems. All rights reserved. 35 * 36 */ 37 38 #ifdef M_RCSID 39 #ifndef lint 40 static char rcsID[] = "$Header: /rd/src/libc/xcurses/rcs/newwin.c 1.9 1995/09/28 20:15:58 ant Exp $"; 41 #endif 42 #endif 43 44 #include <private.h> 45 #include <stdlib.h> 46 47 /*f 48 * Create and return a pointer to a new window or pad. 49 * 50 * For a window, provide the dimensions and location of the upper 51 * left hand corner of the window. If either dimension is zero (0) 52 * then the default sizes will be LINES-begy and COLS-begx. 53 * 54 * For a pad, provide the dimensions and -1 for begy and begx. 55 * If either dimension is zero (0) then the default sizes will be 56 * LINES and COLS. 57 * 58 * If parent is not null, then create a sub-window of the parent 59 * window. 60 */ 61 WINDOW * 62 __m_newwin(parent, nlines, ncols, begy, begx) 63 WINDOW *parent; 64 int nlines, ncols, begy, begx; 65 { 66 WINDOW *w; 67 int x, y, dx, dy; 68 69 #ifdef M_CURSES_TRACE 70 __m_trace( 71 "__m_newwin(%p, %d, %d, %d, %d)", 72 parent, nlines, ncols, begy, begx 73 ); 74 #endif 75 76 if (parent == (WINDOW *) 0) { 77 /* Check for default dimensions. */ 78 if (nlines == 0) { 79 nlines = lines; 80 if (0 <= begy) 81 nlines -= begy; 82 } 83 if (ncols == 0) { 84 ncols = columns; 85 if (0 <= begx) 86 ncols -= begx; 87 } 88 } else { 89 /* Make sure window dimensions remain within parent's 90 * window so that the new subwindow is a proper subset 91 * of the parent. 92 */ 93 if (begy < parent->_begy || begx < parent->_begx 94 || parent->_maxy < (begy-parent->_begy) + nlines 95 || parent->_maxx < (begx-parent->_begx) + ncols) 96 goto error_1; 97 98 /* If either dimension is zero (0), use the max size 99 * for the dimension from the parent window less the 100 * subwindow's starting location. 101 */ 102 if (nlines == 0) 103 nlines = parent->_maxy - (begy - parent->_begy); 104 if (ncols == 0) 105 ncols = parent->_maxx - (begx - parent->_begx); 106 } 107 108 /* Check that a window fits on the screen. */ 109 if (0 <= begy) { 110 if (lines < begy + nlines) 111 goto error_1; 112 } 113 if (0 <= begx) { 114 if (columns < begx + ncols) 115 goto error_1; 116 } 117 118 w = (WINDOW *) calloc(1, sizeof *w); 119 if (w == (WINDOW *) 0) 120 goto error_1; 121 122 w->_first = (short *) calloc( 123 (size_t) (nlines + nlines), sizeof *w->_first 124 ); 125 if (w->_first == (short *) 0) 126 goto error_2; 127 128 w->_last = &w->_first[nlines]; 129 130 w->_line = (cchar_t **) calloc((size_t) nlines, sizeof *w->_line); 131 if (w->_line == (cchar_t **) 0) 132 goto error_2; 133 134 /* Window rendition. */ 135 (void) setcchar( 136 &w->_bg, M_MB_L(" "), WA_NORMAL, 0, (void *) 0 137 ); 138 (void) setcchar( 139 &w->_fg, M_MB_L(" "), WA_NORMAL, 0, (void *) 0 140 ); 141 142 if (parent == (WINDOW *) 0) { 143 w->_base = (cchar_t *) malloc( 144 (size_t) (nlines * ncols) * sizeof *w->_base 145 ); 146 if (w->_base == (cchar_t *) 0) 147 goto error_2; 148 149 w->_line[y = 0] = w->_base; 150 do { 151 for (x = 0; x < ncols; ++x) 152 w->_line[y][x] = w->_bg; 153 w->_line[y+1] = &w->_line[y][x]; 154 } while (++y < nlines-1); 155 } else { 156 /* The new window's origin (0,0) maps to (begy, begx) in the 157 * parent's window. In effect, subwin() is a method by which 158 * a portion of a parent's window can be addressed using a 159 * (0,0) origin. 160 */ 161 dy = begy - parent->_begy; 162 dx = begx - parent->_begx; 163 164 w->_base = (cchar_t *) 0; 165 166 for (y = 0; y < nlines; ++y) 167 w->_line[y] = &parent->_line[dy++][dx]; 168 } 169 170 w->_begy = (short) begy; 171 w->_begx = (short) begx; 172 w->_cury = w->_curx = 0; 173 w->_maxy = (short) nlines; 174 w->_maxx = (short) ncols; 175 w->_parent = parent; 176 177 /* Software scroll region. */ 178 w->_top = 0; 179 w->_bottom = (short) nlines; 180 w->_scroll = 0; 181 182 /* Window initially blocks for input. */ 183 w->_vmin = 1; 184 w->_vtime = 0; 185 w->_flags = W_USE_TIMEOUT; 186 187 /* Determine window properties. */ 188 if ((begy < 0 && begx < 0) 189 || (parent != (WINDOW *) 0 && (parent->_flags & W_IS_PAD))) { 190 w->_flags |= W_IS_PAD; 191 w->_begy = w->_begx = 0; 192 } else if (begx + ncols == columns) { 193 /* Writing to last column should trigger auto-margin wrap. */ 194 w->_flags |= W_END_LINE; 195 196 if (begx == 0) { 197 w->_flags |= W_FULL_LINE; 198 199 if (begy == 0 && nlines == lines) 200 w->_flags |= W_FULL_WINDOW; 201 } 202 203 /* Will writing to bottom-right triggers scroll? */ 204 if (begy + nlines == lines) 205 w->_flags |= W_SCROLL_WINDOW; 206 } 207 208 /* Initial screen clear for full screen windows only. */ 209 if (w->_flags & W_FULL_WINDOW) 210 w->_flags |= W_CLEAR_WINDOW; 211 212 /* Reset dirty region markers. */ 213 (void) wtouchln(w, 0, w->_maxy, 0); 214 215 return __m_return_pointer("__m_newwin", w); 216 error_2: 217 (void) delwin(w); 218 error_1: 219 return __m_return_pointer("__m_newwin", (WINDOW *) 0); 220 } 221 222 int 223 delwin(w) 224 WINDOW *w; 225 { 226 if (w == (WINDOW *) 0) 227 return OK; 228 229 #ifdef M_CURSES_TRACE 230 __m_trace( 231 "delwin(%p) which is a %s%s.", w, 232 (w->_parent == (WINDOW *) 0) ? "normal " : "sub-", 233 (w->_flags & W_IS_PAD) ? "pad" : "window" 234 ); 235 #endif 236 237 if (w->_line != (cchar_t **) 0) { 238 if (w->_base != (cchar_t *) 0) 239 free(w->_base); 240 241 free(w->_line); 242 } 243 244 if (w->_first != (short *) 0) 245 free(w->_first); 246 247 free(w); 248 249 return __m_return_code("delwin", OK); 250 } 251 252 WINDOW * 253 derwin(parent, nlines, ncols, begy, begx) 254 WINDOW *parent; 255 int nlines, ncols, begy, begx; 256 { 257 WINDOW *w; 258 259 #ifdef M_CURSES_TRACE 260 __m_trace( 261 "derwin(%p, %d, %d, %d, %d)", 262 parent, nlines, ncols, begy, begx 263 ); 264 #endif 265 266 if (parent == (WINDOW *) 0) 267 return __m_return_pointer("derwin", (WINDOW *) 0); 268 269 /* Absolute screen address. */ 270 begy += parent->_begy; 271 begx += parent->_begx; 272 273 w = __m_newwin(parent, nlines, ncols, begy, begx); 274 275 return __m_return_pointer("derwin", w); 276 } 277 278 WINDOW * 279 newwin(nlines, ncols, begy, begx) 280 int nlines, ncols, begy, begx; 281 { 282 WINDOW *w; 283 284 #ifdef M_CURSES_TRACE 285 __m_trace("newwin(%d, %d, %d, %d)", nlines, ncols, begy, begx); 286 #endif 287 288 w = __m_newwin((WINDOW *) 0, nlines, ncols, begy, begx); 289 290 return __m_return_pointer("newwin", w); 291 } 292 293 WINDOW * 294 subwin(parent, nlines, ncols, begy, begx) 295 WINDOW *parent; 296 int nlines, ncols, begy, begx; 297 { 298 WINDOW *w; 299 300 #ifdef M_CURSES_TRACE 301 __m_trace( 302 "subwin(%p, %d, %d, %d, %d)", 303 parent, nlines, ncols, begy, begx 304 ); 305 #endif 306 307 if (parent == (WINDOW *) 0) 308 return __m_return_pointer("subwin", (WINDOW *) 0); 309 310 w = __m_newwin(parent, nlines, ncols, begy, begx); 311 312 return __m_return_pointer("subwin", w); 313 } 314 315