xref: /openbsd-src/lib/libcurses/base/lib_overlay.c (revision 62a742911104f98b9185b2c6b6007d9b1c36396c)
1 /*	$OpenBSD: lib_overlay.c,v 1.1 1999/01/18 19:09:55 millert Exp $	*/
2 
3 /****************************************************************************
4  * Copyright (c) 1998 Free Software Foundation, Inc.                        *
5  *                                                                          *
6  * Permission is hereby granted, free of charge, to any person obtaining a  *
7  * copy of this software and associated documentation files (the            *
8  * "Software"), to deal in the Software without restriction, including      *
9  * without limitation the rights to use, copy, modify, merge, publish,      *
10  * distribute, distribute with modifications, sublicense, and/or sell       *
11  * copies of the Software, and to permit persons to whom the Software is    *
12  * furnished to do so, subject to the following conditions:                 *
13  *                                                                          *
14  * The above copyright notice and this permission notice shall be included  *
15  * in all copies or substantial portions of the Software.                   *
16  *                                                                          *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
20  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
23  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
24  *                                                                          *
25  * Except as contained in this notice, the name(s) of the above copyright   *
26  * holders shall not be used in advertising or otherwise to promote the     *
27  * sale, use or other dealings in this Software without prior written       *
28  * authorization.                                                           *
29  ****************************************************************************/
30 
31 /****************************************************************************
32  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
33  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
34  ****************************************************************************/
35 
36 
37 /*
38 **	lib_overlay.c
39 **
40 **	The routines overlay(), copywin(), and overwrite().
41 **
42 */
43 
44 #include <curses.priv.h>
45 
46 MODULE_ID("$From: lib_overlay.c,v 1.12 1998/02/11 12:13:59 tom Exp $")
47 
48 static int overlap(const WINDOW *const s, WINDOW *const d, int const flag)
49 {
50 int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol;
51 
52 	T(("overlap : sby %d, sbx %d, smy %d, smx %d, dby %d, dbx %d, dmy %d, dmx %d",
53 		s->_begy, s->_begx, s->_maxy, s->_maxx,
54 		d->_begy, d->_begx, d->_maxy, d->_maxx));
55 
56 	if (!s || !d)
57 		returnCode(ERR);
58 
59 	sminrow = max(s->_begy, d->_begy) - s->_begy;
60 	smincol = max(s->_begx, d->_begx) - s->_begx;
61 	dminrow = max(s->_begy, d->_begy) - d->_begy;
62 	dmincol = max(s->_begx, d->_begx) - d->_begx;
63 	dmaxrow = min(s->_maxy+s->_begy, d->_maxy+d->_begy) - d->_begy;
64 	dmaxcol = min(s->_maxx+s->_begx, d->_maxx+d->_begx) - d->_begx;
65 
66 	return(copywin(s, d,
67 		       sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol,
68 		       flag));
69 }
70 
71 /*
72 **
73 **	overlay(win1, win2)
74 **
75 **
76 **	overlay() writes the overlapping area of win1 behind win2
77 **	on win2 non-destructively.
78 **
79 **/
80 
81 int overlay(const WINDOW *win1, WINDOW *win2)
82 {
83 	T((T_CALLED("overlay(%p,%p)"), win1, win2));
84 	returnCode(overlap(win1, win2, TRUE));
85 }
86 
87 /*
88 **
89 **	overwrite(win1, win2)
90 **
91 **
92 **	overwrite() writes the overlapping area of win1 behind win2
93 **	on win2 destructively.
94 **
95 **/
96 
97 int overwrite(const WINDOW *win1, WINDOW *win2)
98 {
99 	T((T_CALLED("overwrite(%p,%p)"), win1, win2));
100 	returnCode(overlap(win1, win2, FALSE));
101 }
102 
103 int copywin(const WINDOW *src, WINDOW *dst,
104 	int sminrow, int smincol,
105 	int dminrow, int dmincol, int dmaxrow, int dmaxcol,
106 	int over)
107 {
108 int sx, sy, dx, dy;
109 bool touched;
110 chtype bk = AttrOf(dst->_bkgd);
111 chtype mask = ~(chtype)((bk&A_COLOR) ? A_COLOR : 0);
112 
113 	T((T_CALLED("copywin(%p, %p, %d, %d, %d, %d, %d, %d, %d)"),
114 		src, dst, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, over));
115 
116 	if (!src || !dst)
117 	  returnCode(ERR);
118 
119 	/* make sure rectangle exists in source */
120 	if ((sminrow + dmaxrow - dminrow) > (src->_maxy + 1) ||
121 	    (smincol + dmaxcol - dmincol) > (src->_maxx + 1)) {
122 		returnCode(ERR);
123 	}
124 
125 	T(("rectangle exists in source"));
126 
127 	/* make sure rectangle fits in destination */
128 	if (dmaxrow > dst->_maxy || dmaxcol > dst->_maxx) {
129 		returnCode(ERR);
130 	}
131 
132 	T(("rectangle fits in destination"));
133 
134 	for (dy = dminrow, sy = sminrow; dy <= dmaxrow; sy++, dy++) {
135 	   touched = FALSE;
136 	   for(dx=dmincol, sx=smincol; dx <= dmaxcol; sx++, dx++)
137 	   {
138 		if (over)
139 		{
140 		   if ((TextOf(src->_line[sy].text[sx]) != ' ') &&
141                        (dst->_line[dy].text[dx]!=src->_line[sy].text[sx]))
142 		   {
143 			dst->_line[dy].text[dx] =
144 					(src->_line[sy].text[sx] & mask) | bk;
145 			touched = TRUE;
146 		   }
147 	        }
148 		else {
149 		   if (dst->_line[dy].text[dx] != src->_line[sy].text[sx])
150 		   {
151 			dst->_line[dy].text[dx] = src->_line[sy].text[sx];
152 			touched = TRUE;
153                    }
154                 }
155            }
156 	   if (touched)
157 	   {
158 	      touchline(dst,0,getmaxy(dst));
159 	   }
160 	}
161 	T(("finished copywin"));
162 	returnCode(OK);
163 }
164