1*6348e3f3Sblymn /* $NetBSD: copywin.c,v 1.22 2024/12/23 02:58:03 blymn Exp $ */ 2e79669d6Sblymn 3e79669d6Sblymn /*- 4e79669d6Sblymn * Copyright (c) 1998-1999 Brett Lymn 5e79669d6Sblymn * (blymn@baea.com.au, brett_lymn@yahoo.com.au) 6e79669d6Sblymn * All rights reserved. 7e79669d6Sblymn * 8e79669d6Sblymn * This code has been donated to The NetBSD Foundation by the Author. 9e79669d6Sblymn * 10e79669d6Sblymn * Redistribution and use in source and binary forms, with or without 11e79669d6Sblymn * modification, are permitted provided that the following conditions 12e79669d6Sblymn * are met: 13e79669d6Sblymn * 1. Redistributions of source code must retain the above copyright 14e79669d6Sblymn * notice, this list of conditions and the following disclaimer. 15e79669d6Sblymn * 2. The name of the author may not be used to endorse or promote products 16c03a48d6Swiz * derived from this software without specific prior written permission 17e79669d6Sblymn * 18e79669d6Sblymn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19e79669d6Sblymn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20e79669d6Sblymn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21e79669d6Sblymn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22e79669d6Sblymn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23e79669d6Sblymn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24e79669d6Sblymn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25e79669d6Sblymn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26e79669d6Sblymn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27e79669d6Sblymn * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28e79669d6Sblymn * 29e79669d6Sblymn * 30e79669d6Sblymn */ 31e79669d6Sblymn 3266cab71cSblymn #include <sys/cdefs.h> 3366cab71cSblymn #ifndef lint 34*6348e3f3Sblymn __RCSID("$NetBSD: copywin.c,v 1.22 2024/12/23 02:58:03 blymn Exp $"); 3566cab71cSblymn #endif /* not lint */ 3666cab71cSblymn 37e79669d6Sblymn #include <ctype.h> 3817934cdbSjdc #include <string.h> 39e79669d6Sblymn #include "curses.h" 40e79669d6Sblymn #include "curses_private.h" 41e79669d6Sblymn 42e79669d6Sblymn /* 43e79669d6Sblymn * copywin -- 44e79669d6Sblymn * Copy the box starting at (sminrow, smincol) with a size that 45e79669d6Sblymn * matches the destination box (dminrow, dmincol) by (dmaxrow, dmaxcol) 46e79669d6Sblymn * from the source window srcwin to the destination window dstwin. 479214d0d9Sdsl * All these coordindinates are relative to the relevant window. 4836ddbc2fSlukem * If dooverlay is true then the copy is nondestructive otherwise the 49e79669d6Sblymn * copy is destructive. 50e79669d6Sblymn */ 519214d0d9Sdsl int copywin(const WINDOW *srcwin, WINDOW *dstwin, 529214d0d9Sdsl int sminrow, int smincol, 539214d0d9Sdsl int dminrow, int dmincol, int dmaxrow, int dmaxcol, int dooverlay) 54e79669d6Sblymn { 559214d0d9Sdsl int dcol; 56e79669d6Sblymn __LDATA *sp, *end; 57e124de36Sblymn #ifdef HAVE_WCHAR 58e124de36Sblymn cchar_t cc; 59e124de36Sblymn nschar_t *np; 60e124de36Sblymn #endif /* HAVE_WCHAR */ 61e79669d6Sblymn 624114d261Sblymn __CTRACE(__CTRACE_WINDOW, 634114d261Sblymn "copywin %s mode: from (%d,%d) to (%d,%d-%d,%d)\n", 644114d261Sblymn dooverlay ? "overlay" : "overwrite", 654114d261Sblymn sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol); 664114d261Sblymn 67*6348e3f3Sblymn if ((srcwin == NULL) || (dstwin == NULL)) 68*6348e3f3Sblymn return ERR; 69*6348e3f3Sblymn 709214d0d9Sdsl /* overwrite() and overlay() can come here with -ve srcwin coords */ 719214d0d9Sdsl if (sminrow < 0) { 729214d0d9Sdsl dminrow -= sminrow; 739214d0d9Sdsl sminrow = 0; 749214d0d9Sdsl } 759214d0d9Sdsl if (smincol < 0) { 769214d0d9Sdsl dmincol -= smincol; 779214d0d9Sdsl smincol = 0; 789214d0d9Sdsl } 799214d0d9Sdsl 809214d0d9Sdsl /* for symmetry allow dstwin coords to be -ve as well */ 819214d0d9Sdsl if (dminrow < 0) { 829214d0d9Sdsl sminrow -= dminrow; 839214d0d9Sdsl dminrow = 0; 849214d0d9Sdsl } 859214d0d9Sdsl if (dmincol < 0) { 869214d0d9Sdsl smincol -= dmincol; 879214d0d9Sdsl dmincol = 0; 889214d0d9Sdsl } 899214d0d9Sdsl 909214d0d9Sdsl /* Bound dmaxcol for both windows (should be ok for dstwin) */ 919214d0d9Sdsl if (dmaxcol >= dstwin->maxx) 929214d0d9Sdsl dmaxcol = dstwin->maxx - 1; 939214d0d9Sdsl if (smincol + (dmaxcol - dmincol) >= srcwin->maxx) 9475c6c76bSdsl dmaxcol = srcwin->maxx + dmincol - smincol - 1; 959214d0d9Sdsl if (dmaxcol < dmincol) 969214d0d9Sdsl /* nothing in the intersection */ 979214d0d9Sdsl return OK; 989214d0d9Sdsl 999214d0d9Sdsl /* Bound dmaxrow for both windows (should be ok for dstwin) */ 10075c6c76bSdsl if (dmaxrow >= dstwin->maxy) 1019214d0d9Sdsl dmaxrow = dstwin->maxy - 1; 1029214d0d9Sdsl if (sminrow + (dmaxrow - dminrow) >= srcwin->maxy) 10375c6c76bSdsl dmaxrow = srcwin->maxy + dminrow - sminrow - 1; 104e79669d6Sblymn 1051f221324Sjdc __CTRACE(__CTRACE_WINDOW, 1061f221324Sjdc "copywin %s mode: from (%d,%d) to (%d,%d-%d,%d)\n", 1079214d0d9Sdsl dooverlay ? "overlay" : "overwrite", 1089214d0d9Sdsl sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol); 1099214d0d9Sdsl 1109214d0d9Sdsl for (; dminrow <= dmaxrow; sminrow++, dminrow++) { 11143d5eb45Sroy sp = &srcwin->alines[sminrow]->line[smincol]; 1129214d0d9Sdsl end = sp + dmaxcol - dmincol; 1134114d261Sblymn __CTRACE(__CTRACE_WINDOW, "copywin: row %d\n", sminrow); 11455f0d599Sjdc for (dcol = dmincol; sp <= end; dcol++, sp++) { 11555f0d599Sjdc /* XXX: Perhaps this should check for the 11655f0d599Sjdc * background character 11755f0d599Sjdc */ 11855f0d599Sjdc if ((dooverlay && !isspace(sp->ch)) || !dooverlay) { 1192a780e62Sblymn wmove(dstwin, dminrow, dcol); 1204114d261Sblymn __CTRACE(__CTRACE_WINDOW, "copywin: dcol = %d\n", dcol); 12155f0d599Sjdc #ifndef HAVE_WCHAR 12255f0d599Sjdc __waddch(dstwin, sp); 12355f0d599Sjdc #else 124e124de36Sblymn cc.vals[0] = sp->ch; 125e124de36Sblymn cc.attributes = sp->attr; 126e124de36Sblymn cc.elements = 1; 127e124de36Sblymn np = sp->nsp; 128e124de36Sblymn if (np) { 12955f0d599Sjdc while (np && cc.elements <= 13055f0d599Sjdc CURSES_CCHAR_MAX) { 131e124de36Sblymn cc.vals[cc.elements++] = np->ch; 132e124de36Sblymn np = np->next; 133e124de36Sblymn } 134e124de36Sblymn } 135e124de36Sblymn wadd_wch(dstwin, &cc); 136e124de36Sblymn #endif /* HAVE_WCHAR */ 137e79669d6Sblymn } 138e79669d6Sblymn } 1399214d0d9Sdsl } 140301bf8ccSblymn __touchwin(dstwin, 0); 1419214d0d9Sdsl return OK; 142e79669d6Sblymn } 143