Home | History | Annotate | Line # | Download | only in libcurses
resize.c revision 1.1
      1  1.1  blymn /*	$NetBSD: resize.c,v 1.1 2001/09/20 11:11:54 blymn Exp $	*/
      2  1.1  blymn 
      3  1.1  blymn /*
      4  1.1  blymn  * Copyright (c) 2001
      5  1.1  blymn  *	Brett Lymn.
      6  1.1  blymn  *
      7  1.1  blymn  * This code has been donated to The NetBSD Foundation by the Author.
      8  1.1  blymn  *
      9  1.1  blymn  * Redistribution and use in source and binary forms, with or without
     10  1.1  blymn  * modification, are permitted provided that the following conditions
     11  1.1  blymn  * are met:
     12  1.1  blymn  * 1. Redistributions of source code must retain the above copyright
     13  1.1  blymn  *    notice, this list of conditions and the following disclaimer.
     14  1.1  blymn  * 2. Redistributions in binary form must reproduce the above copyright
     15  1.1  blymn  *    notice, this list of conditions and the following disclaimer in the
     16  1.1  blymn  *    documentation and/or other materials provided with the distribution.
     17  1.1  blymn  * 3. All advertising materials mentioning features or use of this software
     18  1.1  blymn  *    must display the following acknowledgement:
     19  1.1  blymn  *	This product includes software developed by the University of
     20  1.1  blymn  *	California, Berkeley and its contributors.
     21  1.1  blymn  * 4. Neither the name of the University nor the names of its contributors
     22  1.1  blymn  *    may be used to endorse or promote products derived from this software
     23  1.1  blymn  *    without specific prior written permission.
     24  1.1  blymn  *
     25  1.1  blymn  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     26  1.1  blymn  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     27  1.1  blymn  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     28  1.1  blymn  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     29  1.1  blymn  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     30  1.1  blymn  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     31  1.1  blymn  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32  1.1  blymn  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33  1.1  blymn  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34  1.1  blymn  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35  1.1  blymn  * SUCH DAMAGE.
     36  1.1  blymn  */
     37  1.1  blymn 
     38  1.1  blymn #include <sys/cdefs.h>
     39  1.1  blymn #ifndef lint
     40  1.1  blymn #if 0
     41  1.1  blymn static char sccsid[] = "@(#)resize.c   blymn 2001/08/26";
     42  1.1  blymn #else
     43  1.1  blymn __RCSID("$NetBSD: resize.c,v 1.1 2001/09/20 11:11:54 blymn Exp $");
     44  1.1  blymn #endif
     45  1.1  blymn #endif				/* not lint */
     46  1.1  blymn 
     47  1.1  blymn #include <stdlib.h>
     48  1.1  blymn 
     49  1.1  blymn #include "curses.h"
     50  1.1  blymn #include "curses_private.h"
     51  1.1  blymn 
     52  1.1  blymn extern struct __winlist	*winlistp;
     53  1.1  blymn 
     54  1.1  blymn static int __resizewin(WINDOW *win, int nlines, int ncols);
     55  1.1  blymn 
     56  1.1  blymn /*
     57  1.1  blymn  * wresize --
     58  1.1  blymn  *	Resize the given window to the new size.
     59  1.1  blymn  */
     60  1.1  blymn int
     61  1.1  blymn wresize(WINDOW *win, int nlines, int ncols)
     62  1.1  blymn {
     63  1.1  blymn 	__LINE *lp;
     64  1.1  blymn 	int     i, j;
     65  1.1  blymn 	__LDATA *sp;
     66  1.1  blymn 
     67  1.1  blymn 	if ((win == NULL) || (nlines < 0) || (ncols < 0))
     68  1.1  blymn 		return ERR;
     69  1.1  blymn 
     70  1.1  blymn 	if (win->orig == NULL) {
     71  1.1  blymn 		if (nlines == 0)
     72  1.1  blymn 			nlines = LINES - win->begy;
     73  1.1  blymn 		if (ncols == 0)
     74  1.1  blymn 			ncols = COLS - win->begx;
     75  1.1  blymn 	} else {
     76  1.1  blymn 		  /* subwins must fit inside the parent - check this */
     77  1.1  blymn 		if ((nlines == 0)
     78  1.1  blymn 		    || (nlines > (win->orig->maxy + win->orig->begy
     79  1.1  blymn 				  - win->begy)))
     80  1.1  blymn 			nlines = win->orig->maxy + win->orig->begy - win->begy;
     81  1.1  blymn 
     82  1.1  blymn 		if ((ncols == 0)
     83  1.1  blymn 		    || (ncols > (win->orig->maxx + win->orig->begx
     84  1.1  blymn 				 - win->begx)))
     85  1.1  blymn 			ncols = win->orig->maxx + win->orig->begx - win->begx;
     86  1.1  blymn 	}
     87  1.1  blymn 
     88  1.1  blymn 	if ((__resizewin(win, nlines, ncols)) == ERR)
     89  1.1  blymn 		return ERR;
     90  1.1  blymn 
     91  1.1  blymn 	  /*
     92  1.1  blymn 	   * we must zot the window contents otherwise lines may pick
     93  1.1  blymn 	   * up attributes from the previous line when the window is
     94  1.1  blymn 	   * made smaller.  The client will redraw the window anyway
     95  1.1  blymn 	   * so this is no big deal.
     96  1.1  blymn 	   */
     97  1.1  blymn 	for (i = 0; i < win->maxy; i++) {
     98  1.1  blymn 		lp = win->lines[i];
     99  1.1  blymn 		for (sp = lp->line, j = 0; j < win->maxx;
    100  1.1  blymn 		     j++, sp++) {
    101  1.1  blymn 			sp->ch = ' ';
    102  1.1  blymn 			sp->bch = ' ';
    103  1.1  blymn 			sp->attr = 0;
    104  1.1  blymn 			sp->battr = 0;
    105  1.1  blymn 		}
    106  1.1  blymn 		lp->hash = __hash((char *)(void *)lp->line,
    107  1.1  blymn 				  (int) (ncols * __LDATASIZE));
    108  1.1  blymn 	}
    109  1.1  blymn 
    110  1.1  blymn 	return OK;
    111  1.1  blymn }
    112  1.1  blymn 
    113  1.1  blymn /*
    114  1.1  blymn  * resizeterm --
    115  1.1  blymn  *      Resize the terminal window, resizing the dependent windows.
    116  1.1  blymn  */
    117  1.1  blymn int
    118  1.1  blymn resizeterm(int nlines, int ncols)
    119  1.1  blymn {
    120  1.1  blymn 	WINDOW *win;
    121  1.1  blymn 	struct __winlist *list;
    122  1.1  blymn 	int newlines, newcols, ldelta, cdelta;
    123  1.1  blymn 
    124  1.1  blymn 	  /* don't worry if things have not changed... we would like to
    125  1.1  blymn 	     do this but some bastard programs update LINES and COLS before
    126  1.1  blymn 	     calling resizeterm thus negating it's effect.
    127  1.1  blymn 	if ((nlines == LINES) && (ncols == COLS))
    128  1.1  blymn 	return OK;*/
    129  1.1  blymn 
    130  1.1  blymn #ifdef	DEBUG
    131  1.1  blymn 	__CTRACE("resizeterm: (%d, %d)\n", nlines, ncols);
    132  1.1  blymn #endif
    133  1.1  blymn 
    134  1.1  blymn 	ldelta = nlines - __virtscr->maxy;
    135  1.1  blymn 	cdelta = ncols - __virtscr->maxx;
    136  1.1  blymn 
    137  1.1  blymn 	for (list = __winlistp; list != NULL; list = list->nextp) {
    138  1.1  blymn 		win = list->winp;
    139  1.1  blymn 		newlines = win->maxy;
    140  1.1  blymn 		newcols = win->maxx;
    141  1.1  blymn 
    142  1.1  blymn 		if (win->begy >= (nlines - 1)) {
    143  1.1  blymn 			win->begy = nlines - win->maxx - 1;
    144  1.1  blymn 			if (win->begy < 0)
    145  1.1  blymn 				win->begy = 0;
    146  1.1  blymn 		}
    147  1.1  blymn 
    148  1.1  blymn 
    149  1.1  blymn 		if ((newlines + win->begy + ldelta) == nlines)
    150  1.1  blymn 				newlines = nlines;
    151  1.1  blymn 
    152  1.1  blymn 		if (newlines > nlines) {
    153  1.1  blymn 			newlines = nlines - win->begy;
    154  1.1  blymn 			if (newlines < 0)
    155  1.1  blymn 				newlines = 1;
    156  1.1  blymn 		}
    157  1.1  blymn 
    158  1.1  blymn 		if ((newcols + win->begx + cdelta) == ncols)
    159  1.1  blymn 			newcols = ncols;
    160  1.1  blymn 
    161  1.1  blymn 		if (newcols > ncols) {
    162  1.1  blymn 			newcols = ncols - win->begx;
    163  1.1  blymn 			if (newcols < 0)
    164  1.1  blymn 				newcols = 1;
    165  1.1  blymn 		}
    166  1.1  blymn 
    167  1.1  blymn 		if (wresize(win, newlines, newcols) != OK)
    168  1.1  blymn 			return ERR;
    169  1.1  blymn 	}
    170  1.1  blymn 
    171  1.1  blymn 	LINES = nlines;
    172  1.1  blymn 	COLS = ncols;
    173  1.1  blymn 
    174  1.1  blymn 	  /* tweak the flags now that we have updated the LINES and COLS */
    175  1.1  blymn 	for (list = __winlistp; list != NULL; list = list->nextp) {
    176  1.1  blymn 		  __swflags(list->winp);
    177  1.1  blymn 	}
    178  1.1  blymn 
    179  1.1  blymn 	wrefresh(curscr);
    180  1.1  blymn 	return OK;
    181  1.1  blymn }
    182  1.1  blymn 
    183  1.1  blymn /*
    184  1.1  blymn  * __resizewin --
    185  1.1  blymn  *	Resize the given window.
    186  1.1  blymn  */
    187  1.1  blymn static int
    188  1.1  blymn __resizewin(WINDOW *win, int nlines, int ncols)
    189  1.1  blymn {
    190  1.1  blymn 	__LINE			*lp, *olp, **newlines, *newlspace;
    191  1.1  blymn 	__LDATA                 *newwspace;
    192  1.1  blymn 	int			 i;
    193  1.1  blymn 
    194  1.1  blymn #ifdef	DEBUG
    195  1.1  blymn 	__CTRACE("resize: (%d, %d)\n", nlines, ncols);
    196  1.1  blymn 	__CTRACE("resize: win->wattr = %0.2o\n", win->wattr);
    197  1.1  blymn 	__CTRACE("resize: win->flags = %0.2o\n", win->flags);
    198  1.1  blymn 	__CTRACE("resize: win->maxy = %d\n", win->maxy);
    199  1.1  blymn 	__CTRACE("resize: win->maxx = %d\n", win->maxx);
    200  1.1  blymn 	__CTRACE("resize: win->begy = %d\n", win->begy);
    201  1.1  blymn 	__CTRACE("resize: win->begx = %d\n", win->begx);
    202  1.1  blymn 	__CTRACE("resize: win->scr_t = %d\n", win->scr_t);
    203  1.1  blymn 	__CTRACE("resize: win->scr_b = %d\n", win->scr_b);
    204  1.1  blymn #endif
    205  1.1  blymn 
    206  1.1  blymn 	/* Reallocate line pointer array and line space. */
    207  1.1  blymn 	if ((newlines = realloc(win->lines,
    208  1.1  blymn 				nlines * sizeof(__LINE *))) == NULL) {
    209  1.1  blymn 		return ERR;
    210  1.1  blymn 	}
    211  1.1  blymn 	win->lines = newlines;
    212  1.1  blymn 
    213  1.1  blymn 	if ((newlspace = realloc(win->lspace,
    214  1.1  blymn 				 nlines * sizeof(__LINE))) == NULL) {
    215  1.1  blymn 		return ERR;
    216  1.1  blymn 	}
    217  1.1  blymn 	win->lspace = newlspace;
    218  1.1  blymn 
    219  1.1  blymn 	/* Don't allocate window and line space if it's a subwindow */
    220  1.1  blymn 	if (win->orig == NULL) {
    221  1.1  blymn 		/*
    222  1.1  blymn 		 * Allocate window space in one chunk.
    223  1.1  blymn 		 */
    224  1.1  blymn 		if ((newwspace =
    225  1.1  blymn 			realloc(win->wspace,
    226  1.1  blymn 				ncols * nlines * sizeof(__LDATA))) == NULL) {
    227  1.1  blymn 			return ERR;
    228  1.1  blymn 		}
    229  1.1  blymn 
    230  1.1  blymn 		win->wspace = newwspace;
    231  1.1  blymn 
    232  1.1  blymn 		/*
    233  1.1  blymn 		 * Point line pointers to line space, and lines themselves into
    234  1.1  blymn 		 * window space.
    235  1.1  blymn 		 */
    236  1.1  blymn 		for (lp = win->lspace, i = 0; i < nlines; i++, lp++) {
    237  1.1  blymn 			win->lines[i] = lp;
    238  1.1  blymn 			lp->line = &win->wspace[i * ncols];
    239  1.1  blymn 			lp->firstchp = &lp->firstch;
    240  1.1  blymn 			lp->lastchp = &lp->lastch;
    241  1.1  blymn 			lp->firstch = 0;
    242  1.1  blymn 			lp->lastch = ncols - 1;
    243  1.1  blymn 			lp->flags = __ISDIRTY;
    244  1.1  blymn 		}
    245  1.1  blymn 	} else {
    246  1.1  blymn 
    247  1.1  blymn 		win->ch_off = win->begx - win->orig->begx;
    248  1.1  blymn 		  /* Point line pointers to line space. */
    249  1.1  blymn 		for (lp = win->lspace, i = 0; i < nlines; i++, lp++) {
    250  1.1  blymn 			win->lines[i] = lp;
    251  1.1  blymn 			olp = win->orig->lines[i + win->begy
    252  1.1  blymn 					      - win->orig->begy];
    253  1.1  blymn 			lp->line = &olp->line[win->ch_off];
    254  1.1  blymn 			lp->firstchp = &olp->firstch;
    255  1.1  blymn 			lp->lastchp = &olp->lastch;
    256  1.1  blymn 			lp->hash = __hash((char *)(void *)lp->line,
    257  1.1  blymn 					  (int) (win->maxx * __LDATASIZE));
    258  1.1  blymn 			lp->flags = __ISDIRTY;
    259  1.1  blymn 		}
    260  1.1  blymn 	}
    261  1.1  blymn 
    262  1.1  blymn 
    263  1.1  blymn 	win->cury = win->curx = 0;
    264  1.1  blymn 	win->maxy = nlines;
    265  1.1  blymn 	win->maxx = ncols;
    266  1.1  blymn 	win->scr_b = win->maxy - 1;
    267  1.1  blymn 	__swflags(win);
    268  1.1  blymn 
    269  1.1  blymn #ifdef DEBUG
    270  1.1  blymn 	__CTRACE("resize: win->wattr = %0.2o\n", win->wattr);
    271  1.1  blymn 	__CTRACE("resize: win->flags = %0.2o\n", win->flags);
    272  1.1  blymn 	__CTRACE("resize: win->maxy = %d\n", win->maxy);
    273  1.1  blymn 	__CTRACE("resize: win->maxx = %d\n", win->maxx);
    274  1.1  blymn 	__CTRACE("resize: win->begy = %d\n", win->begy);
    275  1.1  blymn 	__CTRACE("resize: win->begx = %d\n", win->begx);
    276  1.1  blymn 	__CTRACE("resize: win->scr_t = %d\n", win->scr_t);
    277  1.1  blymn 	__CTRACE("resize: win->scr_b = %d\n", win->scr_b);
    278  1.1  blymn #endif
    279  1.1  blymn 	return OK;
    280  1.1  blymn }
    281  1.1  blymn 
    282