10e3d5408SPeter Wemm /**************************************************************************** 2*e1865124SBaptiste Daroussin * Copyright 2020 Thomas E. Dickey * 3*e1865124SBaptiste 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*e1865124SBaptiste Daroussin MODULE_ID("$Id: lib_overlay.c,v 1.33 2020/02/02 23:34:34 tom Exp $") 450e3d5408SPeter Wemm 467a69bbfbSPeter Wemm static int 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) { 81aae38d10SBaptiste Daroussin int sminrow = max(sy1, dy1) - sy1; 82aae38d10SBaptiste Daroussin int smincol = max(sx1, dx1) - sx1; 83aae38d10SBaptiste Daroussin int dminrow = max(sy1, dy1) - dy1; 84aae38d10SBaptiste Daroussin int dmincol = max(sx1, dx1) - dx1; 85aae38d10SBaptiste Daroussin int dmaxrow = min(sy2, dy2) - dy1; 86aae38d10SBaptiste 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) 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) 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) 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