summaryrefslogtreecommitdiffstats
path: root/lib/libcurses/lib_pad.c
diff options
context:
space:
mode:
authortholo <tholo@openbsd.org>1996-06-02 06:04:50 +0000
committertholo <tholo@openbsd.org>1996-06-02 06:04:50 +0000
commitca751a4c440c24b9feedffffe0dd93cc1e00ab0c (patch)
tree3ce3bce27611f188dc5c8a99bd9a2e9f5addfcc7 /lib/libcurses/lib_pad.c
parentAdd LIBOLDCURSES (diff)
downloadwireguard-openbsd-ca751a4c440c24b9feedffffe0dd93cc1e00ab0c.tar.xz
wireguard-openbsd-ca751a4c440c24b9feedffffe0dd93cc1e00ab0c.zip
Install ncurses as -lcurses and <curses.h>
Install BSD curses library as -locurses and <ocurses.h>
Diffstat (limited to 'lib/libcurses/lib_pad.c')
-rw-r--r--lib/libcurses/lib_pad.c258
1 files changed, 258 insertions, 0 deletions
diff --git a/lib/libcurses/lib_pad.c b/lib/libcurses/lib_pad.c
new file mode 100644
index 00000000000..392305f658d
--- /dev/null
+++ b/lib/libcurses/lib_pad.c
@@ -0,0 +1,258 @@
+
+/***************************************************************************
+* 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. *
+* *
+***************************************************************************/
+
+
+/*
+ * lib_pad.c
+ * newpad -- create a new pad
+ * pnoutrefresh -- refresh a pad, no update
+ * pechochar -- add a char to a pad and refresh
+ */
+
+#include "curses.priv.h"
+
+#include <stdlib.h>
+#include <errno.h>
+
+#if !HAVE_EXTERN_ERRNO
+extern int errno;
+#endif
+
+WINDOW *newpad(int l, int c)
+{
+WINDOW *win;
+chtype *ptr;
+int i, j;
+
+ T(("newpad(%d, %d) called", l, c));
+
+ if (l <= 0 || c <= 0)
+ return NULL;
+
+ if ((win = _nc_makenew(l,c,0,0)) == NULL)
+ return NULL;
+
+ win->_flags |= _ISPAD;
+
+ for (i = 0; i < l; i++) {
+ win->_line[i].oldindex = _NEWINDEX;
+ if ((win->_line[i].text = (chtype *) calloc((size_t)c, sizeof(chtype))) == NULL) {
+ for (j = 0; j < i; j++)
+ free(win->_line[j].text);
+
+ free(win->_line);
+ free(win);
+
+ errno = ENOMEM;
+ return NULL;
+ }
+ else
+ for (ptr = win->_line[i].text; ptr < win->_line[i].text + c; )
+ *ptr++ = ' ';
+ }
+
+ T(("newpad: returned window is %p", win));
+
+ return(win);
+}
+
+WINDOW *subpad(WINDOW *orig, int l, int c, int begy, int begx)
+{
+WINDOW *win;
+
+ T(("subpad(%d, %d) called", l, c));
+
+ if ((win = derwin(orig, l, c, begy, begx)) == NULL)
+ return NULL;
+
+ win->_flags |= _ISPAD;
+
+ T(("subpad: returned window is %p", win));
+
+ return(win);
+}
+
+int prefresh(WINDOW *win, int pminrow, int pmincol,
+ int sminrow, int smincol, int smaxrow, int smaxcol)
+{
+ T(("prefresh() called"));
+ if (pnoutrefresh(win, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol) != ERR
+ && doupdate() != ERR) {
+ return OK;
+ }
+ return ERR;
+}
+
+int pnoutrefresh(WINDOW *win, int pminrow, int pmincol,
+ int sminrow, int smincol, int smaxrow, int smaxcol)
+{
+short i, j;
+short m, n;
+short pmaxrow;
+short pmaxcol;
+short displaced;
+bool wide;
+
+ T(("pnoutrefresh(%p, %d, %d, %d, %d, %d, %d) called",
+ win, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol));
+
+ if (win == 0)
+ return ERR;
+
+ if (!(win->_flags & _ISPAD))
+ return ERR;
+
+ /* negative values are interpreted as zero */
+ if (pminrow < 0) pminrow = 0;
+ if (pmincol < 0) pmincol = 0;
+ if (sminrow < 0) sminrow = 0;
+ if (smincol < 0) smincol = 0;
+
+ if (smaxrow > screen_lines
+ || smaxcol > screen_columns
+ || sminrow > smaxrow
+ || smincol > smaxcol)
+ return ERR;
+
+ pmaxrow = pminrow + smaxrow - sminrow;
+ pmaxcol = pmincol + smaxcol - smincol;
+
+ T((" pminrow + smaxrow - sminrow %d, win->_maxy %d", pmaxrow, win->_maxy));
+ T((" pmincol + smaxcol - smincol %d, win->_maxx %d", pmaxcol, win->_maxx));
+ if ((pmaxrow > win->_maxy)
+ || (pmaxcol > win->_maxx))
+ return ERR;
+
+ T(("pad being refreshed"));
+
+ if (win->_pad._pad_y >= 0) {
+ displaced = pminrow - win->_pad._pad_y
+ -(sminrow - win->_pad._pad_top);
+ T(("pad being shifted by %d line(s)", displaced));
+ } else
+ displaced = 0;
+
+ /*
+ * For pure efficiency, we'd want to transfer scrolling information
+ * from the pad to newscr whenever the window is wide enough that
+ * its update will dominate the cost of the update for the horizontal
+ * band of newscr that it occupies. Unfortunately, this threshold
+ * tends to be complex to estimate, and in any case scrolling the
+ * whole band and rewriting the parts outside win's image would look
+ * really ugly. So. What we do is consider the pad "wide" if it
+ * either (a) occupies the whole width of newscr, or (b) occupies
+ * all but at most one column on either vertical edge of the screen
+ * (this caters to fussy people who put boxes around full-screen
+ * windows). Note that changing this formula will not break any code,
+ * merely change the costs of various update cases.
+ */
+ wide = (sminrow <= 1 && win->_maxx >= (newscr->_maxx - 1));
+
+ for (i = pminrow, m = sminrow; i <= pmaxrow; i++, m++) {
+ register struct ldat *nline = &newscr->_line[m];
+ register struct ldat *oline = &win->_line[i];
+
+ for (j = pmincol, n = smincol; j <= pmaxcol; j++, n++) {
+ if (oline->text[j] != nline->text[n]) {
+ nline->text[n] = oline->text[j];
+
+ if (nline->firstchar == _NOCHANGE)
+ nline->firstchar = nline->lastchar = n;
+ else if (n < nline->firstchar)
+ nline->firstchar = n;
+ else if (n > nline->lastchar)
+ nline->lastchar = n;
+ }
+ }
+
+ if (wide) {
+ int nind = m + displaced;
+ if (oline->oldindex < 0
+ || nind < sminrow
+ || nind > smaxrow)
+ nind = _NEWINDEX;
+
+ nline->oldindex = nind;
+ }
+ oline->firstchar = oline->lastchar = _NOCHANGE;
+ oline->oldindex = i;
+ }
+
+ /*
+ * Clean up debris from scrolling or resizing the pad, so we do not
+ * accidentally pick up the index value during the next call to this
+ * procedure. The only rows that should have an index value are those
+ * that are displayed during this cycle.
+ */
+ for (i = pminrow-1; (i >= 0) && (win->_line[i].oldindex >= 0); i--)
+ win->_line[i].oldindex = _NEWINDEX;
+ for (i = pmaxrow+1; (i <= win->_maxy) && (win->_line[i].oldindex >= 0); i++)
+ win->_line[i].oldindex = _NEWINDEX;
+
+ win->_begx = smincol;
+ win->_begy = sminrow;
+
+ if (win->_clear) {
+ win->_clear = FALSE;
+ newscr->_clear = TRUE;
+ }
+
+ /*
+ * Use the pad's current position, if it will be visible.
+ * If not, don't do anything; it's not an error.
+ */
+ if (win->_leaveok == FALSE
+ && win->_cury >= pminrow
+ && win->_curx >= pmincol
+ && win->_cury <= pmaxrow
+ && win->_curx <= pmaxcol) {
+ newscr->_cury = win->_cury - pminrow + win->_begy;
+ newscr->_curx = win->_curx - pmincol + win->_begx;
+ }
+ win->_flags &= ~_HASMOVED;
+
+ /*
+ * Update our cache of the line-numbers that we displayed from the pad.
+ * We will use this on subsequent calls to this function to derive
+ * values to stuff into 'oldindex[]' -- for scrolling optimization.
+ */
+ win->_pad._pad_y = pminrow;
+ win->_pad._pad_x = pmincol;
+ win->_pad._pad_top = sminrow;
+ win->_pad._pad_left = smincol;
+ win->_pad._pad_bottom = smaxrow;
+ win->_pad._pad_right = smaxcol;
+
+ return OK;
+}
+
+int pechochar(WINDOW *pad, chtype ch)
+{
+ T(("echochar(%p, %lx)", pad, ch));
+
+ if (pad->_flags & _ISPAD)
+ return ERR;
+
+ waddch(curscr, ch);
+ doupdate();
+ return OK;
+}
+