1*c7ef0cfcSnicm /* $OpenBSD: lib_overlay.c,v 1.4 2023/10/17 09:52:08 nicm Exp $ */
292dd1ec0Smillert
392dd1ec0Smillert /****************************************************************************
4*c7ef0cfcSnicm * Copyright 2020 Thomas E. Dickey *
5*c7ef0cfcSnicm * Copyright 1998-2013,2016 Free Software Foundation, Inc. *
692dd1ec0Smillert * *
792dd1ec0Smillert * Permission is hereby granted, free of charge, to any person obtaining a *
892dd1ec0Smillert * copy of this software and associated documentation files (the *
992dd1ec0Smillert * "Software"), to deal in the Software without restriction, including *
1092dd1ec0Smillert * without limitation the rights to use, copy, modify, merge, publish, *
1192dd1ec0Smillert * distribute, distribute with modifications, sublicense, and/or sell *
1292dd1ec0Smillert * copies of the Software, and to permit persons to whom the Software is *
1392dd1ec0Smillert * furnished to do so, subject to the following conditions: *
1492dd1ec0Smillert * *
1592dd1ec0Smillert * The above copyright notice and this permission notice shall be included *
1692dd1ec0Smillert * in all copies or substantial portions of the Software. *
1792dd1ec0Smillert * *
1892dd1ec0Smillert * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
1992dd1ec0Smillert * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
2092dd1ec0Smillert * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
2192dd1ec0Smillert * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
2292dd1ec0Smillert * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
2392dd1ec0Smillert * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
2492dd1ec0Smillert * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
2592dd1ec0Smillert * *
2692dd1ec0Smillert * Except as contained in this notice, the name(s) of the above copyright *
2792dd1ec0Smillert * holders shall not be used in advertising or otherwise to promote the *
2892dd1ec0Smillert * sale, use or other dealings in this Software without prior written *
2992dd1ec0Smillert * authorization. *
3092dd1ec0Smillert ****************************************************************************/
3192dd1ec0Smillert
3292dd1ec0Smillert /****************************************************************************
3392dd1ec0Smillert * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
3492dd1ec0Smillert * and: Eric S. Raymond <esr@snark.thyrsus.com> *
3592dd1ec0Smillert ****************************************************************************/
3692dd1ec0Smillert
3792dd1ec0Smillert /*
3892dd1ec0Smillert ** lib_overlay.c
3992dd1ec0Smillert **
4092dd1ec0Smillert ** The routines overlay(), copywin(), and overwrite().
4192dd1ec0Smillert **
4292dd1ec0Smillert */
4392dd1ec0Smillert
4492dd1ec0Smillert #include <curses.priv.h>
4592dd1ec0Smillert
46*c7ef0cfcSnicm MODULE_ID("$Id: lib_overlay.c,v 1.4 2023/10/17 09:52:08 nicm Exp $")
4792dd1ec0Smillert
4884af20ceSmillert static int
overlap(const WINDOW * const src,WINDOW * const dst,int const flag)4981d8c4e1Snicm overlap(const WINDOW *const src, WINDOW *const dst, int const flag)
5092dd1ec0Smillert {
5181d8c4e1Snicm int rc = ERR;
5292dd1ec0Smillert
53*c7ef0cfcSnicm T((T_CALLED("overlap(%p,%p,%d)"), (const void *) src, (void *) dst, flag));
5492dd1ec0Smillert
5581d8c4e1Snicm if (src != 0 && dst != 0) {
56*c7ef0cfcSnicm int sx1, sy1, sx2, sy2;
57*c7ef0cfcSnicm int dx1, dy1, dx2, dy2;
58*c7ef0cfcSnicm
5981d8c4e1Snicm _nc_lock_global(curses);
6092dd1ec0Smillert
6181d8c4e1Snicm T(("src : begy %ld, begx %ld, maxy %ld, maxx %ld",
6281d8c4e1Snicm (long) src->_begy,
6381d8c4e1Snicm (long) src->_begx,
6481d8c4e1Snicm (long) src->_maxy,
6581d8c4e1Snicm (long) src->_maxx));
6681d8c4e1Snicm T(("dst : begy %ld, begx %ld, maxy %ld, maxx %ld",
6781d8c4e1Snicm (long) dst->_begy,
6881d8c4e1Snicm (long) dst->_begx,
6981d8c4e1Snicm (long) dst->_maxy,
7081d8c4e1Snicm (long) dst->_maxx));
7192dd1ec0Smillert
7281d8c4e1Snicm sx1 = src->_begx;
7381d8c4e1Snicm sy1 = src->_begy;
7481d8c4e1Snicm sx2 = sx1 + src->_maxx;
7581d8c4e1Snicm sy2 = sy1 + src->_maxy;
7681d8c4e1Snicm
7781d8c4e1Snicm dx1 = dst->_begx;
7881d8c4e1Snicm dy1 = dst->_begy;
7981d8c4e1Snicm dx2 = dx1 + dst->_maxx;
8081d8c4e1Snicm dy2 = dy1 + dst->_maxy;
8181d8c4e1Snicm
8281d8c4e1Snicm if (dx2 >= sx1 && dx1 <= sx2 && dy2 >= sy1 && dy1 <= sy2) {
83*c7ef0cfcSnicm int sminrow = max(sy1, dy1) - sy1;
84*c7ef0cfcSnicm int smincol = max(sx1, dx1) - sx1;
85*c7ef0cfcSnicm int dminrow = max(sy1, dy1) - dy1;
86*c7ef0cfcSnicm int dmincol = max(sx1, dx1) - dx1;
87*c7ef0cfcSnicm int dmaxrow = min(sy2, dy2) - dy1;
88*c7ef0cfcSnicm int dmaxcol = min(sx2, dx2) - dx1;
8981d8c4e1Snicm
9081d8c4e1Snicm rc = copywin(src, dst,
9181d8c4e1Snicm sminrow, smincol,
9281d8c4e1Snicm dminrow, dmincol,
9381d8c4e1Snicm dmaxrow, dmaxcol,
9481d8c4e1Snicm flag);
9581d8c4e1Snicm }
9681d8c4e1Snicm _nc_unlock_global(curses);
9781d8c4e1Snicm }
9881d8c4e1Snicm returnCode(rc);
9992dd1ec0Smillert }
10092dd1ec0Smillert
10192dd1ec0Smillert /*
10292dd1ec0Smillert **
10392dd1ec0Smillert ** overlay(win1, win2)
10492dd1ec0Smillert **
10592dd1ec0Smillert **
10692dd1ec0Smillert ** overlay() writes the overlapping area of win1 behind win2
10792dd1ec0Smillert ** on win2 non-destructively.
10892dd1ec0Smillert **
10992dd1ec0Smillert **/
11092dd1ec0Smillert
11184af20ceSmillert NCURSES_EXPORT(int)
overlay(const WINDOW * win1,WINDOW * win2)11284af20ceSmillert overlay(const WINDOW *win1, WINDOW *win2)
11392dd1ec0Smillert {
114*c7ef0cfcSnicm T((T_CALLED("overlay(%p,%p)"), (const void *) win1, (void *) win2));
11592dd1ec0Smillert returnCode(overlap(win1, win2, TRUE));
11692dd1ec0Smillert }
11792dd1ec0Smillert
11892dd1ec0Smillert /*
11992dd1ec0Smillert **
12092dd1ec0Smillert ** overwrite(win1, win2)
12192dd1ec0Smillert **
12292dd1ec0Smillert **
12392dd1ec0Smillert ** overwrite() writes the overlapping area of win1 behind win2
12492dd1ec0Smillert ** on win2 destructively.
12592dd1ec0Smillert **
12692dd1ec0Smillert **/
12792dd1ec0Smillert
12884af20ceSmillert NCURSES_EXPORT(int)
overwrite(const WINDOW * win1,WINDOW * win2)12984af20ceSmillert overwrite(const WINDOW *win1, WINDOW *win2)
13092dd1ec0Smillert {
131*c7ef0cfcSnicm T((T_CALLED("overwrite(%p,%p)"), (const void *) win1, (void *) win2));
13292dd1ec0Smillert returnCode(overlap(win1, win2, FALSE));
13392dd1ec0Smillert }
13492dd1ec0Smillert
13584af20ceSmillert NCURSES_EXPORT(int)
copywin(const WINDOW * src,WINDOW * dst,int sminrow,int smincol,int dminrow,int dmincol,int dmaxrow,int dmaxcol,int over)13681d8c4e1Snicm copywin(const WINDOW *src, WINDOW *dst,
13792dd1ec0Smillert int sminrow, int smincol,
13881d8c4e1Snicm int dminrow, int dmincol,
13981d8c4e1Snicm int dmaxrow, int dmaxcol,
14092dd1ec0Smillert int over)
14192dd1ec0Smillert {
14281d8c4e1Snicm int rc = ERR;
143*c7ef0cfcSnicm
144*c7ef0cfcSnicm T((T_CALLED("copywin(%p, %p, %d, %d, %d, %d, %d, %d, %d)"),
145*c7ef0cfcSnicm (const void *) src,
146*c7ef0cfcSnicm (void *) dst,
147*c7ef0cfcSnicm sminrow, smincol,
148*c7ef0cfcSnicm dminrow, dmincol,
149*c7ef0cfcSnicm dmaxrow, dmaxcol, over));
150*c7ef0cfcSnicm
151*c7ef0cfcSnicm if (src != 0
152*c7ef0cfcSnicm && dst != 0
153*c7ef0cfcSnicm && dmaxrow >= dminrow
154*c7ef0cfcSnicm && dmaxcol >= dmincol) {
15581d8c4e1Snicm attr_t bk;
15681d8c4e1Snicm attr_t mask;
15792dd1ec0Smillert
15881d8c4e1Snicm _nc_lock_global(curses);
15981d8c4e1Snicm
16081d8c4e1Snicm bk = AttrOf(dst->_nc_bkgd);
16181d8c4e1Snicm mask = ~(attr_t) ((bk & A_COLOR) ? A_COLOR : 0);
16292dd1ec0Smillert
16392dd1ec0Smillert /* make sure rectangle exists in source */
16481d8c4e1Snicm if ((sminrow + dmaxrow - dminrow) <= (src->_maxy + 1) &&
16581d8c4e1Snicm (smincol + dmaxcol - dmincol) <= (src->_maxx + 1)) {
16692dd1ec0Smillert
16792dd1ec0Smillert T(("rectangle exists in source"));
16892dd1ec0Smillert
16992dd1ec0Smillert /* make sure rectangle fits in destination */
17081d8c4e1Snicm if (dmaxrow <= dst->_maxy && dmaxcol <= dst->_maxx) {
171*c7ef0cfcSnicm int sx, sy, dx, dy;
172*c7ef0cfcSnicm bool copied = FALSE;
17392dd1ec0Smillert
17492dd1ec0Smillert T(("rectangle fits in destination"));
17592dd1ec0Smillert
17681d8c4e1Snicm for (dy = dminrow, sy = sminrow;
17781d8c4e1Snicm dy <= dmaxrow;
17881d8c4e1Snicm sy++, dy++) {
179*c7ef0cfcSnicm bool touched;
180*c7ef0cfcSnicm
181*c7ef0cfcSnicm if (dy < 0 || sy < 0)
182*c7ef0cfcSnicm continue;
18381d8c4e1Snicm
18492dd1ec0Smillert touched = FALSE;
18581d8c4e1Snicm for (dx = dmincol, sx = smincol;
18681d8c4e1Snicm dx <= dmaxcol;
18781d8c4e1Snicm sx++, dx++) {
188*c7ef0cfcSnicm
189*c7ef0cfcSnicm if (dx < 0 || sx < 0)
190*c7ef0cfcSnicm continue;
191*c7ef0cfcSnicm copied = TRUE;
192*c7ef0cfcSnicm
19384af20ceSmillert if (over) {
19481d8c4e1Snicm if ((CharOf(src->_line[sy].text[sx]) != L(' ')) &&
19581d8c4e1Snicm (!CharEq(dst->_line[dy].text[dx],
19681d8c4e1Snicm src->_line[sy].text[sx]))) {
19792dd1ec0Smillert dst->_line[dy].text[dx] =
19881d8c4e1Snicm src->_line[sy].text[sx];
19981d8c4e1Snicm SetAttr(dst->_line[dy].text[dx],
20081d8c4e1Snicm ((AttrOf(src->_line[sy].text[sx]) &
20181d8c4e1Snicm mask) | bk));
20292dd1ec0Smillert touched = TRUE;
20392dd1ec0Smillert }
20484af20ceSmillert } else {
20581d8c4e1Snicm if (!CharEq(dst->_line[dy].text[dx],
20681d8c4e1Snicm src->_line[sy].text[sx])) {
20781d8c4e1Snicm dst->_line[dy].text[dx] =
20881d8c4e1Snicm src->_line[sy].text[sx];
20992dd1ec0Smillert touched = TRUE;
21092dd1ec0Smillert }
21192dd1ec0Smillert }
21292dd1ec0Smillert }
21384af20ceSmillert if (touched) {
21481d8c4e1Snicm touchline(dst, dminrow, (dmaxrow - dminrow + 1));
21592dd1ec0Smillert }
21692dd1ec0Smillert }
21792dd1ec0Smillert T(("finished copywin"));
218*c7ef0cfcSnicm if (copied)
21981d8c4e1Snicm rc = OK;
22081d8c4e1Snicm }
22181d8c4e1Snicm }
22281d8c4e1Snicm _nc_unlock_global(curses);
22381d8c4e1Snicm }
22481d8c4e1Snicm returnCode(rc);
22592dd1ec0Smillert }
226