Module Name: src
Committed By: blymn
Date: Thu Feb 20 09:42:42 UTC 2014
Modified Files:
src/lib/libcurses: curses_private.h mvwin.c refresh.c
Log Message:
Correct the implementation of mvderwin, it now works as specified by
SUSv2.
To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 src/lib/libcurses/curses_private.h
cvs rdiff -u -r1.18 -r1.19 src/lib/libcurses/mvwin.c
cvs rdiff -u -r1.78 -r1.79 src/lib/libcurses/refresh.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libcurses/curses_private.h
diff -u src/lib/libcurses/curses_private.h:1.49 src/lib/libcurses/curses_private.h:1.50
--- src/lib/libcurses/curses_private.h:1.49 Sat Nov 9 11:16:59 2013
+++ src/lib/libcurses/curses_private.h Thu Feb 20 09:42:42 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: curses_private.h,v 1.49 2013/11/09 11:16:59 blymn Exp $ */
+/* $NetBSD: curses_private.h,v 1.50 2014/02/20 09:42:42 blymn Exp $ */
/*-
* Copyright (c) 1998-2000 Brett Lymn
@@ -130,6 +130,7 @@ struct __window { /* Window structure.
#define __NOTIMEOUT 0x00020000 /* Wait indefinitely for func keys */
#define __IDCHAR 0x00040000 /* insert/delete char sequences */
#define __ISPAD 0x00080000 /* "window" is a pad */
+#define __ISDERWIN 0x00100000 /* "window" is derived from parent */
unsigned int flags;
int delay; /* delay for getch() */
attr_t wattr; /* Character attributes */
@@ -140,6 +141,9 @@ struct __window { /* Window structure.
int pbegy, pbegx,
sbegy, sbegx,
smaxy, smaxx; /* Saved prefresh() values */
+ int dery, derx; /* derived window coordinates
+ - top left corner of source
+ relative to parent win */
#ifdef HAVE_WCHAR
nschar_t *bnsp; /* Background non-spacing char list */
#endif /* HAVE_WCHAR */
Index: src/lib/libcurses/mvwin.c
diff -u src/lib/libcurses/mvwin.c:1.18 src/lib/libcurses/mvwin.c:1.19
--- src/lib/libcurses/mvwin.c:1.18 Fri Oct 18 19:53:59 2013
+++ src/lib/libcurses/mvwin.c Thu Feb 20 09:42:42 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: mvwin.c,v 1.18 2013/10/18 19:53:59 christos Exp $ */
+/* $NetBSD: mvwin.c,v 1.19 2014/02/20 09:42:42 blymn Exp $ */
/*
* Copyright (c) 1981, 1993, 1994
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)mvwin.c 8.2 (Berkeley) 5/4/94";
#else
-__RCSID("$NetBSD: mvwin.c,v 1.18 2013/10/18 19:53:59 christos Exp $");
+__RCSID("$NetBSD: mvwin.c,v 1.19 2014/02/20 09:42:42 blymn Exp $");
#endif
#endif /* not lint */
@@ -53,12 +53,7 @@ mvderwin(WINDOW *win, int dy, int dx)
{
WINDOW *parent;
int x, i;
- __LINE *lp, *olp;
-#ifdef HAVE_WCHAR
- __LDATA *cp;
- int j;
- nschar_t *np;
-#endif /* HAVE_WCHAR */
+ __LINE *plp;
if (win == NULL)
return ERR;
@@ -72,39 +67,26 @@ mvderwin(WINDOW *win, int dy, int dx)
((win->maxy + dy) > parent->maxy))
return ERR;
+ win->flags |= __ISDERWIN;
+ win->derx = dx;
+ win->dery = dy;
+
x = parent->begx + dx;
- win->ch_off = x;
- /* Point the line pointers to line space */
- for (lp = win->lspace, i = 0; i < win->maxy; i++, lp++) {
- lp->flags = __ISDIRTY;
- win->alines[i] = lp;
- olp = parent->alines[i + dy];
+ /*
+ * Mark the source area for the derwin as changed so it will be
+ * copied to the destination window on refresh.
+ */
+ for (i = 0; i < win->maxy; i++) {
+ plp = parent->alines[i + dy];
+ plp->flags = __ISDIRTY;
+ if (*plp->firstchp > x)
+ *plp->firstchp = x;
+ if (*plp->lastchp < x + win->maxx)
+ *plp->lastchp = x + win->maxx;
#ifdef DEBUG
- lp->sentinel = SENTINEL_VALUE;
+ __CTRACE(__CTRACE_REFRESH, "mvderwin: firstchp = %d, lastchp = %d\n", *plp->firstchp, *plp->lastchp);
#endif
- lp->line = &olp->line[win->ch_off];
- lp->firstchp = &olp->firstch;
- lp->lastchp = &olp->lastch;
-#ifndef HAVE_WCHAR
- lp->hash = __hash((char *)(void *)lp->line,
- (size_t) (win->maxx * __LDATASIZE));
-#else
- for (cp = lp->line, j = 0; j < win->maxx; j++, cp++) {
- lp->hash = __hash_more(&cp->ch, sizeof(wchar_t),
- lp->hash);
- lp->hash = __hash_more(&cp->attr, sizeof(wchar_t),
- lp->hash);
- if (cp->nsp) {
- np = cp->nsp;
- while (np) {
- lp->hash = __hash_more(&np->ch,
- sizeof(wchar_t), lp->hash);
- np = np->next;
- }
- }
- }
-#endif /* HAVE_WCHAR */
}
return OK;
Index: src/lib/libcurses/refresh.c
diff -u src/lib/libcurses/refresh.c:1.78 src/lib/libcurses/refresh.c:1.79
--- src/lib/libcurses/refresh.c:1.78 Fri Dec 6 11:23:47 2013
+++ src/lib/libcurses/refresh.c Thu Feb 20 09:42:42 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: refresh.c,v 1.78 2013/12/06 11:23:47 blymn Exp $ */
+/* $NetBSD: refresh.c,v 1.79 2014/02/20 09:42:42 blymn Exp $ */
/*
* Copyright (c) 1981, 1993, 1994
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)refresh.c 8.7 (Berkeley) 8/13/94";
#else
-__RCSID("$NetBSD: refresh.c,v 1.78 2013/12/06 11:23:47 blymn Exp $");
+__RCSID("$NetBSD: refresh.c,v 1.79 2014/02/20 09:42:42 blymn Exp $");
#endif
#endif /* not lint */
@@ -144,9 +144,9 @@ _cursesi_wnoutrefresh(SCREEN *screen, WI
int wbegy, int wbegx, int maxy, int maxx)
{
- short sy, wy, wx, y_off, x_off, mx;
- __LINE *wlp, *vlp;
- WINDOW *sub_win, *orig;
+ short sy, wy, wx, y_off, x_off, mx, dy_off, dx_off, endy;
+ __LINE *wlp, *vlp, *dwlp;
+ WINDOW *sub_win, *orig, *swin, *dwin;
#ifdef DEBUG
__CTRACE(__CTRACE_REFRESH, "_wnoutrefresh: win %p, flags 0x%08x\n",
@@ -159,15 +159,21 @@ _cursesi_wnoutrefresh(SCREEN *screen, WI
if (screen->curwin)
return OK;
+ swin = dwin = win;
+ if (win->flags & __ISDERWIN)
+ swin = win->orig;
+
/*
* Recurse through any sub-windows, mark as dirty lines on the parent
* window that are dirty on the sub-window and clear the dirty flag on
* the sub-window.
*/
- if (win->orig == 0) {
- orig = win;
- for (sub_win = win->nextp; sub_win != win;
+ if (dwin->orig == 0) {
+ orig = dwin;
+ for (sub_win = dwin->nextp; sub_win != orig;
sub_win = sub_win->nextp) {
+ if (sub_win->flags & __ISDERWIN)
+ continue;
#ifdef DEBUG
__CTRACE(__CTRACE_REFRESH,
"wnout_refresh: win %p, sub_win %p\n",
@@ -191,49 +197,77 @@ _cursesi_wnoutrefresh(SCREEN *screen, WI
}
/* Check that cursor position on "win" is valid for "__virtscr" */
- if (win->cury + wbegy - begy < screen->__virtscr->maxy &&
- win->cury + wbegy - begy >= 0 && win->cury < maxy - begy)
- screen->__virtscr->cury = win->cury + wbegy - begy;
- if (win->curx + wbegx - begx < screen->__virtscr->maxx &&
- win->curx + wbegx - begx >= 0 && win->curx < maxx - begx)
- screen->__virtscr->curx = win->curx + wbegx - begx;
+ if (dwin->cury + wbegy - begy < screen->__virtscr->maxy &&
+ dwin->cury + wbegy - begy >= 0 && dwin->cury < maxy - begy)
+ screen->__virtscr->cury = dwin->cury + wbegy - begy;
+ if (dwin->curx + wbegx - begx < screen->__virtscr->maxx &&
+ dwin->curx + wbegx - begx >= 0 && dwin->curx < maxx - begx)
+ screen->__virtscr->curx = dwin->curx + wbegx - begx;
/* Copy the window flags from "win" to "__virtscr" */
- if (win->flags & __CLEAROK) {
- if (win->flags & __FULLWIN)
+ if (dwin->flags & __CLEAROK) {
+ if (dwin->flags & __FULLWIN)
screen->__virtscr->flags |= __CLEAROK;
- win->flags &= ~__CLEAROK;
+ dwin->flags &= ~__CLEAROK;
}
screen->__virtscr->flags &= ~__LEAVEOK;
- screen->__virtscr->flags |= win->flags;
+ screen->__virtscr->flags |= dwin->flags;
- for (wy = begy, y_off = wbegy; wy < maxy &&
- y_off < screen->__virtscr->maxy; wy++, y_off++) {
- wlp = win->alines[wy];
+ if ((dwin->flags & __ISDERWIN) != 0)
+ endy = begy + maxy;
+ else
+ endy = maxy;
+
+ for (wy = begy, y_off = wbegy, dy_off = 0; wy < endy &&
+ y_off < screen->__virtscr->maxy; wy++, y_off++, dy_off++) {
+ wlp = swin->alines[wy];
+ dwlp = dwin->alines[dy_off];
#ifdef DEBUG
__CTRACE(__CTRACE_REFRESH,
"_wnoutrefresh: wy %d\tf %d\tl %d\tflags %x\n",
wy, *wlp->firstchp, *wlp->lastchp, wlp->flags);
+
+ if ((dwin->flags & __ISDERWIN) != 0) {
+ __CTRACE(__CTRACE_REFRESH,
+ "_wnoutrefresh: derwin wy %d\tf %d\tl %d\tflags %x\n",
+ dy_off, *dwlp->firstchp, *dwlp->lastchp, dwlp->flags);
+ __CTRACE(__CTRACE_REFRESH,
+ "_wnoutrefresh: derwin maxx %d\tch_off %d\n",
+ dwin->maxx, dwin->ch_off);
+ }
#endif
- if ((wlp->flags & (__ISDIRTY | __ISFORCED)) == 0)
+ if (((wlp->flags & (__ISDIRTY | __ISFORCED)) == 0) &&
+ ((dwlp->flags & (__ISDIRTY | __ISFORCED)) == 0))
continue;
vlp = screen->__virtscr->alines[y_off];
- if (*wlp->firstchp < maxx + win->ch_off &&
- *wlp->lastchp >= win->ch_off) {
+ if ((*wlp->firstchp < maxx + swin->ch_off &&
+ *wlp->lastchp >= swin->ch_off) ||
+ ((((dwin->flags & __ISDERWIN) != 0) &&
+ (*dwlp->firstchp < dwin->maxx + dwin->ch_off &&
+ *dwlp->lastchp >= dwin->ch_off)))) {
/* Set start column */
wx = begx;
x_off = wbegx;
- if (*wlp->firstchp - win->ch_off > 0) {
- wx += *wlp->firstchp - win->ch_off;
- x_off += *wlp->firstchp - win->ch_off;
- }
- /* Set finish column */
- mx = maxx;
- if (mx > *wlp->lastchp - win->ch_off + 1)
- mx = *wlp->lastchp - win->ch_off + 1;
- if (x_off + (mx - wx) > __virtscr->maxx)
- mx -= (x_off + maxx) - __virtscr->maxx;
+ dx_off = 0;
+ /*
+ * if a derwin then source change pointers aren't
+ * relevant.
+ */
+ if ((dwin->flags & __ISDERWIN) != 0)
+ mx = wx + maxx;
+ else {
+ if (*wlp->firstchp - swin->ch_off > 0) {
+ wx += *wlp->firstchp - swin->ch_off;
+ x_off += *wlp->firstchp - swin->ch_off;
+ }
+ mx = maxx;
+ if (mx > *wlp->lastchp - swin->ch_off + 1)
+ mx = *dwlp->lastchp - dwin->ch_off + 1;
+ if (x_off + (mx - wx) > __virtscr->maxx)
+ mx -= (x_off + maxx) - __virtscr->maxx;
+ }
+
/* Copy line from "win" to "__virtscr". */
while (wx < mx) {
#ifdef DEBUG
@@ -253,6 +287,13 @@ _cursesi_wnoutrefresh(SCREEN *screen, WI
(vlp->line[x_off].attr &
_cursesi_screen->nca))
vlp->line[x_off].attr &= ~__COLOR;
+ if (win->flags & __ISDERWIN) {
+ dwlp->line[dx_off].ch =
+ wlp->line[wx].ch;
+ dwlp->line[dx_off].attr =
+ wlp->line[wx].attr;
+ }
+
#ifdef HAVE_WCHAR
if (wlp->line[wx].ch
== (wchar_t)btowc((int) win->bch)) {
@@ -262,6 +303,15 @@ _cursesi_wnoutrefresh(SCREEN *screen, WI
&vlp->line[x_off])
== ERR)
return ERR;
+ if (win->flags & __ISDERWIN) {
+ dwlp->line[dx_off].ch =
+ win->bch;
+ SET_WCOL(dwlp->line[dx_off], 1);
+ if (_cursesi_copy_nsp(win->bnsp,
+ &dwlp->line[dx_off])
+ == ERR)
+ return ERR;
+ }
}
#endif /* HAVE_WCHAR */
#ifdef DEBUG
@@ -271,6 +321,7 @@ _cursesi_wnoutrefresh(SCREEN *screen, WI
#endif
wx++;
x_off++;
+ dx_off++;
}
/* Set flags on "__virtscr" and unset on "win". */
@@ -287,6 +338,11 @@ _cursesi_wnoutrefresh(SCREEN *screen, WI
__CTRACE(__CTRACE_REFRESH,
"win: firstch = %d, lastch = %d\n",
*wlp->firstchp, *wlp->lastchp);
+ if (win->flags & __ISDERWIN) {
+ __CTRACE(__CTRACE_REFRESH,
+ "derwin: fistch = %d, lastch = %d\n",
+ *dwlp->firstchp, *dwlp->lastchp);
+ }
#endif
/* Set change pointers on "__virtscr". */
if (*vlp->firstchp >
@@ -297,6 +353,24 @@ _cursesi_wnoutrefresh(SCREEN *screen, WI
*wlp->lastchp + wbegx - win->ch_off)
*vlp->lastchp =
*wlp->lastchp + wbegx - win->ch_off;
+
+ if (win->flags & __ISDERWIN) {
+ if (*vlp->firstchp >
+ *dwlp->firstchp + wbegx - dwin->ch_off) {
+ *vlp->firstchp =
+ *dwlp->firstchp + wbegx
+ - dwin->ch_off;
+ vlp->flags |= __ISDIRTY;
+ }
+
+ if (*vlp->lastchp <
+ *dwlp->lastchp + wbegx - dwin->ch_off) {
+ *vlp->lastchp = *dwlp->lastchp
+ + wbegx - dwin->ch_off;
+ vlp->flags |= __ISDIRTY;
+ }
+ }
+
#ifdef DEBUG
__CTRACE(__CTRACE_REFRESH,
"__virtscr: firstch = %d, lastch = %d\n",
@@ -339,16 +413,26 @@ int
wrefresh(WINDOW *win)
{
int retval;
+ int pbegx, pbegy;
#ifdef DEBUG
__CTRACE(__CTRACE_REFRESH, "wrefresh: win %p\n", win);
#endif
_cursesi_screen->curwin = (win == _cursesi_screen->curscr);
- if (!_cursesi_screen->curwin)
- retval = _cursesi_wnoutrefresh(_cursesi_screen, win, 0, 0,
- win->begy, win->begx, win->maxy, win->maxx);
- else
+ if (!_cursesi_screen->curwin) {
+ pbegx = pbegy = 0;
+ if ((win->flags & __ISDERWIN) == __ISDERWIN) {
+ pbegx = win->derx;
+ pbegy = win->dery;
+#ifdef DEBUG
+ __CTRACE(__CTRACE_REFRESH, "wrefresh: derwin, begy = %d, begx = %x\n",
+ pbegy, pbegx);
+#endif
+ }
+ retval = _cursesi_wnoutrefresh(_cursesi_screen, win, pbegy,
+ pbegx, win->begy, win->begx, win->maxy, win->maxx);
+ } else
retval = OK;
if (retval == OK) {
retval = doupdate();