xref: /freebsd/contrib/ncurses/ncurses/base/lib_overlay.c (revision aa59d4d4c5dda7e1c6f9dc0cc6edc58992a525c7)
10e3d5408SPeter Wemm /****************************************************************************
25ca44d1cSRong-En Fan  * Copyright (c) 1998-2006,2007 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 
43aa59d4d4SRong-En Fan MODULE_ID("$Id: lib_overlay.c,v 1.25 2008/04/12 17:21:59 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 
55aa59d4d4SRong-En Fan     T((T_CALLED("overlap(%p,%p,%d)"), src, dst, flag));
560e3d5408SPeter Wemm 
57aa59d4d4SRong-En Fan     if (src != 0 && dst != 0) {
58aa59d4d4SRong-En Fan 	_nc_lock_window(src);
59aa59d4d4SRong-En Fan 	_nc_lock_window(dst);
60aa59d4d4SRong-En Fan 
614a1a9510SRong-En Fan 	T(("src : begy %ld, begx %ld, maxy %ld, maxx %ld",
62aa59d4d4SRong-En Fan 	   (long) src->_begy,
63aa59d4d4SRong-En Fan 	   (long) src->_begx,
64aa59d4d4SRong-En Fan 	   (long) src->_maxy,
65aa59d4d4SRong-En Fan 	   (long) src->_maxx));
664a1a9510SRong-En Fan 	T(("dst : begy %ld, begx %ld, maxy %ld, maxx %ld",
67aa59d4d4SRong-En Fan 	   (long) dst->_begy,
68aa59d4d4SRong-En Fan 	   (long) dst->_begx,
69aa59d4d4SRong-En Fan 	   (long) dst->_maxy,
70aa59d4d4SRong-En Fan 	   (long) dst->_maxx));
710e3d5408SPeter Wemm 
72aa59d4d4SRong-En Fan 	sx1 = src->_begx;
73aa59d4d4SRong-En Fan 	sy1 = src->_begy;
74aa59d4d4SRong-En Fan 	sx2 = sx1 + src->_maxx;
75aa59d4d4SRong-En Fan 	sy2 = sy1 + src->_maxy;
760e3d5408SPeter Wemm 
77aa59d4d4SRong-En Fan 	dx1 = dst->_begx;
78aa59d4d4SRong-En Fan 	dy1 = dst->_begy;
79aa59d4d4SRong-En Fan 	dx2 = dx1 + dst->_maxx;
80aa59d4d4SRong-En Fan 	dy2 = dy1 + dst->_maxy;
814a1a9510SRong-En Fan 
82aa59d4d4SRong-En Fan 	if (dx2 >= sx1 && dx1 <= sx2 && dy2 >= sy1 && dy1 <= sy2) {
834a1a9510SRong-En Fan 	    sminrow = max(sy1, dy1) - sy1;
844a1a9510SRong-En Fan 	    smincol = max(sx1, dx1) - sx1;
854a1a9510SRong-En Fan 	    dminrow = max(sy1, dy1) - dy1;
864a1a9510SRong-En Fan 	    dmincol = max(sx1, dx1) - dx1;
874a1a9510SRong-En Fan 	    dmaxrow = min(sy2, dy2) - dy1;
884a1a9510SRong-En Fan 	    dmaxcol = min(sx2, dx2) - dx1;
894a1a9510SRong-En Fan 
90aa59d4d4SRong-En Fan 	    rc = copywin(src, dst,
914a1a9510SRong-En Fan 			 sminrow, smincol,
924a1a9510SRong-En Fan 			 dminrow, dmincol,
934a1a9510SRong-En Fan 			 dmaxrow, dmaxcol,
94aa59d4d4SRong-En Fan 			 flag);
950e3d5408SPeter Wemm 	}
96aa59d4d4SRong-En Fan 	_nc_unlock_window(dst);
97aa59d4d4SRong-En Fan 	_nc_unlock_window(src);
984a1a9510SRong-En Fan     }
99aa59d4d4SRong-En Fan     returnCode(rc);
1004a1a9510SRong-En Fan }
1010e3d5408SPeter Wemm 
1020e3d5408SPeter Wemm /*
1030e3d5408SPeter Wemm **
1040e3d5408SPeter Wemm **	overlay(win1, win2)
1050e3d5408SPeter Wemm **
1060e3d5408SPeter Wemm **
1070e3d5408SPeter Wemm **	overlay() writes the overlapping area of win1 behind win2
1080e3d5408SPeter Wemm **	on win2 non-destructively.
1090e3d5408SPeter Wemm **
1100e3d5408SPeter Wemm **/
1110e3d5408SPeter Wemm 
1127a69bbfbSPeter Wemm NCURSES_EXPORT(int)
1137a69bbfbSPeter Wemm overlay(const WINDOW *win1, WINDOW *win2)
1140e3d5408SPeter Wemm {
1150e3d5408SPeter Wemm     T((T_CALLED("overlay(%p,%p)"), win1, win2));
1160e3d5408SPeter Wemm     returnCode(overlap(win1, win2, TRUE));
1170e3d5408SPeter Wemm }
1180e3d5408SPeter Wemm 
1190e3d5408SPeter Wemm /*
1200e3d5408SPeter Wemm **
1210e3d5408SPeter Wemm **	overwrite(win1, win2)
1220e3d5408SPeter Wemm **
1230e3d5408SPeter Wemm **
1240e3d5408SPeter Wemm **	overwrite() writes the overlapping area of win1 behind win2
1250e3d5408SPeter Wemm **	on win2 destructively.
1260e3d5408SPeter Wemm **
1270e3d5408SPeter Wemm **/
1280e3d5408SPeter Wemm 
1297a69bbfbSPeter Wemm NCURSES_EXPORT(int)
1307a69bbfbSPeter Wemm overwrite(const WINDOW *win1, WINDOW *win2)
1310e3d5408SPeter Wemm {
1320e3d5408SPeter Wemm     T((T_CALLED("overwrite(%p,%p)"), win1, win2));
1330e3d5408SPeter Wemm     returnCode(overlap(win1, win2, FALSE));
1340e3d5408SPeter Wemm }
1350e3d5408SPeter Wemm 
1367a69bbfbSPeter Wemm NCURSES_EXPORT(int)
1374a1a9510SRong-En Fan copywin(const WINDOW *src, WINDOW *dst,
1380e3d5408SPeter Wemm 	int sminrow, int smincol,
1394a1a9510SRong-En Fan 	int dminrow, int dmincol,
1404a1a9510SRong-En Fan 	int dmaxrow, int dmaxcol,
1410e3d5408SPeter Wemm 	int over)
1420e3d5408SPeter Wemm {
143aa59d4d4SRong-En Fan     int rc = ERR;
1440e3d5408SPeter Wemm     int sx, sy, dx, dy;
1450e3d5408SPeter Wemm     bool touched;
1465ca44d1cSRong-En Fan     attr_t bk;
1475ca44d1cSRong-En Fan     attr_t mask;
1480e3d5408SPeter Wemm 
1490e3d5408SPeter Wemm     T((T_CALLED("copywin(%p, %p, %d, %d, %d, %d, %d, %d, %d)"),
1500e3d5408SPeter Wemm        src, dst, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, over));
1510e3d5408SPeter Wemm 
152aa59d4d4SRong-En Fan     if (src && dst) {
153aa59d4d4SRong-En Fan 
154aa59d4d4SRong-En Fan 	_nc_lock_window(src);
155aa59d4d4SRong-En Fan 	_nc_lock_window(dst);
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 	}
207aa59d4d4SRong-En Fan 	_nc_unlock_window(dst);
208aa59d4d4SRong-En Fan 	_nc_unlock_window(src);
209aa59d4d4SRong-En Fan     }
210aa59d4d4SRong-En Fan     returnCode(rc);
2110e3d5408SPeter Wemm }
212