1 /* 2 * Copyright (c) 1981 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 /*static char sccsid[] = "from: @(#)newwin.c 5.6 (Berkeley) 8/23/92";*/ 36 static char rcsid[] = "$Id: newwin.c,v 1.4 1993/08/07 05:49:00 mycroft Exp $"; 37 #endif /* not lint */ 38 39 #include <curses.h> 40 #include <stdlib.h> 41 42 #undef nl /* Don't need it here, and it interferes. */ 43 44 static WINDOW *makenew __P((int, int, int, int)); 45 46 /* 47 * newwin -- 48 * Allocate space for and set up defaults for a new window. 49 */ 50 WINDOW * 51 newwin(num_lines, num_cols, begy, begx) 52 int num_lines, num_cols, begy, begx; 53 { 54 register WINDOW *win; 55 register int by, bx, i, j, nl, nc; 56 register char *sp; 57 58 by = begy; 59 bx = begx; 60 nl = num_lines; 61 nc = num_cols; 62 63 if (nl == 0) 64 nl = LINES - by; 65 if (nc == 0) 66 nc = COLS - bx; 67 if ((win = makenew(nl, nc, by, bx)) == NULL) 68 return (NULL); 69 if ((win->_firstch = malloc(nl * sizeof(win->_firstch[0]))) == NULL) { 70 free(win->_y); 71 free(win); 72 return (NULL); 73 } 74 if ((win->_lastch = malloc(nl * sizeof(win->_lastch[0]))) == NULL) { 75 free(win->_y); 76 free(win->_firstch); 77 free(win); 78 return (NULL); 79 } 80 win->_nextp = win; 81 for (i = 0; i < nl; i++) { 82 win->_firstch[i] = _NOCHANGE; 83 win->_lastch[i] = _NOCHANGE; 84 } 85 for (i = 0; i < nl; i++) 86 if ((win->_y[i] = malloc(nc * sizeof(win->_y[0]))) == NULL) { 87 for (j = 0; j < i; j++) 88 free(win->_y[j]); 89 free(win->_firstch); 90 free(win->_lastch); 91 free(win->_y); 92 free(win); 93 return (NULL); 94 } else 95 for (sp = win->_y[i]; sp < win->_y[i] + nc;) 96 *sp++ = ' '; 97 win->_ch_off = 0; 98 #ifdef DEBUG 99 __TRACE("newwin: win->_ch_off = %d\n", win->_ch_off); 100 #endif 101 return (win); 102 } 103 104 WINDOW * 105 subwin(orig, num_lines, num_cols, begy, begx) 106 register WINDOW *orig; 107 int num_lines, num_cols, begy, begx; 108 { 109 register WINDOW *win; 110 register int by, bx, nl, nc; 111 112 by = begy; 113 bx = begx; 114 nl = num_lines; 115 nc = num_cols; 116 117 /* Make sure window fits inside the original one. */ 118 #ifdef DEBUG 119 __TRACE("subwin: (%0.2o, %d, %d, %d, %d)\n", orig, nl, nc, by, bx); 120 #endif 121 if (by < orig->_begy || bx < orig->_begx 122 || by + nl > orig->_maxy + orig->_begy 123 || bx + nc > orig->_maxx + orig->_begx) 124 return (NULL); 125 if (nl == 0) 126 nl = orig->_maxy + orig->_begy - by; 127 if (nc == 0) 128 nc = orig->_maxx + orig->_begx - bx; 129 if ((win = makenew(nl, nc, by, bx)) == NULL) 130 return (NULL); 131 win->_nextp = orig->_nextp; 132 orig->_nextp = win; 133 win->_orig = orig; 134 __set_subwin(orig, win); 135 return (win); 136 } 137 138 /* 139 * This code is shared with mvwin(). 140 */ 141 void 142 __set_subwin(orig, win) 143 register WINDOW *orig, *win; 144 { 145 register int i, j, k; 146 147 j = win->_begy - orig->_begy; 148 k = win->_begx - orig->_begx; 149 win->_ch_off = k; 150 #ifdef DEBUG 151 __TRACE("__set_subwin: win->_ch_off = %d\n", win->_ch_off); 152 #endif 153 win->_firstch = &orig->_firstch[j]; 154 win->_lastch = &orig->_lastch[j]; 155 for (i = 0; i < win->_maxy; i++, j++) 156 win->_y[i] = &orig->_y[j][k]; 157 } 158 159 /* 160 * makenew -- 161 * Set up a window buffer and returns a pointer to it. 162 */ 163 static WINDOW * 164 makenew(num_lines, num_cols, begy, begx) 165 int num_lines, num_cols, begy, begx; 166 { 167 register WINDOW *win; 168 register int by, bx, nl, nc; 169 170 by = begy; 171 bx = begx; 172 nl = num_lines; 173 nc = num_cols; 174 175 #ifdef DEBUG 176 __TRACE("makenew: (%d, %d, %d, %d)\n", nl, nc, by, bx); 177 #endif 178 if ((win = malloc(sizeof(*win))) == NULL) 179 return (NULL); 180 #ifdef DEBUG 181 __TRACE("makenew: nl = %d\n", nl); 182 #endif 183 if ((win->_y = malloc(nl * sizeof(win->_y[0]))) == NULL) { 184 free(win); 185 return (NULL); 186 } 187 #ifdef DEBUG 188 __TRACE("makenew: nc = %d\n", nc); 189 #endif 190 win->_cury = win->_curx = 0; 191 win->_clear = 0; 192 win->_maxy = nl; 193 win->_maxx = nc; 194 win->_begy = by; 195 win->_begx = bx; 196 win->_flags = 0; 197 win->_scroll = win->_leave = 0; 198 __swflags(win); 199 #ifdef DEBUG 200 __TRACE("makenew: win->_clear = %d\n", win->_clear); 201 __TRACE("makenew: win->_leave = %d\n", win->_leave); 202 __TRACE("makenew: win->_scroll = %d\n", win->_scroll); 203 __TRACE("makenew: win->_flags = %0.2o\n", win->_flags); 204 __TRACE("makenew: win->_maxy = %d\n", win->_maxy); 205 __TRACE("makenew: win->_maxx = %d\n", win->_maxx); 206 __TRACE("makenew: win->_begy = %d\n", win->_begy); 207 __TRACE("makenew: win->_begx = %d\n", win->_begx); 208 #endif 209 return (win); 210 } 211 212 void 213 __swflags(win) 214 register WINDOW *win; 215 { 216 win->_flags &= ~(_ENDLINE | _FULLLINE | _FULLWIN | _SCROLLWIN); 217 if (win->_begx + win->_maxx == COLS) { 218 win->_flags |= _ENDLINE; 219 if (win->_begx == 0) { 220 if (AL && DL) 221 win->_flags |= _FULLLINE; 222 if (win->_maxy == LINES && win->_begy == 0) 223 win->_flags |= _FULLWIN; 224 } 225 if (win->_begy + win->_maxy == LINES) 226 win->_flags |= _SCROLLWIN; 227 } 228 } 229