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.8 (Berkeley) 09/21/92"; 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)); 18 static void __swflags __P((WINDOW *)); 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 char *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)) == NULL) 41 return (NULL); 42 43 win->nextp = win; 44 win->ch_off = 0; 45 46 #ifdef DEBUG 47 __TRACE("newwin: win->ch_off = %d\n", win->ch_off); 48 #endif 49 50 for (lp = win->topline, i = 0; i < nl; i++, lp = lp->next) { 51 lp->flags = 0; 52 lp->flags &= ~__ISDIRTY; 53 lp->flags &= ~__ISPASTEOL; 54 for (sp = lp->line; sp < lp->line + nc; sp++) 55 *sp = ' '; 56 lp->hash = __hash(lp->line, nc); 57 } 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 register WINDOW *win; 68 69 /* Make sure window fits inside the original one. */ 70 #ifdef DEBUG 71 __TRACE("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)) == NULL) 82 return (NULL); 83 win->nextp = orig->nextp; 84 orig->nextp = win; 85 win->orig = orig; 86 __set_subwin(orig, win); 87 return (win); 88 } 89 90 /* 91 * This code is shared with mvwin(). 92 */ 93 void 94 __set_subwin(orig, win) 95 register WINDOW *orig, *win; 96 { 97 register int j, k, ocnt, cnt; 98 register LINE *lp, *olp; 99 100 j = win->begy - orig->begy; 101 k = win->begx - orig->begx; 102 win->ch_off = k; 103 #ifdef DEBUG 104 __TRACE("__set_subwin: win->ch_off = %d\n", win->ch_off); 105 #endif 106 107 lp = win->topline; 108 olp = orig->topline; 109 ocnt = 0; 110 for (ocnt = 0; ocnt < orig->maxy && cnt < win->maxy; ocnt++) { 111 if (ocnt >= j) { 112 lp->firstch = olp->firstch; 113 lp->lastch = olp->lastch; 114 lp->line = &olp->line[k]; 115 lp = lp->next; 116 lp->flags = olp->flags; 117 cnt++; 118 } 119 olp = olp->next; 120 } 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) 129 register int by, bx, nl, nc; 130 { 131 register WINDOW *win; 132 register LINE *cur, *prev; 133 int i; 134 135 #ifdef DEBUG 136 __TRACE("makenew: (%d, %d, %d, %d)\n", nl, nc, by, bx); 137 #endif 138 if ((win = malloc(sizeof(*win))) == NULL) 139 return (NULL); 140 #ifdef DEBUG 141 __TRACE("makenew: nl = %d\n", nl); 142 #endif 143 144 /* 145 * Allocate structure of lines in a window. 146 */ 147 if ((win->topline = malloc (nl * sizeof (LINE))) == NULL) { 148 free (win); 149 return NULL; 150 } 151 152 /* 153 * Allocate window space in one chunk. 154 */ 155 if ((win->wspace = malloc(nc * nl)) == NULL) { 156 free(win->topline); 157 free(win); 158 return NULL; 159 } 160 /* 161 * Link up the lines, set up line pointer array and point line pointers 162 * to the line space. 163 */ 164 if ((win->lines = malloc (nl * sizeof (LINE *))) == NULL) { 165 free(win->wspace); 166 free(win->topline); 167 free(win); 168 return NULL; 169 } 170 prev = &win->topline[nl - 1]; 171 cur = win->topline; 172 for (i = 1; i <= nl; i++, prev = cur, cur = cur->next) { 173 cur->next = &win->topline[i % nl]; 174 cur->prev = prev; 175 cur->line = &win->wspace[(i - 1) * nc]; 176 win->lines[i - 1] = cur; 177 } 178 179 #ifdef DEBUG 180 __TRACE("makenew: nc = %d\n", nc); 181 #endif 182 win->cury = win->curx = 0; 183 win->maxy = nl; 184 win->maxx = nc; 185 186 win->begy = by; 187 win->begx = bx; 188 win->flags = 0; 189 __swflags(win); 190 #ifdef DEBUG 191 __TRACE("makenew: win->flags = %0.2o\n", win->flags); 192 __TRACE("makenew: win->maxy = %d\n", win->maxy); 193 __TRACE("makenew: win->maxx = %d\n", win->maxx); 194 __TRACE("makenew: win->begy = %d\n", win->begy); 195 __TRACE("makenew: win->begx = %d\n", win->begx); 196 #endif 197 return (win); 198 } 199 200 static void 201 __swflags(win) 202 register WINDOW *win; 203 { 204 win->flags &= 205 ~(__ENDLINE | __FULLLINE | __FULLWIN | __SCROLLWIN | __LEAVEOK); 206 if (win->begx + win->maxx == COLS) { 207 win->flags |= __ENDLINE; 208 if (win->begx == 0) { 209 if (AL && DL) 210 win->flags |= __FULLLINE; 211 if (win->maxy == LINES && win->begy == 0) 212 win->flags |= __FULLWIN; 213 } 214 if (win->begy + win->maxy == LINES) 215 win->flags |= __SCROLLWIN; 216 } 217 } 218