xref: /minix3/lib/libcurses/border.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /*	$NetBSD: border.c,v 1.15 2013/05/05 14:23:16 jdc Exp $	*/
251ffecc1SBen Gras 
351ffecc1SBen Gras /*
451ffecc1SBen Gras  * Copyright (c) 2000 The NetBSD Foundation, Inc.
551ffecc1SBen Gras  * All rights reserved.
651ffecc1SBen Gras  *
751ffecc1SBen Gras  * This code is derived from software contributed to The NetBSD Foundation
851ffecc1SBen Gras  * by Julian Coleman.
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. Redistributions in binary form must reproduce the above copyright
1651ffecc1SBen Gras  *    notice, this list of conditions and the following disclaimer in the
1751ffecc1SBen Gras  *    documentation and/or other materials provided with the distribution.
1851ffecc1SBen Gras  *
1951ffecc1SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2051ffecc1SBen Gras  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2151ffecc1SBen Gras  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2251ffecc1SBen Gras  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2351ffecc1SBen Gras  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2451ffecc1SBen Gras  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2551ffecc1SBen Gras  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2651ffecc1SBen Gras  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2751ffecc1SBen Gras  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2851ffecc1SBen Gras  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2951ffecc1SBen Gras  * POSSIBILITY OF SUCH DAMAGE.
3051ffecc1SBen Gras  */
3151ffecc1SBen Gras 
3251ffecc1SBen Gras #include <sys/cdefs.h>
3351ffecc1SBen Gras #ifndef lint
34*84d9c625SLionel Sambuc __RCSID("$NetBSD: border.c,v 1.15 2013/05/05 14:23:16 jdc Exp $");
3551ffecc1SBen Gras #endif				/* not lint */
3651ffecc1SBen Gras 
3751ffecc1SBen Gras #include <stdlib.h>
3851ffecc1SBen Gras #include <string.h>
3951ffecc1SBen Gras 
4051ffecc1SBen Gras #include "curses.h"
4151ffecc1SBen Gras #include "curses_private.h"
4251ffecc1SBen Gras 
4351ffecc1SBen Gras #ifndef _CURSES_USE_MACROS
4451ffecc1SBen Gras 
4551ffecc1SBen Gras /*
4651ffecc1SBen Gras  * border --
4751ffecc1SBen Gras  *	Draw a border around stdscr using the specified
4851ffecc1SBen Gras  *	delimiting characters.
4951ffecc1SBen Gras  */
5051ffecc1SBen Gras int
border(chtype left,chtype right,chtype top,chtype bottom,chtype topleft,chtype topright,chtype botleft,chtype botright)5151ffecc1SBen Gras border(chtype left, chtype right, chtype top, chtype bottom, chtype topleft,
5251ffecc1SBen Gras        chtype topright, chtype botleft, chtype botright)
5351ffecc1SBen Gras {
5451ffecc1SBen Gras 	return wborder(stdscr, left, right, top, bottom, topleft, topright,
5551ffecc1SBen Gras 	    botleft, botright);
5651ffecc1SBen Gras }
5751ffecc1SBen Gras 
5851ffecc1SBen Gras #endif
5951ffecc1SBen Gras 
6051ffecc1SBen Gras /*
6151ffecc1SBen Gras  * wborder --
6251ffecc1SBen Gras  *	Draw a border around the given window using the specified delimiting
6351ffecc1SBen Gras  *	characters.
6451ffecc1SBen Gras  */
6551ffecc1SBen Gras int
wborder(WINDOW * win,chtype left,chtype right,chtype top,chtype bottom,chtype topleft,chtype topright,chtype botleft,chtype botright)6651ffecc1SBen Gras wborder(WINDOW *win, chtype left, chtype right, chtype top, chtype bottom,
6751ffecc1SBen Gras 	chtype topleft, chtype topright, chtype botleft, chtype botright)
6851ffecc1SBen Gras {
6951ffecc1SBen Gras #ifndef HAVE_WCHAR
7051ffecc1SBen Gras 	int	 endy, endx, i;
7151ffecc1SBen Gras 	__LDATA	*fp, *lp;
7251ffecc1SBen Gras 
7351ffecc1SBen Gras 	if (!(left & __CHARTEXT))
7451ffecc1SBen Gras 		left |= ACS_VLINE;
7551ffecc1SBen Gras 	if (!(right & __CHARTEXT))
7651ffecc1SBen Gras 		right |= ACS_VLINE;
7751ffecc1SBen Gras 	if (!(top & __CHARTEXT))
7851ffecc1SBen Gras 		top |= ACS_HLINE;
7951ffecc1SBen Gras 	if (!(bottom & __CHARTEXT))
8051ffecc1SBen Gras 		bottom |= ACS_HLINE;
8151ffecc1SBen Gras 	if (!(topleft & __CHARTEXT))
8251ffecc1SBen Gras 		topleft |= ACS_ULCORNER;
8351ffecc1SBen Gras 	if (!(topright & __CHARTEXT))
8451ffecc1SBen Gras 		topright |= ACS_URCORNER;
8551ffecc1SBen Gras 	if (!(botleft & __CHARTEXT))
8651ffecc1SBen Gras 		botleft |= ACS_LLCORNER;
8751ffecc1SBen Gras 	if (!(botright & __CHARTEXT))
8851ffecc1SBen Gras 		botright |= ACS_LRCORNER;
8951ffecc1SBen Gras 
9051ffecc1SBen Gras #ifdef DEBUG
9151ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder: left = %c, 0x%x\n",
9251ffecc1SBen Gras 	    left & __CHARTEXT, left & __ATTRIBUTES);
9351ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder: right = %c, 0x%x\n",
9451ffecc1SBen Gras 	    right & __CHARTEXT, right & __ATTRIBUTES);
9551ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder: top = %c, 0x%x\n",
9651ffecc1SBen Gras 	    top & __CHARTEXT, top & __ATTRIBUTES);
9751ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder: bottom = %c, 0x%x\n",
9851ffecc1SBen Gras 	    bottom & __CHARTEXT, bottom & __ATTRIBUTES);
9951ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder: topleft = %c, 0x%x\n",
10051ffecc1SBen Gras 	    topleft & __CHARTEXT, topleft & __ATTRIBUTES);
10151ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder: topright = %c, 0x%x\n",
10251ffecc1SBen Gras 	    topright & __CHARTEXT, topright & __ATTRIBUTES);
10351ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder: botleft = %c, 0x%x\n",
10451ffecc1SBen Gras 	    botleft & __CHARTEXT, botleft & __ATTRIBUTES);
10551ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder: botright = %c, 0x%x\n",
10651ffecc1SBen Gras 	    botright & __CHARTEXT, botright & __ATTRIBUTES);
10751ffecc1SBen Gras #endif
10851ffecc1SBen Gras 
10951ffecc1SBen Gras 	/* Merge window and background attributes */
11051ffecc1SBen Gras 	left |= (left & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr;
11151ffecc1SBen Gras 	left |= (left & __COLOR) ? (win->battr & ~__COLOR) : win->battr;
11251ffecc1SBen Gras 	right |= (right & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr;
11351ffecc1SBen Gras 	right |= (right & __COLOR) ? (win->battr & ~__COLOR) : win->battr;
11451ffecc1SBen Gras 	top |= (top & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr;
11551ffecc1SBen Gras 	top |= (top & __COLOR) ? (win->battr & ~__COLOR) : win->battr;
11651ffecc1SBen Gras 	bottom |= (bottom & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr;
11751ffecc1SBen Gras 	bottom |= (bottom & __COLOR) ? (win->battr & ~__COLOR) : win->battr;
11851ffecc1SBen Gras 	topleft |= (topleft & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr;
11951ffecc1SBen Gras 	topleft |= (topleft & __COLOR) ? (win->battr & ~__COLOR) : win->battr;
12051ffecc1SBen Gras 	topright |= (topright & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr;
12151ffecc1SBen Gras 	topright |= (topright & __COLOR) ? (win->battr & ~__COLOR) : win->battr;
12251ffecc1SBen Gras 	botleft |= (botleft & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr;
12351ffecc1SBen Gras 	botleft |= (botleft & __COLOR) ? (win->battr & ~__COLOR) : win->battr;
12451ffecc1SBen Gras 	botright |= (botright & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr;
12551ffecc1SBen Gras 	botright |= (botright & __COLOR) ? (win->battr & ~__COLOR) : win->battr;
12651ffecc1SBen Gras 
12751ffecc1SBen Gras 	endx = win->maxx - 1;
12851ffecc1SBen Gras 	endy = win->maxy - 1;
12951ffecc1SBen Gras 	fp = win->alines[0]->line;
13051ffecc1SBen Gras 	lp = win->alines[endy]->line;
13151ffecc1SBen Gras 
13251ffecc1SBen Gras 	/* Sides */
13351ffecc1SBen Gras 	for (i = 1; i < endy; i++) {
13451ffecc1SBen Gras 		win->alines[i]->line[0].ch = (wchar_t) left & __CHARTEXT;
13551ffecc1SBen Gras 		win->alines[i]->line[0].attr = (attr_t) left & __ATTRIBUTES;
13651ffecc1SBen Gras 		win->alines[i]->line[endx].ch = (wchar_t) right & __CHARTEXT;
13751ffecc1SBen Gras 		win->alines[i]->line[endx].attr = (attr_t) right & __ATTRIBUTES;
13851ffecc1SBen Gras 	}
13951ffecc1SBen Gras 	for (i = 1; i < endx; i++) {
14051ffecc1SBen Gras 		fp[i].ch = (wchar_t) top & __CHARTEXT;
14151ffecc1SBen Gras 		fp[i].attr = (attr_t) top & __ATTRIBUTES;
14251ffecc1SBen Gras 		lp[i].ch = (wchar_t) bottom & __CHARTEXT;
14351ffecc1SBen Gras 		lp[i].attr = (attr_t) bottom & __ATTRIBUTES;
14451ffecc1SBen Gras 	}
14551ffecc1SBen Gras 
14651ffecc1SBen Gras 	/* Corners */
14751ffecc1SBen Gras 	if (!(win->maxx == LINES && win->maxy == COLS &&
14851ffecc1SBen Gras 	    (win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) {
14951ffecc1SBen Gras 		fp[0].ch = (wchar_t) topleft & __CHARTEXT;
15051ffecc1SBen Gras 		fp[0].attr = (attr_t) topleft & __ATTRIBUTES;
15151ffecc1SBen Gras 		fp[endx].ch = (wchar_t) topright & __CHARTEXT;
15251ffecc1SBen Gras 		fp[endx].attr = (attr_t) topright & __ATTRIBUTES;
15351ffecc1SBen Gras 		lp[0].ch = (wchar_t) botleft & __CHARTEXT;
15451ffecc1SBen Gras 		lp[0].attr = (attr_t) botleft & __ATTRIBUTES;
15551ffecc1SBen Gras 		lp[endx].ch = (wchar_t) botright & __CHARTEXT;
15651ffecc1SBen Gras 		lp[endx].attr = (attr_t) botright & __ATTRIBUTES;
15751ffecc1SBen Gras 	}
15851ffecc1SBen Gras 	__touchwin(win);
15951ffecc1SBen Gras 	return (OK);
16051ffecc1SBen Gras #else /* HAVE_WCHAR */
16151ffecc1SBen Gras 	cchar_t ls, rs, ts, bs, tl, tr, bl, br;
16251ffecc1SBen Gras 	cchar_t *lsp, *rsp, *tsp, *bsp, *tlp, *trp, *blp, *brp;
16351ffecc1SBen Gras 
16451ffecc1SBen Gras #define S(in, out, def) \
16551ffecc1SBen Gras 	if (in & __CHARTEXT) { \
16651ffecc1SBen Gras 		__cursesi_chtype_to_cchar(in, &out); \
16751ffecc1SBen Gras 	} else { \
16851ffecc1SBen Gras 		memcpy(&out, def, sizeof(cchar_t)); \
16951ffecc1SBen Gras 		out.attributes |= in & __ATTRIBUTES; \
17051ffecc1SBen Gras 	} \
17151ffecc1SBen Gras 	out##p = &out;
17251ffecc1SBen Gras 
17351ffecc1SBen Gras 	S(left, ls, WACS_VLINE);
17451ffecc1SBen Gras 	S(right, rs, WACS_VLINE);
17551ffecc1SBen Gras 	S(top, ts, WACS_HLINE);
17651ffecc1SBen Gras 	S(bottom, bs, WACS_HLINE);
17751ffecc1SBen Gras 	S(topleft, tl, WACS_ULCORNER);
17851ffecc1SBen Gras 	S(topright, tr, WACS_URCORNER);
17951ffecc1SBen Gras 	S(botleft, bl, WACS_LLCORNER);
18051ffecc1SBen Gras 	S(botright, br, WACS_LRCORNER);
18151ffecc1SBen Gras #undef S
18251ffecc1SBen Gras 	return wborder_set(win, lsp, rsp, tsp, bsp, tlp, trp, blp, brp);
18351ffecc1SBen Gras #endif /* HAVE_WCHAR */
18451ffecc1SBen Gras }
18551ffecc1SBen Gras 
border_set(const cchar_t * ls,const cchar_t * rs,const cchar_t * ts,const cchar_t * bs,const cchar_t * tl,const cchar_t * tr,const cchar_t * bl,const cchar_t * br)18651ffecc1SBen Gras int border_set(const cchar_t *ls, const cchar_t *rs, const cchar_t *ts,
18751ffecc1SBen Gras 	   const cchar_t *bs, const cchar_t *tl, const cchar_t *tr,
18851ffecc1SBen Gras 	   const cchar_t *bl, const cchar_t *br)
18951ffecc1SBen Gras {
19051ffecc1SBen Gras #ifndef HAVE_WCHAR
19151ffecc1SBen Gras 	return ERR;
19251ffecc1SBen Gras #else
19351ffecc1SBen Gras 	return wborder_set(stdscr, ls, rs, ts, bs, tl, tr, bl, br);
19451ffecc1SBen Gras #endif /* HAVE_WCHAR */
19551ffecc1SBen Gras }
19651ffecc1SBen Gras 
wborder_set(WINDOW * win,const cchar_t * ls,const cchar_t * rs,const cchar_t * ts,const cchar_t * bs,const cchar_t * tl,const cchar_t * tr,const cchar_t * bl,const cchar_t * br)19751ffecc1SBen Gras int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs,
19851ffecc1SBen Gras 		const cchar_t *ts, const cchar_t *bs,
19951ffecc1SBen Gras 		const cchar_t *tl, const cchar_t *tr,
20051ffecc1SBen Gras 		const cchar_t *bl, const cchar_t *br)
20151ffecc1SBen Gras {
20251ffecc1SBen Gras #ifndef HAVE_WCHAR
20351ffecc1SBen Gras 	return ERR;
20451ffecc1SBen Gras #else
20551ffecc1SBen Gras 	int	 endy, endx, i, j, k, cw, pcw, tlcw, blcw, trcw, brcw;
20651ffecc1SBen Gras 	cchar_t left, right, bottom, top, topleft, topright, botleft, botright;
20751ffecc1SBen Gras 	nschar_t *np, *tnp;
20851ffecc1SBen Gras 
20951ffecc1SBen Gras 	if ( ls && wcwidth( ls->vals[ 0 ]))
21051ffecc1SBen Gras 		memcpy( &left, ls, sizeof( cchar_t ));
21151ffecc1SBen Gras 	else
21251ffecc1SBen Gras 		memcpy( &left, WACS_VLINE, sizeof( cchar_t ));
21351ffecc1SBen Gras 	if ( rs && wcwidth( rs->vals[ 0 ]))
21451ffecc1SBen Gras 		memcpy( &right, rs, sizeof( cchar_t ));
21551ffecc1SBen Gras 	else
21651ffecc1SBen Gras 		memcpy( &right, WACS_VLINE, sizeof( cchar_t ));
21751ffecc1SBen Gras 	if ( ts && wcwidth( ts->vals[ 0 ]))
21851ffecc1SBen Gras 		memcpy( &top, ts, sizeof( cchar_t ));
21951ffecc1SBen Gras 	else
22051ffecc1SBen Gras 		memcpy( &top, WACS_HLINE, sizeof( cchar_t ));
22151ffecc1SBen Gras 	if ( bs && wcwidth( bs->vals[ 0 ]))
22251ffecc1SBen Gras 		memcpy( &bottom, bs, sizeof( cchar_t ));
22351ffecc1SBen Gras 	else
22451ffecc1SBen Gras 		memcpy( &bottom, WACS_HLINE, sizeof( cchar_t ));
22551ffecc1SBen Gras 	if ( tl && wcwidth( tl->vals[ 0 ]))
22651ffecc1SBen Gras 		memcpy( &topleft, tl, sizeof( cchar_t ));
22751ffecc1SBen Gras 	else
22851ffecc1SBen Gras 		memcpy( &topleft, WACS_ULCORNER, sizeof( cchar_t ));
22951ffecc1SBen Gras 	if ( tr && wcwidth( tr->vals[ 0 ]))
23051ffecc1SBen Gras 		memcpy( &topright, tr, sizeof( cchar_t ));
23151ffecc1SBen Gras 	else
23251ffecc1SBen Gras 		memcpy( &topright, WACS_URCORNER, sizeof( cchar_t ));
23351ffecc1SBen Gras 	if ( bl && wcwidth( bl->vals[ 0 ]))
23451ffecc1SBen Gras 		memcpy( &botleft, bl, sizeof( cchar_t ));
23551ffecc1SBen Gras 	else
23651ffecc1SBen Gras 		memcpy( &botleft, WACS_LLCORNER, sizeof( cchar_t ));
23751ffecc1SBen Gras 	if ( br && wcwidth( br->vals[ 0 ]))
23851ffecc1SBen Gras 		memcpy( &botright, br, sizeof( cchar_t ));
23951ffecc1SBen Gras 	else
24051ffecc1SBen Gras 		memcpy( &botright, WACS_LRCORNER, sizeof( cchar_t ));
24151ffecc1SBen Gras 
24251ffecc1SBen Gras #ifdef DEBUG
24351ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder_set: left = %c, 0x%x\n",
24451ffecc1SBen Gras 	    left.vals[0], left.attributes );
24551ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder_set: right = %c, 0x%x\n",
24651ffecc1SBen Gras 	    right.vals[0], right.attributes );
24751ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder_set: top = %c, 0x%x\n",
24851ffecc1SBen Gras 	    top.vals[0], top.attributes );
24951ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder_set: bottom = %c, 0x%x\n",
25051ffecc1SBen Gras 	    bottom.vals[0], bottom.attributes );
25151ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder_set: topleft = %c, 0x%x\n",
25251ffecc1SBen Gras 	    topleft.vals[0], topleft.attributes );
25351ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder_set: topright = %c, 0x%x\n",
25451ffecc1SBen Gras 	    topright.vals[0], topright.attributes );
25551ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder_set: botleft = %c, 0x%x\n",
25651ffecc1SBen Gras 	    botleft.vals[0], botleft.attributes );
25751ffecc1SBen Gras 	__CTRACE(__CTRACE_INPUT, "wborder_set: botright = %c, 0x%x\n",
25851ffecc1SBen Gras 	    botright.vals[0], botright.attributes );
25951ffecc1SBen Gras #endif
26051ffecc1SBen Gras 
26151ffecc1SBen Gras 	/* Merge window attributes */
26251ffecc1SBen Gras 	left.attributes |= (left.attributes & __COLOR) ?
26351ffecc1SBen Gras 		(win->wattr & ~__COLOR) : win->wattr;
264*84d9c625SLionel Sambuc 	left.attributes |= (left.attributes & __COLOR) ?
265*84d9c625SLionel Sambuc 		(win->battr & ~__COLOR) : win->battr;
26651ffecc1SBen Gras 	right.attributes |= (right.attributes & __COLOR) ?
26751ffecc1SBen Gras 		(win->wattr & ~__COLOR) : win->wattr;
268*84d9c625SLionel Sambuc 	right.attributes |= (right.attributes & __COLOR) ?
269*84d9c625SLionel Sambuc 		(win->battr & ~__COLOR) : win->battr;
27051ffecc1SBen Gras 	top.attributes |= (top.attributes & __COLOR) ?
27151ffecc1SBen Gras 		(win->wattr & ~__COLOR) : win->wattr;
272*84d9c625SLionel Sambuc 	top.attributes |= (top.attributes & __COLOR) ?
273*84d9c625SLionel Sambuc 		(win->battr & ~__COLOR) : win->battr;
27451ffecc1SBen Gras 	bottom.attributes |= (bottom.attributes & __COLOR) ?
27551ffecc1SBen Gras 		(win->wattr & ~__COLOR) : win->wattr;
276*84d9c625SLionel Sambuc 	bottom.attributes |= (bottom.attributes & __COLOR) ?
277*84d9c625SLionel Sambuc 		(win->battr & ~__COLOR) : win->battr;
27851ffecc1SBen Gras 	topleft.attributes |= (topleft.attributes & __COLOR) ?
27951ffecc1SBen Gras 		(win->wattr & ~__COLOR) : win->wattr;
280*84d9c625SLionel Sambuc 	topleft.attributes |= (topleft.attributes & __COLOR) ?
281*84d9c625SLionel Sambuc 		(win->battr & ~__COLOR) : win->battr;
28251ffecc1SBen Gras 	topright.attributes |= (topright.attributes & __COLOR) ?
28351ffecc1SBen Gras 		(win->wattr & ~__COLOR) : win->wattr;
284*84d9c625SLionel Sambuc 	topright.attributes |= (topright.attributes & __COLOR) ?
285*84d9c625SLionel Sambuc 		(win->battr & ~__COLOR) : win->battr;
28651ffecc1SBen Gras 	botleft.attributes |= (botleft.attributes & __COLOR) ?
28751ffecc1SBen Gras 		(win->wattr & ~__COLOR) : win->wattr;
288*84d9c625SLionel Sambuc 	botleft.attributes |= (botleft.attributes & __COLOR) ?
289*84d9c625SLionel Sambuc 		(win->battr & ~__COLOR) : win->battr;
29051ffecc1SBen Gras 	botright.attributes |= (botright.attributes & __COLOR) ?
29151ffecc1SBen Gras 		(win->wattr & ~__COLOR) : win->wattr;
292*84d9c625SLionel Sambuc 	botright.attributes |= (botright.attributes & __COLOR) ?
293*84d9c625SLionel Sambuc 		(win->battr & ~__COLOR) : win->battr;
29451ffecc1SBen Gras 
29551ffecc1SBen Gras 	endx = win->maxx - 1;
29651ffecc1SBen Gras 	endy = win->maxy - 1;
29751ffecc1SBen Gras 
29851ffecc1SBen Gras 	/* Sides */
29951ffecc1SBen Gras 	for (i = 1; i < endy; i++) {
30051ffecc1SBen Gras 		/* left border */
30151ffecc1SBen Gras 		cw = wcwidth( left.vals[ 0 ]);
30251ffecc1SBen Gras 		if (cw < 0)
30351ffecc1SBen Gras 			cw = 1;
30451ffecc1SBen Gras 		for ( j = 0; j < cw; j++ ) {
30551ffecc1SBen Gras 			win->alines[i]->line[j].ch = left.vals[ 0 ];
30651ffecc1SBen Gras 			win->alines[i]->line[j].attr = left.attributes;
30751ffecc1SBen Gras 			np = win->alines[i]->line[j].nsp;
30851ffecc1SBen Gras 			if (np) {
30951ffecc1SBen Gras 				while ( np ) {
31051ffecc1SBen Gras 					tnp = np->next;
31151ffecc1SBen Gras 					free( np );
31251ffecc1SBen Gras 					np = tnp;
31351ffecc1SBen Gras 				}
31451ffecc1SBen Gras 				win->alines[i]->line[j].nsp = NULL;
31551ffecc1SBen Gras 			}
31651ffecc1SBen Gras 			if ( j )
31751ffecc1SBen Gras 				SET_WCOL( win->alines[i]->line[j], -j );
31851ffecc1SBen Gras 			else {
31951ffecc1SBen Gras 				SET_WCOL( win->alines[i]->line[j], cw );
32051ffecc1SBen Gras 				if ( left.elements > 1 ) {
32151ffecc1SBen Gras 					for (k = 1; k < left.elements; k++) {
32251ffecc1SBen Gras 						np = (nschar_t *)malloc(sizeof(nschar_t));
32351ffecc1SBen Gras 						if (!np)
32451ffecc1SBen Gras 							return ERR;
32551ffecc1SBen Gras 						np->ch = left.vals[ k ];
32651ffecc1SBen Gras 						np->next = win->alines[i]->line[j].nsp;
32751ffecc1SBen Gras 						win->alines[i]->line[j].nsp
32851ffecc1SBen Gras 							= np;
32951ffecc1SBen Gras 					}
33051ffecc1SBen Gras 				}
33151ffecc1SBen Gras 			}
33251ffecc1SBen Gras 		}
33351ffecc1SBen Gras 		for ( j = cw; WCOL( win->alines[i]->line[j]) < 0; j++ ) {
33451ffecc1SBen Gras #ifdef DEBUG
33551ffecc1SBen Gras 			__CTRACE(__CTRACE_INPUT,
33651ffecc1SBen Gras 			    "wborder_set: clean out partial char[%d]", j);
33751ffecc1SBen Gras #endif /* DEBUG */
33851ffecc1SBen Gras 			win->alines[i]->line[j].ch = ( wchar_t )btowc(win->bch);
33951ffecc1SBen Gras 			if (_cursesi_copy_nsp(win->bnsp,
34051ffecc1SBen Gras 					      &win->alines[i]->line[j]) == ERR)
34151ffecc1SBen Gras 				return ERR;
34251ffecc1SBen Gras 			SET_WCOL( win->alines[i]->line[j], 1 );
34351ffecc1SBen Gras 		}
34451ffecc1SBen Gras 		/* right border */
34551ffecc1SBen Gras 		cw = wcwidth( right.vals[ 0 ]);
34651ffecc1SBen Gras 		if (cw < 0)
34751ffecc1SBen Gras 			cw = 1;
34851ffecc1SBen Gras 		pcw = WCOL( win->alines[i]->line[endx - cw]);
34951ffecc1SBen Gras 		for ( j = endx - cw + 1; j <= endx; j++ ) {
35051ffecc1SBen Gras 			win->alines[i]->line[j].ch = right.vals[ 0 ];
35151ffecc1SBen Gras 			win->alines[i]->line[j].attr = right.attributes;
35251ffecc1SBen Gras 			np = win->alines[i]->line[j].nsp;
35351ffecc1SBen Gras 			if (np) {
35451ffecc1SBen Gras 				while ( np ) {
35551ffecc1SBen Gras 					tnp = np->next;
35651ffecc1SBen Gras 					free( np );
35751ffecc1SBen Gras 					np = tnp;
35851ffecc1SBen Gras 				}
35951ffecc1SBen Gras 				win->alines[i]->line[j].nsp = NULL;
36051ffecc1SBen Gras 			}
36151ffecc1SBen Gras 			if ( j == endx - cw + 1 ) {
36251ffecc1SBen Gras 				SET_WCOL( win->alines[i]->line[j], cw );
36351ffecc1SBen Gras 				if ( right.elements > 1 ) {
36451ffecc1SBen Gras 					for (k = 1; k < right.elements; k++) {
36551ffecc1SBen Gras 						np = (nschar_t *)malloc(sizeof(nschar_t));
36651ffecc1SBen Gras 						if (!np)
36751ffecc1SBen Gras 							return ERR;
36851ffecc1SBen Gras 						np->ch = right.vals[ k ];
36951ffecc1SBen Gras 						np->next = win->alines[i]->line[j].nsp;
37051ffecc1SBen Gras 						win->alines[i]->line[j].nsp
37151ffecc1SBen Gras 							= np;
37251ffecc1SBen Gras 					}
37351ffecc1SBen Gras 				}
37451ffecc1SBen Gras 			} else
37551ffecc1SBen Gras 				SET_WCOL( win->alines[i]->line[j],
37651ffecc1SBen Gras 					endx - cw + 1 - j );
37751ffecc1SBen Gras 		}
37851ffecc1SBen Gras 		if ( pcw != 1 ) {
37951ffecc1SBen Gras #ifdef DEBUG
38051ffecc1SBen Gras 			__CTRACE(__CTRACE_INPUT,
38151ffecc1SBen Gras 			    "wborder_set: clean out partial chars[%d:%d]",
38251ffecc1SBen Gras 			    endx - cw + pcw, endx - cw );
38351ffecc1SBen Gras #endif /* DEBUG */
38451ffecc1SBen Gras 			k = pcw < 0 ? endx -cw + pcw : endx - cw;
38551ffecc1SBen Gras 			for ( j = endx - cw; j >= k; j-- ) {
38651ffecc1SBen Gras 				win->alines[i]->line[j].ch
38751ffecc1SBen Gras 					= (wchar_t)btowc(win->bch);
38851ffecc1SBen Gras 				if (_cursesi_copy_nsp(win->bnsp,
38951ffecc1SBen Gras 					       &win->alines[i]->line[j]) == ERR)
39051ffecc1SBen Gras 					return ERR;
39151ffecc1SBen Gras 				win->alines[i]->line[j].attr = win->battr;
39251ffecc1SBen Gras 				SET_WCOL( win->alines[i]->line[j], 1 );
39351ffecc1SBen Gras 			}
39451ffecc1SBen Gras 		}
39551ffecc1SBen Gras 	}
39651ffecc1SBen Gras 	tlcw = wcwidth( topleft.vals[ 0 ]);
39751ffecc1SBen Gras 	if (tlcw < 0)
39851ffecc1SBen Gras 		tlcw = 1;
39951ffecc1SBen Gras 	blcw = wcwidth( botleft.vals[ 0 ]);
40051ffecc1SBen Gras 	if (blcw < 0)
40151ffecc1SBen Gras 		blcw = 1;
40251ffecc1SBen Gras 	trcw = wcwidth( topright.vals[ 0 ]);
40351ffecc1SBen Gras 	if (trcw < 0)
40451ffecc1SBen Gras 		trcw = 1;
40551ffecc1SBen Gras 	brcw = wcwidth( botright.vals[ 0 ]);
40651ffecc1SBen Gras 	if (brcw < 0)
40751ffecc1SBen Gras 		brcw = 1;
40851ffecc1SBen Gras 	/* upper border */
40951ffecc1SBen Gras 	cw = wcwidth( top.vals[ 0 ]);
41051ffecc1SBen Gras 	if (cw < 0)
41151ffecc1SBen Gras 		cw = 1;
41251ffecc1SBen Gras 	for (i = tlcw; i <= min( endx - cw, endx - trcw ); i += cw ) {
41351ffecc1SBen Gras 		for ( j = 0; j < cw; j++ ) {
41451ffecc1SBen Gras 			win->alines[ 0 ]->line[i + j].ch = top.vals[ 0 ];
41551ffecc1SBen Gras 			win->alines[ 0 ]->line[i + j].attr = top.attributes;
41651ffecc1SBen Gras 			np = win->alines[ 0 ]->line[i + j].nsp;
41751ffecc1SBen Gras 			if (np) {
41851ffecc1SBen Gras 				while ( np ) {
41951ffecc1SBen Gras 					tnp = np->next;
42051ffecc1SBen Gras 					free( np );
42151ffecc1SBen Gras 					np = tnp;
42251ffecc1SBen Gras 				}
42351ffecc1SBen Gras 				win->alines[ 0 ]->line[i + j].nsp = NULL;
42451ffecc1SBen Gras 			}
42551ffecc1SBen Gras 			if ( j )
42651ffecc1SBen Gras 				SET_WCOL( win->alines[ 0 ]->line[ i + j ], -j );
42751ffecc1SBen Gras 			else {
42851ffecc1SBen Gras 				SET_WCOL( win->alines[ 0 ]->line[ i + j ], cw );
42951ffecc1SBen Gras 				if ( top.elements > 1 ) {
43051ffecc1SBen Gras 					for ( k = 1; k < top.elements; k++ ) {
43151ffecc1SBen Gras 						np = (nschar_t *)malloc(sizeof(nschar_t));
43251ffecc1SBen Gras 						if (!np)
43351ffecc1SBen Gras 							return ERR;
43451ffecc1SBen Gras 						np->ch = top.vals[ k ];
43551ffecc1SBen Gras 						np->next = win->alines[0]->line[i + j].nsp;
43651ffecc1SBen Gras 						win->alines[0]->line[i + j].nsp
43751ffecc1SBen Gras 							= np;
43851ffecc1SBen Gras 					}
43951ffecc1SBen Gras 				}
44051ffecc1SBen Gras 			}
44151ffecc1SBen Gras 		}
44251ffecc1SBen Gras 	}
44351ffecc1SBen Gras 	while ( i <= endx - trcw ) {
44451ffecc1SBen Gras 		win->alines[0]->line[i].ch =
44551ffecc1SBen Gras 			( wchar_t )btowc(( int ) win->bch );
44651ffecc1SBen Gras 		if (_cursesi_copy_nsp(win->bnsp,
44751ffecc1SBen Gras 				      &win->alines[0]->line[i]) == ERR)
44851ffecc1SBen Gras 			return ERR;
44951ffecc1SBen Gras 		win->alines[ 0 ]->line[ i ].attr = win->battr;
45051ffecc1SBen Gras 		SET_WCOL( win->alines[ 0 ]->line[ i ], 1 );
45151ffecc1SBen Gras 		i++;
45251ffecc1SBen Gras 	}
45351ffecc1SBen Gras 	/* lower border */
45451ffecc1SBen Gras 	for (i = blcw; i <= min( endx - cw, endx - brcw ); i += cw ) {
45551ffecc1SBen Gras 		for ( j = 0; j < cw; j++ ) {
45651ffecc1SBen Gras 			win->alines[ endy ]->line[i + j].ch = bottom.vals[ 0 ];
45751ffecc1SBen Gras 			win->alines[endy]->line[i + j].attr = bottom.attributes;
45851ffecc1SBen Gras 			np = win->alines[ endy ]->line[i + j].nsp;
45951ffecc1SBen Gras 			if (np) {
46051ffecc1SBen Gras 				while ( np ) {
46151ffecc1SBen Gras 					tnp = np->next;
46251ffecc1SBen Gras 					free( np );
46351ffecc1SBen Gras 					np = tnp;
46451ffecc1SBen Gras 				}
46551ffecc1SBen Gras 				win->alines[ endy ]->line[i + j].nsp = NULL;
46651ffecc1SBen Gras 			}
46751ffecc1SBen Gras 			if ( j )
46851ffecc1SBen Gras 				SET_WCOL( win->alines[endy]->line[i + j], -j);
46951ffecc1SBen Gras 			else {
47051ffecc1SBen Gras 				SET_WCOL( win->alines[endy]->line[i + j], cw );
47151ffecc1SBen Gras 				if ( bottom.elements > 1 ) {
47251ffecc1SBen Gras 					for ( k = 1; k < bottom.elements;
47351ffecc1SBen Gras 							k++ ) {
47451ffecc1SBen Gras 						if ( !( np = ( nschar_t *)malloc( sizeof( nschar_t ))))
47551ffecc1SBen Gras 							return ERR;
47651ffecc1SBen Gras 						np->ch = bottom.vals[ k ];
47751ffecc1SBen Gras 						np->next = win->alines[endy]->line[i + j].nsp;
47851ffecc1SBen Gras 						win->alines[endy]->line[i + j].nsp = np;
47951ffecc1SBen Gras 					}
48051ffecc1SBen Gras 				}
48151ffecc1SBen Gras 			}
48251ffecc1SBen Gras 		}
48351ffecc1SBen Gras 	}
48451ffecc1SBen Gras 	while ( i <= endx - brcw ) {
48551ffecc1SBen Gras 		win->alines[endy]->line[i].ch =
48651ffecc1SBen Gras 			(wchar_t)btowc((int) win->bch );
48751ffecc1SBen Gras 		if (_cursesi_copy_nsp(win->bnsp,
48851ffecc1SBen Gras 				      &win->alines[endy]->line[i]) == ERR)
48951ffecc1SBen Gras 			return ERR;
49051ffecc1SBen Gras 		win->alines[ endy ]->line[ i ].attr = win->battr;
49151ffecc1SBen Gras 		SET_WCOL( win->alines[ endy ]->line[ i ], 1 );
49251ffecc1SBen Gras 		i++;
49351ffecc1SBen Gras 	}
49451ffecc1SBen Gras 
49551ffecc1SBen Gras 	/* Corners */
49651ffecc1SBen Gras 	if (!(win->maxx == LINES && win->maxy == COLS &&
49751ffecc1SBen Gras 		(win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) {
49851ffecc1SBen Gras 		for ( i = 0; i < tlcw; i++ ) {
49951ffecc1SBen Gras 			win->alines[ 0 ]->line[i].ch = topleft.vals[ 0 ];
50051ffecc1SBen Gras 			win->alines[ 0 ]->line[i].attr = topleft.attributes;
50151ffecc1SBen Gras 			np = win->alines[ 0 ]->line[i].nsp;
50251ffecc1SBen Gras 			if (np) {
50351ffecc1SBen Gras 				while ( np ) {
50451ffecc1SBen Gras 					tnp = np->next;
50551ffecc1SBen Gras 					free( np );
50651ffecc1SBen Gras 					np = tnp;
50751ffecc1SBen Gras 				}
50851ffecc1SBen Gras 				win->alines[ 0 ]->line[i].nsp = NULL;
50951ffecc1SBen Gras 			}
51051ffecc1SBen Gras 			if ( i )
51151ffecc1SBen Gras 				SET_WCOL( win->alines[ 0 ]->line[ i ], -i );
51251ffecc1SBen Gras 			else {
51351ffecc1SBen Gras 				SET_WCOL( win->alines[ 0 ]->line[ i ], tlcw );
51451ffecc1SBen Gras 				if ( topleft.elements > 1 ) {
51551ffecc1SBen Gras 					for ( k = 1; k < topleft.elements;
51651ffecc1SBen Gras 							k++ ) {
51751ffecc1SBen Gras 						np = (nschar_t *)malloc(sizeof(nschar_t));
51851ffecc1SBen Gras 						if (!np)
51951ffecc1SBen Gras 							return ERR;
52051ffecc1SBen Gras 						np->ch = topleft.vals[ k ];
52151ffecc1SBen Gras 						np->next = win->alines[ 0 ]->line[i].nsp;
52251ffecc1SBen Gras 						win->alines[ 0 ]->line[i].nsp
52351ffecc1SBen Gras 							= np;
52451ffecc1SBen Gras 					}
52551ffecc1SBen Gras 				}
52651ffecc1SBen Gras 			}
52751ffecc1SBen Gras 		}
52851ffecc1SBen Gras 		for ( i = endx - trcw + 1; i <= endx; i++ ) {
52951ffecc1SBen Gras 			win->alines[ 0 ]->line[i].ch = topright.vals[ 0 ];
53051ffecc1SBen Gras 			win->alines[ 0 ]->line[i].attr = topright.attributes;
53151ffecc1SBen Gras 			np = win->alines[ 0 ]->line[i].nsp;
53251ffecc1SBen Gras 			if (np) {
53351ffecc1SBen Gras 				while ( np ) {
53451ffecc1SBen Gras 					tnp = np->next;
53551ffecc1SBen Gras 					free( np );
53651ffecc1SBen Gras 					np = tnp;
53751ffecc1SBen Gras 				}
53851ffecc1SBen Gras 				win->alines[ 0 ]->line[i].nsp = NULL;
53951ffecc1SBen Gras 			}
54051ffecc1SBen Gras 			if ( i == endx - trcw + 1 ) {
54151ffecc1SBen Gras 				SET_WCOL( win->alines[ 0 ]->line[ i ], trcw );
54251ffecc1SBen Gras 				if ( topright.elements > 1 ) {
54351ffecc1SBen Gras 					for ( k = 1; k < topright.elements;
54451ffecc1SBen Gras 							k++ ) {
54551ffecc1SBen Gras 						np = (nschar_t *)malloc(sizeof(nschar_t));
54651ffecc1SBen Gras 						if (!np)
54751ffecc1SBen Gras 							return ERR;
54851ffecc1SBen Gras 						np->ch = topright.vals[ k ];
54951ffecc1SBen Gras 						np->next = win->alines[0]->line[i].nsp;
55051ffecc1SBen Gras 						win->alines[ 0 ]->line[i].nsp
55151ffecc1SBen Gras 							= np;
55251ffecc1SBen Gras 					}
55351ffecc1SBen Gras 				}
55451ffecc1SBen Gras 			} else
55551ffecc1SBen Gras 				SET_WCOL( win->alines[ 0 ]->line[ i ],
55651ffecc1SBen Gras 					  endx - trcw + 1 - i );
55751ffecc1SBen Gras 		}
55851ffecc1SBen Gras 		for ( i = 0; i < blcw; i++ ) {
55951ffecc1SBen Gras 			win->alines[ endy ]->line[i].ch = botleft.vals[ 0 ];
56051ffecc1SBen Gras 			win->alines[ endy ]->line[i].attr = botleft.attributes;
56151ffecc1SBen Gras 			np = win->alines[ endy ]->line[i].nsp;
56251ffecc1SBen Gras 			if (np) {
56351ffecc1SBen Gras 				while ( np ) {
56451ffecc1SBen Gras 					tnp = np->next;
56551ffecc1SBen Gras 					free( np );
56651ffecc1SBen Gras 					np = tnp;
56751ffecc1SBen Gras 				}
56851ffecc1SBen Gras 				win->alines[ endy ]->line[i].nsp = NULL;
56951ffecc1SBen Gras 			}
57051ffecc1SBen Gras 			if ( i )
57151ffecc1SBen Gras 				SET_WCOL( win->alines[endy]->line[i], -i );
57251ffecc1SBen Gras 			else {
57351ffecc1SBen Gras 				SET_WCOL( win->alines[endy]->line[i], blcw );
57451ffecc1SBen Gras 				if ( botleft.elements > 1 ) {
57551ffecc1SBen Gras 					for ( k = 1; k < botleft.elements;
57651ffecc1SBen Gras 							k++ ) {
57751ffecc1SBen Gras 						np = (nschar_t *)malloc(sizeof(nschar_t));
57851ffecc1SBen Gras 						if (!np)
57951ffecc1SBen Gras 							return ERR;
58051ffecc1SBen Gras 						np->ch = botleft.vals[ k ];
58151ffecc1SBen Gras 						np->next = win->alines[endy]->line[i].nsp;
58251ffecc1SBen Gras 						win->alines[endy]->line[i].nsp
58351ffecc1SBen Gras 							= np;
58451ffecc1SBen Gras 					}
58551ffecc1SBen Gras 				}
58651ffecc1SBen Gras 			}
58751ffecc1SBen Gras 		}
58851ffecc1SBen Gras 		for ( i = endx - brcw + 1; i <= endx; i++ ) {
58951ffecc1SBen Gras 			win->alines[ endy ]->line[i].ch = botright.vals[ 0 ];
59051ffecc1SBen Gras 			win->alines[ endy ]->line[i].attr = botright.attributes;
59151ffecc1SBen Gras 			np = win->alines[ endy ]->line[i].nsp;
59251ffecc1SBen Gras 			if (np) {
59351ffecc1SBen Gras 				while ( np ) {
59451ffecc1SBen Gras 					tnp = np->next;
59551ffecc1SBen Gras 					free( np );
59651ffecc1SBen Gras 					np = tnp;
59751ffecc1SBen Gras 				}
59851ffecc1SBen Gras 				win->alines[ endy ]->line[i].nsp = NULL;
59951ffecc1SBen Gras 			}
60051ffecc1SBen Gras 			if ( i == endx - brcw + 1 ) {
60151ffecc1SBen Gras 				SET_WCOL( win->alines[ endy ]->line[ i ],
60251ffecc1SBen Gras 					  brcw );
60351ffecc1SBen Gras 				if ( botright.elements > 1 ) {
60451ffecc1SBen Gras 					for ( k = 1; k < botright.elements; k++ ) {
60551ffecc1SBen Gras 						np = (nschar_t *)malloc(sizeof(nschar_t));
60651ffecc1SBen Gras 						if (!np)
60751ffecc1SBen Gras 							return ERR;
60851ffecc1SBen Gras 						np->ch = botright.vals[ k ];
60951ffecc1SBen Gras 						np->next = win->alines[endy]->line[i].nsp;
61051ffecc1SBen Gras 						win->alines[endy]->line[i].nsp
61151ffecc1SBen Gras 							= np;
61251ffecc1SBen Gras 					}
61351ffecc1SBen Gras 				}
61451ffecc1SBen Gras 			} else
61551ffecc1SBen Gras 				SET_WCOL( win->alines[ endy ]->line[ i ],
61651ffecc1SBen Gras 					endx - brcw + 1 - i );
61751ffecc1SBen Gras 		}
61851ffecc1SBen Gras 	}
61951ffecc1SBen Gras 	__touchwin(win);
62051ffecc1SBen Gras 	return (OK);
62151ffecc1SBen Gras #endif /* HAVE_WCHAR */
62251ffecc1SBen Gras }
623