118757Sedward /* 233514Sbostic * Copyright (c) 1983 Regents of the University of California. 333514Sbostic * All rights reserved. 433514Sbostic * 5*42835Sbostic * %sccs.include.redist.c% 618757Sedward */ 718757Sedward 833514Sbostic #ifndef lint 9*42835Sbostic static char sccsid[] = "@(#)wwsize.c 3.8 (Berkeley) 06/02/90"; 1033514Sbostic #endif /* not lint */ 1133514Sbostic 1218208Sedward #include "ww.h" 1342834Sedward #ifdef POSIX_TTY 1442834Sedward #include <sys/ioctl.h> 1542834Sedward #endif 1618208Sedward 1718208Sedward /* 1818208Sedward * Resize a window. Should be unattached. 1918208Sedward */ 2018208Sedward wwsize(w, nrow, ncol) 2118208Sedward register struct ww *w; 2218208Sedward { 2318208Sedward register i, j; 2418208Sedward int nline; 2518208Sedward union ww_char **buf = 0; 2618208Sedward char **win = 0; 2718208Sedward short *nvis = 0; 2818208Sedward char **fmap = 0; 2918208Sedward char m; 3018208Sedward 3118208Sedward /* 3218208Sedward * First allocate new buffers. 3318208Sedward */ 3418208Sedward win = wwalloc(w->ww_w.t, w->ww_w.l, nrow, ncol, sizeof (char)); 3518208Sedward if (win == 0) 3618208Sedward goto bad; 3718208Sedward if (w->ww_fmap != 0) { 3818208Sedward fmap = wwalloc(w->ww_w.t, w->ww_w.l, nrow, ncol, sizeof (char)); 3918208Sedward if (fmap == 0) 4018208Sedward goto bad; 4118208Sedward } 4218208Sedward if (nrow > w->ww_b.nr || ncol > w->ww_b.nc) { 4318208Sedward nline = MAX(w->ww_b.nr, nrow); 4418208Sedward buf = (union ww_char **) wwalloc(w->ww_b.t, w->ww_b.l, 4518208Sedward nline, ncol, sizeof (union ww_char)); 4618208Sedward if (buf == 0) 4718208Sedward goto bad; 4818208Sedward } 4918208Sedward nvis = (short *)malloc((unsigned) nrow * sizeof (short)); 5018208Sedward if (nvis == 0) { 5118208Sedward wwerrno = WWE_NOMEM; 5218208Sedward goto bad; 5318208Sedward } 5418208Sedward nvis -= w->ww_w.t; 5518208Sedward /* 5618208Sedward * Copy text buffer. 5718208Sedward */ 5818208Sedward if (buf != 0) { 5918208Sedward int b, r; 6018208Sedward 6118208Sedward b = w->ww_b.t + nline; 6218208Sedward r = w->ww_b.l + ncol; 6318208Sedward if (ncol < w->ww_b.nc) 6418208Sedward for (i = w->ww_b.t; i < w->ww_b.b; i++) 6518208Sedward for (j = w->ww_b.l; j < r; j++) 6618208Sedward buf[i][j] = w->ww_buf[i][j]; 6718208Sedward else 6818208Sedward for (i = w->ww_b.t; i < w->ww_b.b; i++) { 6918208Sedward for (j = w->ww_b.l; j < w->ww_b.r; j++) 7018208Sedward buf[i][j] = w->ww_buf[i][j]; 7118208Sedward for (; j < r; j++) 7218208Sedward buf[i][j].c_w = ' '; 7318208Sedward } 7418208Sedward for (; i < b; i++) 7518208Sedward for (j = w->ww_b.l; j < r; j++) 7618208Sedward buf[i][j].c_w = ' '; 7718208Sedward } 7818208Sedward /* 7918208Sedward * Now free the old stuff. 8018208Sedward */ 8118208Sedward wwfree((char **)w->ww_win, w->ww_w.t); 8218208Sedward w->ww_win = win; 8318208Sedward if (buf != 0) { 8418208Sedward wwfree((char **)w->ww_buf, w->ww_b.t); 8518208Sedward w->ww_buf = buf; 8618208Sedward } 8718208Sedward if (w->ww_fmap != 0) { 8818208Sedward wwfree((char **)w->ww_fmap, w->ww_w.t); 8918208Sedward w->ww_fmap = fmap; 9018208Sedward } 9118208Sedward free((char *)(w->ww_nvis + w->ww_w.t)); 9218208Sedward w->ww_nvis = nvis; 9318208Sedward /* 9418208Sedward * Set new sizes. 9518208Sedward */ 9618208Sedward /* window */ 9718208Sedward w->ww_w.b = w->ww_w.t + nrow; 9818208Sedward w->ww_w.r = w->ww_w.l + ncol; 9918208Sedward w->ww_w.nr = nrow; 10018208Sedward w->ww_w.nc = ncol; 10118208Sedward /* text buffer */ 10218208Sedward if (buf != 0) { 10318208Sedward w->ww_b.b = w->ww_b.t + nline; 10418208Sedward w->ww_b.r = w->ww_b.l + ncol; 10518208Sedward w->ww_b.nr = nline; 10618208Sedward w->ww_b.nc = ncol; 10718208Sedward } 10818208Sedward /* scroll */ 10918208Sedward if ((i = w->ww_b.b - w->ww_w.b) < 0 || 11018208Sedward (i = w->ww_cur.r - w->ww_w.b + 1) > 0) { 11118208Sedward w->ww_buf += i; 11218208Sedward w->ww_b.t -= i; 11318208Sedward w->ww_b.b -= i; 11418208Sedward w->ww_cur.r -= i; 11518208Sedward } 11618208Sedward /* interior */ 11718208Sedward w->ww_i.b = MIN(w->ww_w.b, wwnrow); 11818208Sedward w->ww_i.r = MIN(w->ww_w.r, wwncol); 11918208Sedward w->ww_i.nr = w->ww_i.b - w->ww_i.t; 12018208Sedward w->ww_i.nc = w->ww_i.r - w->ww_i.l; 12118208Sedward /* 12218208Sedward * Initialize new buffers. 12318208Sedward */ 12418208Sedward /* window */ 12518208Sedward m = 0; 12618208Sedward if (w->ww_oflags & WWO_GLASS) 12718208Sedward m |= WWM_GLS; 12818208Sedward if (w->ww_oflags & WWO_REVERSE) 12918208Sedward m |= WWM_REV; 13018208Sedward for (i = w->ww_w.t; i < w->ww_w.b; i++) 13118208Sedward for (j = w->ww_w.l; j < w->ww_w.r; j++) 13218208Sedward w->ww_win[i][j] = m; 13318208Sedward /* frame map */ 13418208Sedward if (fmap != 0) 13518208Sedward for (i = w->ww_w.t; i < w->ww_w.b; i++) 13618208Sedward for (j = w->ww_w.l; j < w->ww_w.r; j++) 13718208Sedward w->ww_fmap[i][j] = 0; 13818208Sedward /* visibility */ 13918208Sedward j = m ? 0 : w->ww_w.nc; 14018208Sedward for (i = w->ww_w.t; i < w->ww_w.b; i++) 14118208Sedward w->ww_nvis[i] = j; 14218208Sedward /* 14318208Sedward * Put cursor back. 14418208Sedward */ 14518208Sedward if (w->ww_hascursor) { 14618208Sedward w->ww_hascursor = 0; 14718208Sedward wwcursor(w, 1); 14818208Sedward } 14918208Sedward /* 15018208Sedward * Fool with pty. 15118208Sedward */ 15218208Sedward if (w->ww_ispty && w->ww_pty >= 0) { 15318208Sedward struct winsize winsize; 15418208Sedward 15518208Sedward winsize.ws_row = nrow; 15618208Sedward winsize.ws_col = ncol; 15718208Sedward winsize.ws_xpixel = winsize.ws_ypixel = 0; 15829723Sedward (void) ioctl(w->ww_pty, TIOCSWINSZ, (char *)&winsize); 15918208Sedward } 16018208Sedward return 0; 16118208Sedward bad: 16218208Sedward if (win != 0) 16318208Sedward wwfree(win, w->ww_w.t); 16418208Sedward if (fmap != 0) 16518208Sedward wwfree(fmap, w->ww_w.t); 16618208Sedward if (buf != 0) 16718208Sedward wwfree((char **)buf, w->ww_b.t); 16818208Sedward if (nvis != 0) 16918208Sedward free((char *)(nvis + w->ww_w.t)); 17018208Sedward return -1; 17118208Sedward } 172