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