xref: /minix3/lib/libcurses/copywin.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
151ffecc1SBen Gras /*	$NetBSD: copywin.c,v 1.15 2009/07/22 16:57:14 roy Exp $	*/
251ffecc1SBen Gras 
351ffecc1SBen Gras /*-
451ffecc1SBen Gras  * Copyright (c) 1998-1999 Brett Lymn
551ffecc1SBen Gras  *                         (blymn@baea.com.au, brett_lymn@yahoo.com.au)
651ffecc1SBen Gras  * All rights reserved.
751ffecc1SBen Gras  *
851ffecc1SBen Gras  * This code has been donated to The NetBSD Foundation by the Author.
951ffecc1SBen Gras  *
1051ffecc1SBen Gras  * Redistribution and use in source and binary forms, with or without
1151ffecc1SBen Gras  * modification, are permitted provided that the following conditions
1251ffecc1SBen Gras  * are met:
1351ffecc1SBen Gras  * 1. Redistributions of source code must retain the above copyright
1451ffecc1SBen Gras  *    notice, this list of conditions and the following disclaimer.
1551ffecc1SBen Gras  * 2. The name of the author may not be used to endorse or promote products
1651ffecc1SBen Gras  *    derived from this software without specific prior written permission
1751ffecc1SBen Gras  *
1851ffecc1SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1951ffecc1SBen Gras  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2051ffecc1SBen Gras  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2151ffecc1SBen Gras  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2251ffecc1SBen Gras  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2351ffecc1SBen Gras  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2451ffecc1SBen Gras  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2551ffecc1SBen Gras  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2651ffecc1SBen Gras  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2751ffecc1SBen Gras  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2851ffecc1SBen Gras  *
2951ffecc1SBen Gras  *
3051ffecc1SBen Gras  */
3151ffecc1SBen Gras 
3251ffecc1SBen Gras #include <sys/cdefs.h>
3351ffecc1SBen Gras #ifndef lint
3451ffecc1SBen Gras __RCSID("$NetBSD: copywin.c,v 1.15 2009/07/22 16:57:14 roy Exp $");
3551ffecc1SBen Gras #endif				/* not lint */
3651ffecc1SBen Gras 
3751ffecc1SBen Gras #include <ctype.h>
3851ffecc1SBen Gras #include <string.h>
3951ffecc1SBen Gras #include "curses.h"
4051ffecc1SBen Gras #include "curses_private.h"
4151ffecc1SBen Gras 
4251ffecc1SBen Gras /*
4351ffecc1SBen Gras  * copywin --
4451ffecc1SBen Gras  *     Copy the box starting at (sminrow, smincol) with a size that
4551ffecc1SBen Gras  *     matches the destination box (dminrow, dmincol) by (dmaxrow, dmaxcol)
4651ffecc1SBen Gras  *     from the source window srcwin to the destination window dstwin.
4751ffecc1SBen Gras  *     All these coordindinates are relative to the relevant window.
4851ffecc1SBen Gras  *     If dooverlay is true then the copy is nondestructive otherwise the
4951ffecc1SBen Gras  *     copy is destructive.
5051ffecc1SBen Gras  */
copywin(const WINDOW * srcwin,WINDOW * dstwin,int sminrow,int smincol,int dminrow,int dmincol,int dmaxrow,int dmaxcol,int dooverlay)5151ffecc1SBen Gras int copywin(const WINDOW *srcwin, WINDOW *dstwin,
5251ffecc1SBen Gras 	    int sminrow, int smincol,
5351ffecc1SBen Gras 	    int dminrow, int dmincol, int dmaxrow, int dmaxcol, int dooverlay)
5451ffecc1SBen Gras {
5551ffecc1SBen Gras 	int dcol;
5651ffecc1SBen Gras 	__LDATA *sp, *end;
5751ffecc1SBen Gras #ifdef HAVE_WCHAR
5851ffecc1SBen Gras 	cchar_t cc;
5951ffecc1SBen Gras 	nschar_t *np;
6051ffecc1SBen Gras #endif /* HAVE_WCHAR */
6151ffecc1SBen Gras 
6251ffecc1SBen Gras 	/* overwrite() and overlay() can come here with -ve srcwin coords */
6351ffecc1SBen Gras 	if (sminrow < 0) {
6451ffecc1SBen Gras 		dminrow -= sminrow;
6551ffecc1SBen Gras 		sminrow = 0;
6651ffecc1SBen Gras 	}
6751ffecc1SBen Gras 	if (smincol < 0) {
6851ffecc1SBen Gras 		dmincol -= smincol;
6951ffecc1SBen Gras 		smincol = 0;
7051ffecc1SBen Gras 	}
7151ffecc1SBen Gras 
7251ffecc1SBen Gras 	/* for symmetry allow dstwin coords to be -ve as well */
7351ffecc1SBen Gras 	if (dminrow < 0) {
7451ffecc1SBen Gras 		sminrow -= dminrow;
7551ffecc1SBen Gras 		dminrow = 0;
7651ffecc1SBen Gras 	}
7751ffecc1SBen Gras 	if (dmincol < 0) {
7851ffecc1SBen Gras 		smincol -= dmincol;
7951ffecc1SBen Gras 		dmincol = 0;
8051ffecc1SBen Gras 	}
8151ffecc1SBen Gras 
8251ffecc1SBen Gras 	/* Bound dmaxcol for both windows (should be ok for dstwin) */
8351ffecc1SBen Gras 	if (dmaxcol >= dstwin->maxx)
8451ffecc1SBen Gras 		dmaxcol = dstwin->maxx - 1;
8551ffecc1SBen Gras 	if (smincol + (dmaxcol - dmincol) >= srcwin->maxx)
8651ffecc1SBen Gras 		dmaxcol = srcwin->maxx + dmincol - smincol - 1;
8751ffecc1SBen Gras 	if (dmaxcol < dmincol)
8851ffecc1SBen Gras 		/* nothing in the intersection */
8951ffecc1SBen Gras 		return OK;
9051ffecc1SBen Gras 
9151ffecc1SBen Gras 	/* Bound dmaxrow for both windows (should be ok for dstwin) */
9251ffecc1SBen Gras 	if (dmaxrow >= dstwin->maxy)
9351ffecc1SBen Gras 		dmaxrow = dstwin->maxy - 1;
9451ffecc1SBen Gras 	if (sminrow + (dmaxrow - dminrow) >= srcwin->maxy)
9551ffecc1SBen Gras 		dmaxrow = srcwin->maxy + dminrow - sminrow - 1;
9651ffecc1SBen Gras 
9751ffecc1SBen Gras #ifdef DEBUG
9851ffecc1SBen Gras 	__CTRACE(__CTRACE_WINDOW,
9951ffecc1SBen Gras 	    "copywin %s mode: from (%d,%d) to (%d,%d-%d,%d)\n",
10051ffecc1SBen Gras 	    dooverlay ? "overlay" : "overwrite",
10151ffecc1SBen Gras 	    sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol);
10251ffecc1SBen Gras #endif
10351ffecc1SBen Gras 
10451ffecc1SBen Gras 	for (; dminrow <= dmaxrow; sminrow++, dminrow++) {
10551ffecc1SBen Gras 		sp = &srcwin->alines[sminrow]->line[smincol];
10651ffecc1SBen Gras 		end = sp + dmaxcol - dmincol;
10751ffecc1SBen Gras 		for (dcol = dmincol; sp <= end; dcol++, sp++) {
10851ffecc1SBen Gras 			/* XXX: Perhaps this should check for the
10951ffecc1SBen Gras 			 * background character
11051ffecc1SBen Gras 			 */
11151ffecc1SBen Gras 			if ((dooverlay && !isspace(sp->ch)) || !dooverlay) {
11251ffecc1SBen Gras 				wmove(dstwin, dminrow, dcol);
11351ffecc1SBen Gras #ifndef HAVE_WCHAR
11451ffecc1SBen Gras 				__waddch(dstwin, sp);
11551ffecc1SBen Gras #else
11651ffecc1SBen Gras 				cc.vals[0] = sp->ch;
11751ffecc1SBen Gras 				cc.attributes = sp->attr;
11851ffecc1SBen Gras 				cc.elements = 1;
11951ffecc1SBen Gras 				np = sp->nsp;
12051ffecc1SBen Gras 				if (np) {
121*84d9c625SLionel Sambuc 					/* MINIX: off by one error, has to be strictly less than. */
122ffba9c2dSLionel Sambuc 					while (np && cc.elements <
12351ffecc1SBen Gras 					    CURSES_CCHAR_MAX) {
12451ffecc1SBen Gras 						cc.vals[cc.elements++] = np->ch;
12551ffecc1SBen Gras 						np = np->next;
12651ffecc1SBen Gras 					}
12751ffecc1SBen Gras 				}
12851ffecc1SBen Gras 				wadd_wch(dstwin, &cc);
12951ffecc1SBen Gras #endif /* HAVE_WCHAR */
13051ffecc1SBen Gras 			}
13151ffecc1SBen Gras 		}
13251ffecc1SBen Gras 	}
13351ffecc1SBen Gras 	__touchwin(dstwin);
13451ffecc1SBen Gras 	return OK;
13551ffecc1SBen Gras }
13651ffecc1SBen Gras 
137