diff options
author | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-06-02 06:06:27 +0000 |
---|---|---|
committer | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-06-02 06:06:27 +0000 |
commit | 97548ea6b6ae9322fb78df90b7633d40df4e11df (patch) | |
tree | ab5a82d85a6c89f0dfdb1e44cc10cc6d80167d0c /lib/libcurses/lib_resize.c | |
parent | 4eae3aa9e113650162ffb0bbb09e47503936e77e (diff) |
Install ncurses as -lcurses and <curses.h>
Install BSD curses library as -locurses and <ocurses.h>
Diffstat (limited to 'lib/libcurses/lib_resize.c')
-rw-r--r-- | lib/libcurses/lib_resize.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/lib/libcurses/lib_resize.c b/lib/libcurses/lib_resize.c new file mode 100644 index 00000000000..b1052f042d4 --- /dev/null +++ b/lib/libcurses/lib_resize.c @@ -0,0 +1,152 @@ + +/*************************************************************************** +* COPYRIGHT NOTICE * +**************************************************************************** +* ncurses is copyright (C) 1992-1995 * +* Zeyd M. Ben-Halim * +* zmbenhal@netcom.com * +* Eric S. Raymond * +* esr@snark.thyrsus.com * +* * +* Permission is hereby granted to reproduce and distribute ncurses * +* by any means and for any fee, whether alone or as part of a * +* larger distribution, in source or in binary form, PROVIDED * +* this notice is included with any such distribution, and is not * +* removed from any of its header files. Mention of ncurses in any * +* applications linked with it is highly appreciated. * +* * +* ncurses comes AS IS with no warranty, implied or expressed. * +* * +***************************************************************************/ + +/* + * Note: This code is not part of the SVr4/XSI Curses API! + */ + +#include "curses.priv.h" +#include <stdlib.h> + +int wresize(WINDOW *win, int new_lines, int new_cols) +{ + chtype blank = _nc_render(win, ' ', BLANK); + register int i, j; + + T(("wresize(win=%p, lines=%d, cols=%d) called", win, new_lines, new_cols)); + + if (new_lines <= 0 || new_cols <= 0) + return ERR; + + /* window height is different, must mess with the line vector */ + if (new_lines != win->_maxy+1) + { + struct ldat *tp; + + /* free old lines no longer used */ + if (!(win->_flags & _SUBWIN)) + for (i = new_lines + 1; i <= win->_maxy; i++) + free((char *)(win->_line[i].text)); + + /* resize the window line vector */ + if (!(win->_line = realloc(win->_line, sizeof(struct ldat) * new_lines))) + return(ERR); + + /* grab new lines for the window if needed */ + for (tp=&win->_line[i=win->_maxy+1]; tp<&win->_line[new_lines]; i++,tp++) + { + if (win->_flags & _SUBWIN) /* set up alias pointers */ + tp->text = &(win->_parent->_line[win->_pary+i].text[win->_parx]); + else /* allocate new lines if needed */ + { + if (!(tp->text = (chtype *)malloc(sizeof(chtype) * new_cols))) + return(ERR); + for (j = 0; j < new_cols; j++) + tp->text[j] = blank; + } + + tp->firstchar = 0; + tp->lastchar = new_cols; + tp->oldindex = i; + } + + /* + * This is kind of nasty. We have to clip the scrolling region to + * within the new window size. We also have to assume that if the + * bottom of the scrolling region is the last line, the user wants + * that bottom to stick to the bottom of the resized window. The + * real problem here is that the API doesn't distinguish between + * resetting the scroll region to the entire window and setting it + * to an explicit scroll region that happens to include the whole + * window. + */ + if (win->_regtop > new_lines - 1 || win->_regtop == win->_maxy) + win->_regtop = new_lines - 1; + if (win->_regbottom > new_lines - 1 || win->_regbottom == win->_maxy) + win->_regbottom = new_lines - 1; + } + + /* window width is different, resize all old lines */ + if (new_cols != win->_maxx+1) + for (i = 0; i < min(new_lines, win->_maxy+1); i++) + { + /* if not a subwindow, we have our own storage; resize each line */ + if (!(win->_flags & _SUBWIN)) + { + win->_line[i].text=realloc(win->_line[i].text,sizeof(chtype)*new_cols); + if (win->_line[i].text == (chtype *)NULL) + return(ERR); + } + + if (new_cols > win->_maxx+1) /* window is growing horizontally */ + { + if (win->_line[i].firstchar == _NOCHANGE) + win->_line[i].firstchar = win->_maxx+1; + win->_line[i].lastchar = new_cols; + for (j = win->_maxx+1; j < new_cols; j++) /* blank-fill ends */ + win->_line[i].text[j] = blank; + } + else /* window is shrinking horizontally */ + { + if (win->_line[i].firstchar > win->_maxx+1) + win->_line[i].firstchar = _NOCHANGE; + else if (win->_line[i].lastchar > new_cols) + win->_line[i].lastchar = new_cols; + } + } + + /* clip the cursor position to within the new size */ + if (win->_curx > new_cols - 1) + win->_curx = new_cols - 1; + if (win->_cury > new_lines - 1) + win->_cury = new_lines - 1; + + /* whether this is a full-width or full-depth window may have changed */ + win->_flags &=~ (_ENDLINE|_FULLWIN|_SCROLLWIN); + if (win->_begx + new_cols == screen_columns) + { + win->_flags |= _ENDLINE; + + if (win->_begx == 0 && new_lines == screen_lines && win->_begy == 0) + win->_flags |= _FULLWIN; + + if (win->_begy + new_lines == screen_lines) + win->_flags |= _SCROLLWIN; + } + + /* right margin may have moved, set _NEED_WRAP properly */ + if ((win->_flags & _NEED_WRAP) && win->_curx != new_cols - 1) + { + win->_curx++; + win->_flags &=~ _NEED_WRAP; + } + if (!(win->_flags & _NEED_WRAP) && win->_curx == new_cols) + { + win->_curx--; + win->_flags |= _NEED_WRAP; + } + + /* finally, update size members */ + win->_maxy = new_lines - 1; + win->_maxx = new_cols - 1; + + return OK; +} |