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