xref: /freebsd/contrib/ncurses/ncurses/base/lib_overlay.c (revision 06bfebdedb0d353f1771adb65731f64461d9bd01)
10e3d5408SPeter Wemm /****************************************************************************
2*06bfebdeSXin LI  * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc.              *
30e3d5408SPeter Wemm  *                                                                          *
40e3d5408SPeter Wemm  * Permission is hereby granted, free of charge, to any person obtaining a  *
50e3d5408SPeter Wemm  * copy of this software and associated documentation files (the            *
60e3d5408SPeter Wemm  * "Software"), to deal in the Software without restriction, including      *
70e3d5408SPeter Wemm  * without limitation the rights to use, copy, modify, merge, publish,      *
80e3d5408SPeter Wemm  * distribute, distribute with modifications, sublicense, and/or sell       *
90e3d5408SPeter Wemm  * copies of the Software, and to permit persons to whom the Software is    *
100e3d5408SPeter Wemm  * furnished to do so, subject to the following conditions:                 *
110e3d5408SPeter Wemm  *                                                                          *
120e3d5408SPeter Wemm  * The above copyright notice and this permission notice shall be included  *
130e3d5408SPeter Wemm  * in all copies or substantial portions of the Software.                   *
140e3d5408SPeter Wemm  *                                                                          *
150e3d5408SPeter Wemm  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
160e3d5408SPeter Wemm  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
170e3d5408SPeter Wemm  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
180e3d5408SPeter Wemm  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
190e3d5408SPeter Wemm  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
200e3d5408SPeter Wemm  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
210e3d5408SPeter Wemm  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
220e3d5408SPeter Wemm  *                                                                          *
230e3d5408SPeter Wemm  * Except as contained in this notice, the name(s) of the above copyright   *
240e3d5408SPeter Wemm  * holders shall not be used in advertising or otherwise to promote the     *
250e3d5408SPeter Wemm  * sale, use or other dealings in this Software without prior written       *
260e3d5408SPeter Wemm  * authorization.                                                           *
270e3d5408SPeter Wemm  ****************************************************************************/
280e3d5408SPeter Wemm 
290e3d5408SPeter Wemm /****************************************************************************
300e3d5408SPeter Wemm  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
310e3d5408SPeter Wemm  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
320e3d5408SPeter Wemm  ****************************************************************************/
330e3d5408SPeter Wemm 
340e3d5408SPeter Wemm /*
350e3d5408SPeter Wemm **	lib_overlay.c
360e3d5408SPeter Wemm **
370e3d5408SPeter Wemm **	The routines overlay(), copywin(), and overwrite().
380e3d5408SPeter Wemm **
390e3d5408SPeter Wemm */
400e3d5408SPeter Wemm 
410e3d5408SPeter Wemm #include <curses.priv.h>
420e3d5408SPeter Wemm 
43*06bfebdeSXin LI MODULE_ID("$Id: lib_overlay.c,v 1.29 2009/10/24 23:21:31 tom Exp $")
440e3d5408SPeter Wemm 
457a69bbfbSPeter Wemm static int
46aa59d4d4SRong-En Fan overlap(const WINDOW *const src, WINDOW *const dst, int const flag)
470e3d5408SPeter Wemm {
48aa59d4d4SRong-En Fan     int rc = ERR;
494a1a9510SRong-En Fan     int sx1, sy1, sx2, sy2;
504a1a9510SRong-En Fan     int dx1, dy1, dx2, dy2;
514a1a9510SRong-En Fan     int sminrow, smincol;
524a1a9510SRong-En Fan     int dminrow, dmincol;
534a1a9510SRong-En Fan     int dmaxrow, dmaxcol;
540e3d5408SPeter Wemm 
55*06bfebdeSXin LI     T((T_CALLED("overlap(%p,%p,%d)"), (const void *) src, (void *) dst, flag));
560e3d5408SPeter Wemm 
57aa59d4d4SRong-En Fan     if (src != 0 && dst != 0) {
585d08fb1fSRong-En Fan 	_nc_lock_global(curses);
59aa59d4d4SRong-En Fan 
604a1a9510SRong-En Fan 	T(("src : begy %ld, begx %ld, maxy %ld, maxx %ld",
61aa59d4d4SRong-En Fan 	   (long) src->_begy,
62aa59d4d4SRong-En Fan 	   (long) src->_begx,
63aa59d4d4SRong-En Fan 	   (long) src->_maxy,
64aa59d4d4SRong-En Fan 	   (long) src->_maxx));
654a1a9510SRong-En Fan 	T(("dst : begy %ld, begx %ld, maxy %ld, maxx %ld",
66aa59d4d4SRong-En Fan 	   (long) dst->_begy,
67aa59d4d4SRong-En Fan 	   (long) dst->_begx,
68aa59d4d4SRong-En Fan 	   (long) dst->_maxy,
69aa59d4d4SRong-En Fan 	   (long) dst->_maxx));
700e3d5408SPeter Wemm 
71aa59d4d4SRong-En Fan 	sx1 = src->_begx;
72aa59d4d4SRong-En Fan 	sy1 = src->_begy;
73aa59d4d4SRong-En Fan 	sx2 = sx1 + src->_maxx;
74aa59d4d4SRong-En Fan 	sy2 = sy1 + src->_maxy;
750e3d5408SPeter Wemm 
76aa59d4d4SRong-En Fan 	dx1 = dst->_begx;
77aa59d4d4SRong-En Fan 	dy1 = dst->_begy;
78aa59d4d4SRong-En Fan 	dx2 = dx1 + dst->_maxx;
79aa59d4d4SRong-En Fan 	dy2 = dy1 + dst->_maxy;
804a1a9510SRong-En Fan 
81aa59d4d4SRong-En Fan 	if (dx2 >= sx1 && dx1 <= sx2 && dy2 >= sy1 && dy1 <= sy2) {
824a1a9510SRong-En Fan 	    sminrow = max(sy1, dy1) - sy1;
834a1a9510SRong-En Fan 	    smincol = max(sx1, dx1) - sx1;
844a1a9510SRong-En Fan 	    dminrow = max(sy1, dy1) - dy1;
854a1a9510SRong-En Fan 	    dmincol = max(sx1, dx1) - dx1;
864a1a9510SRong-En Fan 	    dmaxrow = min(sy2, dy2) - dy1;
874a1a9510SRong-En Fan 	    dmaxcol = min(sx2, dx2) - dx1;
884a1a9510SRong-En Fan 
89aa59d4d4SRong-En Fan 	    rc = copywin(src, dst,
904a1a9510SRong-En Fan 			 sminrow, smincol,
914a1a9510SRong-En Fan 			 dminrow, dmincol,
924a1a9510SRong-En Fan 			 dmaxrow, dmaxcol,
93aa59d4d4SRong-En Fan 			 flag);
940e3d5408SPeter Wemm 	}
955d08fb1fSRong-En Fan 	_nc_unlock_global(curses);
964a1a9510SRong-En Fan     }
97aa59d4d4SRong-En Fan     returnCode(rc);
984a1a9510SRong-En Fan }
990e3d5408SPeter Wemm 
1000e3d5408SPeter Wemm /*
1010e3d5408SPeter Wemm **
1020e3d5408SPeter Wemm **	overlay(win1, win2)
1030e3d5408SPeter Wemm **
1040e3d5408SPeter Wemm **
1050e3d5408SPeter Wemm **	overlay() writes the overlapping area of win1 behind win2
1060e3d5408SPeter Wemm **	on win2 non-destructively.
1070e3d5408SPeter Wemm **
1080e3d5408SPeter Wemm **/
1090e3d5408SPeter Wemm 
1107a69bbfbSPeter Wemm NCURSES_EXPORT(int)
1117a69bbfbSPeter Wemm overlay(const WINDOW *win1, WINDOW *win2)
1120e3d5408SPeter Wemm {
113*06bfebdeSXin LI     T((T_CALLED("overlay(%p,%p)"), (const void *) win1, (void *) win2));
1140e3d5408SPeter Wemm     returnCode(overlap(win1, win2, TRUE));
1150e3d5408SPeter Wemm }
1160e3d5408SPeter Wemm 
1170e3d5408SPeter Wemm /*
1180e3d5408SPeter Wemm **
1190e3d5408SPeter Wemm **	overwrite(win1, win2)
1200e3d5408SPeter Wemm **
1210e3d5408SPeter Wemm **
1220e3d5408SPeter Wemm **	overwrite() writes the overlapping area of win1 behind win2
1230e3d5408SPeter Wemm **	on win2 destructively.
1240e3d5408SPeter Wemm **
1250e3d5408SPeter Wemm **/
1260e3d5408SPeter Wemm 
1277a69bbfbSPeter Wemm NCURSES_EXPORT(int)
1287a69bbfbSPeter Wemm overwrite(const WINDOW *win1, WINDOW *win2)
1290e3d5408SPeter Wemm {
130*06bfebdeSXin LI     T((T_CALLED("overwrite(%p,%p)"), (const void *) win1, (void *) win2));
1310e3d5408SPeter Wemm     returnCode(overlap(win1, win2, FALSE));
1320e3d5408SPeter Wemm }
1330e3d5408SPeter Wemm 
1347a69bbfbSPeter Wemm NCURSES_EXPORT(int)
1354a1a9510SRong-En Fan copywin(const WINDOW *src, WINDOW *dst,
1360e3d5408SPeter Wemm 	int sminrow, int smincol,
1374a1a9510SRong-En Fan 	int dminrow, int dmincol,
1384a1a9510SRong-En Fan 	int dmaxrow, int dmaxcol,
1390e3d5408SPeter Wemm 	int over)
1400e3d5408SPeter Wemm {
141aa59d4d4SRong-En Fan     int rc = ERR;
1420e3d5408SPeter Wemm     int sx, sy, dx, dy;
1430e3d5408SPeter Wemm     bool touched;
1445ca44d1cSRong-En Fan     attr_t bk;
1455ca44d1cSRong-En Fan     attr_t mask;
1460e3d5408SPeter Wemm 
1470e3d5408SPeter Wemm     T((T_CALLED("copywin(%p, %p, %d, %d, %d, %d, %d, %d, %d)"),
148*06bfebdeSXin LI        (const void *) src,
149*06bfebdeSXin LI        (void *) dst,
150*06bfebdeSXin LI        sminrow, smincol,
151*06bfebdeSXin LI        dminrow, dmincol,
152*06bfebdeSXin LI        dmaxrow, dmaxcol, over));
1530e3d5408SPeter Wemm 
154aa59d4d4SRong-En Fan     if (src && dst) {
1555d08fb1fSRong-En Fan 	_nc_lock_global(curses);
1560e3d5408SPeter Wemm 
1575ca44d1cSRong-En Fan 	bk = AttrOf(dst->_nc_bkgd);
1585ca44d1cSRong-En Fan 	mask = ~(attr_t) ((bk & A_COLOR) ? A_COLOR : 0);
1595ca44d1cSRong-En Fan 
1600e3d5408SPeter Wemm 	/* make sure rectangle exists in source */
161aa59d4d4SRong-En Fan 	if ((sminrow + dmaxrow - dminrow) <= (src->_maxy + 1) &&
162aa59d4d4SRong-En Fan 	    (smincol + dmaxcol - dmincol) <= (src->_maxx + 1)) {
1630e3d5408SPeter Wemm 
1640e3d5408SPeter Wemm 	    T(("rectangle exists in source"));
1650e3d5408SPeter Wemm 
1660e3d5408SPeter Wemm 	    /* make sure rectangle fits in destination */
167aa59d4d4SRong-En Fan 	    if (dmaxrow <= dst->_maxy && dmaxcol <= dst->_maxx) {
1680e3d5408SPeter Wemm 
1690e3d5408SPeter Wemm 		T(("rectangle fits in destination"));
1700e3d5408SPeter Wemm 
171aa59d4d4SRong-En Fan 		for (dy = dminrow, sy = sminrow;
172aa59d4d4SRong-En Fan 		     dy <= dmaxrow;
173aa59d4d4SRong-En Fan 		     sy++, dy++) {
174aa59d4d4SRong-En Fan 
1750e3d5408SPeter Wemm 		    touched = FALSE;
176aa59d4d4SRong-En Fan 		    for (dx = dmincol, sx = smincol;
177aa59d4d4SRong-En Fan 			 dx <= dmaxcol;
178aa59d4d4SRong-En Fan 			 sx++, dx++) {
1797a69bbfbSPeter Wemm 			if (over) {
18039f2269fSPeter Wemm 			    if ((CharOf(src->_line[sy].text[sx]) != L(' ')) &&
181aa59d4d4SRong-En Fan 				(!CharEq(dst->_line[dy].text[dx],
182aa59d4d4SRong-En Fan 					 src->_line[sy].text[sx]))) {
183aa59d4d4SRong-En Fan 				dst->_line[dy].text[dx] =
184aa59d4d4SRong-En Fan 				    src->_line[sy].text[sx];
18539f2269fSPeter Wemm 				SetAttr(dst->_line[dy].text[dx],
186aa59d4d4SRong-En Fan 					((AttrOf(src->_line[sy].text[sx]) &
187aa59d4d4SRong-En Fan 					  mask) | bk));
1880e3d5408SPeter Wemm 				touched = TRUE;
1890e3d5408SPeter Wemm 			    }
1907a69bbfbSPeter Wemm 			} else {
191aa59d4d4SRong-En Fan 			    if (!CharEq(dst->_line[dy].text[dx],
192aa59d4d4SRong-En Fan 					src->_line[sy].text[sx])) {
193aa59d4d4SRong-En Fan 				dst->_line[dy].text[dx] =
194aa59d4d4SRong-En Fan 				    src->_line[sy].text[sx];
1950e3d5408SPeter Wemm 				touched = TRUE;
1960e3d5408SPeter Wemm 			    }
1970e3d5408SPeter Wemm 			}
1980e3d5408SPeter Wemm 		    }
1997a69bbfbSPeter Wemm 		    if (touched) {
2004a1a9510SRong-En Fan 			touchline(dst, dminrow, (dmaxrow - dminrow + 1));
2010e3d5408SPeter Wemm 		    }
2020e3d5408SPeter Wemm 		}
2030e3d5408SPeter Wemm 		T(("finished copywin"));
204aa59d4d4SRong-En Fan 		rc = OK;
205aa59d4d4SRong-En Fan 	    }
206aa59d4d4SRong-En Fan 	}
2075d08fb1fSRong-En Fan 	_nc_unlock_global(curses);
208aa59d4d4SRong-En Fan     }
209aa59d4d4SRong-En Fan     returnCode(rc);
2100e3d5408SPeter Wemm }
211