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