10e3d5408SPeter Wemm /****************************************************************************
2*21817992SBaptiste Daroussin * Copyright 2020,2023 Thomas E. Dickey *
3e1865124SBaptiste Daroussin * Copyright 1998-2013,2016 Free Software Foundation, Inc. *
40e3d5408SPeter Wemm * *
50e3d5408SPeter Wemm * Permission is hereby granted, free of charge, to any person obtaining a *
60e3d5408SPeter Wemm * copy of this software and associated documentation files (the *
70e3d5408SPeter Wemm * "Software"), to deal in the Software without restriction, including *
80e3d5408SPeter Wemm * without limitation the rights to use, copy, modify, merge, publish, *
90e3d5408SPeter Wemm * distribute, distribute with modifications, sublicense, and/or sell *
100e3d5408SPeter Wemm * copies of the Software, and to permit persons to whom the Software is *
110e3d5408SPeter Wemm * furnished to do so, subject to the following conditions: *
120e3d5408SPeter Wemm * *
130e3d5408SPeter Wemm * The above copyright notice and this permission notice shall be included *
140e3d5408SPeter Wemm * in all copies or substantial portions of the Software. *
150e3d5408SPeter Wemm * *
160e3d5408SPeter Wemm * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
170e3d5408SPeter Wemm * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
180e3d5408SPeter Wemm * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
190e3d5408SPeter Wemm * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
200e3d5408SPeter Wemm * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
210e3d5408SPeter Wemm * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
220e3d5408SPeter Wemm * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
230e3d5408SPeter Wemm * *
240e3d5408SPeter Wemm * Except as contained in this notice, the name(s) of the above copyright *
250e3d5408SPeter Wemm * holders shall not be used in advertising or otherwise to promote the *
260e3d5408SPeter Wemm * sale, use or other dealings in this Software without prior written *
270e3d5408SPeter Wemm * authorization. *
280e3d5408SPeter Wemm ****************************************************************************/
290e3d5408SPeter Wemm
300e3d5408SPeter Wemm /****************************************************************************
310e3d5408SPeter Wemm * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
320e3d5408SPeter Wemm * and: Eric S. Raymond <esr@snark.thyrsus.com> *
330e3d5408SPeter Wemm ****************************************************************************/
340e3d5408SPeter Wemm
350e3d5408SPeter Wemm /*
360e3d5408SPeter Wemm ** lib_overlay.c
370e3d5408SPeter Wemm **
380e3d5408SPeter Wemm ** The routines overlay(), copywin(), and overwrite().
390e3d5408SPeter Wemm **
400e3d5408SPeter Wemm */
410e3d5408SPeter Wemm
420e3d5408SPeter Wemm #include <curses.priv.h>
430e3d5408SPeter Wemm
44*21817992SBaptiste Daroussin MODULE_ID("$Id: lib_overlay.c,v 1.34 2023/09/16 16:39:07 tom Exp $")
450e3d5408SPeter Wemm
467a69bbfbSPeter Wemm static int
overlap(const WINDOW * const src,WINDOW * const dst,int const flag)47aa59d4d4SRong-En Fan overlap(const WINDOW *const src, WINDOW *const dst, int const flag)
480e3d5408SPeter Wemm {
49aa59d4d4SRong-En Fan int rc = ERR;
500e3d5408SPeter Wemm
5106bfebdeSXin LI T((T_CALLED("overlap(%p,%p,%d)"), (const void *) src, (void *) dst, flag));
520e3d5408SPeter Wemm
53aa59d4d4SRong-En Fan if (src != 0 && dst != 0) {
54aae38d10SBaptiste Daroussin int sx1, sy1, sx2, sy2;
55aae38d10SBaptiste Daroussin int dx1, dy1, dx2, dy2;
56aae38d10SBaptiste Daroussin
575d08fb1fSRong-En Fan _nc_lock_global(curses);
58aa59d4d4SRong-En Fan
594a1a9510SRong-En Fan T(("src : begy %ld, begx %ld, maxy %ld, maxx %ld",
60aa59d4d4SRong-En Fan (long) src->_begy,
61aa59d4d4SRong-En Fan (long) src->_begx,
62aa59d4d4SRong-En Fan (long) src->_maxy,
63aa59d4d4SRong-En Fan (long) src->_maxx));
644a1a9510SRong-En Fan T(("dst : begy %ld, begx %ld, maxy %ld, maxx %ld",
65aa59d4d4SRong-En Fan (long) dst->_begy,
66aa59d4d4SRong-En Fan (long) dst->_begx,
67aa59d4d4SRong-En Fan (long) dst->_maxy,
68aa59d4d4SRong-En Fan (long) dst->_maxx));
690e3d5408SPeter Wemm
70aa59d4d4SRong-En Fan sx1 = src->_begx;
71aa59d4d4SRong-En Fan sy1 = src->_begy;
72aa59d4d4SRong-En Fan sx2 = sx1 + src->_maxx;
73aa59d4d4SRong-En Fan sy2 = sy1 + src->_maxy;
740e3d5408SPeter Wemm
75aa59d4d4SRong-En Fan dx1 = dst->_begx;
76aa59d4d4SRong-En Fan dy1 = dst->_begy;
77aa59d4d4SRong-En Fan dx2 = dx1 + dst->_maxx;
78aa59d4d4SRong-En Fan dy2 = dy1 + dst->_maxy;
794a1a9510SRong-En Fan
80aa59d4d4SRong-En Fan if (dx2 >= sx1 && dx1 <= sx2 && dy2 >= sy1 && dy1 <= sy2) {
81*21817992SBaptiste Daroussin int sminrow = Max(sy1, dy1) - sy1;
82*21817992SBaptiste Daroussin int smincol = Max(sx1, dx1) - sx1;
83*21817992SBaptiste Daroussin int dminrow = Max(sy1, dy1) - dy1;
84*21817992SBaptiste Daroussin int dmincol = Max(sx1, dx1) - dx1;
85*21817992SBaptiste Daroussin int dmaxrow = Min(sy2, dy2) - dy1;
86*21817992SBaptiste Daroussin int dmaxcol = Min(sx2, dx2) - dx1;
874a1a9510SRong-En Fan
88aa59d4d4SRong-En Fan rc = copywin(src, dst,
894a1a9510SRong-En Fan sminrow, smincol,
904a1a9510SRong-En Fan dminrow, dmincol,
914a1a9510SRong-En Fan dmaxrow, dmaxcol,
92aa59d4d4SRong-En Fan flag);
930e3d5408SPeter Wemm }
945d08fb1fSRong-En Fan _nc_unlock_global(curses);
954a1a9510SRong-En Fan }
96aa59d4d4SRong-En Fan returnCode(rc);
974a1a9510SRong-En Fan }
980e3d5408SPeter Wemm
990e3d5408SPeter Wemm /*
1000e3d5408SPeter Wemm **
1010e3d5408SPeter Wemm ** overlay(win1, win2)
1020e3d5408SPeter Wemm **
1030e3d5408SPeter Wemm **
1040e3d5408SPeter Wemm ** overlay() writes the overlapping area of win1 behind win2
1050e3d5408SPeter Wemm ** on win2 non-destructively.
1060e3d5408SPeter Wemm **
1070e3d5408SPeter Wemm **/
1080e3d5408SPeter Wemm
1097a69bbfbSPeter Wemm NCURSES_EXPORT(int)
overlay(const WINDOW * win1,WINDOW * win2)1107a69bbfbSPeter Wemm overlay(const WINDOW *win1, WINDOW *win2)
1110e3d5408SPeter Wemm {
11206bfebdeSXin LI T((T_CALLED("overlay(%p,%p)"), (const void *) win1, (void *) win2));
1130e3d5408SPeter Wemm returnCode(overlap(win1, win2, TRUE));
1140e3d5408SPeter Wemm }
1150e3d5408SPeter Wemm
1160e3d5408SPeter Wemm /*
1170e3d5408SPeter Wemm **
1180e3d5408SPeter Wemm ** overwrite(win1, win2)
1190e3d5408SPeter Wemm **
1200e3d5408SPeter Wemm **
1210e3d5408SPeter Wemm ** overwrite() writes the overlapping area of win1 behind win2
1220e3d5408SPeter Wemm ** on win2 destructively.
1230e3d5408SPeter Wemm **
1240e3d5408SPeter Wemm **/
1250e3d5408SPeter Wemm
1267a69bbfbSPeter Wemm NCURSES_EXPORT(int)
overwrite(const WINDOW * win1,WINDOW * win2)1277a69bbfbSPeter Wemm overwrite(const WINDOW *win1, WINDOW *win2)
1280e3d5408SPeter Wemm {
12906bfebdeSXin LI T((T_CALLED("overwrite(%p,%p)"), (const void *) win1, (void *) win2));
1300e3d5408SPeter Wemm returnCode(overlap(win1, win2, FALSE));
1310e3d5408SPeter Wemm }
1320e3d5408SPeter Wemm
1337a69bbfbSPeter Wemm NCURSES_EXPORT(int)
copywin(const WINDOW * src,WINDOW * dst,int sminrow,int smincol,int dminrow,int dmincol,int dmaxrow,int dmaxcol,int over)1344a1a9510SRong-En Fan copywin(const WINDOW *src, WINDOW *dst,
1350e3d5408SPeter Wemm int sminrow, int smincol,
1364a1a9510SRong-En Fan int dminrow, int dmincol,
1374a1a9510SRong-En Fan int dmaxrow, int dmaxcol,
1380e3d5408SPeter Wemm int over)
1390e3d5408SPeter Wemm {
140aa59d4d4SRong-En Fan int rc = ERR;
1410e3d5408SPeter Wemm
1420e3d5408SPeter Wemm T((T_CALLED("copywin(%p, %p, %d, %d, %d, %d, %d, %d, %d)"),
14306bfebdeSXin LI (const void *) src,
14406bfebdeSXin LI (void *) dst,
14506bfebdeSXin LI sminrow, smincol,
14606bfebdeSXin LI dminrow, dmincol,
14706bfebdeSXin LI dmaxrow, dmaxcol, over));
1480e3d5408SPeter Wemm
14973f0a83dSXin LI if (src != 0
15073f0a83dSXin LI && dst != 0
15173f0a83dSXin LI && dmaxrow >= dminrow
15273f0a83dSXin LI && dmaxcol >= dmincol) {
153aae38d10SBaptiste Daroussin attr_t bk;
154aae38d10SBaptiste Daroussin attr_t mask;
155aae38d10SBaptiste Daroussin
1565d08fb1fSRong-En Fan _nc_lock_global(curses);
1570e3d5408SPeter Wemm
1585ca44d1cSRong-En Fan bk = AttrOf(dst->_nc_bkgd);
1595ca44d1cSRong-En Fan mask = ~(attr_t) ((bk & A_COLOR) ? A_COLOR : 0);
1605ca44d1cSRong-En Fan
1610e3d5408SPeter Wemm /* make sure rectangle exists in source */
162aa59d4d4SRong-En Fan if ((sminrow + dmaxrow - dminrow) <= (src->_maxy + 1) &&
163aa59d4d4SRong-En Fan (smincol + dmaxcol - dmincol) <= (src->_maxx + 1)) {
1640e3d5408SPeter Wemm
1650e3d5408SPeter Wemm T(("rectangle exists in source"));
1660e3d5408SPeter Wemm
1670e3d5408SPeter Wemm /* make sure rectangle fits in destination */
168aa59d4d4SRong-En Fan if (dmaxrow <= dst->_maxy && dmaxcol <= dst->_maxx) {
169aae38d10SBaptiste Daroussin int sx, sy, dx, dy;
170aae38d10SBaptiste Daroussin bool copied = FALSE;
1710e3d5408SPeter Wemm
1720e3d5408SPeter Wemm T(("rectangle fits in destination"));
1730e3d5408SPeter Wemm
174aa59d4d4SRong-En Fan for (dy = dminrow, sy = sminrow;
175aa59d4d4SRong-En Fan dy <= dmaxrow;
176aa59d4d4SRong-En Fan sy++, dy++) {
177aae38d10SBaptiste Daroussin bool touched;
178aa59d4d4SRong-En Fan
17973f0a83dSXin LI if (dy < 0 || sy < 0)
18073f0a83dSXin LI continue;
18173f0a83dSXin LI
1820e3d5408SPeter Wemm touched = FALSE;
183aa59d4d4SRong-En Fan for (dx = dmincol, sx = smincol;
184aa59d4d4SRong-En Fan dx <= dmaxcol;
185aa59d4d4SRong-En Fan sx++, dx++) {
18673f0a83dSXin LI
18773f0a83dSXin LI if (dx < 0 || sx < 0)
18873f0a83dSXin LI continue;
18973f0a83dSXin LI copied = TRUE;
19073f0a83dSXin LI
1917a69bbfbSPeter Wemm if (over) {
19239f2269fSPeter Wemm if ((CharOf(src->_line[sy].text[sx]) != L(' ')) &&
193aa59d4d4SRong-En Fan (!CharEq(dst->_line[dy].text[dx],
194aa59d4d4SRong-En Fan src->_line[sy].text[sx]))) {
195aa59d4d4SRong-En Fan dst->_line[dy].text[dx] =
196aa59d4d4SRong-En Fan src->_line[sy].text[sx];
19739f2269fSPeter Wemm SetAttr(dst->_line[dy].text[dx],
198aa59d4d4SRong-En Fan ((AttrOf(src->_line[sy].text[sx]) &
199aa59d4d4SRong-En Fan mask) | bk));
2000e3d5408SPeter Wemm touched = TRUE;
2010e3d5408SPeter Wemm }
2027a69bbfbSPeter Wemm } else {
203aa59d4d4SRong-En Fan if (!CharEq(dst->_line[dy].text[dx],
204aa59d4d4SRong-En Fan src->_line[sy].text[sx])) {
205aa59d4d4SRong-En Fan dst->_line[dy].text[dx] =
206aa59d4d4SRong-En Fan src->_line[sy].text[sx];
2070e3d5408SPeter Wemm touched = TRUE;
2080e3d5408SPeter Wemm }
2090e3d5408SPeter Wemm }
2100e3d5408SPeter Wemm }
2117a69bbfbSPeter Wemm if (touched) {
2124a1a9510SRong-En Fan touchline(dst, dminrow, (dmaxrow - dminrow + 1));
2130e3d5408SPeter Wemm }
2140e3d5408SPeter Wemm }
2150e3d5408SPeter Wemm T(("finished copywin"));
21673f0a83dSXin LI if (copied)
217aa59d4d4SRong-En Fan rc = OK;
218aa59d4d4SRong-En Fan }
219aa59d4d4SRong-En Fan }
2205d08fb1fSRong-En Fan _nc_unlock_global(curses);
221aa59d4d4SRong-En Fan }
222aa59d4d4SRong-En Fan returnCode(rc);
2230e3d5408SPeter Wemm }
224