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