1*0a6a1f1dSLionel Sambuc /* $NetBSD: touchwin.c,v 1.27 2013/12/06 11:23:47 blymn Exp $ */
251ffecc1SBen Gras
351ffecc1SBen Gras /*
451ffecc1SBen Gras * Copyright (c) 1981, 1993, 1994
551ffecc1SBen Gras * The Regents of the University of California. All rights reserved.
651ffecc1SBen Gras *
751ffecc1SBen Gras * Redistribution and use in source and binary forms, with or without
851ffecc1SBen Gras * modification, are permitted provided that the following conditions
951ffecc1SBen Gras * are met:
1051ffecc1SBen Gras * 1. Redistributions of source code must retain the above copyright
1151ffecc1SBen Gras * notice, this list of conditions and the following disclaimer.
1251ffecc1SBen Gras * 2. Redistributions in binary form must reproduce the above copyright
1351ffecc1SBen Gras * notice, this list of conditions and the following disclaimer in the
1451ffecc1SBen Gras * documentation and/or other materials provided with the distribution.
1551ffecc1SBen Gras * 3. Neither the name of the University nor the names of its contributors
1651ffecc1SBen Gras * may be used to endorse or promote products derived from this software
1751ffecc1SBen Gras * without specific prior written permission.
1851ffecc1SBen Gras *
1951ffecc1SBen Gras * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2051ffecc1SBen Gras * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2151ffecc1SBen Gras * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2251ffecc1SBen Gras * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2351ffecc1SBen Gras * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2451ffecc1SBen Gras * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2551ffecc1SBen Gras * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2651ffecc1SBen Gras * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2751ffecc1SBen Gras * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2851ffecc1SBen Gras * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2951ffecc1SBen Gras * SUCH DAMAGE.
3051ffecc1SBen Gras */
3151ffecc1SBen Gras
3251ffecc1SBen Gras #include <sys/cdefs.h>
3351ffecc1SBen Gras #ifndef lint
3451ffecc1SBen Gras #if 0
3551ffecc1SBen Gras static char sccsid[] = "@(#)touchwin.c 8.2 (Berkeley) 5/4/94";
3651ffecc1SBen Gras #else
37*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: touchwin.c,v 1.27 2013/12/06 11:23:47 blymn Exp $");
3851ffecc1SBen Gras #endif
3951ffecc1SBen Gras #endif /* not lint */
4051ffecc1SBen Gras
4151ffecc1SBen Gras #include "curses.h"
4251ffecc1SBen Gras #include "curses_private.h"
4351ffecc1SBen Gras
44*0a6a1f1dSLionel Sambuc static int _cursesi_touchline_force(WINDOW *, int, int, int, int);
45*0a6a1f1dSLionel Sambuc
4651ffecc1SBen Gras /*
4751ffecc1SBen Gras * is_linetouched --
4851ffecc1SBen Gras * Indicate if line has been touched or not.
4951ffecc1SBen Gras */
5051ffecc1SBen Gras bool
is_linetouched(WINDOW * win,int line)5151ffecc1SBen Gras is_linetouched(WINDOW *win, int line)
5251ffecc1SBen Gras {
5351ffecc1SBen Gras if (line > win->maxy)
5451ffecc1SBen Gras return FALSE;
5551ffecc1SBen Gras
5651ffecc1SBen Gras return ((win->alines[line]->flags & __ISDIRTY) != 0);
5751ffecc1SBen Gras }
5851ffecc1SBen Gras
5951ffecc1SBen Gras /*
6051ffecc1SBen Gras * touchline --
6151ffecc1SBen Gras * Touch count lines starting at start. This is the SUS v2 compliant
6251ffecc1SBen Gras * version.
6351ffecc1SBen Gras */
6451ffecc1SBen Gras int
touchline(WINDOW * win,int start,int count)6551ffecc1SBen Gras touchline(WINDOW *win, int start, int count)
6651ffecc1SBen Gras {
6751ffecc1SBen Gras #ifdef DEBUG
6851ffecc1SBen Gras __CTRACE(__CTRACE_LINE, "touchline: (%p, %d, %d)\n", win, start, count);
6951ffecc1SBen Gras #endif
7051ffecc1SBen Gras return wtouchln(win, start, count, 1);
7151ffecc1SBen Gras }
7251ffecc1SBen Gras
7351ffecc1SBen Gras /*
7451ffecc1SBen Gras * wredrawln --
7551ffecc1SBen Gras * Mark count lines starting at start as corrupted. Implemented using
7651ffecc1SBen Gras * wtouchln().
7751ffecc1SBen Gras */
wredrawln(WINDOW * win,int start,int count)7851ffecc1SBen Gras int wredrawln(WINDOW *win, int start, int count)
7951ffecc1SBen Gras {
8051ffecc1SBen Gras #ifdef DEBUG
8151ffecc1SBen Gras __CTRACE(__CTRACE_LINE, "wredrawln: (%p, %d, %d)\n", win, start, count);
8251ffecc1SBen Gras #endif
8351ffecc1SBen Gras return wtouchln(win, start, count, 1);
8451ffecc1SBen Gras }
8551ffecc1SBen Gras
8651ffecc1SBen Gras /*
8751ffecc1SBen Gras * is_wintouched --
8851ffecc1SBen Gras * Check if the window has been touched.
8951ffecc1SBen Gras */
9051ffecc1SBen Gras bool
is_wintouched(WINDOW * win)9151ffecc1SBen Gras is_wintouched(WINDOW *win)
9251ffecc1SBen Gras {
9351ffecc1SBen Gras int y, maxy;
9451ffecc1SBen Gras
9551ffecc1SBen Gras maxy = win->maxy;
9651ffecc1SBen Gras for (y = 0; y < maxy; y++) {
9751ffecc1SBen Gras if (is_linetouched(win, y) == TRUE)
9851ffecc1SBen Gras return TRUE;
9951ffecc1SBen Gras }
10051ffecc1SBen Gras
10151ffecc1SBen Gras return FALSE;
10251ffecc1SBen Gras }
10351ffecc1SBen Gras
10451ffecc1SBen Gras /*
10551ffecc1SBen Gras * touchwin --
10651ffecc1SBen Gras * Make it look like the whole window has been changed.
10751ffecc1SBen Gras */
10851ffecc1SBen Gras int
touchwin(WINDOW * win)10951ffecc1SBen Gras touchwin(WINDOW *win)
11051ffecc1SBen Gras {
11151ffecc1SBen Gras #ifdef DEBUG
11251ffecc1SBen Gras __CTRACE(__CTRACE_LINE, "touchwin: (%p)\n", win);
11351ffecc1SBen Gras #endif
11451ffecc1SBen Gras return wtouchln(win, 0, win->maxy, 1);
11551ffecc1SBen Gras }
11651ffecc1SBen Gras
11751ffecc1SBen Gras /*
11851ffecc1SBen Gras * redrawwin --
11951ffecc1SBen Gras * Mark entire window as corrupted. Implemented using wtouchln().
12051ffecc1SBen Gras */
12151ffecc1SBen Gras int
redrawwin(WINDOW * win)12251ffecc1SBen Gras redrawwin(WINDOW *win)
12351ffecc1SBen Gras {
12451ffecc1SBen Gras #ifdef DEBUG
12551ffecc1SBen Gras __CTRACE(__CTRACE_LINE, "redrawwin: (%p)\n", win);
12651ffecc1SBen Gras #endif
12751ffecc1SBen Gras return wtouchln(win, 0, win->maxy, 1);
12851ffecc1SBen Gras }
12951ffecc1SBen Gras
13051ffecc1SBen Gras /*
13151ffecc1SBen Gras * untouchwin --
13251ffecc1SBen Gras * Make it look like the window has not been changed.
13351ffecc1SBen Gras */
13451ffecc1SBen Gras int
untouchwin(WINDOW * win)13551ffecc1SBen Gras untouchwin(WINDOW *win)
13651ffecc1SBen Gras {
13751ffecc1SBen Gras #ifdef DEBUG
13851ffecc1SBen Gras __CTRACE(__CTRACE_LINE, "untouchwin: (%p)\n", win);
13951ffecc1SBen Gras #endif
14051ffecc1SBen Gras return wtouchln(win, 0, win->maxy, 0);
14151ffecc1SBen Gras }
14251ffecc1SBen Gras
14351ffecc1SBen Gras /*
14451ffecc1SBen Gras * wtouchln --
14551ffecc1SBen Gras * If changed is 1 then touch n lines starting at line. If changed
14651ffecc1SBen Gras * is 0 then mark the lines as unchanged.
14751ffecc1SBen Gras */
14851ffecc1SBen Gras int
wtouchln(WINDOW * win,int line,int n,int changed)14951ffecc1SBen Gras wtouchln(WINDOW *win, int line, int n, int changed)
15051ffecc1SBen Gras {
15151ffecc1SBen Gras int y;
15251ffecc1SBen Gras __LINE *wlp;
15351ffecc1SBen Gras
15451ffecc1SBen Gras #ifdef DEBUG
15551ffecc1SBen Gras __CTRACE(__CTRACE_LINE, "wtouchln: (%p) %d, %d, %d\n",
15651ffecc1SBen Gras win, line, n, changed);
15751ffecc1SBen Gras #endif
15851ffecc1SBen Gras if (line + n > win->maxy)
15951ffecc1SBen Gras line = win->maxy - n;
16051ffecc1SBen Gras for (y = line; y < line + n; y++) {
16151ffecc1SBen Gras if (changed == 1)
162*0a6a1f1dSLionel Sambuc _cursesi_touchline_force(win, y, 0,
163*0a6a1f1dSLionel Sambuc (int) win->maxx - 1, 1);
16451ffecc1SBen Gras else {
16551ffecc1SBen Gras wlp = win->alines[y];
16651ffecc1SBen Gras if (*wlp->firstchp >= win->ch_off &&
16751ffecc1SBen Gras *wlp->firstchp < win->maxx + win->ch_off)
16851ffecc1SBen Gras *wlp->firstchp = win->maxx + win->ch_off;
16951ffecc1SBen Gras if (*wlp->lastchp >= win->ch_off &&
17051ffecc1SBen Gras *wlp->lastchp < win->maxx + win->ch_off)
17151ffecc1SBen Gras *wlp->lastchp = win->ch_off;
172*0a6a1f1dSLionel Sambuc wlp->flags &= ~(__ISDIRTY | __ISFORCED);
17351ffecc1SBen Gras }
17451ffecc1SBen Gras }
17551ffecc1SBen Gras
17651ffecc1SBen Gras return OK;
17751ffecc1SBen Gras }
17851ffecc1SBen Gras
17951ffecc1SBen Gras int
__touchwin(WINDOW * win)18051ffecc1SBen Gras __touchwin(WINDOW *win)
18151ffecc1SBen Gras {
18251ffecc1SBen Gras int y, maxy;
18351ffecc1SBen Gras
18451ffecc1SBen Gras #ifdef DEBUG
18551ffecc1SBen Gras __CTRACE(__CTRACE_LINE, "__touchwin: (%p)\n", win);
18651ffecc1SBen Gras #endif
18751ffecc1SBen Gras maxy = win->maxy;
18851ffecc1SBen Gras for (y = 0; y < maxy; y++)
18951ffecc1SBen Gras __touchline(win, y, 0, (int) win->maxx - 1);
19051ffecc1SBen Gras return (OK);
19151ffecc1SBen Gras }
19251ffecc1SBen Gras
19351ffecc1SBen Gras int
__touchline(WINDOW * win,int y,int sx,int ex)19451ffecc1SBen Gras __touchline(WINDOW *win, int y, int sx, int ex)
19551ffecc1SBen Gras {
196*0a6a1f1dSLionel Sambuc return (_cursesi_touchline_force(win, y, sx, ex, 0));
197*0a6a1f1dSLionel Sambuc }
198*0a6a1f1dSLionel Sambuc
199*0a6a1f1dSLionel Sambuc /*
200*0a6a1f1dSLionel Sambuc * Touch line y on window win starting from column sx and ending at
201*0a6a1f1dSLionel Sambuc * column ex. If force is 1 then we mark this line as a forced update
202*0a6a1f1dSLionel Sambuc * which will bypass screen optimisation in the refresh code to rewrite
203*0a6a1f1dSLionel Sambuc * this line unconditionally (even if refresh thinks the screen matches
204*0a6a1f1dSLionel Sambuc * what is in the virtscr)
205*0a6a1f1dSLionel Sambuc */
206*0a6a1f1dSLionel Sambuc static int
_cursesi_touchline_force(WINDOW * win,int y,int sx,int ex,int force)207*0a6a1f1dSLionel Sambuc _cursesi_touchline_force(WINDOW *win, int y, int sx, int ex, int force)
208*0a6a1f1dSLionel Sambuc {
20951ffecc1SBen Gras #ifdef DEBUG
21051ffecc1SBen Gras __CTRACE(__CTRACE_LINE, "__touchline: (%p, %d, %d, %d)\n",
21151ffecc1SBen Gras win, y, sx, ex);
21251ffecc1SBen Gras __CTRACE(__CTRACE_LINE, "__touchline: first = %d, last = %d\n",
21351ffecc1SBen Gras *win->alines[y]->firstchp, *win->alines[y]->lastchp);
21451ffecc1SBen Gras #endif
21551ffecc1SBen Gras sx += win->ch_off;
21651ffecc1SBen Gras ex += win->ch_off;
21751ffecc1SBen Gras win->alines[y]->flags |= __ISDIRTY;
218*0a6a1f1dSLionel Sambuc if (force == 1)
219*0a6a1f1dSLionel Sambuc win->alines[y]->flags |= __ISFORCED;
22051ffecc1SBen Gras /* firstchp/lastchp are shared between parent window and sub-window. */
22151ffecc1SBen Gras if (*win->alines[y]->firstchp > sx)
22251ffecc1SBen Gras *win->alines[y]->firstchp = sx;
22351ffecc1SBen Gras if (*win->alines[y]->lastchp < ex)
22451ffecc1SBen Gras *win->alines[y]->lastchp = ex;
22551ffecc1SBen Gras #ifdef DEBUG
22651ffecc1SBen Gras __CTRACE(__CTRACE_LINE, "__touchline: first = %d, last = %d\n",
22751ffecc1SBen Gras *win->alines[y]->firstchp, *win->alines[y]->lastchp);
22851ffecc1SBen Gras #endif
22951ffecc1SBen Gras return (OK);
23051ffecc1SBen Gras }
23151ffecc1SBen Gras
23251ffecc1SBen Gras void
wsyncup(WINDOW * win)23351ffecc1SBen Gras wsyncup(WINDOW *win)
23451ffecc1SBen Gras {
23551ffecc1SBen Gras
23651ffecc1SBen Gras do {
237*0a6a1f1dSLionel Sambuc __touchwin(win);
23851ffecc1SBen Gras win = win->orig;
23951ffecc1SBen Gras } while (win);
24051ffecc1SBen Gras }
24151ffecc1SBen Gras
24251ffecc1SBen Gras void
wsyncdown(WINDOW * win)24351ffecc1SBen Gras wsyncdown(WINDOW *win)
24451ffecc1SBen Gras {
24551ffecc1SBen Gras WINDOW *w = win->orig;
24651ffecc1SBen Gras
24751ffecc1SBen Gras while (w) {
24851ffecc1SBen Gras if (is_wintouched(w)) {
249*0a6a1f1dSLionel Sambuc __touchwin(win);
25051ffecc1SBen Gras break;
25151ffecc1SBen Gras }
25251ffecc1SBen Gras w = w->orig;
25351ffecc1SBen Gras }
25451ffecc1SBen Gras }
255