1 /* 2 * Copyright (c) 1981, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)newwin.c 8.3 (Berkeley) 07/27/94"; 10 #endif /* not lint */ 11 12 #include <stdlib.h> 13 14 #include "curses.h" 15 16 #undef nl /* Don't need it here, and it interferes. */ 17 18 static WINDOW *__makenew __P((int, int, int, int, int)); 19 20 void __set_subwin __P((WINDOW *, WINDOW *)); 21 22 /* 23 * newwin -- 24 * Allocate space for and set up defaults for a new window. 25 */ 26 WINDOW * 27 newwin(nl, nc, by, bx) 28 register int nl, nc, by, bx; 29 { 30 register WINDOW *win; 31 register __LINE *lp; 32 register int i, j; 33 register __LDATA *sp; 34 35 if (nl == 0) 36 nl = LINES - by; 37 if (nc == 0) 38 nc = COLS - bx; 39 40 if ((win = __makenew(nl, nc, by, bx, 0)) == NULL) 41 return (NULL); 42 43 win->nextp = win; 44 win->ch_off = 0; 45 win->orig = NULL; 46 47 #ifdef DEBUG 48 __CTRACE("newwin: win->ch_off = %d\n", win->ch_off); 49 #endif 50 51 for (i = 0; i < nl; i++) { 52 lp = win->lines[i]; 53 lp->flags = 0; 54 for (sp = lp->line, j = 0; j < nc; j++, sp++) { 55 sp->ch = ' '; 56 sp->attr = 0; 57 } 58 lp->hash = __hash((char *) lp->line, nc * __LDATASIZE); 59 } 60 return (win); 61 } 62 63 WINDOW * 64 subwin(orig, nl, nc, by, bx) 65 register WINDOW *orig; 66 register int by, bx, nl, nc; 67 { 68 int i; 69 __LINE *lp; 70 register WINDOW *win; 71 72 /* Make sure window fits inside the original one. */ 73 #ifdef DEBUG 74 __CTRACE("subwin: (%0.2o, %d, %d, %d, %d)\n", orig, nl, nc, by, bx); 75 #endif 76 if (by < orig->begy || bx < orig->begx 77 || by + nl > orig->maxy + orig->begy 78 || bx + nc > orig->maxx + orig->begx) 79 return (NULL); 80 if (nl == 0) 81 nl = orig->maxy + orig->begy - by; 82 if (nc == 0) 83 nc = orig->maxx + orig->begx - bx; 84 if ((win = __makenew(nl, nc, by, bx, 1)) == NULL) 85 return (NULL); 86 win->nextp = orig->nextp; 87 orig->nextp = win; 88 win->orig = orig; 89 90 /* Initialize flags here so that refresh can also use __set_subwin. */ 91 for (lp = win->lspace, i = 0; i < win->maxy; i++, lp++) 92 lp->flags = 0; 93 __set_subwin(orig, win); 94 return (win); 95 } 96 97 /* 98 * This code is shared with mvwin(). 99 */ 100 void 101 __set_subwin(orig, win) 102 register WINDOW *orig, *win; 103 { 104 int i; 105 __LINE *lp, *olp; 106 107 win->ch_off = win->begx - orig->begx; 108 /* Point line pointers to line space. */ 109 for (lp = win->lspace, i = 0; i < win->maxy; i++, lp++) { 110 win->lines[i] = lp; 111 olp = orig->lines[i + win->begy]; 112 lp->line = &olp->line[win->begx]; 113 lp->firstchp = &olp->firstch; 114 lp->lastchp = &olp->lastch; 115 lp->hash = __hash((char *) lp->line, win->maxx * __LDATASIZE); 116 } 117 118 #ifdef DEBUG 119 __CTRACE("__set_subwin: win->ch_off = %d\n", win->ch_off); 120 #endif 121 } 122 123 /* 124 * __makenew -- 125 * Set up a window buffer and returns a pointer to it. 126 */ 127 static WINDOW * 128 __makenew(nl, nc, by, bx, sub) 129 register int by, bx, nl, nc; 130 int sub; 131 { 132 register WINDOW *win; 133 register __LINE *lp; 134 int i; 135 136 137 #ifdef DEBUG 138 __CTRACE("makenew: (%d, %d, %d, %d)\n", nl, nc, by, bx); 139 #endif 140 if ((win = malloc(sizeof(*win))) == NULL) 141 return (NULL); 142 #ifdef DEBUG 143 __CTRACE("makenew: nl = %d\n", nl); 144 #endif 145 146 /* 147 * Set up line pointer array and line space. 148 */ 149 if ((win->lines = malloc (nl * sizeof(__LINE *))) == NULL) { 150 free(win); 151 return NULL; 152 } 153 if ((win->lspace = malloc (nl * sizeof(__LINE))) == NULL) { 154 free (win); 155 free (win->lines); 156 return NULL; 157 } 158 159 /* Don't allocate window and line space if it's a subwindow */ 160 if (!sub) { 161 /* 162 * Allocate window space in one chunk. 163 */ 164 if ((win->wspace = 165 malloc(nc * nl * sizeof(__LDATA))) == NULL) { 166 free(win->lines); 167 free(win->lspace); 168 free(win); 169 return NULL; 170 } 171 172 /* 173 * Point line pointers to line space, and lines themselves into 174 * window space. 175 */ 176 for (lp = win->lspace, i = 0; i < nl; i++, lp++) { 177 win->lines[i] = lp; 178 lp->line = &win->wspace[i * nc]; 179 lp->firstchp = &lp->firstch; 180 lp->lastchp = &lp->lastch; 181 lp->firstch = 0; 182 lp->lastch = 0; 183 } 184 } 185 #ifdef DEBUG 186 __CTRACE("makenew: nc = %d\n", nc); 187 #endif 188 win->cury = win->curx = 0; 189 win->maxy = nl; 190 win->maxx = nc; 191 192 win->begy = by; 193 win->begx = bx; 194 win->flags = 0; 195 __swflags(win); 196 #ifdef DEBUG 197 __CTRACE("makenew: win->flags = %0.2o\n", win->flags); 198 __CTRACE("makenew: win->maxy = %d\n", win->maxy); 199 __CTRACE("makenew: win->maxx = %d\n", win->maxx); 200 __CTRACE("makenew: win->begy = %d\n", win->begy); 201 __CTRACE("makenew: win->begx = %d\n", win->begx); 202 #endif 203 return (win); 204 } 205 206 void 207 __swflags(win) 208 register WINDOW *win; 209 { 210 win->flags &= ~(__ENDLINE | __FULLWIN | __SCROLLWIN | __LEAVEOK); 211 if (win->begx + win->maxx == COLS) { 212 win->flags |= __ENDLINE; 213 if (win->begx == 0 && win->maxy == LINES && win->begy == 0) 214 win->flags |= __FULLWIN; 215 if (win->begy + win->maxy == LINES) 216 win->flags |= __SCROLLWIN; 217 } 218 } 219