xref: /minix3/lib/libcurses/touchwin.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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