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